// Hatchway CLI - Built with Rollup
import { existsSync, mkdirSync, appendFileSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { EventEmitter } from 'node:events';
import chalk from 'chalk';

/**
 * File-based logger for debugging when TUI console interception interferes
 * Writes to /logs directory for easy tail -f monitoring
 */
const LOGS_DIR = join(process.cwd(), 'logs');
const RUNNER_LOG = join(LOGS_DIR, 'runner.log');
const STREAM_LOG = join(LOGS_DIR, 'stream.log');
const ERRORS_LOG = join(LOGS_DIR, 'errors.log');
// Ensure logs directory exists
if (!existsSync(LOGS_DIR)) {
    mkdirSync(LOGS_DIR, { recursive: true });
}
function timestamp() {
    return new Date().toISOString();
}
function writeLog(file, level, ...args) {
    const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)).join(' ');
    const logLine = `[${timestamp()}] [${level}] ${message}\n`;
    try {
        appendFileSync(file, logLine);
    }
    catch (err) {
        // Silently fail - don't want logging to crash the app
        console.error('Failed to write log:', err);
    }
}
/**
 * General runner logs - everything goes here
 */
const fileLog = {
    info: (...args) => writeLog(RUNNER_LOG, 'INFO', ...args),
    warn: (...args) => writeLog(RUNNER_LOG, 'WARN', ...args),
    error: (...args) => {
        writeLog(RUNNER_LOG, 'ERROR', ...args);
        writeLog(ERRORS_LOG, 'ERROR', ...args);
    },
    debug: (...args) => writeLog(RUNNER_LOG, 'DEBUG', ...args),
};
/**
 * Stream-specific logs - for tracking AI SDK events
 */
const streamLog = {
    info: (...args) => writeLog(STREAM_LOG, 'INFO', ...args),
    warn: (...args) => writeLog(STREAM_LOG, 'WARN', ...args),
    event: (eventNumber, eventType, data) => {
        writeLog(STREAM_LOG, 'EVENT', `#${eventNumber} type="${eventType}"`, data);
    },
    yield: (messageType, data) => {
        writeLog(STREAM_LOG, 'YIELD', `type="${messageType}"`, data);
    },
    error: (...args) => {
        writeLog(STREAM_LOG, 'ERROR', ...args);
        writeLog(ERRORS_LOG, 'ERROR', ...args);
    },
};
// TUI mode flag - when true, don't output to terminal (only to file)
let tuiModeEnabled = false;
/**
 * Enable TUI mode - suppresses terminal output, only writes to files
 * Also sets SILENT_MODE env var to suppress agent-core build-logger output
 */
function setFileLoggerTuiMode(enabled) {
    tuiModeEnabled = enabled;
    // Set env var so agent-core's build-logger also silences itself
    {
        process.env.SILENT_MODE = '1';
    }
}
// Intercept console methods to also write to file
const originalConsole = {
    log: console.log,
    error: console.error,
    warn: console.warn,
    info: console.info,
    debug: console.debug,
};
// Helper to check if we should suppress terminal output
// Check both the runtime flag AND the environment variable (set early in CLI)
function shouldSuppressTerminal() {
    return tuiModeEnabled || process.env.SILENT_MODE === '1';
}
// Override console methods to write to file (and optionally terminal)
console.log = (...args) => {
    if (!shouldSuppressTerminal()) {
        originalConsole.log(...args);
    }
    fileLog.info(...args);
};
console.error = (...args) => {
    if (!shouldSuppressTerminal()) {
        originalConsole.error(...args);
    }
    fileLog.error(...args);
};
console.warn = (...args) => {
    if (!shouldSuppressTerminal()) {
        originalConsole.warn(...args);
    }
    fileLog.warn(...args);
};
console.info = (...args) => {
    if (!shouldSuppressTerminal()) {
        originalConsole.info(...args);
    }
    fileLog.info(...args);
};
console.debug = (...args) => {
    if (!shouldSuppressTerminal()) {
        originalConsole.debug(...args);
    }
    fileLog.debug(...args);
};
// Log startup
fileLog.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
fileLog.info('Runner started - console interception enabled');
fileLog.info('Log files:');
fileLog.info(`  - General: ${RUNNER_LOG}`);
fileLog.info(`  - Stream:  ${STREAM_LOG}`);
fileLog.info(`  - Errors:  ${ERRORS_LOG}`);
fileLog.info('All console.log/error/warn/info/debug will be captured here');
fileLog.info('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');

