{"version":3,"file":"index.mjs","names":["PHASE_ORDER"],"sources":["../src/RateLimiter.ts","../src/Logger/LogFormatter.ts","../src/Logger/Transports/SinkTransport.ts","../src/Logger/TransportFactory.ts","../src/Logger/LoggerChannelRegistry.ts","../src/Logger/LoggerUtilities.ts","../src/Logger/Logger.ts","../src/StrictEventEmitter.ts","../src/Lifecycle/CoordinatedLifecycle.ts","../src/Lifecycle/CoordinatedShutdown.ts","../src/HealthCheck.ts","../src/Lifecycle/CoordinatedStartup.ts","../src/index.ts"],"sourcesContent":["import type { EpochMs } from '@seedcord/types';\n\nconst SWEEP_INTERVAL_MS = 60_000;\n\n/**\n * A usage window for a {@link RateLimiter} key.\n */\nexport interface RateLimitWindow {\n    /** Window length in milliseconds. */\n    delay: number;\n    /**\n     * Hits allowed inside the window before the key is limited.\n     *\n     * @defaultValue `1`\n     */\n    limit?: number;\n}\n\n/**\n * The outcome of a {@link RateLimiter.hit}.\n */\nexport interface RateLimitResult {\n    /** Whether the key is at or over its limit for the current window. */\n    limited: boolean;\n    /** Absolute epoch milliseconds when the key next frees up. Convert to seconds for Discord timestamp markup. */\n    expires: EpochMs;\n}\n\n/**\n * Tracks per-key usage windows and reports when a key is limited and when it frees up.\n *\n * Each key holds a sliding window of hit expiry times, and is limited once its live-hit count\n * reaches the window's `limit`. Expired hits are dropped on the next read, and a background sweep\n * drops fully-expired keys so the map does not grow without bound.\n */\nexport class RateLimiter {\n    private readonly map = new Map<string, number[]>();\n\n    constructor() {\n        // keep the sweep from holding the process open\n        setInterval(() => {\n            this.sweep();\n        }, SWEEP_INTERVAL_MS).unref();\n    }\n\n    /** Number of keys currently tracked. */\n    get size(): number {\n        return this.map.size;\n    }\n\n    /**\n     * Records a hit for `key` and reports whether the key is now limited.\n     *\n     * @param key - The bucket to record against. The caller builds it from its own scope.\n     * @param window - The usage window to apply for this hit.\n     */\n    hit(key: string, window: RateLimitWindow): RateLimitResult {\n        const now = Date.now();\n        // a window must allow at least one hit, so 0 or a negative never means \"block everything\"\n        const limit = Math.max(1, window.limit ?? 1);\n\n        const live = this.live(key, now);\n\n        if (live.length >= limit) {\n            this.map.set(key, live);\n            // soonest a slot frees is the earliest expiry\n            return { limited: true, expires: Math.min(...live) as EpochMs };\n        }\n\n        const expires: EpochMs = (now + window.delay) as EpochMs;\n        live.push(expires);\n        this.map.set(key, live);\n\n        return { limited: false, expires };\n    }\n\n    /**\n     * Reports whether `key` is limited right now without recording a hit.\n     *\n     * The read half of a peek-then-commit. A gate calls `peek` to decide whether to refuse, and\n     * `hit` to charge the slot only once it is the gate that let the request through.\n     */\n    peek(key: string, window: RateLimitWindow): RateLimitResult {\n        const now = Date.now();\n        const limit = Math.max(1, window.limit ?? 1);\n        // a read, so it never writes the filtered hits back, hit owns the only mutation\n        const live = this.live(key, now);\n\n        if (live.length >= limit) return { limited: true, expires: Math.min(...live) as EpochMs };\n        return { limited: false, expires: (now + window.delay) as EpochMs };\n    }\n\n    private live(key: string, now: number): number[] {\n        return (this.map.get(key) ?? []).filter((exp) => exp > now);\n    }\n\n    private sweep(): void {\n        const now = Date.now();\n        for (const [key, live] of this.map) {\n            const kept = live.filter((exp) => exp > now);\n            if (kept.length === 0) this.map.delete(key);\n            else this.map.set(key, kept);\n        }\n    }\n}\n","import stripAnsi from 'strip-ansi';\nimport { format } from 'winston';\n\nimport type { Logform } from 'winston';\n\n/** An Error temporarily annotated with its ANSI-formatted name while pretty-printing stacks. */\ntype FormattedError = Error & { __formattedName?: string; __plainName?: string };\n\n/**\n * Options for pretty log formatting.\n */\nexport interface PrettyFormatOptions {\n    /**\n     * Number of spaces to pad the log level to.\n     *\n     * @defaultValue `7`\n     */\n    padding?: number;\n    /**\n     * Whether to strip ANSI codes from extra log data.\n     *\n     * @defaultValue `false`\n     */\n    stripExtras?: boolean;\n}\n\n/**\n * Options for JSON log formatting.\n * @internal\n */\nexport interface JsonFormatOptions {\n    /**\n     * Whether to strip ANSI codes from log messages and extra data.\n     *\n     * @defaultValue `false`\n     */\n    stripAnsi?: boolean;\n    /**\n     * Whether to produce minimal JSON output without extra fields.\n     *\n     * @defaultValue `false`\n     */\n    minimal?: boolean;\n}\n\n/**\n * Formats log records for console and file outputs.\n *\n * Supports pretty-printed colored logs for development\n * and JSON logs for production with optional ANSI stripping.\n * @internal\n */\nexport class LogFormatter {\n    private readonly DEFAULT_PADDING = 7;\n    private readonly SPLAT: symbol = Symbol.for('splat');\n\n    private safeString(value: unknown): string {\n        if (typeof value === 'string') return value;\n        if (value === undefined || value === null) return '';\n        if (typeof (value as { toString?: () => string }).toString === 'function') {\n            return String((value as { toString: () => string }).toString());\n        }\n        if (typeof value === 'object') {\n            try {\n                return JSON.stringify(value);\n            } catch {\n                return '';\n            }\n        }\n        return '';\n    }\n\n    private sanitizeAnsi(value: unknown): unknown {\n        if (typeof value === 'string') return stripAnsi(value);\n        if (value instanceof Error) {\n            const error = value;\n            const sanitized = new Error(stripAnsi(error.message));\n            sanitized.name = error.name;\n            if (typeof error.stack === 'string') sanitized.stack = stripAnsi(error.stack);\n            return sanitized;\n        }\n        return value;\n    }\n\n    private getExtras(info: Logform.TransformableInfo): unknown[] {\n        const raw = info[this.SPLAT];\n        return Array.isArray(raw) ? raw : [];\n    }\n\n    private readonly FORMAT_SPECIFIERS = /%[sdifjoO]/gu;\n    private readonly HAD_FORMAT_KEY = Symbol.for('hadFormatSpecifiers');\n    private readonly SAVED_SPLAT_KEY = Symbol.for('savedSplat');\n\n    private markFormatSpecifiers(): Logform.Format {\n        return format((info) => {\n            const msg = typeof info.message === 'string' ? info.message : '';\n            const extras = this.getExtras(info);\n            const matches = msg.match(this.FORMAT_SPECIFIERS);\n            const formatCount = matches ? matches.length : 0;\n            info[this.HAD_FORMAT_KEY] = formatCount;\n            info[this.SAVED_SPLAT_KEY] = [...extras];\n            return info;\n        })();\n    }\n\n    public createPreFormat(): Logform.Format {\n        return this.markFormatSpecifiers();\n    }\n\n    private preserveErrorFormatting(): Logform.Format {\n        return format((info) => {\n            const extras = this.getExtras(info);\n\n            for (const item of extras) {\n                if (item instanceof Error && /\\u001b/.test(item.name)) {\n                    const originalName = item.name;\n                    const plainName = stripAnsi(item.name);\n\n                    const formatted = item as FormattedError;\n                    formatted.__formattedName = originalName;\n                    formatted.__plainName = plainName;\n                }\n            }\n\n            return info;\n        })();\n    }\n\n    private restoreErrorFormatting(): Logform.Format {\n        return format((info) => {\n            if (typeof info.stack === 'string') {\n                const extras = this.getExtras(info);\n\n                for (const item of extras) {\n                    if (item instanceof Error) {\n                        const { __formattedName: formattedName, __plainName: plainName } = item as FormattedError;\n\n                        if (typeof formattedName === 'string' && typeof plainName === 'string') {\n                            info.stack = (info.stack as string).replace(\n                                new RegExp(`^${this.escapeRegex(plainName)}`, 'm'),\n                                formattedName\n                            );\n                        }\n                    }\n                }\n            }\n\n            return info;\n        })();\n    }\n\n    private escapeRegex(str: string): string {\n        return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n    }\n\n    /**\n     * Creates pretty-printed format with colors and timestamps.\n     *\n     * Ideal for development environments where human readability matters.\n     *\n     * @param options - Formatting options including padding and ANSI stripping\n     * @returns Array of Winston format transformers\n     */\n    public pretty(options: PrettyFormatOptions = {}): Logform.Format[] {\n        const padding = options.padding ?? this.DEFAULT_PADDING;\n        return [\n            this.preserveErrorFormatting(),\n            format.errors({ stack: true }),\n            this.restoreErrorFormatting(),\n            format.splat(),\n            format.colorize({ level: true }),\n            format.timestamp({ format: 'D MMM, hh:mm:ss a' }),\n            // eslint-disable-next-line max-statements\n            format.printf((info: Logform.TransformableInfo) => {\n                let ts = this.safeString(info.timestamp);\n                let lvl = this.safeString(info.level).padEnd(padding);\n                let lbl = this.safeString(info.label);\n                let msg = this.safeString(info.message);\n\n                if (options.stripExtras) {\n                    ts = stripAnsi(ts);\n                    lvl = stripAnsi(lvl);\n                    lbl = stripAnsi(lbl);\n                    msg = stripAnsi(msg);\n                }\n\n                const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;\n                const savedExtras = info[this.SAVED_SPLAT_KEY];\n                // Array.isArray narrows to any[]; keep the elements as unknown so the filter below stays safe.\n                const extras: unknown[] = Array.isArray(savedExtras) ? savedExtras : this.getExtras(info);\n\n                let rendered = base;\n\n                if (typeof info.stack === 'string') {\n                    let stack = this.safeString(info.stack);\n                    if (options.stripExtras) stack = stripAnsi(stack);\n                    rendered += `\\n${stack}`;\n                }\n\n                const cleaned = options.stripExtras ? extras.map((entry) => this.sanitizeAnsi(entry)) : extras;\n                const rawFormatCount = info[this.HAD_FORMAT_KEY];\n                const formatSpecifierCount = typeof rawFormatCount === 'number' ? rawFormatCount : 0;\n                const filtered = cleaned.filter((x, index) => {\n                    if (x === null || x === undefined) return false;\n                    if (x instanceof Error && typeof info.stack === 'string') return false;\n                    if (typeof x !== 'object') {\n                        return index >= formatSpecifierCount;\n                    }\n                    return Object.keys(x).length > 0;\n                });\n\n                if (filtered.length) {\n                    const primitives: string[] = [];\n                    const objects: string[] = [];\n\n                    for (const x of filtered) {\n                        if (typeof x === 'string' || typeof x === 'number' || typeof x === 'boolean') {\n                            primitives.push(String(x));\n                        } else {\n                            try {\n                                objects.push(JSON.stringify(x, null, 2));\n                            } catch {\n                                objects.push(String(x));\n                            }\n                        }\n                    }\n\n                    if (primitives.length) {\n                        rendered += ` ${primitives.join(' ')}`;\n                    }\n                    if (objects.length) {\n                        rendered += `\\n${objects.join('\\n')}`;\n                    }\n                }\n\n                return rendered;\n            })\n        ];\n    }\n\n    /**\n     * Creates JSON format for structured logging.\n     *\n     * Best for production environments where logs are parsed by tools.\n     *\n     * @param options - JSON formatting options including ANSI stripping and minimal mode\n     * @returns Array of Winston format transformers\n     */\n    public json(options: JsonFormatOptions = {}): Logform.Format[] {\n        const base = [format.timestamp(), format.errors({ stack: true })];\n\n        if (options.stripAnsi) {\n            base.push(\n                format((info) => {\n                    info.message = typeof info.message === 'string' ? stripAnsi(info.message) : info.message;\n                    if (typeof info.stack === 'string') info.stack = stripAnsi(info.stack);\n                    const extras = this.getExtras(info);\n                    if (extras.length) info.extras = extras.map((entry) => this.sanitizeAnsi(entry));\n                    return info;\n                })()\n            );\n        }\n\n        base.push(options.minimal ? format.json({}) : format.json({ bigint: true, space: 0 }));\n\n        return base;\n    }\n}\n","import TransportStream from 'winston-transport';\n\nimport type { Logform } from 'winston';\nimport type { TransportStreamOptions } from 'winston-transport';\n\n/**\n * Options for creating a SinkTransport.\n * @internal\n */\nexport interface SinkTransportOptions extends TransportStreamOptions {\n    readonly channel: string;\n    readonly sink: ILoggerSink;\n}\n\n/**\n * A log entry passed to custom sinks.\n */\nexport interface LoggerSinkLogEntry {\n    /** Channel the log originated from */\n    readonly channel: string;\n    /** Pre-formatted log message ready for display */\n    readonly rendered: string;\n    /** Raw Winston log info object */\n    readonly info: Logform.TransformableInfo;\n}\n\n/**\n * Custom sink interface for capturing logger output.\n *\n * Implement this to route logs to custom destinations.\n */\nexport interface ILoggerSink {\n    /**\n     * Called when a log entry is emitted.\n     *\n     * @param entry - The log entry with channel, rendered message, and raw info\n     */\n    onLog(entry: LoggerSinkLogEntry): void;\n}\n\n/**\n * Handle for managing a sink's lifecycle.\n */\nexport interface ILoggerSinkHandle {\n    /**\n     * Removes the sink and restores console output if muted.\n     */\n    dispose(): void;\n}\n\n/**\n * Winston transport that forwards logs to custom sinks.\n * @internal\n */\nexport class SinkTransport extends TransportStream {\n    private readonly channelName: string;\n    private readonly sink: ILoggerSink;\n\n    public constructor(options: SinkTransportOptions) {\n        super(options);\n        this.channelName = options.channel;\n        this.sink = options.sink;\n    }\n\n    public override log(info: Logform.TransformableInfo, callback: () => void): void {\n        setImmediate(() => this.emit('logged', info));\n\n        const rendered = this.resolveRendered(info);\n        const channel = this.resolveChannel(info);\n\n        this.sink.onLog({ channel, rendered, info });\n\n        callback();\n    }\n\n    private resolveChannel(info: Logform.TransformableInfo): string {\n        const channel = info.channel;\n        return typeof channel === 'string' ? channel : this.channelName;\n    }\n\n    private resolveRendered(info: Logform.TransformableInfo): string {\n        const msg = info[Symbol.for('message')];\n\n        if (typeof msg === 'string') return msg;\n\n        const fallback = info.message;\n        if (typeof fallback === 'string') return fallback;\n\n        if (fallback instanceof Error) return fallback.stack ?? fallback.message;\n\n        // eslint-disable-next-line @typescript-eslint/no-base-to-string -- last-resort stringify for a non-string, non-Error message value\n        return String(fallback ?? '');\n    }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { Envapter } from 'envapt';\nimport { format, transports } from 'winston';\n\nimport { LogFormatter } from './LogFormatter';\nimport { SinkTransport } from './Transports/SinkTransport';\n\nimport type { ILoggerSink } from './Transports/SinkTransport';\nimport type { LoggerFormatMode, LoggerLevel, TransportConfig, WinstonTransport } from './Types';\n\n/**\n * Input parameters for building a Winston transport.\n * @internal\n */\nexport interface TransportBuildInput {\n    channel: string;\n    label: string;\n    level: LoggerLevel;\n    config: TransportConfig;\n    defaultFormat: LoggerFormatMode;\n    stripAnsi: boolean;\n}\n\n/**\n * Input parameters for building a sink transport.\n * @internal\n */\ninterface BuildInput {\n    readonly channel: string;\n    readonly label: string;\n    readonly level: LoggerLevel;\n}\n\n/**\n * Creates Winston transports with proper formatting and file path resolution.\n *\n * Builds console and file transports with environment-aware defaults,\n * filename template expansion, and format selection.\n * @internal\n */\nexport class TransportFactory {\n    private readonly formatter: LogFormatter;\n    private readonly MILLISECOND_PAD = 3;\n    private cachedSessionTimestamp: { date: string; timestamp: string } | null = null;\n\n    constructor() {\n        this.formatter = new LogFormatter();\n    }\n\n    private ensureDir(filepath: string): void {\n        const dir = path.dirname(filepath);\n        if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n    }\n\n    private withDefaultLabel(label: string): ReturnType<typeof format.combine> {\n        return format.combine(\n            format((info) => {\n                info.label ??= label;\n                return info;\n            })()\n        );\n    }\n\n    public buildPreFormat(): ReturnType<typeof format.combine> {\n        return format.combine(this.formatter.createPreFormat());\n    }\n\n    private buildConsoleFormat(label: string): ReturnType<typeof format.combine> {\n        // Use JSON format in production, pretty format in development\n        if (Envapter.isProduction) {\n            return format.combine(this.withDefaultLabel(label), ...this.formatter.json({ stripAnsi: true }));\n        }\n        return format.combine(this.withDefaultLabel(label), ...this.formatter.pretty());\n    }\n\n    private buildFileFormat(\n        label: string,\n        mode: LoggerFormatMode,\n        stripAnsi: boolean\n    ): ReturnType<typeof format.combine> {\n        const formats =\n            mode === 'pretty' ? this.formatter.pretty({ stripExtras: stripAnsi }) : this.formatter.json({ stripAnsi });\n        return format.combine(this.withDefaultLabel(label), ...formats);\n    }\n\n    private buildStreamFormat(\n        label: string,\n        mode: LoggerFormatMode,\n        stripAnsi: boolean\n    ): ReturnType<typeof format.combine> {\n        // Stream transport uses similar formatting to file transport\n        const formats =\n            mode === 'pretty' ? this.formatter.pretty({ stripExtras: stripAnsi }) : this.formatter.json({ stripAnsi });\n        return format.combine(this.withDefaultLabel(label), ...formats);\n    }\n\n    private pad(value: number): string {\n        return value.toString().padStart(2, '0');\n    }\n\n    private buildTimestamp(): { date: string; timestamp: string } {\n        if (this.cachedSessionTimestamp) {\n            return this.cachedSessionTimestamp;\n        }\n\n        const now = new Date();\n        const yyyy = now.getFullYear();\n        const mm = this.pad(now.getMonth() + 1);\n        const dd = this.pad(now.getDate());\n        const hh = this.pad(now.getHours());\n        const min = this.pad(now.getMinutes());\n        const ss = this.pad(now.getSeconds());\n        const ms = now.getMilliseconds().toString().padStart(this.MILLISECOND_PAD, '0');\n\n        const date = `${yyyy}-${mm}-${dd}`;\n        const timestamp = `${date}-${hh}${min}${ss}-${ms}`;\n\n        this.cachedSessionTimestamp = { date, timestamp };\n        return this.cachedSessionTimestamp;\n    }\n\n    private resolveFilename(template: string, channel: string): string {\n        const { date, timestamp } = this.buildTimestamp();\n        return template\n            .replaceAll('{channel}', channel)\n            .replaceAll('{date}', date)\n            .replaceAll('{timestamp}', timestamp);\n    }\n\n    /**\n     * Builds a Winston transport from configuration.\n     *\n     * Creates console, file, or stream transport with proper formatting,\n     * level filtering, and file rotation settings.\n     *\n     * @param input - Transport configuration parameters\n     * @returns Configured Winston transport instance\n     */\n    public build(input: TransportBuildInput): WinstonTransport {\n        const effectiveFormat = input.config.format ?? input.defaultFormat;\n        const shouldStripAnsi = input.config.stripAnsi ?? input.stripAnsi;\n        const level = input.config.level ?? input.level;\n\n        if (input.config.type === 'console') {\n            return new transports.Console({\n                level,\n                format: this.buildConsoleFormat(input.label)\n            });\n        }\n\n        if (input.config.type === 'stream') {\n            return new transports.Stream({\n                level,\n                stream: input.config.stream,\n                format: this.buildStreamFormat(input.label, effectiveFormat, shouldStripAnsi)\n            });\n        }\n\n        const filenameTemplate = input.config.filename ?? 'logs/application-{timestamp}.log';\n        const resolvedFilename = this.resolveFilename(filenameTemplate, input.channel);\n        this.ensureDir(resolvedFilename);\n\n        return new transports.File({\n            level,\n            filename: resolvedFilename,\n            ...(input.config.maxSize !== undefined ? { maxsize: input.config.maxSize } : {}),\n            ...(input.config.maxFiles !== undefined ? { maxFiles: input.config.maxFiles } : {}),\n            tailable: true,\n            format: this.buildFileFormat(input.label, effectiveFormat, shouldStripAnsi)\n        });\n    }\n\n    /**\n     * Builds a sink transport for routing logs to custom destinations.\n     *\n     * @param input - Transport configuration with channel and level info\n     * @param sink - Custom sink to receive log entries\n     * @returns Configured sink transport instance\n     */\n    public buildSinkTransport(input: BuildInput, sink: ILoggerSink): WinstonTransport {\n        const format = this.buildConsoleFormat(input.label);\n\n        return new SinkTransport({\n            level: input.level,\n            channel: input.channel,\n            sink,\n            format\n        });\n    }\n}\n","import path from 'node:path';\n\nimport { Envapter } from 'envapt';\nimport winston, { createLogger } from 'winston';\n\nimport { TransportFactory } from './TransportFactory';\n\nimport type { ILoggerSink, ILoggerSinkHandle } from './Transports/SinkTransport';\nimport type {\n    ChannelConfig,\n    LoggerConfiguration,\n    LoggerLevel,\n    TransportConfig,\n    WinstonInstance,\n    WinstonTransport\n} from './Types';\n\n/**\n * Manages Winston logger instances per channel with caching.\n *\n * Stores channel configuration and creates transports for each channel\n * with environment-aware defaults.\n */\nexport class LoggerChannelRegistry {\n    private static _instance: LoggerChannelRegistry | null = null;\n\n    private nextSinkId = 1;\n    private readonly sinks = new Map<\n        number,\n        {\n            readonly sink: ILoggerSink;\n            readonly muteConsole: boolean;\n            readonly transportsByChannel: Map<string, WinstonTransport>;\n            readonly removedConsoleByChannel: Map<string, WinstonTransport[]>;\n        }\n    >();\n\n    private readonly DEFAULT_LEVEL: LoggerLevel = Envapter.isDevelopment\n        ? 'silly'\n        : Envapter.isStaging\n          ? 'debug'\n          : 'info';\n\n    private config: LoggerConfiguration = {\n        defaultChannel: 'default',\n        channels: {},\n        files: {\n            maxSizeMB: 10,\n            maxFiles: 5,\n            patterns: {\n                dev: 'logs/{channel}-{timestamp}.log',\n                staging: 'logs/staging-{date}-{timestamp}.jsonl',\n                prod: 'logs/production-{date}.jsonl'\n            }\n        }\n    };\n\n    private readonly FORMAT = Envapter.isDevelopment ? 'pretty' : 'json';\n\n    private readonly cache = new Map<string, WinstonInstance>();\n    private readonly transportFactory: TransportFactory;\n\n    private constructor() {\n        this.transportFactory = new TransportFactory();\n    }\n\n    /**\n     * Gets the singleton instance of the registry.\n     */\n    public static get instance(): LoggerChannelRegistry {\n        return (this._instance ??= new LoggerChannelRegistry());\n    }\n\n    private getDefaultChannelConfig(name: string): ChannelConfig {\n        return {\n            name,\n            level: this.DEFAULT_LEVEL,\n            transports: [\n                { type: 'console', level: this.DEFAULT_LEVEL, format: this.FORMAT, stripAnsi: !Envapter.isDevelopment },\n                {\n                    type: 'file',\n                    level: this.DEFAULT_LEVEL,\n                    filename: Envapter.isDevelopment\n                        ? this.config.files.patterns.dev\n                        : Envapter.isStaging\n                          ? this.config.files.patterns.staging\n                          : this.config.files.patterns.prod,\n                    format: this.FORMAT,\n                    stripAnsi: true,\n                    maxSize: this.config.files.maxSizeMB * 1024 * 1024,\n                    maxFiles: this.config.files.maxFiles\n                }\n            ]\n        };\n    }\n\n    private mergeChannelConfig(base: ChannelConfig, override?: ChannelConfig): ChannelConfig {\n        if (!override) return base;\n\n        const level = override.level ?? base.level;\n        const stripAnsi = override.stripAnsi ?? base.stripAnsi;\n        const format = override.format ?? base.format;\n        const transports = override.transports ?? base.transports;\n        const name = override.name || base.name;\n\n        return {\n            name,\n            ...(level !== undefined ? { level } : {}),\n            ...(stripAnsi !== undefined ? { stripAnsi } : {}),\n            ...(format !== undefined ? { format } : {}),\n            ...(transports !== undefined ? { transports } : {})\n        };\n    }\n\n    /**\n     * Updates global logger configuration and clears cache.\n     *\n     * @param config - Partial configuration to merge with existing settings\n     */\n    public configure(config: Partial<LoggerConfiguration>): void {\n        this.disposeCachedLoggers();\n        this.config = { ...this.config, ...config, channels: { ...this.config.channels, ...(config.channels ?? {}) } };\n        this.cache.clear();\n    }\n\n    // configure() rebuilds every logger; detach + close the old transports and reset sink\n    // bookkeeping first, or the discarded loggers leak transports (and their file handles /\n    // sink wrappers) across reconfigures, e.g. on every dev HMR cycle.\n    private disposeCachedLoggers(): void {\n        for (const logger of this.cache.values()) {\n            for (const transport of [...logger.transports]) {\n                logger.remove(transport);\n                transport.close?.();\n            }\n        }\n        for (const record of this.sinks.values()) {\n            record.transportsByChannel.clear();\n            record.removedConsoleByChannel.clear();\n        }\n    }\n\n    /**\n     * Returns the name of the default channel.\n     */\n    public getDefaultChannel(): string {\n        return this.config.defaultChannel;\n    }\n\n    /**\n     * Returns a list of all known channels (configured or cached).\n     */\n    public getChannels(): string[] {\n        const configuredChannels = Object.keys(this.config.channels);\n        const cachedChannels = Array.from(this.cache.keys());\n        const allChannels = new Set([...configuredChannels, ...cachedChannels, this.config.defaultChannel]);\n        return Array.from(allChannels).sort();\n    }\n\n    /**\n     * Gets the log file path for a specific channel, if one exists.\n     *\n     * @param channel - Channel name to get log file path for\n     * @returns The log file path, or null if no file transport exists\n     */\n    public getLogFilePath(channel: string): string | null {\n        const logger = this.cache.get(channel);\n        if (!logger) return null;\n\n        for (const transport of logger.transports) {\n            if (transport instanceof winston.transports.File) {\n                return path.resolve(transport.dirname, transport.filename);\n            }\n        }\n\n        return null;\n    }\n\n    /**\n     * Gets or creates a Winston logger instance for the given channel.\n     *\n     * @param channel - Channel name to get logger for\n     * @returns Configured Winston logger instance\n     */\n    public get(channel: string): WinstonInstance {\n        const cached = this.cache.get(channel);\n        if (cached) return cached;\n\n        const channelConfig = this.mergeChannelConfig(\n            this.getDefaultChannelConfig(channel),\n            this.config.channels[channel]\n        );\n\n        const effectiveLevel = channelConfig.level ?? this.DEFAULT_LEVEL;\n\n        const consoleMuted = this.isConsoleMuted();\n\n        const transports = (channelConfig.transports ?? [])\n            .filter((transportConfig: TransportConfig) => !(consoleMuted && transportConfig.type === 'console'))\n            .map((transportConfig: TransportConfig) =>\n                this.transportFactory.build({\n                    channel,\n                    label: channel,\n                    level: effectiveLevel,\n                    config: transportConfig,\n                    defaultFormat: channelConfig.format ?? 'pretty',\n                    stripAnsi: channelConfig.stripAnsi ?? true\n                })\n            );\n\n        const logger = createLogger({\n            level: effectiveLevel,\n            format: this.transportFactory.buildPreFormat(),\n            transports\n        });\n\n        for (const entry of this.sinks.values()) {\n            this.applySinkToCachedLogger(channel, logger, entry);\n        }\n\n        this.cache.set(channel, logger);\n        return logger;\n    }\n\n    private isConsoleMuted(): boolean {\n        for (const entry of this.sinks.values()) {\n            if (entry.muteConsole) return true;\n        }\n        return false;\n    }\n\n    /**\n     * Installs a custom sink to capture log output across all channels.\n     *\n     * Useful for routing logs to custom destinations like TUIs or remote services.\n     *\n     * @param sink - Custom sink implementation to receive log entries\n     * @param options - Optional configuration for console muting behavior\n     * @returns Handle to dispose the sink when no longer needed\n     */\n    public installSink(sink: ILoggerSink, options?: { muteConsole?: boolean }): ILoggerSinkHandle {\n        const id = this.nextSinkId;\n        this.nextSinkId += 1;\n\n        const record = {\n            sink,\n            muteConsole: options?.muteConsole ?? true,\n            transportsByChannel: new Map<string, WinstonTransport>(),\n            removedConsoleByChannel: new Map<string, WinstonTransport[]>()\n        };\n\n        this.sinks.set(id, record);\n\n        for (const [channel, logger] of this.cache.entries()) {\n            this.applySinkToCachedLogger(channel, logger, record);\n        }\n\n        return new (class implements ILoggerSinkHandle {\n            public constructor(\n                private readonly registry: LoggerChannelRegistry,\n                private readonly key: number\n            ) {}\n            public dispose(): void {\n                this.registry.uninstallSink(this.key);\n            }\n        })(this, id);\n    }\n\n    private uninstallSink(id: number): void {\n        const record = this.sinks.get(id);\n        if (!record) return;\n\n        for (const [channel, logger] of this.cache.entries()) {\n            const sinkTransport = record.transportsByChannel.get(channel);\n            if (sinkTransport) logger.remove(sinkTransport);\n\n            const removed = record.removedConsoleByChannel.get(channel);\n            if (removed?.length) {\n                for (const t of removed) logger.add(t);\n            }\n        }\n\n        this.sinks.delete(id);\n    }\n\n    private applySinkToCachedLogger(\n        channel: string,\n        logger: WinstonInstance,\n        record: {\n            readonly sink: ILoggerSink;\n            readonly muteConsole: boolean;\n            readonly transportsByChannel: Map<string, WinstonTransport>;\n            readonly removedConsoleByChannel: Map<string, WinstonTransport[]>;\n        }\n    ): void {\n        if (record.muteConsole) {\n            const removed: WinstonTransport[] = [];\n            for (const t of logger.transports) {\n                if (t instanceof winston.transports.Console) {\n                    removed.push(t);\n                }\n            }\n            if (removed.length) {\n                for (const t of removed) logger.remove(t);\n                record.removedConsoleByChannel.set(channel, removed);\n            }\n        }\n\n        const sinkTransport = this.transportFactory.buildSinkTransport(\n            { channel, label: channel, level: logger.level as unknown as LoggerLevel },\n            record.sink\n        );\n\n        logger.add(sinkTransport);\n        record.transportsByChannel.set(channel, sinkTransport);\n    }\n}\n","import { formatFilePath } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport type { LoggerLevel } from './Types';\nimport type { ILogger } from '@seedcord/types';\n\n/**\n * Provides access to common logging utilities.\n */\nexport class LoggerUtilities {\n    constructor(private readonly logger: ILogger) {}\n\n    private arrow(text: string): string {\n        return `${chalk.gray('→')} ${text}`;\n    }\n\n    /**\n     * Logs a single item with an arrow prefix.\n     * @param text - The text to log\n     */\n    public item(text: string, level: LoggerLevel = 'info'): void {\n        this.logger[level](this.arrow(text));\n    }\n\n    /**\n     * Logs a list of items with optional heading.\n     *\n     * @param items - Array of items to log as a list\n     * @param heading - Optional heading to display above the list\n     */\n    public list(items: string[], heading?: string, level: LoggerLevel = 'info'): void {\n        if (heading) this.logger[level](heading);\n        for (const item of items) {\n            this.logger[level](this.arrow(item));\n        }\n    }\n\n    /**\n     * Logs a summary with title and key-value pairs.\n     * Example: \"Loaded: 5 handlers, 3 commands\"\n     *\n     * @param title - The title of the summary\n     * @param items - Object with counts/values to display\n     */\n    public summary(title: string, items: Record<string, number | string>, level: LoggerLevel = 'info'): void {\n        const entries = Object.entries(items).map(([key, value]) => `${chalk.magenta.bold(String(value))} ${key}`);\n        this.logger[level](`${chalk.bold.green(title)}: ${entries.join(', ')}`);\n    }\n\n    /**\n     * Logs a component registration message.\n     *\n     * @param name - Name of the component being registered\n     * @param from - File path the component is from\n     * @param type - Optional type label (e.g., 'middleware', 'handler')\n     */\n    public registration(name: string, from: string, type?: string, level: LoggerLevel = 'info'): void {\n        const scope = type ? `${type} ` : '';\n        this.logger[level](\n            `${chalk.italic('Registered')} ${chalk.bold.yellow(scope)}${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(from))}`\n        );\n    }\n\n    /**\n     * Logs component initialization start/end.\n     *\n     * @param component - Name of the component\n     * @param action - 'start' or 'end' to indicate initialization phase\n     */\n    public initialization(component: string, action: 'start' | 'end', level: LoggerLevel = 'info'): void {\n        const verb = action === 'start' ? 'Initializing' : 'Initialized';\n        this.logger[level](chalk.bold(`${verb} ${component}`));\n    }\n\n    /**\n     * Logs progress as \"[current/total]\" with optional item label.\n     *\n     * @param current - Current progress count\n     * @param total - Total count\n     * @param item - Optional item label to append\n     */\n    public progress(current: number, total: number, item?: string, level: LoggerLevel = 'info'): void {\n        const base = `[${current}/${total}]`;\n        const suffix = item ? ` ${item}` : '';\n        this.logger[level](`${chalk.cyan(base)}${suffix}`);\n    }\n\n    /**\n     * Logs content in a decorative box.\n     *\n     * @param title - Title to display in the box\n     * @param content - Lines of content to display in the box\n     */\n    public box(title: string, content: string[], level: LoggerLevel = 'info'): void {\n        const width = Math.max(title.length, ...content.map((line) => line.length)) + 2;\n        const horizontal = '─'.repeat(width);\n        this.logger[level](`╭${horizontal}╮`);\n        this.logger[level](`│ ${title.padEnd(width - 1, ' ')}│`);\n        for (const line of content) {\n            this.logger[level](`│ ${line.padEnd(width - 1, ' ')}│`);\n        }\n        this.logger[level](`╰${horizontal}╯`);\n    }\n}\n","import { LoggerChannelRegistry } from './LoggerChannelRegistry';\nimport { LoggerUtilities } from './LoggerUtilities';\n\nimport type { LoggerConfiguration, LoggerOptions } from './Types';\nimport type { ILogger } from '@seedcord/types';\nimport type { Logger as Winston } from 'winston';\n\n/**\n * Public logging service with channel-aware transports and per-run file output.\n *\n * - Channel separation (e.g., bot, cli, hmr)\n * - Production-safe JSON logs with ANSI stripping\n * - Unique log files per run via filename templates\n */\nexport class Logger implements ILogger {\n    declare private logger: Winston;\n    private readonly label: string;\n    private channel: string;\n    private readonly registry = LoggerChannelRegistry.instance;\n\n    public readonly utils: LoggerUtilities;\n\n    /**\n     * Configures global logger settings, applied to all channels.\n     *\n     * @param config - Partial configuration to merge with defaults\n     */\n    public static configure(config: Partial<LoggerConfiguration>): void {\n        LoggerChannelRegistry.instance.configure(config);\n    }\n\n    /**\n     * Creates a new Logger instance.\n     *\n     * @param label - Prefix/label for all log entries from this logger\n     * @param options - Optional configuration for channel, format, and ANSI handling\n     */\n    constructor(label: string, options?: LoggerOptions) {\n        this.label = label;\n        this.channel = options?.channel ?? this.registry.getDefaultChannel();\n        this.logger = this.registry.get(this.channel).child({ label: this.label, channel: this.channel });\n\n        this.utils = new LoggerUtilities(this);\n    }\n\n    /**\n     * Switches this logger to a different channel.\n     *\n     * @param channel - Channel name to switch to\n     */\n    public setChannel(channel: string): void {\n        this.channel = channel;\n        this.logger = this.registry.get(channel).child({ label: this.label, channel });\n    }\n\n    /**\n     * Returns a new Logger for this label on the specified channel.\n     *\n     * @param channel - Channel name to use\n     */\n    public inChannel(channel: string): Logger {\n        return new Logger(this.label, { channel });\n    }\n\n    /**\n     * Logs an error message with optional additional data.\n     *\n     * @param msg - The error message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public error(msg: string, ...args: unknown[]): void {\n        this.logger.error(msg, ...args);\n    }\n\n    /**\n     * Logs a warning message with optional additional data.\n     *\n     * @param msg - The warning message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public warn(msg: string, ...args: unknown[]): void {\n        this.logger.warn(msg, ...args);\n    }\n\n    /**\n     * Logs an informational message with optional additional data.\n     *\n     * @param msg - The informational message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public info(msg: string, ...args: unknown[]): void {\n        this.logger.info(msg, ...args);\n    }\n\n    /**\n     * Logs an HTTP-related message with optional additional data.\n     *\n     * @param msg - The HTTP message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public http(msg: string, ...args: unknown[]): void {\n        this.logger.http(msg, ...args);\n    }\n\n    /**\n     * Logs a verbose message with optional additional data.\n     *\n     * @param msg - The verbose message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public verbose(msg: string, ...args: unknown[]): void {\n        this.logger.verbose(msg, ...args);\n    }\n\n    /**\n     * Logs a debug message with optional additional data.\n     *\n     * @param msg - The debug message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public debug(msg: string, ...args: unknown[]): void {\n        this.logger.debug(msg, ...args);\n    }\n\n    /**\n     * Logs a silly/trace level message with optional additional data.\n     *\n     * @param msg - The silly message to log\n     * @param args - Additional data to include in the log entry\n     */\n    public silly(msg: string, ...args: unknown[]): void {\n        this.logger.silly(msg, ...args);\n    }\n}\n","import { EventEmitter } from 'node:events';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\n/** Tuple type used for all event payloads. */\nexport type SEArgsTuple = readonly unknown[];\n\n/** Convenience map for emitters that intentionally expose no events. */\nexport type SENoEvents = Record<never, SEArgsTuple>;\n\n/**\n * Accepts any object type and constrains every value to be a tuple.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport type SEEventMapLike<TEvents extends object> = { [K in keyof TEvents]: SEArgsTuple };\n\n/**\n * Narrows a provided event map to the keys that can be emitted or listened for.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n * @internal\n */\ntype SEEventKey<TEvents extends object> = Extract<keyof TEvents, string | symbol>;\n\n/**\n * Typed wrapper around Node.js {@link EventEmitter} enforcing tuple payloads per event name.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport class StrictEventEmitter<TEvents extends SEEventMapLike<TEvents>> extends EventEmitter {\n    /**\n     * Registers a persistent listener with tuple-safe arguments for the given event.\n     *\n     * @param event - The event name to attach to\n     * @param listener - Callback operating on the typed argument tuple for the event\n     * @returns This emitter instance for chaining\n     */\n    override on<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        listener: (...args: TEvents[TEventKey]) => void\n    ): this {\n        return super.on(event, listener);\n    }\n\n    /**\n     * Registers a one time listener that is removed after the first invocation.\n     *\n     * @param event - The event name to attach to\n     * @param listener - Callback operating on the typed argument tuple for the event\n     * @returns This emitter instance for chaining\n     */\n    override once<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        listener: (...args: TEvents[TEventKey]) => void\n    ): this {\n        return super.once(event, listener);\n    }\n\n    /**\n     * Removes a previously registered listener for the given event.\n     *\n     * @param event - The event name whose listener should be removed\n     * @param listener - Callback originally registered for the event\n     * @returns This emitter instance for chaining\n     */\n    override off<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        listener: (...args: TEvents[TEventKey]) => void\n    ): this {\n        return super.off(event, listener);\n    }\n\n    /**\n     * Alias of {@link StrictEventEmitter.on} for compatibility with Node.js EventEmitter APIs.\n     *\n     * @param event - The event name to attach to\n     * @param listener - Callback operating on the typed argument tuple for the event\n     * @returns This emitter instance for chaining\n     */\n    override addListener<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        listener: (...args: TEvents[TEventKey]) => void\n    ): this {\n        return this.on(event, listener);\n    }\n\n    /**\n     * Alias of {@link StrictEventEmitter.off} for compatibility with Node.js EventEmitter APIs.\n     *\n     * @param event - The event name whose listener should be removed\n     * @param listener - Callback originally registered for the event\n     * @returns This emitter instance for chaining\n     */\n    override removeListener<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        listener: (...args: TEvents[TEventKey]) => void\n    ): this {\n        return super.removeListener(event, listener);\n    }\n\n    /**\n     * Emits an event with the strictly typed argument tuple for the event name.\n     *\n     * @param event - The event name to emit\n     * @param args - Tuple payload for the event\n     * @returns True when the event had listeners, false otherwise\n     */\n    override emit<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, ...args: TEvents[TEventKey]): boolean {\n        // justified: widen the per-event tuple to its base array type so it spreads into Node's\n        // `emit(event, ...args: any[])`. There's no declaration fix for Node's base signature.\n        return super.emit(event, ...(args as readonly unknown[]));\n    }\n\n    /**\n     * Retrieves the listener list for a given event with the correct tuple signature.\n     *\n     * @param event - The event name to inspect\n     * @returns Array of listeners registered for the event\n     */\n    override listeners<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey\n    ): ((...args: TEvents[TEventKey]) => void)[] {\n        return super.listeners(event) as ((...args: TEvents[TEventKey]) => void)[];\n    }\n\n    /**\n     * Counts listeners for an event without widening the return type of {@link EventEmitter.listenerCount}.\n     *\n     * @param event - The event name to inspect\n     * @returns The total number of listeners registered for the event\n     */\n    listenerCountTyped<TEventKey extends SEEventKey<TEvents>>(event: TEventKey): number {\n        return super.listenerCount(event);\n    }\n\n    /**\n     * Returns the list of event names known to the emitter with the mapped key type.\n     *\n     * @returns Array of event keys supported by the emitter\n     */\n    eventNamesTyped(): SEEventKey<TEvents>[] {\n        return super.eventNames() as SEEventKey<TEvents>[];\n    }\n\n    /**\n     * Waits for an event to be emitted, resolving with the listener arguments tuple once triggered.\n     * Supports optional abort signals and timeouts for cancellation semantics.\n     *\n     * @param event - The event name to wait for\n     * @param opts - Optional abort signal or timeout in milliseconds\n     * @returns Promise resolving with the emitted argument tuple; rejects when aborted or timed out\n     */\n    waitFor<TEventKey extends SEEventKey<TEvents>>(\n        event: TEventKey,\n        opts?: { signal?: AbortSignal; timeoutMs?: number }\n    ): Promise<TEvents[TEventKey]> {\n        return new Promise<TEvents[TEventKey]>((resolve, reject) => {\n            const onEvent = (...args: TEvents[TEventKey]): void => {\n                cleanup();\n                resolve(args);\n            };\n\n            const onAbort = (): void => {\n                cleanup();\n                reject(new SeedcordError(SeedcordErrorCode.EventEmitterWaitForAborted));\n            };\n\n            let timeoutId: NodeJS.Timeout | null = null;\n\n            const cleanup = (): void => {\n                this.off(event, onEvent);\n                opts?.signal?.removeEventListener('abort', onAbort);\n                if (timeoutId) clearTimeout(timeoutId);\n            };\n\n            this.once(event, onEvent);\n\n            if (opts?.signal) {\n                if (opts.signal.aborted) return onAbort();\n                opts.signal.addEventListener('abort', onAbort, { once: true });\n            }\n\n            if (opts?.timeoutMs !== undefined) {\n                const timeoutMs = opts.timeoutMs;\n                timeoutId = setTimeout(() => {\n                    cleanup();\n                    reject(new SeedcordError(SeedcordErrorCode.EventEmitterWaitForTimeout, [timeoutMs]));\n                }, timeoutMs);\n            }\n        });\n    }\n}\n","/*\n * Inspired by Akka Coordinated Shutdown: https://doc.akka.io/libraries/akka-core/current/coordinated-shutdown.html\n * and Lewis's implementation in a private repo elsewhere (https://github.com/Yomanz)\n */\n\nimport { EventEmitter } from 'node:events';\n\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport chalk from 'chalk';\n\nimport { Logger } from '../Logger';\nimport { StrictEventEmitter } from '../StrictEventEmitter';\n\nimport type { LifecycleTask } from './LifecycleTypes';\nimport type { SEEventMapLike } from '../StrictEventEmitter';\n\n/**\n * Abstract base class for coordinated lifecycle management (startup/shutdown)\n */\nexport abstract class CoordinatedLifecycle<\n    TPhase extends number,\n    TEvents extends SEEventMapLike<TEvents>\n> extends StrictEventEmitter<TEvents> {\n    protected readonly logger: Logger;\n    protected readonly tasksMap = new Map<TPhase, LifecycleTask[]>();\n\n    protected constructor(\n        loggerName: string,\n        protected readonly phaseOrder: TPhase[],\n        protected readonly phaseEnum: Record<number, string>\n    ) {\n        super();\n        this.logger = new Logger(loggerName);\n        this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));\n    }\n\n    /**\n     * Adds a lifecycle task to a specific phase.\n     *\n     * Tasks are executed in phase order during lifecycle operations.\n     * Each task has a timeout to prevent hanging operations.\n     *\n     * @param phase - The lifecycle phase to add the task to\n     * @param taskName - Unique name for the task (used for logging and removal)\n     * @param task - Async function to execute during the phase\n     * @param timeoutMs - Maximum time allowed for task execution in milliseconds\n     * @example\n     * ```typescript\n     * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {\n     *   await database.connect();\n     * }, 10000);\n     * ```\n     */\n    public addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void {\n        if (!this.canAddTask()) return;\n\n        const tasks = this.tasksMap.get(phase);\n        if (!tasks) {\n            throw new SeedcordError(SeedcordErrorCode.LifecycleUnknownPhase, [phase]);\n        }\n\n        tasks.push({ name: taskName, task, timeout: timeoutMs });\n        this.logger.debug(\n            `${chalk.italic('Added')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} to phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n        );\n    }\n\n    /**\n     * Removes a lifecycle task from a specific phase.\n     *\n     * @param phase - The lifecycle phase to remove the task from\n     * @param taskName - Name of the task to remove\n     * @returns True if the task was found and removed, false otherwise\n     */\n    public removeTask(phase: TPhase, taskName: string): boolean {\n        if (!this.canRemoveTask()) return false;\n\n        const tasks = this.tasksMap.get(phase);\n        if (!tasks) return false;\n\n        const initialLength = tasks.length;\n        const filteredTasks = tasks.filter((task) => task.name !== taskName);\n        this.tasksMap.set(phase, filteredTasks);\n\n        const removed = initialLength !== filteredTasks.length;\n        if (removed) {\n            this.logger.debug(\n                `${chalk.italic('Removed')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} from phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n            );\n        }\n\n        return removed;\n    }\n\n    /**\n     * Run all tasks in a specific phase\n     */\n    protected async runPhase(phase: TPhase): Promise<void> {\n        const tasks = this.tasksMap.get(phase) ?? [];\n        if (tasks.length === 0) {\n            this.logger.warn(`No tasks to run in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`);\n            return;\n        }\n\n        this.logger.info(\n            `${chalk.bold.yellow('Running')} ${this.getTaskType()} phase ${chalk.bold.magenta(this.phaseEnum[phase])} with ${chalk.bold.cyan(tasks.length)} tasks`\n        );\n        this.emitPhase(phase, 'start');\n\n        const results: PromiseSettledResult<void>[] = await this.executeTasksInPhase(phase, tasks);\n\n        const failures = results.filter((r) => r.status === 'rejected').length;\n        if (failures > 0) {\n            // Pass the raw phase name; chalk's ANSI codes would otherwise leak into the serialized\n            // error message (e.g. the unknown-exception webhook payload).\n            throw new SeedcordError(SeedcordErrorCode.LifecyclePhaseFailures, [this.phaseEnum[phase], failures]);\n        } else {\n            this.logger.info(\n                `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} ${chalk.bold.green('completed successfully')}`\n            );\n        }\n\n        this.emitPhase(phase, 'complete');\n    }\n\n    /**\n     * Run a single task with timeout\n     */\n    protected async runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void> {\n        this.logger.info(\n            `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n        );\n\n        let timeoutId: NodeJS.Timeout | undefined;\n\n        try {\n            await Promise.race([\n                task.task(),\n                new Promise<void>((_, reject) => {\n                    timeoutId = setTimeout(() => {\n                        reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [task.name, task.timeout]));\n                    }, task.timeout);\n                })\n            ]);\n\n            this.logger.info(\n                `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n            );\n        } catch (error) {\n            this.logger.error(\n                `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}:`,\n                error\n            );\n            throw error;\n        } finally {\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n        }\n    }\n\n    // The phase event key is interpolated from phaseOrder at runtime; the subclass event map derives\n    // its phase keys from the same range, so the key is always valid, but TS can't correlate a\n    // template-literal key with the generic TEvents. Emit the no-payload event via the base emitter.\n    private emitPhase(phase: TPhase, action: 'start' | 'complete'): void {\n        EventEmitter.prototype.emit.call(this, `phase:${phase}:${action}`);\n    }\n\n    // Abstract methods to be implemented by subclasses\n    protected abstract canAddTask(): boolean;\n    protected abstract canRemoveTask(): boolean;\n    protected abstract getTaskType(): string;\n    protected abstract executeTasksInPhase(\n        phase: TPhase,\n        tasks: LifecycleTask[]\n    ): Promise<PromiseSettledResult<void>[]>;\n}\n","import chalk from 'chalk';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEventMap } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Shutdown phases for coordinated application shutdown.\n */\nexport enum ShutdownPhase {\n    /** Stop accepting new requests/interactions */\n    StopAcceptingRequests = 1,\n    /** Stop background services (health checks, etc.) */\n    StopServices,\n    /** Disconnect from external resources (database, APIs) */\n    ExternalResources,\n    /** Disconnect from Discord */\n    DiscordCleanup,\n    /** Final cleanup tasks */\n    FinalCleanup\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: ShutdownPhase[] = [\n    ShutdownPhase.StopAcceptingRequests,\n    ShutdownPhase.StopServices,\n    ShutdownPhase.ExternalResources,\n    ShutdownPhase.DiscordCleanup,\n    ShutdownPhase.FinalCleanup\n];\n\n/**\n * Strict-event-emitter payload map for coordinated shutdown phases.\n */\nexport type CoordinatedShutdownEvents = PhaseEventMap<'shutdown', UnionToTuple<ShutdownPhase>>;\n\n// Delay process.exit so winston has a window to flush buffered log lines before the event loop dies.\nconst LOG_FLUSH_DELAY_MS = 500;\n\n/**\n * CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.\n *\n * It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.\n * Tasks can be added or removed dynamically, and each task has an associated timeout.\n */\nexport class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase, CoordinatedShutdownEvents> {\n    private readonly isShutdownEnabled: boolean;\n\n    private isShuttingDown = false;\n    private exitCode = 0;\n    private onSigTerm: (() => void) | null = null;\n    private onSigInt: (() => void) | null = null;\n\n    public constructor(enabled = true) {\n        super('CoordinatedShutdown', PHASE_ORDER, ShutdownPhase);\n\n        this.isShutdownEnabled = enabled;\n        this.registerSignalHandlers();\n    }\n\n    protected canAddTask(): boolean {\n        return this.isShutdownEnabled;\n    }\n\n    protected canRemoveTask(): boolean {\n        return true;\n    }\n\n    protected getTaskType(): string {\n        return 'shutdown';\n    }\n\n    protected async executeTasksInPhase(\n        phase: ShutdownPhase,\n        tasks: LifecycleTask[]\n    ): Promise<PromiseSettledResult<void>[]> {\n        const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));\n        return Promise.allSettled(promises);\n    }\n\n    private registerSignalHandlers(): void {\n        if (!this.isShutdownEnabled) return;\n\n        this.onSigTerm = () => {\n            this.logger.info(`Received ${chalk.yellow.bold('SIGTERM')} signal`);\n            void this.run(0);\n        };\n\n        this.onSigInt = () => {\n            this.logger.info(`Received ${chalk.yellow.bold('SIGINT')} signal`);\n            void this.run(0);\n        };\n\n        process.on('SIGTERM', this.onSigTerm);\n        process.on('SIGINT', this.onSigInt);\n    }\n\n    private removeSignalHandlers(): void {\n        if (this.onSigTerm) {\n            process.off('SIGTERM', this.onSigTerm);\n            this.onSigTerm = null;\n        }\n        if (this.onSigInt) {\n            process.off('SIGINT', this.onSigInt);\n            this.onSigInt = null;\n        }\n    }\n\n    /**\n     * Adds a task to a specific shutdown phase with timeout.\n     *\n     * @param phase - The shutdown phase from {@link ShutdownPhase}\n     * @param taskName - Unique identifier for the task\n     * @param task - Async function to execute\n     * @param timeoutMs - Task timeout in milliseconds. {@default `5000`}\n     */\n    public override addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs = 5000): void {\n        super.addTask(phase, taskName, task, timeoutMs);\n    }\n\n    /**\n     * Removes a task from a specific shutdown phase.\n     *\n     * @param phase - The shutdown phase to remove from\n     * @param taskName - Name of the task to remove\n     * @returns True if task was found and removed\n     */\n    public override removeTask(phase: ShutdownPhase, taskName: string): boolean {\n        return super.removeTask(phase, taskName);\n    }\n\n    /**\n     * Executes the coordinated shutdown sequence.\n     *\n     * Runs all registered tasks across shutdown phases in reverse order.\n     * Tasks within each phase are executed in parallel for faster shutdown.\n     * Process exits with the specified code when complete.\n     *\n     * @param exitCode - Process exit code. {@default `0`}\n     * @param exitProcess - Whether to exit the process after shutdown. {@default `true`}\n     * @returns Promise that resolves when shutdown is complete\n     * @example\n     * ```typescript\n     * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);\n     * await shutdown.run(0); // Graceful shutdown\n     * ```\n     */\n    public async run(exitCode = 0, exitProcess = true): Promise<void> {\n        this.removeSignalHandlers();\n\n        if (this.isShuttingDown) {\n            this.logger.warn('Shutdown sequence already in progress');\n            return;\n        }\n\n        this.isShuttingDown = true;\n        this.exitCode = exitCode;\n        this.logger.info(\n            `${chalk.bold.yellow('Starting')} coordinated shutdown with exit code ${chalk.bold.cyan(exitCode)}`\n        );\n        this.emit('shutdown:start');\n\n        try {\n            for (const phase of PHASE_ORDER) {\n                await this.runPhase(phase);\n            }\n\n            this.logger.info(`${chalk.bold.green('Coordinated shutdown completed')} successfully`);\n            this.emit('shutdown:complete');\n        } catch (error) {\n            this.logger.error(`${chalk.bold.red('Coordinated shutdown failed')}`);\n            this.emit('shutdown:error', error);\n        } finally {\n            if (exitProcess) {\n                this.logger.info(`${chalk.bold.red('Exiting')} process with code ${chalk.bold.cyan(this.exitCode)}`);\n                setTimeout(() => {\n                    process.exit(this.exitCode);\n                }, LOG_FLUSH_DELAY_MS);\n            } else {\n                this.logger.info(`${chalk.bold.yellow('Skipping')} process exit (dev mode)`);\n                this.isShuttingDown = false;\n            }\n        }\n    }\n}\n","import { createServer } from 'http';\n\nimport chalk from 'chalk';\n\nimport { ShutdownPhase } from './Lifecycle/CoordinatedShutdown';\nimport { Logger } from './Logger';\n\nimport type { CoordinatedShutdown } from './Lifecycle/CoordinatedShutdown';\nimport type { HealthCheckConfig } from '@seedcord/types';\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst HTTP_OK = 200;\nconst HTTP_NOT_FOUND = 404;\n\nconst DEFAULT_HEALTH_CHECK_PORT = 6967;\nconst DEFAULT_HEALTH_CHECK_PATH = '/healthcheck';\n\n/**\n * HTTP health check service for monitoring bot status.\n *\n * Provides a simple HTTP endpoint that responds with JSON status\n * information, useful for container orchestration and monitoring.\n */\nexport class HealthCheck {\n    /** @internal */\n    public readonly logger = new Logger('HealthCheck');\n\n    public readonly port: number;\n    public readonly path: string;\n    public readonly host: string | undefined;\n\n    private server?: Server;\n\n    constructor(shutdown: CoordinatedShutdown, options?: HealthCheckConfig) {\n        this.port = options?.port ?? DEFAULT_HEALTH_CHECK_PORT;\n        this.path = options?.path ?? DEFAULT_HEALTH_CHECK_PATH;\n        this.host = options?.host;\n\n        shutdown.addTask(ShutdownPhase.StopServices, 'stop-healthcheck-server', async () => await this.stop());\n    }\n\n    /**\n     * Starts the health check server.\n     * @returns Promise that resolves when the server is listening\n     * @internal\n     */\n    public async init(): Promise<void> {\n        return new Promise<void>((resolve, reject) => {\n            const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n                if (req.method === 'GET' && req.url === this.path) {\n                    res.writeHead(HTTP_OK, { 'Content-Type': 'application/json' });\n                    res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));\n                } else {\n                    res.writeHead(HTTP_NOT_FOUND, { 'Content-Type': 'application/json' });\n                    res.end(JSON.stringify({ status: 'not found' }));\n                }\n            });\n            this.server = server;\n\n            const onListenError = (err: Error): void => reject(err);\n            server.on('error', onListenError);\n\n            server.once('listening', () => {\n                // Swap the listen-time reject handler for a logging one: keeping it would reject an\n                // already-settled promise on a late error, and removing it without a replacement\n                // would crash the process on an unhandled 'error' event.\n                server.removeListener('error', onListenError);\n                server.on('error', (err) => this.logger.error('Health check server error', err));\n\n                const address = this.host ?? 'localhost';\n                this.logger.info(\n                    `${chalk.green.bold('✓')} Health check server listening on ${chalk.cyan(`http://${address}:${this.port}${this.path}`)}`\n                );\n                resolve();\n            });\n\n            if (this.host) {\n                this.logger.debug(`Binding health check server to ${this.host}`);\n                server.listen(this.port, this.host);\n            } else {\n                this.logger.debug('Binding health check server to all interfaces');\n                server.listen(this.port);\n            }\n        });\n    }\n\n    /**\n     * Stops the health check server.\n     *\n     * @returns Promise that resolves when the server is closed\n     * @internal\n     */\n    public stop(): Promise<void> {\n        const server = this.server;\n        // close() on a non-listening server invokes its callback with ERR_SERVER_NOT_RUNNING and\n        // never fires 'close', so without this guard the promise would hang the shutdown phase.\n        if (!server?.listening) return Promise.resolve();\n\n        return new Promise((resolve, reject) => {\n            server.once('close', () => resolve());\n            server.close((err) => {\n                if (err) {\n                    reject(err);\n                    return;\n                }\n                this.logger.info(chalk.bold.red('Health check server stopped'));\n            });\n        });\n    }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport chalk from 'chalk';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEventMap } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Startup phases for coordinated initialization\n *\n * Defines the order in which different components are initialized during bot startup.\n */\nexport enum StartupPhase {\n    /** Validate environment variables and config files */\n    Validation = 1,\n    /** Discover plugin constructors via decorators or registry */\n    Discovery,\n    /** Register plugin metadata and declared dependencies */\n    Registration,\n    /** Inject and validate plugin-specific configuration */\n    Configuration,\n    /** Instantiate plugin classes with Core and arguments */\n    Instantiation,\n    /** Activate plugins by calling their init/setup methods */\n    Activation,\n    /** Mark seedcord as ready and start handling interactions */\n    Ready\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: StartupPhase[] = [\n    StartupPhase.Validation,\n    StartupPhase.Discovery,\n    StartupPhase.Registration,\n    StartupPhase.Configuration,\n    StartupPhase.Instantiation,\n    StartupPhase.Activation,\n    StartupPhase.Ready\n];\n\n/**\n * Strict-event-emitter payload map for coordinated startup phases.\n */\nexport type CoordinatedStartupEvents = PhaseEventMap<'startup', UnionToTuple<StartupPhase>>;\n\n/**\n * Manages bot startup lifecycle with ordered phases\n *\n * Coordinates initialization of all bot components in a predictable sequence.\n * Tasks are executed within their designated phases to ensure proper dependency order.\n */\nexport class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase, CoordinatedStartupEvents> {\n    private isStartingUp = false;\n    private hasStarted = false;\n\n    public constructor() {\n        super('CoordinatedStartup', PHASE_ORDER, StartupPhase);\n    }\n\n    /**\n     * Adds a task to a specific startup phase with timeout.\n     *\n     * @param phase - The startup phase from {@link StartupPhase}\n     * @param taskName - Unique identifier for the task\n     * @param task - Async function to execute\n     * @param timeoutMs - Task timeout in milliseconds. {@default `10000`}\n     */\n    public override addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs = 10000): void {\n        super.addTask(phase, taskName, task, timeoutMs);\n    }\n\n    protected canAddTask(): boolean {\n        if (this.hasStarted) {\n            throw new SeedcordError(SeedcordErrorCode.LifecycleAddAfterCompletion);\n        }\n\n        if (this.isStartingUp) {\n            throw new SeedcordError(SeedcordErrorCode.LifecycleAddDuringRun);\n        }\n\n        return true;\n    }\n\n    protected canRemoveTask(): boolean {\n        if (this.isStartingUp) {\n            throw new SeedcordError(SeedcordErrorCode.LifecycleRemoveDuringRun);\n        }\n\n        return true;\n    }\n\n    protected getTaskType(): string {\n        return 'startup';\n    }\n\n    protected async executeTasksInPhase(\n        phase: StartupPhase,\n        tasks: LifecycleTask[]\n    ): Promise<PromiseSettledResult<void>[]> {\n        const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));\n        return Promise.allSettled(promises);\n    }\n\n    /**\n     * Executes the coordinated startup sequence.\n     *\n     * Runs all registered tasks across startup phases in the correct order.\n     * Each phase completes before the next phase begins. Tasks within a phase\n     * are executed sequentially to maintain predictable initialization.\n     *\n     * @returns Promise that resolves when startup is complete\n     * @throws An {@link Error} If startup fails or is called multiple times\n     * @example\n     * ```typescript\n     * const startup = new CoordinatedStartup();\n     * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);\n     * await startup.run();\n     * ```\n     */\n    public async run(): Promise<void> {\n        if (this.hasStarted) {\n            this.logger.warn('Startup sequence has already completed');\n            return;\n        }\n\n        if (this.isStartingUp) {\n            this.logger.warn('Startup sequence already in progress');\n            return;\n        }\n\n        this.isStartingUp = true;\n        this.logger.info(`${chalk.bold.green('Starting')} coordinated startup sequence`);\n        this.emit('startup:start');\n\n        try {\n            for (const phase of PHASE_ORDER) {\n                // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- abort() can flip isStartingUp to false mid-loop from the cli\n                if (!this.isStartingUp) {\n                    this.logger.warn('Startup sequence aborted');\n                    return;\n                }\n                await this.runPhase(phase);\n            }\n\n            this.hasStarted = true;\n            this.logger.info(`${chalk.bold.green('Coordinated startup completed')} successfully`);\n            this.emit('startup:complete');\n        } catch (error) {\n            // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- abort() can flip isStartingUp to false before this catch runs\n            if (!this.isStartingUp) {\n                this.logger.warn('Startup sequence aborted during error handling');\n                return;\n            }\n            this.logger.error(`${chalk.bold.red('Coordinated startup failed')}`);\n            this.emit('startup:error', error);\n            throw error;\n        } finally {\n            this.isStartingUp = false;\n        }\n    }\n\n    protected override async runTaskWithTimeout(phase: StartupPhase, task: LifecycleTask): Promise<void> {\n        this.logger.info(\n            `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}`\n        );\n\n        let timeoutId: NodeJS.Timeout | undefined;\n\n        try {\n            await Promise.race([\n                task.task(),\n                new Promise<void>((_, reject) => {\n                    timeoutId = setTimeout(() => {\n                        reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [task.name, task.timeout]));\n                    }, task.timeout);\n                })\n            ]);\n\n            this.logger.info(\n                `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}`\n            );\n        } catch (error) {\n            if (!this.isStartingUp) {\n                return;\n            }\n\n            this.logger.error(\n                `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}:`,\n                error\n            );\n            throw error;\n        } finally {\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n        }\n    }\n\n    /**\n     * Aborts the startup sequence if it is currently running.\n     */\n    public abort(): void {\n        if (this.isStartingUp) {\n            this.isStartingUp = false;\n            this.logger.warn('Aborting coordinated startup sequence');\n        }\n    }\n\n    /**\n     * Check if startup has completed\n     */\n    public get isReady(): boolean {\n        return this.hasStarted;\n    }\n\n    /**\n     * Check if startup is currently running\n     */\n    public get isRunning(): boolean {\n        return this.isStartingUp;\n    }\n}\n","export * from './RateLimiter';\nexport * from './HealthCheck';\nexport * from './Lifecycle';\nexport * from './Logger';\nexport * from './StrictEventEmitter';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":"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"}