/** * In-Process Log Buffer * * Ring buffer that captures structured output from in-process Crewly Agent * runtimes. Provides the same interface as PTY terminal capture so the * frontend Side Terminal panel can display crewly-agent activity. * * Extends EventEmitter to support real-time WebSocket streaming of log entries * to the frontend Side Terminal panel. * * Also persists log entries to disk at ~/.crewly/logs/sessions/{sessionName}.log, * matching the file-based logging that PTY-based agents get via PtySessionBackend. * * @module services/agent/crewly-agent/in-process-log-buffer */ import { EventEmitter } from 'events'; /** * Single log entry from an in-process agent session. */ export interface LogEntry { /** ISO timestamp */ timestamp: string; /** Log level */ level: 'info' | 'debug' | 'warn' | 'error'; /** Log message */ message: string; } /** * Singleton buffer that captures in-process agent output. * * Used by CrewlyAgentRuntimeService to log tool calls, responses, * and errors. The terminal controller reads from this buffer when * the requested session is an in-process agent (no PTY). * * Emits 'data' events with (sessionName, formattedLine) when new entries * are appended, enabling real-time WebSocket streaming via TerminalGateway. * * @example * ```typescript * const buffer = InProcessLogBuffer.getInstance(); * buffer.append('crewly-assistant', 'info', 'Calling get_team_status tool...'); * const output = buffer.capture('crewly-assistant', 50); * * // Real-time streaming * buffer.on('data', (sessionName, formattedLine) => { * console.log(`[${sessionName}] ${formattedLine}`); * }); * ``` */ export declare class InProcessLogBuffer extends EventEmitter { private static instance; private sessions; /** File write streams for persisting logs to disk */ private logStreams; /** Resolved path to ~/.crewly/logs/sessions/ */ private sessionLogsDir; /** Cached exact secret values from the backend env (see getKnownSecrets) */ private knownSecrets; constructor(); /** * Get the singleton instance. * * @returns The shared InProcessLogBuffer instance */ static getInstance(): InProcessLogBuffer; /** * Reset the singleton (for testing). */ static resetInstance(): void; /** * Format a log entry into a single display line. * * @param entry - The log entry to format * @returns Formatted string like "[HH:MM:SS.mmm] ERROR: message" */ private formatEntry; /** * Append a log entry for a session. * * Emits a 'data' event with the session name and formatted line for * real-time WebSocket streaming. * * @param sessionName - In-process agent session name * @param level - Log level * @param message - Log message text */ append(sessionName: string, level: LogEntry['level'], message: string): void; /** * Check if a session has any log entries. * * @param sessionName - Session to check * @returns True if the session has been registered with at least one entry */ hasSession(sessionName: string): boolean; /** * Capture recent output from an in-process session, formatted like * terminal output for frontend compatibility. * * @param sessionName - Session to capture from * @param lines - Maximum number of lines to return * @returns Formatted output string (one log entry per line) */ capture(sessionName: string, lines?: number): string; /** * Register a session (creates empty entry list and opens a file log stream). * * @param sessionName - Session to register */ registerSession(sessionName: string): void; /** * Remove a session's log buffer and close its file stream. * The log file is preserved on disk for post-mortem analysis. * * @param sessionName - Session to remove */ removeSession(sessionName: string): void; /** * Get all registered in-process session names. * * @returns Array of session names */ getSessionNames(): string[]; /** * Clear all sessions and close all file streams (for testing). */ clear(): void; /** * Get the file path for a session's persistent log. * * @param sessionName - Session name * @returns Absolute path to the log file */ private getLogPath; /** * Open a writable file stream for a session log. * Appends a session marker so multiple runs are distinguishable. * * @param sessionName - Session name */ private openLogStream; /** * Close and remove the file stream for a session. * * @param sessionName - Session name */ private closeLogStream; /** * Exact secret values held in the backend env, masked in every log line. * Computed once (lazily) — the backend env does not gain secrets at runtime. * * @returns Secret values, longest first */ private getKnownSecrets; /** * Write a formatted log entry to the session's file stream. * Non-blocking, fire-and-forget — errors are silently ignored. * * @param sessionName - Session name * @param entry - The log entry (for full timestamp in file) * @param formattedLine - Pre-formatted display line */ private writeToFile; } //# sourceMappingURL=in-process-log-buffer.d.ts.map