/**
 * LogBuffer - File-backed circular buffer for log entries
 *
 * Maintains an in-memory buffer of the most recent 100 entries
 * and persists all logs to a file for full history access.
 */
const DEFAULT_BUFFER_SIZE = 100;
const LOG_DIR = 'logs';
const LOG_FILE = 'runner-tui.log';
class LogBuffer extends EventEmitter {
    constructor(options) {
        super();
        this.buffer = [];
        this.maxSize = options?.maxSize ?? DEFAULT_BUFFER_SIZE;
        this.sessionStartTime = Date.now();
        // Set up log file path
        const logDir = options?.logDir ?? LOG_DIR;
        if (!existsSync(logDir)) {
            mkdirSync(logDir, { recursive: true });
        }
        this.logFilePath = join(logDir, LOG_FILE);
        // Write session start marker
        this.writeToFile(`\n${'='.repeat(60)}\n`);
        this.writeToFile(`SESSION START: ${new Date().toISOString()}\n`);
        this.writeToFile(`${'='.repeat(60)}\n\n`);
    }
    /**
     * Add a log entry to the buffer and file
     */
    add(entry) {
        // Add to in-memory buffer (circular)
        this.buffer.push(entry);
        if (this.buffer.length > this.maxSize) {
            this.buffer.shift();
        }
        // Write to file
        this.writeToFile(this.formatEntryForFile(entry));
        // Emit event for subscribers (TUI components)
        this.emit('log', entry);
    }
    /**
     * Get the most recent N entries from memory
     */
    getRecent(count) {
        const n = count ?? this.maxSize;
        return this.buffer.slice(-n);
    }
    /**
     * Get all entries currently in memory
     */
    getAll() {
        return [...this.buffer];
    }
    /**
     * Get filtered entries from memory
     */
    getFiltered(filter) {
        return this.buffer.filter(entry => this.matchesFilter(entry, filter));
    }
    /**
     * Read entries from the log file (for full history)
     * Returns parsed log entries from the current session
     */
    readFromFile(maxLines) {
        if (!existsSync(this.logFilePath)) {
            return [];
        }
        try {
            const content = readFileSync(this.logFilePath, 'utf-8');
            const lines = content.split('\n').filter(line => line.trim());
            // Find the last session marker and only read from there
            let sessionStart = 0;
            for (let i = lines.length - 1; i >= 0; i--) {
                if (lines[i].includes('SESSION START:')) {
                    sessionStart = i + 1;
                    break;
                }
            }
            const sessionLines = lines.slice(sessionStart);
            const entries = [];
            for (const line of sessionLines) {
                const parsed = this.parseLogLine(line);
                if (parsed) {
                    entries.push(parsed);
                }
            }
            if (maxLines && entries.length > maxLines) {
                return entries.slice(-maxLines);
            }
            return entries;
        }
        catch (error) {
            console.error('Failed to read log file:', error);
            return [];
        }
    }
    /**
     * Get the log file path for external access
     */
    getLogFilePath() {
        return this.logFilePath;
    }
    /**
     * Convert buffer contents to plain text (for copying)
     */
    toText(entries) {
        const items = entries ?? this.buffer;
        return items.map(entry => this.formatEntryForDisplay(entry)).join('\n');
    }
    /**
     * Clear the in-memory buffer (file is preserved)
     */
    clear() {
        this.buffer = [];
        this.emit('clear');
    }
    /**
     * Subscribe to new log entries
     */
    onLog(callback) {
        this.on('log', callback);
        return () => this.off('log', callback);
    }
    // Private methods
    writeToFile(content) {
        try {
            appendFileSync(this.logFilePath, content);
        }
        catch (error) {
            // Silently fail - don't break logging if file write fails
        }
    }
    formatEntryForFile(entry) {
        const timestamp = new Date(entry.timestamp).toISOString();
        const level = entry.level.toUpperCase().padEnd(7);
        const category = entry.category.padEnd(12);
        let line = `[${timestamp}] [${level}] [${category}] ${entry.message}`;
        if (entry.toolName) {
            line += ` | tool=${entry.toolName}`;
            if (entry.toolArgs) {
                line += ` args=${entry.toolArgs}`;
            }
        }
        if (entry.buildId) {
            line += ` | build=${entry.buildId}`;
        }
        if (entry.data && Object.keys(entry.data).length > 0) {
            line += ` | data=${JSON.stringify(entry.data)}`;
        }
        return line + '\n';
    }
    formatEntryForDisplay(entry) {
        const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {
            hour12: false,
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
        });
        const levelIcon = {
            debug: '  ',
            info: '●',
            success: '✓',
            warn: '⚠',
            error: '✗',
        }[entry.level];
        if (entry.toolName) {
            return `${time}   🔧 ${entry.toolName}${entry.toolArgs ? ` ${entry.toolArgs}` : ''}`;
        }
        return `${time} ${levelIcon} ${entry.message}`;
    }
    parseLogLine(line) {
        // Parse format: [ISO_TIMESTAMP] [LEVEL  ] [CATEGORY    ] message | key=value...
        const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] (.+)$/);
        if (!match) {
            return null;
        }
        const [, timestamp, levelRaw, categoryRaw, rest] = match;
        const level = levelRaw.trim().toLowerCase();
        const category = categoryRaw.trim();
        // Parse message and optional fields
        const parts = rest.split(' | ');
        const message = parts[0];
        const entry = {
            id: `${Date.parse(timestamp)}-${Math.random().toString(36).slice(2, 8)}`,
            timestamp: Date.parse(timestamp),
            level,
            category,
            message,
        };
        // Parse optional key=value pairs
        for (let i = 1; i < parts.length; i++) {
            const [key, ...valueParts] = parts[i].split('=');
            const value = valueParts.join('=');
            switch (key) {
                case 'tool':
                    entry.toolName = value;
                    break;
                case 'args':
                    entry.toolArgs = value;
                    break;
                case 'build':
                    entry.buildId = value;
                    break;
                case 'data':
                    try {
                        entry.data = JSON.parse(value);
                    }
                    catch {
                        // Ignore parse errors
                    }
                    break;
            }
        }
        return entry;
    }
    matchesFilter(entry, filter) {
        if (filter.levels && !filter.levels.includes(entry.level)) {
            return false;
        }
        if (filter.categories && !filter.categories.includes(entry.category)) {
            return false;
        }
        if (filter.buildId && entry.buildId !== filter.buildId) {
            return false;
        }
        if (filter.verbose === false && entry.verbose) {
            return false;
        }
        if (filter.search) {
            const searchLower = filter.search.toLowerCase();
            const messageMatch = entry.message.toLowerCase().includes(searchLower);
            const toolMatch = entry.toolName?.toLowerCase().includes(searchLower);
            const argsMatch = entry.toolArgs?.toLowerCase().includes(searchLower);
            if (!messageMatch && !toolMatch && !argsMatch) {
                return false;
            }
        }
        return true;
    }
}
// Singleton instance
let instance$1 = null;
function getLogBuffer() {
    if (!instance$1) {
        instance$1 = new LogBuffer();
    }
    return instance$1;
}
function createLogBuffer(options) {
    instance$1 = new LogBuffer(options);
    return instance$1;
}

