tmux-manager 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/ensure-tmux.ts","../src/tmux-manager.ts","../src/adapters/adapter-registry.ts","../src/tmux-session.ts","../src/logger.ts","../src/tmux-transport.ts","../src/task-completion-trace.ts","../src/adapters/base-adapter.ts","../src/adapters/adapter-factory.ts","../src/adapters/shell-adapter.ts"],"sourcesContent":["/**\n * tmux-manager\n *\n * Tmux-based session manager with lifecycle management,\n * pluggable adapters, and blocking prompt detection.\n *\n * Drop-in alternative to pty-manager — no native addons required.\n */\n\n// Tmux preflight check\nexport { ensureTmux, resetTmuxCheck } from './ensure-tmux.js';\n\n// Core classes\nexport { TmuxManager } from './tmux-manager.js';\nexport { TmuxSession, SPECIAL_KEYS } from './tmux-session.js';\nexport { TmuxTransport, TMUX_KEY_MAP } from './tmux-transport.js';\nexport {\n extractTaskCompletionTraceRecords,\n buildTaskCompletionTimeline,\n} from './task-completion-trace.js';\n\n// Adapter system\nexport {\n AdapterRegistry,\n BaseCLIAdapter,\n createAdapter,\n ShellAdapter,\n} from './adapters/index.js';\n\nexport type { CLIAdapter, ShellAdapterOptions } from './adapters/index.js';\n\n// Types\nexport type {\n // Session types\n SessionStatus,\n MessageType,\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n\n // Adapter types\n ParsedOutput,\n LoginDetection,\n AuthRequiredMethod,\n AuthRequiredInfo,\n BlockingPromptType,\n BlockingPromptDetection,\n AutoResponseRule,\n BlockingPromptInfo,\n\n // Stall detection types\n StallClassification,\n\n // Tool running detection\n ToolRunningInfo,\n\n // Manager types\n Logger,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n TmuxManagerConfig,\n\n // Factory types\n AdapterFactoryConfig,\n} from './types.js';\n\n// Event types\nexport type { TmuxManagerEvents } from './tmux-manager.js';\nexport type { TmuxSessionEvents } from './tmux-session.js';\nexport type {\n TaskCompletionTraceRecord,\n TaskCompletionTimelineStep,\n TaskCompletionTurnTimeline,\n TaskCompletionTimelineResult,\n BuildTimelineOptions,\n} from './task-completion-trace.js';\n\n// Transport types\nexport type { TmuxSpawnOptions, TmuxCaptureOptions } from './tmux-transport.js';\n","/**\n * Ensure tmux is installed and accessible.\n *\n * Checks that tmux is available on PATH and returns its version.\n * Throws a descriptive error if tmux is not found.\n */\n\nimport { execSync } from 'child_process';\n\nlet _checked = false;\nlet _version: string | undefined;\n\n/**\n * Verify that tmux is installed and usable.\n * Caches the result after the first successful check.\n *\n * @param log - Optional log callback for status messages\n * @returns The tmux version string (e.g., \"3.4\")\n */\nexport function ensureTmux(log?: (msg: string) => void): string {\n if (_checked && _version) {\n return _version;\n }\n\n try {\n const output = execSync('tmux -V', {\n encoding: 'utf-8',\n timeout: 5000,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n // tmux -V outputs something like \"tmux 3.4\" or \"tmux next-3.5\"\n const match = output.match(/tmux\\s+([\\w.\\-]+)/);\n _version = match?.[1] ?? output;\n _checked = true;\n\n log?.(`tmux ${_version} found`);\n return _version;\n } catch {\n throw new Error(\n 'tmux is required but not found on PATH. ' +\n 'Install it with: brew install tmux (macOS) or apt install tmux (Linux)'\n );\n }\n}\n\n/**\n * Reset the cached check (useful for testing).\n */\nexport function resetTmuxCheck(): void {\n _checked = false;\n _version = undefined;\n}\n","/**\n * Tmux Manager\n *\n * Manages multiple tmux sessions for CLI tools.\n * Mirrors PTYManager's API but uses tmux as the transport layer.\n */\n\nimport { EventEmitter } from 'events';\nimport type { CLIAdapter } from './adapters/adapter-interface.js';\nimport { AdapterRegistry } from './adapters/adapter-registry.js';\nimport { TmuxSession } from './tmux-session.js';\nimport { TmuxTransport } from './tmux-transport.js';\nimport { consoleLogger } from './logger.js';\nimport type {\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n SessionStatus,\n BlockingPromptInfo,\n AuthRequiredInfo,\n AutoResponseRule,\n StallClassification,\n ToolRunningInfo,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n TmuxManagerConfig,\n Logger,\n} from './types.js';\n\nexport interface TmuxManagerEvents {\n session_started: (session: SessionHandle) => void;\n session_ready: (session: SessionHandle) => void;\n session_stopped: (session: SessionHandle, reason: string) => void;\n session_error: (session: SessionHandle, error: string) => void;\n login_required: (session: SessionHandle, instructions?: string, url?: string) => void;\n auth_required: (session: SessionHandle, info: AuthRequiredInfo) => void;\n blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (session: SessionHandle, question: string) => void;\n stall_detected: (session: SessionHandle, recentOutput: string, stallDurationMs: number) => void;\n session_status_changed: (session: SessionHandle) => void;\n task_complete: (session: SessionHandle) => void;\n tool_running: (session: SessionHandle, info: ToolRunningInfo) => void;\n}\n\nexport class TmuxManager extends EventEmitter {\n private sessions: Map<string, TmuxSession> = new Map();\n private outputLogs: Map<string, string[]> = new Map();\n private maxLogLines: number;\n private logger: Logger;\n private transport: TmuxTransport;\n public readonly adapters: AdapterRegistry;\n\n // Stall detection config\n private _stallDetectionEnabled: boolean;\n private _stallTimeoutMs: number;\n private _onStallClassify?: (\n sessionId: string,\n recentOutput: string,\n stallDurationMs: number\n ) => Promise<StallClassification | null>;\n\n // Tmux-specific config\n private _historyLimit: number;\n private _sessionPrefix: string;\n\n constructor(config: TmuxManagerConfig = {}) {\n super();\n this.adapters = new AdapterRegistry();\n this.logger = config.logger || consoleLogger;\n this.maxLogLines = config.maxLogLines || 1000;\n this._stallDetectionEnabled = config.stallDetectionEnabled ?? false;\n this._stallTimeoutMs = config.stallTimeoutMs ?? 8000;\n this._onStallClassify = config.onStallClassify;\n this._historyLimit = config.historyLimit ?? 50000;\n this._sessionPrefix = config.sessionPrefix ?? 'parallax';\n this.transport = new TmuxTransport();\n }\n\n /**\n * Register a CLI adapter\n */\n registerAdapter(adapter: CLIAdapter): void {\n this.adapters.register(adapter);\n }\n\n /**\n * Spawn a new tmux session\n */\n async spawn(config: SpawnConfig): Promise<SessionHandle> {\n const adapter = this.adapters.get(config.type);\n if (!adapter) {\n throw new Error(\n `No adapter found for type: ${config.type}. Registered adapters: ${this.adapters.list().join(', ') || 'none'}`\n );\n }\n\n if (config.id && this.sessions.has(config.id)) {\n throw new Error(`Session with ID ${config.id} already exists`);\n }\n\n this.logger.info(\n { type: config.type, name: config.name },\n 'Spawning tmux session'\n );\n\n const session = new TmuxSession(\n adapter,\n config,\n this.logger,\n this._stallDetectionEnabled,\n this._stallTimeoutMs,\n this.transport,\n this._sessionPrefix,\n this._historyLimit,\n );\n\n this.setupSessionEvents(session);\n this.sessions.set(session.id, session);\n this.outputLogs.set(session.id, []);\n\n await session.start();\n\n const handle = session.toHandle();\n this.emit('session_started', handle);\n\n return handle;\n }\n\n /**\n * Set up event handlers for a session\n */\n private setupSessionEvents(session: TmuxSession): void {\n session.on('output', (data: string) => {\n const logs = this.outputLogs.get(session.id) || [];\n const lines = data.split('\\n');\n logs.push(...lines);\n\n while (logs.length > this.maxLogLines) {\n logs.shift();\n }\n this.outputLogs.set(session.id, logs);\n });\n\n session.on('ready', () => {\n this.emit('session_ready', session.toHandle());\n });\n\n session.on('login_required', (instructions?: string, url?: string) => {\n this.emit('login_required', session.toHandle(), instructions, url);\n });\n\n session.on('auth_required', (info: AuthRequiredInfo) => {\n this.emit('auth_required', session.toHandle(), info);\n });\n\n session.on('blocking_prompt', (promptInfo: BlockingPromptInfo, autoResponded: boolean) => {\n this.emit('blocking_prompt', session.toHandle(), promptInfo, autoResponded);\n });\n\n session.on('message', (message: SessionMessage) => {\n this.emit('message', message);\n });\n\n session.on('question', (question: string) => {\n this.emit('question', session.toHandle(), question);\n });\n\n session.on('exit', (code: number) => {\n const reason = code === 0 ? 'normal exit' : `exit code ${code}`;\n this.emit('session_stopped', session.toHandle(), reason);\n });\n\n session.on('error', (error: Error) => {\n this.emit('session_error', session.toHandle(), error.message);\n });\n\n session.on('status_changed', () => {\n this.emit('session_status_changed', session.toHandle());\n });\n\n session.on('task_complete', () => {\n this.emit('task_complete', session.toHandle());\n });\n\n session.on('tool_running', (info: ToolRunningInfo) => {\n this.emit('tool_running', session.toHandle(), info);\n });\n\n session.on('stall_detected', (recentOutput: string, stallDurationMs: number) => {\n const handle = session.toHandle();\n this.emit('stall_detected', handle, recentOutput, stallDurationMs);\n\n if (this._onStallClassify) {\n const sanitized = recentOutput\n .slice(-1500)\n .replace(/\\b(ignore|disregard|forget)\\s+(all\\s+)?(previous|above|prior)\\s+(instructions?|prompts?|rules?)\\b/gi, '[REDACTED]')\n .replace(/\\b(you\\s+are|act\\s+as|pretend\\s+to\\s+be|you\\s+must|system\\s*:)\\b/gi, '[REDACTED]');\n this._onStallClassify(session.id, sanitized, stallDurationMs)\n .then((classification) => {\n session.handleStallClassification(classification);\n })\n .catch((err) => {\n this.logger.error(\n { sessionId: session.id, error: err },\n 'Stall classification callback failed'\n );\n session.handleStallClassification(null);\n });\n }\n });\n }\n\n /**\n * Stop a session\n */\n async stop(sessionId: string, options?: StopOptions): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n this.logger.info({ sessionId, force: options?.force }, 'Stopping session');\n\n const timeout = options?.timeout || 5000;\n\n return new Promise((resolve) => {\n const timer = setTimeout(() => {\n session.kill('SIGKILL');\n // Give SIGKILL a moment then clean up\n setTimeout(() => {\n session.removeAllListeners();\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n }, 500);\n }, timeout);\n\n session.once('exit', () => {\n clearTimeout(timer);\n session.removeAllListeners();\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n });\n\n session.kill(options?.force ? 'SIGKILL' : 'SIGTERM');\n });\n }\n\n /**\n * Stop all sessions\n */\n async stopAll(options?: StopOptions): Promise<void> {\n const stopPromises = Array.from(this.sessions.keys()).map((id) =>\n this.stop(id, options).catch((err) => {\n this.logger.warn({ sessionId: id, error: err }, 'Error stopping session');\n })\n );\n\n await Promise.all(stopPromises);\n }\n\n /**\n * Get a session by ID\n */\n get(sessionId: string): SessionHandle | null {\n const session = this.sessions.get(sessionId);\n return session ? session.toHandle() : null;\n }\n\n /**\n * List all sessions\n */\n list(filter?: SessionFilter): SessionHandle[] {\n const handles: SessionHandle[] = [];\n\n for (const session of this.sessions.values()) {\n const handle = session.toHandle();\n\n if (filter) {\n if (filter.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];\n if (!statuses.includes(handle.status)) continue;\n }\n\n if (filter.type) {\n const types = Array.isArray(filter.type) ? filter.type : [filter.type];\n if (!types.includes(handle.type)) continue;\n }\n }\n\n handles.push(handle);\n }\n\n return handles;\n }\n\n /**\n * Send a message to a session\n */\n send(sessionId: string, message: string): SessionMessage {\n const session = this.sessions.get(sessionId);\n if (!session) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n return session.send(message);\n }\n\n /**\n * Get logs for a session\n */\n async *logs(sessionId: string, options?: LogOptions): AsyncIterable<string> {\n const logBuffer = this.outputLogs.get(sessionId);\n if (!logBuffer) {\n throw new Error(`Session not found: ${sessionId}`);\n }\n\n const lines = options?.tail\n ? logBuffer.slice(-options.tail)\n : logBuffer;\n\n for (const line of lines) {\n yield line;\n }\n }\n\n /**\n * Get metrics for a session\n */\n metrics(sessionId: string): { uptime?: number; messageCount?: number } | null {\n const session = this.sessions.get(sessionId);\n if (!session) return null;\n\n const handle = session.toHandle();\n const uptime = handle.startedAt\n ? Math.floor((Date.now() - handle.startedAt.getTime()) / 1000)\n : undefined;\n\n return { uptime };\n }\n\n /**\n * Shutdown manager and stop all sessions\n */\n async shutdown(): Promise<void> {\n this.logger.info({ count: this.sessions.size }, 'Shutting down all tmux sessions');\n\n await this.stopAll({ timeout: 3000 });\n\n this.sessions.clear();\n this.outputLogs.clear();\n this.transport.destroy();\n }\n\n /**\n * Get count of sessions by status\n */\n getStatusCounts(): Record<SessionStatus, number> {\n const counts: Record<SessionStatus, number> = {\n pending: 0,\n starting: 0,\n authenticating: 0,\n ready: 0,\n busy: 0,\n stopping: 0,\n stopped: 0,\n error: 0,\n };\n\n for (const session of this.sessions.values()) {\n counts[session.status]++;\n }\n\n return counts;\n }\n\n /**\n * Attach to a session's terminal for raw I/O streaming\n */\n attachTerminal(sessionId: string): TerminalAttachment | null {\n const session = this.sessions.get(sessionId);\n if (!session) return null;\n\n return {\n onData: (callback: (data: string) => void) => {\n session.on('output', callback);\n return () => session.off('output', callback);\n },\n write: (data: string) => {\n session.writeRaw(data);\n },\n resize: (cols: number, rows: number) => {\n session.resize(cols, rows);\n },\n };\n }\n\n /**\n * Check if a session exists\n */\n has(sessionId: string): boolean {\n return this.sessions.has(sessionId);\n }\n\n /**\n * Get the underlying TmuxSession (for advanced use)\n */\n getSession(sessionId: string): TmuxSession | undefined {\n return this.sessions.get(sessionId);\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Tmux-Specific Features\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * List orphaned tmux sessions from previous runs.\n * These are tmux sessions with the configured prefix that aren't tracked by this manager.\n */\n listOrphanedSessions(): Array<{ name: string; created: string; attached: boolean }> {\n const tmuxSessions = TmuxTransport.listSessions(this._sessionPrefix);\n const managedNames = new Set(\n Array.from(this.sessions.values()).map(s => s.tmuxName)\n );\n\n return tmuxSessions.filter(s => !managedNames.has(s.name));\n }\n\n /**\n * Clean up orphaned tmux sessions from previous runs.\n */\n cleanupOrphanedSessions(): number {\n const orphans = this.listOrphanedSessions();\n for (const orphan of orphans) {\n try {\n this.transport.kill(orphan.name);\n this.logger.info({ tmuxSession: orphan.name }, 'Cleaned up orphaned tmux session');\n } catch {\n this.logger.warn({ tmuxSession: orphan.name }, 'Failed to clean up orphaned tmux session');\n }\n }\n return orphans.length;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Stall Detection Configuration\n // ─────────────────────────────────────────────────────────────────────────────\n\n configureStallDetection(\n enabled: boolean,\n timeoutMs?: number,\n classify?: (sessionId: string, recentOutput: string, stallDurationMs: number) => Promise<StallClassification | null>,\n ): void {\n this._stallDetectionEnabled = enabled;\n if (timeoutMs !== undefined) {\n this._stallTimeoutMs = timeoutMs;\n }\n if (classify !== undefined) {\n this._onStallClassify = classify;\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Runtime Auto-Response Rules API\n // ─────────────────────────────────────────────────────────────────────────────\n\n addAutoResponseRule(sessionId: string, rule: AutoResponseRule): void {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Session not found: ${sessionId}`);\n session.addAutoResponseRule(rule);\n }\n\n removeAutoResponseRule(sessionId: string, pattern: RegExp): boolean {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Session not found: ${sessionId}`);\n return session.removeAutoResponseRule(pattern);\n }\n\n setAutoResponseRules(sessionId: string, rules: AutoResponseRule[]): void {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Session not found: ${sessionId}`);\n session.setAutoResponseRules(rules);\n }\n\n getAutoResponseRules(sessionId: string): AutoResponseRule[] {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Session not found: ${sessionId}`);\n return session.getAutoResponseRules();\n }\n\n clearAutoResponseRules(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Session not found: ${sessionId}`);\n session.clearAutoResponseRules();\n }\n}\n","/**\n * Adapter Registry — re-exported from adapter-types\n */\nexport { AdapterRegistry } from 'adapter-types';\n","/**\n * Tmux Session\n *\n * Manages a single tmux session for a CLI tool.\n * Mirrors PTYSession's API but uses TmuxTransport instead of node-pty.\n */\n\nimport { EventEmitter } from 'events';\nimport { randomUUID } from 'crypto';\nimport type { CLIAdapter } from './adapters/adapter-interface.js';\nimport type {\n SpawnConfig,\n SessionStatus,\n SessionHandle,\n SessionMessage,\n BlockingPromptInfo,\n AuthRequiredInfo,\n LoginDetection,\n AutoResponseRule,\n StallClassification,\n ToolRunningInfo,\n Logger,\n} from './types.js';\nimport { consoleLogger } from './logger.js';\nimport { TmuxTransport } from './tmux-transport.js';\n\nexport interface TmuxSessionEvents {\n output: (data: string) => void;\n ready: () => void;\n login_required: (instructions?: string, url?: string) => void;\n auth_required: (info: AuthRequiredInfo) => void;\n blocking_prompt: (prompt: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (question: string) => void;\n exit: (code: number) => void;\n error: (error: Error) => void;\n stall_detected: (recentOutput: string, stallDurationMs: number) => void;\n status_changed: (status: SessionStatus) => void;\n task_complete: () => void;\n tool_running: (info: ToolRunningInfo) => void;\n}\n\n/**\n * Special key mappings to escape sequences (for compatibility with adapters that reference SPECIAL_KEYS)\n */\nexport const SPECIAL_KEYS: Record<string, string> = {\n // Control keys\n 'ctrl+a': '\\x01', 'ctrl+b': '\\x02', 'ctrl+c': '\\x03', 'ctrl+d': '\\x04',\n 'ctrl+e': '\\x05', 'ctrl+f': '\\x06', 'ctrl+g': '\\x07', 'ctrl+h': '\\x08',\n 'ctrl+i': '\\x09', 'ctrl+j': '\\x0a', 'ctrl+k': '\\x0b', 'ctrl+l': '\\x0c',\n 'ctrl+m': '\\x0d', 'ctrl+n': '\\x0e', 'ctrl+o': '\\x0f', 'ctrl+p': '\\x10',\n 'ctrl+q': '\\x11', 'ctrl+r': '\\x12', 'ctrl+s': '\\x13', 'ctrl+t': '\\x14',\n 'ctrl+u': '\\x15', 'ctrl+v': '\\x16', 'ctrl+w': '\\x17', 'ctrl+x': '\\x18',\n 'ctrl+y': '\\x19', 'ctrl+z': '\\x1a',\n // Navigation\n 'up': '\\x1b[A', 'down': '\\x1b[B', 'right': '\\x1b[C', 'left': '\\x1b[D',\n 'home': '\\x1b[H', 'end': '\\x1b[F', 'pageup': '\\x1b[5~', 'pagedown': '\\x1b[6~',\n // Editing\n 'enter': '\\r', 'return': '\\r', 'tab': '\\t', 'backspace': '\\x7f',\n 'delete': '\\x1b[3~', 'insert': '\\x1b[2~', 'escape': '\\x1b', 'esc': '\\x1b', 'space': ' ',\n // Function keys\n 'f1': '\\x1bOP', 'f2': '\\x1bOQ', 'f3': '\\x1bOR', 'f4': '\\x1bOS',\n 'f5': '\\x1b[15~', 'f6': '\\x1b[17~', 'f7': '\\x1b[18~', 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~', 'f10': '\\x1b[21~', 'f11': '\\x1b[23~', 'f12': '\\x1b[24~',\n};\n\nfunction generateId(): string {\n return `tmux-${Date.now()}-${randomUUID().slice(0, 8)}`;\n}\n\nexport class TmuxSession extends EventEmitter {\n private transport: TmuxTransport;\n private tmuxSessionName: string;\n private outputBuffer: string = '';\n private _status: SessionStatus = 'pending';\n private _startedAt: Date | null = null;\n private _lastActivityAt: Date | null = null;\n private messageCounter: number = 0;\n private logger: Logger;\n private sessionRules: AutoResponseRule[] = [];\n private _firedOnceRules: Set<string> = new Set();\n private _lastBlockingPromptHash: string | null = null;\n private _ruleOverrides: Map<string, Partial<AutoResponseRule>> = new Map();\n private _disabledRulePatterns: Set<string> = new Set();\n\n // Stall detection\n private _stallTimer: ReturnType<typeof setTimeout> | null = null;\n private _stallTimeoutMs: number;\n private _stallDetectionEnabled: boolean;\n private _lastStallHash: string | null = null;\n private _stallStartedAt: number | null = null;\n private _lastContentHash: string | null = null;\n private _stallBackoffMs: number = 0;\n private static readonly MAX_STALL_BACKOFF_MS = 30_000;\n private _stallEmissionCount: number = 0;\n private static readonly MAX_STALL_EMISSIONS = 5;\n\n // Task completion detection\n private _taskCompleteTimer: ReturnType<typeof setTimeout> | null = null;\n private _taskCompletePending = false;\n private static readonly TASK_COMPLETE_DEBOUNCE_MS = 1500;\n\n // Ready detection settle delay\n private _readySettleTimer: ReturnType<typeof setTimeout> | null = null;\n private _readySettlePending = false;\n\n // Tool running deduplication\n private _lastToolRunningName: string | null = null;\n\n // Output buffer cap\n private static readonly MAX_OUTPUT_BUFFER = 100_000;\n\n // Poll-based exit detection\n private _exitPollTimer: ReturnType<typeof setInterval> | null = null;\n\n // Session prefix for tmux session naming\n private sessionPrefix: string;\n\n // History limit for tmux scrollback\n private historyLimit: number;\n\n public readonly id: string;\n public readonly config: SpawnConfig;\n\n constructor(\n private adapter: CLIAdapter,\n config: SpawnConfig,\n logger?: Logger,\n stallDetectionEnabled?: boolean,\n defaultStallTimeoutMs?: number,\n transport?: TmuxTransport,\n sessionPrefix?: string,\n historyLimit?: number,\n ) {\n super();\n this.id = config.id || generateId();\n this.config = { ...config, id: this.id };\n this.logger = logger || consoleLogger;\n this._stallDetectionEnabled = stallDetectionEnabled ?? false;\n this._stallTimeoutMs = config.stallTimeoutMs ?? defaultStallTimeoutMs ?? 8000;\n this._stallBackoffMs = this._stallTimeoutMs;\n this.transport = transport || new TmuxTransport();\n this.sessionPrefix = sessionPrefix || 'parallax';\n this.historyLimit = historyLimit || 50000;\n this.tmuxSessionName = `${this.sessionPrefix}-${this.id}`;\n\n if (config.ruleOverrides) {\n for (const [key, value] of Object.entries(config.ruleOverrides)) {\n if (value === null) {\n this._disabledRulePatterns.add(key);\n } else {\n this._ruleOverrides.set(key, value);\n }\n }\n }\n }\n\n get status(): SessionStatus {\n return this._status;\n }\n\n get pid(): number | undefined {\n return this.transport.getPanePid(this.tmuxSessionName);\n }\n\n get startedAt(): Date | undefined {\n return this._startedAt ?? undefined;\n }\n\n get lastActivityAt(): Date | undefined {\n return this._lastActivityAt ?? undefined;\n }\n\n /**\n * Get the tmux session name (for reconnection/debugging).\n */\n get tmuxName(): string {\n return this.tmuxSessionName;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Runtime Auto-Response Rules API\n // ─────────────────────────────────────────────────────────────────────────────\n\n addAutoResponseRule(rule: AutoResponseRule): void {\n const existingIndex = this.sessionRules.findIndex(\n (r) => r.pattern.source === rule.pattern.source && r.pattern.flags === rule.pattern.flags\n );\n\n if (existingIndex >= 0) {\n this.sessionRules[existingIndex] = rule;\n } else {\n this.sessionRules.push(rule);\n }\n }\n\n removeAutoResponseRule(pattern: RegExp): boolean {\n const initialLength = this.sessionRules.length;\n this.sessionRules = this.sessionRules.filter(\n (r) => !(r.pattern.source === pattern.source && r.pattern.flags === pattern.flags)\n );\n return this.sessionRules.length < initialLength;\n }\n\n setAutoResponseRules(rules: AutoResponseRule[]): void {\n this.sessionRules = [...rules];\n }\n\n getAutoResponseRules(): AutoResponseRule[] {\n return [...this.sessionRules];\n }\n\n clearAutoResponseRules(): void {\n this.sessionRules = [];\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Stall Detection\n // ─────────────────────────────────────────────────────────────────────────────\n\n private resetStallTimer(): void {\n if (!this._stallDetectionEnabled || (this._status !== 'busy' && this._status !== 'authenticating')) {\n this.clearStallTimer();\n return;\n }\n\n const stripped = this.stripAnsiForStall(this.outputBuffer).trim();\n const tail = stripped.slice(-500);\n const hash = this.simpleHash(tail);\n\n if (hash === this._lastContentHash) {\n return;\n }\n this._lastContentHash = hash;\n this._stallEmissionCount = 0;\n\n if (this._stallTimer) {\n clearTimeout(this._stallTimer);\n this._stallTimer = null;\n }\n this._stallStartedAt = Date.now();\n this._lastStallHash = null;\n this._stallBackoffMs = this._stallTimeoutMs;\n\n this._stallTimer = setTimeout(() => {\n this.onStallTimerFired();\n }, this._stallTimeoutMs);\n }\n\n private clearStallTimer(): void {\n if (this._stallTimer) {\n clearTimeout(this._stallTimer);\n this._stallTimer = null;\n }\n this._stallStartedAt = null;\n this._lastContentHash = null;\n this._stallBackoffMs = this._stallTimeoutMs;\n this._stallEmissionCount = 0;\n }\n\n private onStallTimerFired(): void {\n if (this._status !== 'busy' && this._status !== 'authenticating') {\n return;\n }\n\n // Fast path: adapter task completion\n if (this._status === 'busy' && this.adapter.detectTaskComplete?.(this.outputBuffer)) {\n this._status = 'ready';\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.clearStallTimer();\n this.emit('status_changed', 'ready');\n this.emit('task_complete');\n this.logger.info({ sessionId: this.id }, 'Task complete (adapter fast-path)');\n return;\n }\n\n // Loading suppression\n if (this.adapter.detectLoading?.(this.outputBuffer)) {\n this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);\n return;\n }\n\n // Tool running suppression\n const toolInfo = this.adapter.detectToolRunning?.(this.outputBuffer);\n if (toolInfo) {\n if (toolInfo.toolName !== this._lastToolRunningName) {\n this._lastToolRunningName = toolInfo.toolName;\n this.emit('tool_running', toolInfo);\n }\n this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);\n return;\n }\n if (this._lastToolRunningName) {\n this._lastToolRunningName = null;\n }\n\n // Dedup hash check\n const tail = this.outputBuffer.slice(-500);\n const hash = this.simpleHash(tail);\n if (hash === this._lastStallHash) {\n this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);\n return;\n }\n this._lastStallHash = hash;\n\n this._stallEmissionCount++;\n if (this._stallEmissionCount > TmuxSession.MAX_STALL_EMISSIONS) {\n this.logger.warn({ sessionId: this.id }, 'Max stall emissions reached');\n this.clearStallTimer();\n return;\n }\n\n const recentRaw = this.outputBuffer.slice(-2000);\n const recentOutput = this.stripAnsiForClassifier(recentRaw).trim();\n const stallDurationMs = this._stallStartedAt\n ? Date.now() - this._stallStartedAt\n : this._stallTimeoutMs;\n\n this.emit('stall_detected', recentOutput, stallDurationMs);\n this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);\n }\n\n handleStallClassification(classification: StallClassification | null): void {\n if (this._status !== 'busy' && this._status !== 'authenticating') {\n return;\n }\n\n if (!classification || classification.state === 'still_working') {\n this._stallBackoffMs = Math.min(\n this._stallBackoffMs * 2,\n TmuxSession.MAX_STALL_BACKOFF_MS,\n );\n this._lastContentHash = null;\n this._lastStallHash = null;\n if (this._stallTimer) {\n clearTimeout(this._stallTimer);\n this._stallTimer = null;\n }\n this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);\n return;\n }\n\n switch (classification.state) {\n case 'waiting_for_input': {\n const promptInfo: BlockingPromptInfo = {\n type: 'stall_classified',\n prompt: classification.prompt,\n canAutoRespond: !!classification.suggestedResponse,\n };\n\n if (classification.suggestedResponse) {\n const resp = classification.suggestedResponse;\n if (resp.startsWith('keys:')) {\n const keys = resp.slice(5).split(',').map(k => k.trim());\n this.sendKeySequence(keys);\n } else {\n this.transport.sendText(this.tmuxSessionName, resp);\n this.transport.sendKey(this.tmuxSessionName, 'enter');\n }\n this.outputBuffer = '';\n this.emit('blocking_prompt', promptInfo, true);\n } else {\n this.emit('blocking_prompt', promptInfo, false);\n }\n break;\n }\n\n case 'task_complete':\n this._status = 'ready';\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.clearStallTimer();\n this.emit('ready');\n break;\n\n case 'error':\n this.clearStallTimer();\n this.emit('error', new Error(classification.prompt || 'Stall classified as error'));\n break;\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Task Completion Detection\n // ─────────────────────────────────────────────────────────────────────────────\n\n private scheduleTaskComplete(): void {\n if (this._taskCompleteTimer) {\n clearTimeout(this._taskCompleteTimer);\n }\n this._taskCompletePending = true;\n\n this._taskCompleteTimer = setTimeout(() => {\n this._taskCompleteTimer = null;\n this._taskCompletePending = false;\n\n const signal = this.isTaskCompleteSignal(this.outputBuffer);\n if (this._status !== 'busy') return;\n if (!signal) return;\n\n this._status = 'ready';\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.clearStallTimer();\n this.emit('status_changed', 'ready');\n this.emit('task_complete');\n this.logger.info({ sessionId: this.id }, 'Task complete — agent returned to idle prompt');\n }, TmuxSession.TASK_COMPLETE_DEBOUNCE_MS);\n }\n\n private isTaskCompleteSignal(output: string): boolean {\n if (this.adapter.detectTaskComplete) {\n return this.adapter.detectTaskComplete(output);\n }\n return this.adapter.detectReady(output);\n }\n\n private cancelTaskComplete(): void {\n if (this._taskCompleteTimer) {\n clearTimeout(this._taskCompleteTimer);\n this._taskCompleteTimer = null;\n }\n this._taskCompletePending = false;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Ready Detection Settle Delay\n // ─────────────────────────────────────────────────────────────────────────────\n\n private scheduleReadySettle(): void {\n this._readySettlePending = true;\n if (this._readySettleTimer) {\n clearTimeout(this._readySettleTimer);\n }\n const settleMs = this.config.readySettleMs ?? this.adapter.readySettleMs ?? 100;\n this._readySettleTimer = setTimeout(() => {\n this._readySettleTimer = null;\n this._readySettlePending = false;\n if (this._status !== 'starting' && this._status !== 'authenticating') return;\n if (!this.adapter.detectReady(this.outputBuffer)) return;\n this._status = 'ready';\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.clearStallTimer();\n this.emit('ready');\n this.logger.info({ sessionId: this.id }, 'Session ready (after settle)');\n }, settleMs);\n }\n\n private cancelReadySettle(): void {\n if (this._readySettleTimer) {\n clearTimeout(this._readySettleTimer);\n this._readySettleTimer = null;\n }\n this._readySettlePending = false;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Lifecycle\n // ─────────────────────────────────────────────────────────────────────────────\n\n async start(): Promise<void> {\n this._status = 'starting';\n this._startedAt = new Date();\n\n const command = this.adapter.getCommand();\n const args = this.adapter.getArgs(this.config);\n const adapterEnv = this.adapter.getEnv(this.config);\n const env = TmuxSession.buildSpawnEnv(this.config, adapterEnv);\n\n this.logger.info(\n { sessionId: this.id, command, args: args.join(' '), tmuxSession: this.tmuxSessionName },\n 'Starting tmux session'\n );\n\n try {\n this.transport.spawn(this.tmuxSessionName, {\n command,\n args,\n cwd: this.config.workdir || process.cwd(),\n env,\n cols: this.config.cols || 120,\n rows: this.config.rows || 40,\n historyLimit: this.historyLimit,\n });\n\n // Start streaming output\n this.transport.startOutputStreaming(this.tmuxSessionName, (data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n if (this.outputBuffer.length > TmuxSession.MAX_OUTPUT_BUFFER) {\n this.outputBuffer = this.outputBuffer.slice(-TmuxSession.MAX_OUTPUT_BUFFER);\n }\n\n this.emit('output', data);\n this.processOutputBuffer();\n });\n\n // Poll for process exit (tmux remain-on-exit keeps the pane alive)\n this._exitPollTimer = setInterval(() => {\n if (!this.transport.isPaneAlive(this.tmuxSessionName)) {\n const exitCode = this.transport.getPaneExitStatus(this.tmuxSessionName) ?? 0;\n this.handleExit(exitCode);\n }\n }, 1000);\n\n this.logger.info(\n { sessionId: this.id, pid: this.pid, tmuxSession: this.tmuxSessionName },\n 'Tmux session started'\n );\n } catch (error) {\n this._status = 'error';\n this.logger.error({ sessionId: this.id, error }, 'Failed to start tmux session');\n throw error;\n }\n }\n\n /**\n * Reconnect to an existing tmux session.\n * Used for crash recovery.\n */\n async reconnect(existingTmuxName: string): Promise<void> {\n if (!this.transport.isAlive(existingTmuxName)) {\n throw new Error(`Tmux session ${existingTmuxName} does not exist`);\n }\n\n this.tmuxSessionName = existingTmuxName;\n this._status = 'starting';\n this._startedAt = new Date();\n\n // Re-attach output streaming\n this.transport.startOutputStreaming(this.tmuxSessionName, (data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n if (this.outputBuffer.length > TmuxSession.MAX_OUTPUT_BUFFER) {\n this.outputBuffer = this.outputBuffer.slice(-TmuxSession.MAX_OUTPUT_BUFFER);\n }\n\n this.emit('output', data);\n this.processOutputBuffer();\n });\n\n // Capture current pane content to seed the output buffer\n const currentContent = this.transport.capturePane(this.tmuxSessionName, { ansi: true });\n if (currentContent) {\n this.outputBuffer = currentContent;\n this.processOutputBuffer();\n }\n\n // Start exit polling\n this._exitPollTimer = setInterval(() => {\n if (!this.transport.isPaneAlive(this.tmuxSessionName)) {\n const exitCode = this.transport.getPaneExitStatus(this.tmuxSessionName) ?? 0;\n this.handleExit(exitCode);\n }\n }, 1000);\n\n this.logger.info(\n { sessionId: this.id, tmuxSession: this.tmuxSessionName },\n 'Reconnected to tmux session'\n );\n }\n\n private handleExit(exitCode: number): void {\n if (this._status === 'stopped' || this._status === 'stopping') return;\n this._status = 'stopped';\n this.clearStallTimer();\n this.cancelTaskComplete();\n this.cancelReadySettle();\n this.stopExitPolling();\n this.transport.stopOutputStreaming(this.tmuxSessionName);\n this.logger.info({ sessionId: this.id, exitCode }, 'Tmux session exited');\n this.emit('exit', exitCode);\n }\n\n private stopExitPolling(): void {\n if (this._exitPollTimer) {\n clearInterval(this._exitPollTimer);\n this._exitPollTimer = null;\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Output Processing\n // ─────────────────────────────────────────────────────────────────────────────\n\n private processOutputBuffer(): void {\n if (this._status === 'busy' || this._status === 'authenticating') {\n this.resetStallTimer();\n }\n\n if (this._readySettlePending) {\n if (\n (this._status === 'starting' || this._status === 'authenticating') &&\n this.adapter.detectReady(this.outputBuffer)\n ) {\n this.scheduleReadySettle();\n } else {\n this.cancelReadySettle();\n }\n return;\n }\n\n // Ready detection\n if (\n (this._status === 'starting' || this._status === 'authenticating') &&\n this.adapter.detectReady(this.outputBuffer)\n ) {\n this.scheduleReadySettle();\n return;\n }\n\n // Tool running detection\n if (this._status === 'busy') {\n const toolInfo = this.adapter.detectToolRunning?.(this.outputBuffer);\n if (toolInfo) {\n if (toolInfo.toolName !== this._lastToolRunningName) {\n this._lastToolRunningName = toolInfo.toolName;\n this.emit('tool_running', toolInfo);\n }\n } else if (this._lastToolRunningName) {\n this._lastToolRunningName = null;\n }\n }\n\n // Task completion detection\n if (this._status === 'busy') {\n const signal = this.isTaskCompleteSignal(this.outputBuffer);\n if (this._taskCompletePending || signal) {\n this.scheduleTaskComplete();\n }\n }\n\n // Auto-response / blocking prompt detection\n if (this._status !== 'stopping' && this._status !== 'stopped') {\n const blockingPrompt = this.detectAndHandleBlockingPrompt();\n if (blockingPrompt) return;\n }\n\n // Login detection\n if (this._status !== 'ready' && this._status !== 'busy') {\n const loginDetection = this.adapter.detectLogin(this.outputBuffer);\n if (loginDetection.required && this._status !== 'authenticating') {\n this._status = 'authenticating';\n this.clearStallTimer();\n this.emitAuthRequired({\n type: loginDetection.type,\n url: loginDetection.url,\n deviceCode: loginDetection.deviceCode,\n instructions: loginDetection.instructions,\n });\n return;\n }\n }\n\n // Exit detection (adapter-level)\n const exitDetection = this.adapter.detectExit(this.outputBuffer);\n if (exitDetection.exited) {\n this._status = 'stopped';\n this.clearStallTimer();\n this.emit('exit', exitDetection.code || 0);\n }\n\n // Parse output when ready\n if (this._status === 'ready') {\n this.tryParseOutput();\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Blocking Prompt Detection & Auto-Response\n // ─────────────────────────────────────────────────────────────────────────────\n\n private detectAndHandleBlockingPrompt(): boolean {\n const autoHandled = this.tryAutoResponse();\n if (autoHandled) return true;\n\n if (this.adapter.detectBlockingPrompt) {\n const detection = this.adapter.detectBlockingPrompt(this.outputBuffer);\n\n if (detection.detected) {\n const normalizedPrompt = (detection.prompt || '')\n .replace(/\\s+/g, ' ')\n .replace(/\\d+/g, '#')\n .trim()\n .slice(0, 100);\n const promptHash = `${detection.type}:${normalizedPrompt}`;\n if (promptHash === this._lastBlockingPromptHash) return true;\n this._lastBlockingPromptHash = promptHash;\n\n const promptInfo: BlockingPromptInfo = {\n type: detection.type || 'unknown',\n prompt: detection.prompt,\n options: detection.options,\n canAutoRespond: detection.canAutoRespond || false,\n instructions: detection.instructions,\n url: detection.url,\n };\n\n if (detection.canAutoRespond && detection.suggestedResponse && !this.config.skipAdapterAutoResponse) {\n const resp = detection.suggestedResponse;\n if (resp.startsWith('keys:')) {\n const keys = resp.slice(5).split(',').map(k => k.trim());\n this.sendKeySequence(keys);\n } else {\n this.transport.sendText(this.tmuxSessionName, resp);\n this.transport.sendKey(this.tmuxSessionName, 'enter');\n }\n this.outputBuffer = '';\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n }\n\n if (detection.type === 'login') {\n this._status = 'authenticating';\n const inferred = this.adapter.detectLogin(this.outputBuffer);\n this.emitAuthRequired({\n type: inferred.required ? inferred.type : undefined,\n url: detection.url ?? inferred.url,\n deviceCode: inferred.required ? inferred.deviceCode : undefined,\n instructions: detection.instructions ?? inferred.instructions,\n });\n }\n\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n } else {\n this._lastBlockingPromptHash = null;\n }\n }\n\n return false;\n }\n\n private tryAutoResponse(): boolean {\n const adapterRules = (this.adapter.autoResponseRules || [])\n .filter(r => !this._disabledRulePatterns.has(r.pattern.source))\n .map(r => {\n const override = this._ruleOverrides.get(r.pattern.source);\n return override ? { ...r, ...override } : r;\n });\n const allRules = [...this.sessionRules, ...adapterRules];\n\n if (allRules.length === 0) return false;\n\n const stripped = this.stripAnsiForStall(this.outputBuffer);\n\n for (const rule of allRules) {\n if (rule.once) {\n const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;\n if (this._firedOnceRules.has(ruleKey)) continue;\n }\n\n if (rule.pattern.test(stripped)) {\n const safe = rule.safe !== false;\n\n if (safe) {\n const useKeys = rule.keys && rule.keys.length > 0;\n const isTuiDefault = !rule.responseType && !rule.keys && this.adapter.usesTuiMenus;\n\n if (useKeys) {\n this.sendKeySequence(rule.keys!);\n } else if (isTuiDefault) {\n this.sendKeys('enter');\n } else {\n this.transport.sendText(this.tmuxSessionName, rule.response);\n this.transport.sendKey(this.tmuxSessionName, 'enter');\n }\n\n if (rule.once) {\n const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;\n this._firedOnceRules.add(ruleKey);\n }\n\n this.outputBuffer = '';\n\n const promptInfo: BlockingPromptInfo = {\n type: rule.type,\n prompt: rule.description,\n canAutoRespond: true,\n };\n\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n } else {\n const promptInfo: BlockingPromptInfo = {\n type: rule.type,\n prompt: rule.description,\n canAutoRespond: false,\n instructions: `Prompt matched but requires user confirmation: ${rule.description}`,\n };\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n }\n\n return false;\n }\n\n private tryParseOutput(): void {\n const parsed = this.adapter.parseOutput(this.outputBuffer);\n\n if (parsed && parsed.isComplete) {\n this.outputBuffer = '';\n\n const message: SessionMessage = {\n id: `${this.id}-msg-${++this.messageCounter}`,\n sessionId: this.id,\n direction: 'outbound',\n type: parsed.type,\n content: parsed.content,\n metadata: parsed.metadata,\n timestamp: new Date(),\n };\n\n this.emit('message', message);\n\n if (parsed.isQuestion) {\n this.emit('question', parsed.content);\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // I/O Methods\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Write data to the session (formatted by adapter, with Enter)\n */\n write(data: string): void {\n this._lastActivityAt = new Date();\n const formatted = this.adapter.formatInput(data);\n this.transport.sendText(this.tmuxSessionName, formatted);\n this.transport.sendKey(this.tmuxSessionName, 'enter');\n }\n\n /**\n * Write raw data directly (no formatting, no Enter)\n */\n writeRaw(data: string): void {\n this._lastActivityAt = new Date();\n this.transport.sendText(this.tmuxSessionName, data);\n }\n\n /**\n * Send a task/message to the session\n */\n send(message: string): SessionMessage {\n this._status = 'busy';\n this.outputBuffer = '';\n this.emit('status_changed', 'busy');\n this._stallEmissionCount = 0;\n this.resetStallTimer();\n\n const msg: SessionMessage = {\n id: `${this.id}-msg-${++this.messageCounter}`,\n sessionId: this.id,\n direction: 'inbound',\n type: 'task',\n content: message,\n timestamp: new Date(),\n };\n\n const formatted = this.adapter.formatInput(message);\n this.transport.sendText(this.tmuxSessionName, formatted);\n\n // Send Enter separately after a brief delay for TUI compatibility\n setTimeout(() => {\n this.transport.sendKey(this.tmuxSessionName, 'enter');\n }, 50);\n\n return msg;\n }\n\n /**\n * Resize the terminal\n */\n resize(cols: number, rows: number): void {\n this.transport.resize(this.tmuxSessionName, cols, rows);\n }\n\n /**\n * Send special keys to the session.\n * Uses tmux send-keys with named keys.\n */\n sendKeys(keys: string | string[]): void {\n const keyList = Array.isArray(keys) ? keys : [keys];\n const normalized = TmuxSession.normalizeKeyList(keyList);\n this._stallEmissionCount = 0;\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.resetStallTimer();\n\n for (const key of normalized) {\n this._lastActivityAt = new Date();\n this.transport.sendKey(this.tmuxSessionName, key);\n }\n }\n\n /**\n * Select a TUI menu option by index (0-based).\n */\n async selectMenuOption(optionIndex: number): Promise<void> {\n for (let i = 0; i < optionIndex; i++) {\n this.sendKeys('down');\n await this.delay(50);\n }\n this.sendKeys('enter');\n }\n\n /**\n * Send a sequence of keys with staggered timing.\n */\n private sendKeySequence(keys: string[]): void {\n keys.forEach((key, i) => {\n setTimeout(() => this.sendKeys(key), i * 50);\n });\n }\n\n /**\n * Paste text using bracketed paste mode\n */\n paste(text: string, useBracketedPaste: boolean = true): void {\n this._lastActivityAt = new Date();\n\n if (useBracketedPaste) {\n // Send bracketed paste escape sequences around the text\n this.transport.sendText(this.tmuxSessionName, '\\x1b[200~' + text + '\\x1b[201~');\n } else {\n this.transport.sendText(this.tmuxSessionName, text);\n }\n }\n\n /**\n * Notify the session of an external hook event.\n */\n notifyHookEvent(event: string): void {\n switch (event) {\n case 'tool_running':\n this._lastActivityAt = new Date();\n this.resetStallTimer();\n break;\n case 'task_complete':\n this._status = 'ready';\n this._lastBlockingPromptHash = null;\n this.outputBuffer = '';\n this.clearStallTimer();\n this.emit('status_changed', 'ready');\n this.emit('task_complete');\n break;\n case 'permission_approved':\n this._lastActivityAt = new Date();\n this.outputBuffer = '';\n this.resetStallTimer();\n break;\n default:\n this._lastActivityAt = new Date();\n this.resetStallTimer();\n break;\n }\n }\n\n /**\n * Kill the session.\n */\n kill(signal?: string): void {\n this._status = 'stopping';\n this.clearStallTimer();\n this.cancelTaskComplete();\n this.cancelReadySettle();\n this.stopExitPolling();\n\n if (signal === 'SIGKILL') {\n // Force kill: signal the process then destroy the tmux session\n this.transport.signal(this.tmuxSessionName, 'SIGKILL');\n setTimeout(() => {\n this.transport.kill(this.tmuxSessionName);\n this._status = 'stopped';\n this.emit('exit', 137);\n }, 200);\n } else {\n // Graceful: send SIGTERM and let the process exit\n this.transport.signal(this.tmuxSessionName, signal || 'SIGTERM');\n }\n\n this.logger.info({ sessionId: this.id, signal }, 'Killing tmux session');\n }\n\n /**\n * Get current output buffer\n */\n getOutputBuffer(): string {\n return this.outputBuffer;\n }\n\n /**\n * Clear output buffer\n */\n clearOutputBuffer(): void {\n this.outputBuffer = '';\n }\n\n /**\n * Convert to SessionHandle\n */\n toHandle(): SessionHandle {\n return {\n id: this.id,\n name: this.config.name,\n type: this.config.type,\n status: this._status,\n pid: this.pid,\n startedAt: this._startedAt ?? undefined,\n lastActivityAt: this._lastActivityAt ?? undefined,\n tmuxSessionName: this.tmuxSessionName,\n };\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Static Utilities\n // ─────────────────────────────────────────────────────────────────────────────\n\n static buildSpawnEnv(\n config: SpawnConfig,\n adapterEnv: Record<string, string>,\n ): Record<string, string> {\n const baseEnv = config.inheritProcessEnv !== false ? process.env : {};\n return {\n ...baseEnv,\n ...adapterEnv,\n ...config.env,\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n } as Record<string, string>;\n }\n\n static normalizeKeyList(keys: string[]): string[] {\n const MODIFIER_MAP: Record<string, string> = {\n control: 'ctrl',\n command: 'meta',\n cmd: 'meta',\n option: 'alt',\n opt: 'alt',\n };\n\n const MODIFIER_NAMES = new Set([\n 'ctrl', 'alt', 'shift', 'meta',\n ...Object.keys(MODIFIER_MAP),\n ]);\n\n const result: string[] = [];\n let i = 0;\n\n while (i < keys.length) {\n let key = keys[i].toLowerCase().trim();\n\n if (MODIFIER_MAP[key]) {\n key = MODIFIER_MAP[key];\n }\n\n if (MODIFIER_NAMES.has(key) && i + 1 < keys.length) {\n let nextKey = keys[i + 1].toLowerCase().trim();\n if (MODIFIER_MAP[nextKey]) {\n nextKey = MODIFIER_MAP[nextKey];\n }\n if (!MODIFIER_NAMES.has(nextKey)) {\n result.push(`${key}+${nextKey}`);\n i += 2;\n continue;\n }\n }\n\n result.push(key);\n i++;\n }\n\n return result;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Private Helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash |= 0;\n }\n return hash.toString(36);\n }\n\n private mapLoginTypeToAuthMethod(type: LoginDetection['type'] | undefined): AuthRequiredInfo['method'] {\n switch (type) {\n case 'api_key': return 'api_key';\n case 'cli_auth': return 'cli_auth';\n case 'device_code': return 'device_code';\n case 'oauth':\n case 'browser': return 'oauth_browser';\n default: return 'unknown';\n }\n }\n\n private emitAuthRequired(details: {\n type?: LoginDetection['type'];\n url?: string;\n deviceCode?: string;\n instructions?: string;\n }): void {\n const info: AuthRequiredInfo = {\n method: this.mapLoginTypeToAuthMethod(details.type),\n url: details.url,\n deviceCode: details.deviceCode,\n instructions: details.instructions,\n };\n\n this.emit('auth_required', info);\n this.emit('login_required', info.instructions, info.url);\n }\n\n /**\n * Strip ANSI codes for stall detection hashing.\n * Simplified compared to pty-manager since tmux capture-pane can give clean text.\n */\n private stripAnsiForStall(str: string): string {\n let result = str.replace(/\\x1b\\[\\d*[CDABGdEF]/g, ' ');\n result = result.replace(/\\x1b\\[\\d*(?:;\\d+)?[Hf]/g, ' ');\n result = result.replace(/\\x1b\\[\\d*[JK]/g, ' ');\n result = result.replace(/\\x1b\\](?:[^\\x07\\x1b]|\\x1b[^\\\\])*(?:\\x07|\\x1b\\\\)/g, '');\n result = result.replace(/\\x1bP(?:[^\\x1b]|\\x1b[^\\\\])*\\x1b\\\\/g, '');\n // eslint-disable-next-line no-control-regex\n result = result.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n // eslint-disable-next-line no-control-regex\n result = result.replace(/[\\x00-\\x08\\x0b-\\x1f\\x7f]/g, '');\n result = result.replace(/\\xa0/g, ' ');\n result = result.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷✻✶✳✢⏺←→↑↓⬆⬇◆◇▪▫■□▲△▼▽◈⟨⟩⌘⏎⏏⌫⌦⇧⇪⌥]/g, ' ');\n result = result.replace(/\\d+[hms](?:\\s+\\d+[hms])*/g, '0s');\n result = result.replace(/ {2,}/g, ' ');\n return result;\n }\n\n /**\n * Less-aggressive ANSI stripping for classifier context.\n */\n private stripAnsiForClassifier(str: string): string {\n let result = str.replace(/\\x1b\\[\\d*[CDABGdEF]/g, ' ');\n result = result.replace(/\\x1b\\[\\d*(?:;\\d+)?[Hf]/g, ' ');\n result = result.replace(/\\x1b\\[\\d*[JK]/g, ' ');\n result = result.replace(/\\x1b\\](?:[^\\x07\\x1b]|\\x1b[^\\\\])*(?:\\x07|\\x1b\\\\)/g, '');\n result = result.replace(/\\x1bP(?:[^\\x1b]|\\x1b[^\\\\])*\\x1b\\\\/g, '');\n // eslint-disable-next-line no-control-regex\n result = result.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n // eslint-disable-next-line no-control-regex\n result = result.replace(/[\\x00-\\x08\\x0b-\\x1f\\x7f]/g, '');\n result = result.replace(/\\xa0/g, ' ');\n result = result.replace(/ {2,}/g, ' ');\n return result;\n }\n}\n","/**\n * Console-based logger fallback.\n *\n * Shared between TmuxManager and TmuxSession to avoid duplication.\n * Supports both pino-style (context, message) and printf-style (message, context) calls.\n */\n\nimport type { Logger } from './types.js';\n\nexport const consoleLogger: Logger = {\n debug: (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n console.debug(args[0], args[1]);\n } else {\n console.debug(args[1], args[0]);\n }\n },\n info: (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n console.info(args[0], args[1]);\n } else {\n console.info(args[1], args[0]);\n }\n },\n warn: (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n console.warn(args[0], args[1]);\n } else {\n console.warn(args[1], args[0]);\n }\n },\n error: (...args: unknown[]) => {\n if (typeof args[0] === 'string') {\n console.error(args[0], args[1]);\n } else {\n console.error(args[1], args[0]);\n }\n },\n};\n","/**\n * Tmux Transport Layer\n *\n * Low-level interface to tmux sessions via the tmux CLI.\n * Replaces node-pty as the PTY backend — no native addons required.\n */\n\nimport { execSync } from 'child_process';\nimport { ensureTmux } from './ensure-tmux.js';\n\nexport interface TmuxSpawnOptions {\n command: string;\n args: string[];\n cwd: string;\n env: Record<string, string>;\n cols: number;\n rows: number;\n historyLimit: number;\n}\n\nexport interface TmuxCaptureOptions {\n /** Include ANSI escape codes (default: false) */\n ansi?: boolean;\n /** Number of lines from scrollback to include (default: visible only) */\n scrollback?: number;\n}\n\n/**\n * Mapping from our SPECIAL_KEYS names to tmux send-keys key names.\n */\nexport const TMUX_KEY_MAP: Record<string, string> = {\n 'enter': 'Enter',\n 'return': 'Enter',\n 'tab': 'Tab',\n 'escape': 'Escape',\n 'esc': 'Escape',\n 'space': 'Space',\n 'backspace': 'BSpace',\n 'delete': 'DC',\n 'insert': 'IC',\n 'up': 'Up',\n 'down': 'Down',\n 'left': 'Left',\n 'right': 'Right',\n 'home': 'Home',\n 'end': 'End',\n 'pageup': 'PageUp',\n 'pagedown': 'PageDown',\n 'f1': 'F1',\n 'f2': 'F2',\n 'f3': 'F3',\n 'f4': 'F4',\n 'f5': 'F5',\n 'f6': 'F6',\n 'f7': 'F7',\n 'f8': 'F8',\n 'f9': 'F9',\n 'f10': 'F10',\n 'f11': 'F11',\n 'f12': 'F12',\n // Ctrl keys map to tmux C- prefix\n 'ctrl+a': 'C-a', 'ctrl+b': 'C-b', 'ctrl+c': 'C-c', 'ctrl+d': 'C-d',\n 'ctrl+e': 'C-e', 'ctrl+f': 'C-f', 'ctrl+g': 'C-g', 'ctrl+h': 'C-h',\n 'ctrl+i': 'C-i', 'ctrl+j': 'C-j', 'ctrl+k': 'C-k', 'ctrl+l': 'C-l',\n 'ctrl+m': 'C-m', 'ctrl+n': 'C-n', 'ctrl+o': 'C-o', 'ctrl+p': 'C-p',\n 'ctrl+q': 'C-q', 'ctrl+r': 'C-r', 'ctrl+s': 'C-s', 'ctrl+t': 'C-t',\n 'ctrl+u': 'C-u', 'ctrl+v': 'C-v', 'ctrl+w': 'C-w', 'ctrl+x': 'C-x',\n 'ctrl+y': 'C-y', 'ctrl+z': 'C-z',\n // Shift combinations\n 'shift+up': 'S-Up', 'shift+down': 'S-Down',\n 'shift+left': 'S-Left', 'shift+right': 'S-Right',\n 'shift+tab': 'BTab',\n};\n\n/**\n * Low-level tmux session transport.\n * Manages tmux sessions via CLI commands.\n */\nexport class TmuxTransport {\n private pollingTimers: Map<string, ReturnType<typeof setInterval>> = new Map();\n private lastCapture: Map<string, string> = new Map();\n\n constructor() {\n // No setup needed — tmux is a system binary\n }\n\n /**\n * Spawn a new tmux session running the given command.\n */\n spawn(sessionName: string, options: TmuxSpawnOptions): void {\n ensureTmux();\n\n // Build the full command string\n const fullCommand = [options.command, ...options.args].join(' ');\n\n // Build environment exports to prepend\n const envExports = Object.entries(options.env)\n .map(([k, v]) => `export ${k}=${this.shellEscape(v)}`)\n .join('; ');\n const shellCommand = envExports\n ? `${envExports}; exec ${fullCommand}`\n : `exec ${fullCommand}`;\n\n // Create detached session with specified dimensions\n execSync(\n `tmux new-session -d -s ${this.shellEscape(sessionName)} ` +\n `-x ${options.cols} -y ${options.rows} ` +\n `-c ${this.shellEscape(options.cwd)} ` +\n `${this.shellEscape(shellCommand)}`,\n { stdio: 'pipe', timeout: 10000 }\n );\n\n // Configure session options\n this.tmuxExec(`set-option -t ${this.shellEscape(sessionName)} history-limit ${options.historyLimit}`);\n this.tmuxExec(`set-option -t ${this.shellEscape(sessionName)} remain-on-exit on`);\n }\n\n /**\n * Check if a tmux session exists and is alive.\n */\n isAlive(sessionName: string): boolean {\n try {\n execSync(`tmux has-session -t ${this.shellEscape(sessionName)}`, {\n stdio: 'pipe',\n timeout: 3000,\n });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Kill a tmux session.\n */\n kill(sessionName: string): void {\n this.stopOutputStreaming(sessionName);\n try {\n this.tmuxExec(`kill-session -t ${this.shellEscape(sessionName)}`);\n } catch {\n // Session may already be dead\n }\n }\n\n /**\n * Send a signal to the process in the tmux pane.\n */\n signal(sessionName: string, sig: string): void {\n // Get the pane PID and send signal via kill\n try {\n const pid = this.getPanePid(sessionName);\n if (pid) {\n const nodeSignal = sig === 'SIGKILL' ? '-9' : sig === 'SIGTERM' ? '-15' : `-${sig}`;\n execSync(`kill ${nodeSignal} ${pid}`, { stdio: 'pipe', timeout: 3000 });\n }\n } catch {\n // Process may already be dead\n }\n }\n\n /**\n * Send literal text to the tmux session (no key interpretation).\n */\n sendText(sessionName: string, text: string): void {\n this.tmuxExec(`send-keys -t ${this.shellEscape(sessionName)} -l ${this.shellEscape(text)}`);\n }\n\n /**\n * Send a named key to the tmux session.\n * Uses TMUX_KEY_MAP for translation from our key names.\n */\n sendKey(sessionName: string, key: string): void {\n const tmuxKey = TMUX_KEY_MAP[key.toLowerCase()];\n if (tmuxKey) {\n this.tmuxExec(`send-keys -t ${this.shellEscape(sessionName)} ${tmuxKey}`);\n } else {\n // Try sending as literal text\n this.tmuxExec(`send-keys -t ${this.shellEscape(sessionName)} -l ${this.shellEscape(key)}`);\n }\n }\n\n /**\n * Capture the current pane content.\n */\n capturePane(sessionName: string, options: TmuxCaptureOptions = {}): string {\n const flags = ['-p']; // Print to stdout\n if (options.ansi) {\n flags.push('-e'); // Include escape sequences\n }\n if (options.scrollback !== undefined) {\n flags.push(`-S -${options.scrollback}`);\n }\n\n try {\n return execSync(\n `tmux capture-pane -t ${this.shellEscape(sessionName)} ${flags.join(' ')}`,\n { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }\n );\n } catch {\n return '';\n }\n }\n\n /**\n * Start polling output from a tmux session via capture-pane.\n * Polls at the given interval and calls the callback with new/changed content.\n *\n * Uses capture-pane with ANSI codes (-e) and scrollback for full fidelity.\n * Compares against last capture to detect changes and emit only new data.\n */\n startOutputStreaming(\n sessionName: string,\n callback: (data: string) => void,\n pollIntervalMs: number = 100,\n ): void {\n this.lastCapture.set(sessionName, '');\n\n const timer = setInterval(() => {\n try {\n const current = this.capturePane(sessionName, { ansi: true, scrollback: 500 });\n const last = this.lastCapture.get(sessionName) || '';\n\n if (current !== last) {\n this.lastCapture.set(sessionName, current);\n\n // Find the new content by comparing with previous capture\n if (current.startsWith(last)) {\n // Common case: new content appended\n const newData = current.slice(last.length);\n if (newData) callback(newData);\n } else {\n // Screen was redrawn (TUI, clear, etc.) — emit full content\n callback(current);\n }\n }\n } catch {\n // Session may have died\n }\n }, pollIntervalMs);\n\n this.pollingTimers.set(sessionName, timer);\n }\n\n /**\n * Stop polling output from a tmux session.\n */\n stopOutputStreaming(sessionName: string): void {\n const timer = this.pollingTimers.get(sessionName);\n if (timer) {\n clearInterval(timer);\n this.pollingTimers.delete(sessionName);\n }\n this.lastCapture.delete(sessionName);\n }\n\n /**\n * Get the PID of the process running in the tmux pane.\n */\n getPanePid(sessionName: string): number | undefined {\n try {\n const output = execSync(\n `tmux display-message -t ${this.shellEscape(sessionName)} -p '#{pane_pid}'`,\n { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n const pid = parseInt(output, 10);\n return isNaN(pid) ? undefined : pid;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Get the pane dimensions.\n */\n getPaneDimensions(sessionName: string): { cols: number; rows: number } {\n try {\n const output = execSync(\n `tmux display-message -t ${this.shellEscape(sessionName)} -p '#{pane_width}x#{pane_height}'`,\n { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n const [cols, rows] = output.split('x').map(Number);\n return { cols: cols || 120, rows: rows || 40 };\n } catch {\n return { cols: 120, rows: 40 };\n }\n }\n\n /**\n * Resize a tmux session window.\n */\n resize(sessionName: string, cols: number, rows: number): void {\n try {\n this.tmuxExec(`resize-window -t ${this.shellEscape(sessionName)} -x ${cols} -y ${rows}`);\n } catch {\n // May fail if window doesn't exist\n }\n }\n\n /**\n * Check if the pane's process has exited.\n * Uses remain-on-exit to detect dead panes.\n */\n isPaneAlive(sessionName: string): boolean {\n try {\n const output = execSync(\n `tmux display-message -t ${this.shellEscape(sessionName)} -p '#{pane_dead}'`,\n { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n return output !== '1';\n } catch {\n return false;\n }\n }\n\n /**\n * Get the exit status of a dead pane.\n */\n getPaneExitStatus(sessionName: string): number | undefined {\n try {\n const output = execSync(\n `tmux display-message -t ${this.shellEscape(sessionName)} -p '#{pane_dead_status}'`,\n { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n const code = parseInt(output, 10);\n return isNaN(code) ? undefined : code;\n } catch {\n return undefined;\n }\n }\n\n /**\n * List all tmux sessions matching a prefix.\n */\n static listSessions(prefix?: string): Array<{ name: string; created: string; attached: boolean }> {\n try {\n const output = execSync(\n `tmux list-sessions -F '#{session_name}|#{session_created}|#{session_attached}'`,\n { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n\n if (!output) return [];\n\n return output.split('\\n')\n .map(line => {\n const [name, created, attached] = line.split('|');\n return { name, created, attached: attached === '1' };\n })\n .filter(s => !prefix || s.name.startsWith(prefix));\n } catch {\n return [];\n }\n }\n\n /**\n * Clean up resources.\n */\n destroy(): void {\n for (const [, timer] of this.pollingTimers) {\n clearInterval(timer);\n }\n this.pollingTimers.clear();\n this.lastCapture.clear();\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Private helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n private tmuxExec(args: string): void {\n execSync(`tmux ${args}`, { stdio: 'pipe', timeout: 5000 });\n }\n\n private shellEscape(str: string): string {\n // Wrap in single quotes and escape any embedded single quotes\n return `'${str.replace(/'/g, \"'\\\\''\")}'`;\n }\n}\n","/**\n * Task completion trace analysis helpers.\n *\n * Parses structured \"Task completion trace\" logs and builds a compact\n * per-turn confidence timeline useful for debugging idle/completion detection.\n */\n\nexport interface TaskCompletionTraceRecord {\n sessionId?: string;\n adapterType?: string;\n event: string;\n status?: string;\n taskCompletePending?: boolean;\n signal?: boolean;\n wasPending?: boolean;\n debounceMs?: number;\n detectTaskComplete?: boolean;\n detectReady?: boolean;\n detectLoading?: boolean;\n tailHash?: string;\n tailSnippet?: string;\n timestamp?: string | number | Date;\n}\n\nexport interface TaskCompletionTimelineStep {\n event: string;\n atIndex: number;\n status: 'active' | 'active_loading' | 'likely_complete' | 'completed' | 'rejected';\n confidence: number;\n signal?: boolean;\n detectTaskComplete?: boolean;\n detectReady?: boolean;\n detectLoading?: boolean;\n}\n\nexport interface TaskCompletionTurnTimeline {\n turn: number;\n startIndex: number;\n endIndex: number;\n completed: boolean;\n maxConfidence: number;\n finalConfidence: number;\n events: TaskCompletionTimelineStep[];\n}\n\nexport interface TaskCompletionTimelineResult {\n turns: TaskCompletionTurnTimeline[];\n totalRecords: number;\n ignoredRecords: number;\n}\n\nexport interface BuildTimelineOptions {\n adapterType?: string;\n}\n\n/**\n * Extract trace records from mixed log inputs.\n */\nexport function extractTaskCompletionTraceRecords(\n entries: Array<string | Record<string, unknown>>,\n): TaskCompletionTraceRecord[] {\n const out: TaskCompletionTraceRecord[] = [];\n\n for (const entry of entries) {\n let obj: Record<string, unknown> | null = null;\n\n if (typeof entry === 'string') {\n const line = entry.trim();\n if (!line.startsWith('{') || !line.endsWith('}')) continue;\n try {\n obj = JSON.parse(line) as Record<string, unknown>;\n } catch {\n continue;\n }\n } else if (entry && typeof entry === 'object') {\n obj = entry;\n }\n\n if (!obj) continue;\n if (obj.msg !== 'Task completion trace') continue;\n if (typeof obj.event !== 'string') continue;\n\n out.push({\n sessionId: asString(obj.sessionId),\n adapterType: asString(obj.adapterType),\n event: obj.event,\n status: asString(obj.status),\n taskCompletePending: asBool(obj.taskCompletePending),\n signal: asBool(obj.signal),\n wasPending: asBool(obj.wasPending),\n debounceMs: asNumber(obj.debounceMs),\n detectTaskComplete: asBool(obj.detectTaskComplete),\n detectReady: asBool(obj.detectReady),\n detectLoading: asBool(obj.detectLoading),\n tailHash: asString(obj.tailHash),\n tailSnippet: asString(obj.tailSnippet),\n timestamp: asTimestamp(obj.time) ?? asTimestamp(obj.timestamp),\n });\n }\n\n return out;\n}\n\n/**\n * Build a per-turn confidence timeline from task-completion traces.\n */\nexport function buildTaskCompletionTimeline(\n records: TaskCompletionTraceRecord[],\n options: BuildTimelineOptions = {},\n): TaskCompletionTimelineResult {\n const filtered = records.filter((r) => {\n if (!options.adapterType) return true;\n return r.adapterType === options.adapterType;\n });\n\n const turns: TaskCompletionTurnTimeline[] = [];\n let current: TaskCompletionTurnTimeline | null = null;\n let ignored = 0;\n\n filtered.forEach((record, index) => {\n if (record.event === 'busy_signal' && current && current.completed) {\n current = null;\n }\n\n if (!current) {\n current = {\n turn: turns.length + 1,\n startIndex: index,\n endIndex: index,\n completed: false,\n maxConfidence: 0,\n finalConfidence: 0,\n events: [],\n };\n turns.push(current);\n }\n\n const step = toStep(record, index);\n if (!step) {\n ignored++;\n return;\n }\n\n current.events.push(step);\n current.endIndex = index;\n current.maxConfidence = Math.max(current.maxConfidence, step.confidence);\n current.finalConfidence = step.confidence;\n\n if (step.status === 'completed') {\n current.completed = true;\n }\n });\n\n return {\n turns,\n totalRecords: filtered.length,\n ignoredRecords: ignored,\n };\n}\n\nfunction toStep(record: TaskCompletionTraceRecord, atIndex: number): TaskCompletionTimelineStep | null {\n const event = record.event;\n const confidence = scoreConfidence(record);\n\n if (event === 'transition_ready') {\n return withCommon(record, { event, atIndex, status: 'completed', confidence: 100 });\n }\n\n if (event === 'debounce_reject_signal' || event === 'debounce_reject_status') {\n return withCommon(record, { event, atIndex, status: 'rejected', confidence });\n }\n\n if (record.detectLoading) {\n return withCommon(record, { event, atIndex, status: 'active_loading', confidence });\n }\n\n if (event === 'debounce_fire' && record.signal) {\n return withCommon(record, { event, atIndex, status: 'likely_complete', confidence });\n }\n\n if (event === 'busy_signal' || event === 'debounce_schedule' || event === 'debounce_fire') {\n return withCommon(record, { event, atIndex, status: 'active', confidence });\n }\n\n return null;\n}\n\nfunction scoreConfidence(record: TaskCompletionTraceRecord): number {\n let score = 10;\n if (record.detectLoading) score -= 40;\n if (record.detectReady) score += 20;\n if (record.detectTaskComplete) score += 45;\n if (record.signal) score += 20;\n if (record.event === 'debounce_reject_signal' || record.event === 'debounce_reject_status') {\n score -= 30;\n }\n if (record.event === 'transition_ready') score = 100;\n if (score < 0) return 0;\n if (score > 100) return 100;\n return score;\n}\n\nfunction withCommon(\n record: TaskCompletionTraceRecord,\n step: Omit<TaskCompletionTimelineStep, 'signal' | 'detectTaskComplete' | 'detectReady' | 'detectLoading'>,\n): TaskCompletionTimelineStep {\n return {\n ...step,\n signal: record.signal,\n detectTaskComplete: record.detectTaskComplete,\n detectReady: record.detectReady,\n detectLoading: record.detectLoading,\n };\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction asBool(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n return typeof value === 'number' ? value : undefined;\n}\n\nfunction asTimestamp(value: unknown): string | number | Date | undefined {\n if (typeof value === 'string' || typeof value === 'number' || value instanceof Date) {\n return value;\n }\n return undefined;\n}\n","/**\n * Base CLI Adapter — re-exported from adapter-types\n */\nexport { BaseCLIAdapter } from 'adapter-types';\n","/**\n * Adapter Factory — re-exported from adapter-types\n */\nexport { createAdapter } from 'adapter-types';\n","/**\n * Shell Adapter\n *\n * Built-in adapter for bash/zsh shell sessions.\n */\n\nimport type {\n CLIAdapter,\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from 'adapter-types';\n\n/**\n * Options for the shell adapter\n */\nexport interface ShellAdapterOptions {\n /** Shell to use (default: $SHELL or /bin/bash) */\n shell?: string;\n\n /** Custom prompt string (default: 'pty> ') */\n prompt?: string;\n}\n\n/**\n * Built-in adapter for shell sessions (bash/zsh)\n */\nexport class ShellAdapter implements CLIAdapter {\n readonly adapterType = 'shell';\n readonly displayName = 'Shell';\n readonly autoResponseRules: AutoResponseRule[] = [];\n\n private shell: string;\n private promptStr: string;\n\n constructor(options: ShellAdapterOptions = {}) {\n this.shell = options.shell || process.env.SHELL || '/bin/bash';\n this.promptStr = options.prompt || 'pty> ';\n }\n\n getCommand(): string {\n return this.shell;\n }\n\n getArgs(_config: SpawnConfig): string[] {\n // Use -f for zsh to prevent rc files from overriding our prompt\n if (this.shell.endsWith('/zsh') || this.shell === 'zsh') {\n return ['-f'];\n }\n // Use --norc --noprofile for bash to prevent rc files from overriding our prompt\n if (this.shell.endsWith('/bash') || this.shell === 'bash') {\n return ['--norc', '--noprofile'];\n }\n return [];\n }\n\n getEnv(_config: SpawnConfig): Record<string, string> {\n return {\n PS1: this.promptStr,\n PROMPT: this.promptStr, // zsh uses PROMPT instead of PS1\n };\n }\n\n detectLogin(_output: string): LoginDetection {\n return { required: false };\n }\n\n detectBlockingPrompt(_output: string): BlockingPromptDetection {\n return { detected: false };\n }\n\n detectReady(output: string): boolean {\n if (this.isContinuationPrompt(output)) {\n return false;\n }\n\n return this.getPromptPattern().test(this.stripAnsi(output));\n }\n\n private isContinuationPrompt(output: string): boolean {\n const stripped = this.stripAnsi(output);\n return /(?:quote|dquote|heredoc|bquote|cmdsubst|pipe|then|else|do|loop)>\\s*$/.test(stripped)\n || /(?:quote|dquote|heredoc|bquote)>\\s*$/m.test(stripped);\n }\n\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n if (output.includes('exit')) {\n return { exited: true, code: 0 };\n }\n return { exited: false };\n }\n\n parseOutput(output: string): ParsedOutput | null {\n const cleaned = this.stripAnsi(output).trim();\n if (!cleaned) return null;\n\n return {\n type: 'response',\n content: cleaned,\n isComplete: true,\n isQuestion: false,\n };\n }\n\n formatInput(message: string): string {\n return message;\n }\n\n getPromptPattern(): RegExp {\n // Trim trailing space from prompt for matching — tmux capture-pane strips trailing whitespace\n const escaped = this.promptStr.trimEnd().replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:${escaped}|\\\\$|#)\\\\s*$`, 'm');\n }\n\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n return { installed: true };\n }\n\n private stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n }\n}\n"],"mappings":"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","names":["import_events","import_child_process","import_adapter_types","import_adapter_types"]}