/**
 * RunnerLogger - Unified logging for the Hatchway Runner
 *
 * Provides structured logging with:
 * - Verbose mode filtering
 * - Build lifecycle tracking
 * - Tool call logging with truncated args
 * - Event emission for TUI components
 * - File persistence via LogBuffer
 */
const MAX_ARG_LENGTH = 40;
const MAX_MESSAGE_LENGTH = 80;
class RunnerLogger extends EventEmitter {
    constructor(options) {
        super();
        this.builds = new Map();
        this.currentBuildId = null;
        this.connected = false;
        this.verbose = options?.verbose ?? false;
        this.tuiMode = options?.tuiMode ?? true;
        this.buffer = options?.logDir
            ? createLogBuffer({ logDir: options.logDir })
            : getLogBuffer();
    }
    // ============================================
    // Configuration
    // ============================================
    setVerbose(verbose) {
        this.verbose = verbose;
        this.emit('verboseChange', verbose);
    }
    isVerbose() {
        return this.verbose;
    }
    setTuiMode(tuiMode) {
        this.tuiMode = tuiMode;
    }
    // ============================================
    // Connection Status
    // ============================================
    setConnected(connected) {
        this.connected = connected;
        if (connected) {
            this.success('system', 'Connected to server');
            this.emit('connected');
        }
        else {
            this.warn('system', 'Disconnected from server');
            this.emit('disconnected');
        }
    }
    isConnected() {
        return this.connected;
    }
    // ============================================
    // Startup / Header
    // ============================================
    /**
     * Print the startup header with runner configuration
     */
    header(config) {
        if (this.tuiMode) {
            // In TUI mode, header is rendered by the dashboard
            // Just emit the config for the TUI to use
            this.emit('config', config);
            return;
        }
        // Plain text mode - print formatted header
        const line = '━'.repeat(60);
        console.log(chalk.cyan(line));
        console.log(chalk.cyan.bold(' Hatchway Runner'));
        console.log(chalk.cyan(line));
        console.log(chalk.gray(' Runner ID  '), chalk.white(config.runnerId));
        console.log(chalk.gray(' Server     '), chalk.white(config.serverUrl));
        console.log(chalk.gray(' Workspace  '), chalk.white(config.workspace));
        if (config.apiUrl) {
            console.log(chalk.gray(' API        '), chalk.white(config.apiUrl));
        }
        console.log(chalk.cyan(line));
        console.log();
    }
    // ============================================
    // Generic Log Methods
    // ============================================
    info(category, message, data) {
        this.log('info', category, message, data);
    }
    success(category, message, data) {
        this.log('success', category, message, data);
    }
    warn(category, message, data) {
        this.log('warn', category, message, data);
    }
    error(category, message, data) {
        this.log('error', category, message, data);
    }
    debug(category, message, data) {
        this.log('debug', category, message, data, true);
    }
    // ============================================
    // Build Lifecycle
    // ============================================
    /**
     * Log when a build command is received
     */
    buildReceived(build) {
        const buildInfo = {
            id: build.commandId,
            projectId: build.projectId,
            projectSlug: build.projectSlug,
            projectName: build.projectName,
            prompt: build.prompt,
            operation: build.operation,
            agent: build.agent,
            model: build.model,
            startTime: Date.now(),
            status: 'pending',
            todos: [],
            toolCallCount: 0,
        };
        this.builds.set(build.commandId, buildInfo);
        this.currentBuildId = build.commandId;
        // Log the build received event
        this.info('build', `Build received: ${build.projectSlug}`, { buildId: build.commandId });
        // Log the prompt (truncated in normal mode, full in verbose)
        const truncatedPrompt = this.truncate(build.prompt, this.verbose ? 200 : 60);
        this.log('info', 'build', `Prompt: "${truncatedPrompt}"`, undefined, !this.verbose && build.prompt.length > 60);
        this.log('info', 'build', `Operation: ${build.operation}`, undefined, true);
        this.emit('buildStart', buildInfo);
    }
    /**
     * Log template selection and download
     */
    template(info) {
        switch (info.status) {
            case 'selected':
                this.info('template', `Template: ${info.name}${info.id ? ` (${info.id})` : ''}`);
                break;
            case 'downloading':
                this.log('info', 'template', `Downloading from ${info.source}...`, undefined, true);
                break;
            case 'downloaded':
                this.info('template', `Downloaded (${info.fileCount} files)`);
                break;
        }
        if (this.currentBuildId) {
            const build = this.builds.get(this.currentBuildId);
            if (build) {
                build.template = info.name;
                build.templateId = info.id;
                this.emit('buildUpdate', build);
            }
        }
    }
    /**
     * Log when build execution starts
     */
    buildStart(info) {
        this.info('build', 'Build started');
        if (info?.agent) {
            this.log('info', 'build', `Agent: ${info.agent}${info.model ? ` (${info.model})` : ''}`, undefined, true);
        }
        if (info?.directory) {
            this.log('info', 'build', `Directory: ${info.directory}`, undefined, true);
        }
        if (this.currentBuildId) {
            const build = this.builds.get(this.currentBuildId);
            if (build) {
                build.status = 'running';
                build.directory = info?.directory;
                this.emit('buildUpdate', build);
            }
        }
    }
    /**
     * Log build completion
     */
    buildComplete(stats) {
        const elapsed = this.formatDuration(stats.elapsedTime);
        this.success('build', `Build complete (${elapsed})`);
        this.info('build', `Tool calls: ${stats.toolCallCount} | Tokens: ${stats.totalTokens.toLocaleString()}`);
        this.log('info', 'build', `Directory: ${stats.directory}`, undefined, true);
        if (this.currentBuildId) {
            const build = this.builds.get(this.currentBuildId);
            if (build) {
                build.status = 'completed';
                build.endTime = Date.now();
                build.totalTokens = stats.totalTokens;
                this.emit('buildComplete', build, stats);
            }
            this.currentBuildId = null;
        }
    }
    /**
     * Log build failure
     */
    buildFailed(error) {
        const message = error instanceof Error ? error.message : error;
        this.error('build', `Build failed: ${message}`);
        if (this.currentBuildId) {
            const build = this.builds.get(this.currentBuildId);
            if (build) {
                build.status = 'failed';
                build.endTime = Date.now();
                build.error = message;
                this.emit('buildComplete', build, {
                    elapsedTime: (build.endTime - build.startTime) / 1000,
                    toolCallCount: build.toolCallCount,
                    totalTokens: build.totalTokens ?? 0,
                    directory: build.directory ?? '',
                });
            }
            this.currentBuildId = null;
        }
    }
    // ============================================
    // Tool Calls
    // ============================================
    /**
     * Log a tool call with truncated arguments
     */
    tool(toolName, args) {
        const truncatedArgs = this.formatToolArgs(toolName, args);
        const entry = {
            id: this.generateId(),
            timestamp: Date.now(),
            level: 'info',
            category: 'tool',
            message: `${toolName}${truncatedArgs ? ` ${truncatedArgs}` : ''}`,
            toolName,
            toolArgs: truncatedArgs,
            buildId: this.currentBuildId ?? undefined,
        };
        this.buffer.add(entry);
        // Increment tool count
        if (this.currentBuildId) {
            const build = this.builds.get(this.currentBuildId);
            if (build) {
                build.toolCallCount++;
                this.emit('buildUpdate', build);
            }
        }
        if (!this.tuiMode) {
            this.printEntry(entry);
        }
        this.emit('log', entry);
    }
    /**
     * Format tool arguments for display
     */
    formatToolArgs(toolName, args) {
        if (!args)
            return '';
        // If already a string, just truncate it
        if (typeof args === 'string') {
            return `(${this.truncate(args, MAX_ARG_LENGTH)})`;
        }
        // Format based on tool type
        switch (toolName) {
            case 'Read':
            case 'read':
            case 'Write':
            case 'write':
            case 'Edit':
            case 'edit':
                // Try various path field names used by different SDKs
                const pathValue = args.filePath || args.file_path || args.path || args.target || args.file;
                if (pathValue) {
                    const path = String(pathValue);
                    // Show just the filename or last part of path
                    const fileName = path.split('/').pop() || path;
                    return fileName;
                }
                break;
            case 'Bash':
                if (args.command) {
                    return `(${this.truncate(String(args.command), MAX_ARG_LENGTH)})`;
                }
                break;
            case 'Glob':
            case 'Grep':
                if (args.pattern) {
                    return `(${this.truncate(String(args.pattern), MAX_ARG_LENGTH)})`;
                }
                break;
            case 'TodoWrite':
                if (Array.isArray(args.todos)) {
                    return `(${args.todos.length} items)`;
                }
                break;
            default:
                // For other tools, try to show the first string value
                for (const [key, value] of Object.entries(args)) {
                    if (typeof value === 'string' && value.length > 0) {
                        return `(${this.truncate(value, MAX_ARG_LENGTH)})`;
                    }
                }
        }
        return '';
    }
    // ============================================
    // Agent Messages
    // ============================================
    /**
     * Log agent thinking/message
     */
    agent(message) {
        const truncated = this.truncate(message, MAX_MESSAGE_LENGTH);
        this.log('info', 'agent', truncated, undefined, message.length > MAX_MESSAGE_LENGTH);
    }
    // ============================================
    // Todo List Updates
    // ============================================
    /**
     * Update the todo list for the current build
     */
    updateTodos(todos) {
        if (!this.currentBuildId)
            return;
        const build = this.builds.get(this.currentBuildId);
        if (build) {
            build.todos = todos;
            this.emit('todoUpdate', this.currentBuildId, todos);
            this.emit('buildUpdate', build);
        }
    }
    // ============================================
    // Dev Server / Tunnel
    // ============================================
    devServer(info) {
        switch (info.status) {
            case 'starting':
                this.info('server', `Starting dev server on port ${info.port}...`);
                break;
            case 'started':
                this.success('server', `Dev server running on port ${info.port}`);
                if (info.url) {
                    this.info('server', `URL: ${info.url}`);
                }
                break;
            case 'stopped':
                this.info('server', 'Dev server stopped');
                break;
            case 'error':
                this.error('server', `Dev server error: ${info.error}`);
                break;
        }
    }
    tunnel(info) {
        switch (info.status) {
            case 'creating':
                this.log('info', 'server', `Creating tunnel for port ${info.port}...`, undefined, true);
                break;
            case 'created':
                this.success('server', `Tunnel: ${info.url} → localhost:${info.port}`);
                break;
            case 'closed':
                this.info('server', 'Tunnel closed');
                break;
            case 'error':
                this.error('server', `Tunnel error: ${info.error}`);
                break;
        }
    }
    // ============================================
    // Build Access
    // ============================================
    getCurrentBuild() {
        if (!this.currentBuildId)
            return null;
        return this.builds.get(this.currentBuildId) ?? null;
    }
    getAllBuilds() {
        return Array.from(this.builds.values());
    }
    getBuild(buildId) {
        return this.builds.get(buildId) ?? null;
    }
    // ============================================
    // Buffer Access
    // ============================================
    getBuffer() {
        return this.buffer;
    }
    // ============================================
    // Private Helpers
    // ============================================
    log(level, category, message, data, verbose = false) {
        // Skip verbose logs when not in verbose mode
        if (verbose && !this.verbose) {
            return;
        }
        const entry = {
            id: this.generateId(),
            timestamp: Date.now(),
            level,
            category,
            message,
            data,
            buildId: this.currentBuildId ?? undefined,
            verbose,
        };
        this.buffer.add(entry);
        if (!this.tuiMode) {
            this.printEntry(entry);
        }
        this.emit('log', entry);
    }
    printEntry(entry) {
        const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {
            hour12: false,
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit',
        });
        const levelStyles = {
            debug: chalk.gray,
            info: chalk.blue,
            success: chalk.green,
            warn: chalk.yellow,
            error: chalk.red,
        };
        const levelIcons = {
            debug: '  ',
            info: '●',
            success: '✓',
            warn: '⚠',
            error: '✗',
        };
        const style = levelStyles[entry.level];
        const icon = levelIcons[entry.level];
        if (entry.toolName) {
            // Tool calls get special formatting
            console.log(chalk.gray(time), '  ', chalk.cyan('🔧'), chalk.white(entry.toolName), entry.toolArgs ? chalk.gray(entry.toolArgs) : '');
        }
        else {
            // Regular log entries
            console.log(chalk.gray(time), style(icon), style(entry.message));
        }
    }
    truncate(str, maxLength) {
        if (str.length <= maxLength)
            return str;
        return str.substring(0, maxLength - 3) + '...';
    }
    formatDuration(seconds) {
        if (seconds < 60) {
            return `${Math.round(seconds)}s`;
        }
        const mins = Math.floor(seconds / 60);
        const secs = Math.round(seconds % 60);
        return `${mins}m ${secs}s`;
    }
    generateId() {
        return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
    }
}
// Singleton instance
let instance = null;
function getRunnerLogger() {
    if (!instance) {
        instance = new RunnerLogger();
    }
    return instance;
}
function createRunnerLogger(options) {
    instance = new RunnerLogger(options);
    return instance;
}

/**
 * RunnerLogger Instance Management
 *
 * This module provides the singleton logger instance that can be:
 * - Configured at startup (via initRunnerLogger)
 * - Accessed from anywhere in the runner (via getLogger)
 * - Integrated with the TUI dashboard
 *
 * Note: Uses the same singleton as runner-logger.ts to ensure
 * all code shares the same instance.
 */
let loggerOptions = {};
let initialized = false;
/**
 * Initialize the logger with options
 * Call this early in the runner startup
 *
 * If already initialized (e.g., by TUI before startRunner), returns the existing instance
 * to preserve event subscriptions.
 */
function initRunnerLogger(options) {
    if (initialized) {
        // Already initialized - return existing instance to preserve subscriptions
        // But update options if needed
        const logger = getRunnerLogger();
        if (options.verbose !== undefined) {
            logger.setVerbose(options.verbose);
        }
        return logger;
    }
    loggerOptions = options;
    initialized = true;
    return createRunnerLogger(options);
}
/**
 * Get the current logger instance
 * Uses the shared singleton from runner-logger.ts
 */
function getLogger() {
    if (!initialized) {
        // Create with default options if not initialized
        return createRunnerLogger(loggerOptions);
    }
    return getRunnerLogger();
}

export { streamLog as a, getLogger as b, fileLog as f, getLogBuffer as g, initRunnerLogger as i, setFileLoggerTuiMode as s };
//# sourceMappingURL=runner-logger-instance-Dj_JMznn.js.map
