pty-manager 1.2.2 → 1.2.3
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.
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +29 -0
- package/dist/index.mjs.map +1 -1
- package/dist/pty-worker.js +32 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1462,6 +1462,35 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
|
|
|
1462
1462
|
this.emit("worker_error", event.message);
|
|
1463
1463
|
}
|
|
1464
1464
|
break;
|
|
1465
|
+
case "blocking_prompt": {
|
|
1466
|
+
const session = this.sessions.get(id);
|
|
1467
|
+
if (session) {
|
|
1468
|
+
this.emit("blocking_prompt", session, event.promptInfo, event.autoResponded);
|
|
1469
|
+
}
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
case "login_required": {
|
|
1473
|
+
const session = this.sessions.get(id);
|
|
1474
|
+
if (session) {
|
|
1475
|
+
this.emit("login_required", session, event.instructions, event.url);
|
|
1476
|
+
}
|
|
1477
|
+
break;
|
|
1478
|
+
}
|
|
1479
|
+
case "message": {
|
|
1480
|
+
const msg = event.message;
|
|
1481
|
+
this.emit("message", {
|
|
1482
|
+
...msg,
|
|
1483
|
+
timestamp: new Date(msg.timestamp)
|
|
1484
|
+
});
|
|
1485
|
+
break;
|
|
1486
|
+
}
|
|
1487
|
+
case "question": {
|
|
1488
|
+
const session = this.sessions.get(id);
|
|
1489
|
+
if (session) {
|
|
1490
|
+
this.emit("question", session, event.question);
|
|
1491
|
+
}
|
|
1492
|
+
break;
|
|
1493
|
+
}
|
|
1465
1494
|
case "list": {
|
|
1466
1495
|
const sessions = event.sessions.map((s) => ({
|
|
1467
1496
|
...s,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/pty-manager.ts","../src/adapters/adapter-registry.ts","../src/pty-session.ts","../src/adapters/base-adapter.ts","../src/adapters/adapter-factory.ts","../src/adapters/shell-adapter.ts","../src/bun-compat.ts"],"sourcesContent":["/**\n * pty-manager\n *\n * PTY session manager with lifecycle management,\n * pluggable adapters, and blocking prompt detection.\n */\n\n// Core classes\nexport { PTYManager } from './pty-manager';\nexport { PTYSession, SPECIAL_KEYS } from './pty-session';\n\n// Adapter system\nexport {\n AdapterRegistry,\n BaseCLIAdapter,\n createAdapter,\n ShellAdapter,\n} from './adapters';\n\nexport type { CLIAdapter, ShellAdapterOptions } from './adapters';\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 BlockingPromptType,\n BlockingPromptDetection,\n AutoResponseRule,\n BlockingPromptInfo,\n\n // Manager types\n Logger,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n\n // Factory types\n AdapterFactoryConfig,\n} from './types';\n\n// Event types\nexport type { PTYManagerEvents } from './pty-manager';\nexport type { PTYSessionEvents } from './pty-session';\n\n// Bun compatibility layer\nexport {\n BunCompatiblePTYManager,\n createPTYManager,\n isBun,\n} from './bun-compat';\n\nexport type {\n WorkerSessionHandle,\n BunPTYManagerOptions,\n} from './bun-compat';\n","/**\n * PTY Manager\n *\n * Manages multiple PTY sessions for CLI tools.\n */\n\nimport { EventEmitter } from 'events';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport { AdapterRegistry } from './adapters/adapter-registry';\nimport { PTYSession } from './pty-session';\nimport type {\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n SessionStatus,\n BlockingPromptInfo,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n Logger,\n} from './types';\n\nexport interface PTYManagerEvents {\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 blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (session: SessionHandle, question: string) => void;\n}\n\n/**\n * Console-based logger fallback\n */\nconst 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\nexport class PTYManager extends EventEmitter {\n private sessions: Map<string, PTYSession> = new Map();\n private outputLogs: Map<string, string[]> = new Map();\n private maxLogLines: number;\n private logger: Logger;\n public readonly adapters: AdapterRegistry;\n\n constructor(config: PTYManagerConfig = {}) {\n super();\n this.adapters = new AdapterRegistry();\n this.logger = config.logger || consoleLogger;\n this.maxLogLines = config.maxLogLines || 1000;\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 PTY session\n */\n async spawn(config: SpawnConfig): Promise<SessionHandle> {\n // Get adapter for this type\n const adapter = this.adapters.get(config.type);\n if (!adapter) {\n throw new Error(`No adapter found for type: ${config.type}. Registered adapters: ${this.adapters.list().join(', ') || 'none'}`);\n }\n\n // Check if ID already exists\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 session'\n );\n\n // Create session\n const session = new PTYSession(adapter, config, this.logger);\n\n // Set up event forwarding\n this.setupSessionEvents(session);\n\n // Store session\n this.sessions.set(session.id, session);\n this.outputLogs.set(session.id, []);\n\n // Start the session\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: PTYSession): void {\n session.on('output', (data: string) => {\n // Store in log buffer\n const logs = this.outputLogs.get(session.id) || [];\n const lines = data.split('\\n');\n logs.push(...lines);\n\n // Trim to max lines\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('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\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 // Force kill if graceful shutdown times out\n session.kill('SIGKILL');\n resolve();\n }, timeout);\n\n session.once('exit', () => {\n clearTimeout(timer);\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n });\n\n // Send graceful signal\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 // Apply filters\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) {\n return null;\n }\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 sessions');\n\n await this.stopAll({ timeout: 3000 });\n\n this.sessions.clear();\n this.outputLogs.clear();\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) {\n return null;\n }\n\n return {\n /**\n * Subscribe to raw terminal output\n * Returns an unsubscribe function\n */\n onData: (callback: (data: string) => void) => {\n session.on('output', callback);\n return () => session.off('output', callback);\n },\n\n /**\n * Write raw data to terminal (no formatting applied)\n */\n write: (data: string) => {\n session.writeRaw(data);\n },\n\n /**\n * Resize the terminal\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 PTYSession (for advanced use)\n */\n getSession(sessionId: string): PTYSession | undefined {\n return this.sessions.get(sessionId);\n }\n}\n","/**\n * Adapter Registry\n *\n * Registry for managing CLI adapters.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\n\n/**\n * Registry of available CLI adapters\n */\nexport class AdapterRegistry {\n private adapters: Map<string, CLIAdapter> = new Map();\n\n /**\n * Register an adapter\n */\n register(adapter: CLIAdapter): void {\n this.adapters.set(adapter.adapterType, adapter);\n }\n\n /**\n * Get adapter for type\n */\n get(adapterType: string): CLIAdapter | undefined {\n return this.adapters.get(adapterType);\n }\n\n /**\n * Check if adapter exists for type\n */\n has(adapterType: string): boolean {\n return this.adapters.has(adapterType);\n }\n\n /**\n * Unregister an adapter\n */\n unregister(adapterType: string): boolean {\n return this.adapters.delete(adapterType);\n }\n\n /**\n * List all registered adapter types\n */\n list(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Get all adapters\n */\n all(): CLIAdapter[] {\n return Array.from(this.adapters.values());\n }\n\n /**\n * Clear all adapters\n */\n clear(): void {\n this.adapters.clear();\n }\n}\n","/**\n * PTY Session\n *\n * Manages a single pseudo-terminal session for a CLI tool.\n */\n\nimport { EventEmitter } from 'events';\nimport type * as ptyModule from 'node-pty';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport type {\n SpawnConfig,\n SessionStatus,\n SessionHandle,\n SessionMessage,\n BlockingPromptInfo,\n Logger,\n} from './types';\n\n// Lazy-load node-pty to avoid issues in environments where it's not installed\nlet ptyCache: typeof ptyModule | null = null;\nfunction loadPty(): typeof ptyModule {\n if (!ptyCache) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n ptyCache = require('node-pty') as typeof ptyModule;\n } catch {\n throw new Error(\n 'node-pty is required but not installed. Run: npm install node-pty'\n );\n }\n }\n return ptyCache!;\n}\n\nexport interface PTYSessionEvents {\n output: (data: string) => void;\n ready: () => void;\n login_required: (instructions?: string, url?: string) => 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}\n\n/**\n * Console-based logger fallback\n */\nconst 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/**\n * Generate a unique ID\n */\nfunction generateId(): string {\n return `pty-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Special key mappings to escape sequences\n *\n * Modifier codes for arrows/function keys:\n * 2 = Shift, 3 = Alt, 4 = Shift+Alt, 5 = Ctrl, 6 = Ctrl+Shift, 7 = Ctrl+Alt, 8 = Ctrl+Alt+Shift\n */\nexport const SPECIAL_KEYS: Record<string, string> = {\n // Control keys (Ctrl+letter = ASCII control code)\n 'ctrl+a': '\\x01',\n 'ctrl+b': '\\x02',\n 'ctrl+c': '\\x03',\n 'ctrl+d': '\\x04',\n 'ctrl+e': '\\x05',\n 'ctrl+f': '\\x06',\n 'ctrl+g': '\\x07',\n 'ctrl+h': '\\x08',\n 'ctrl+i': '\\x09',\n 'ctrl+j': '\\x0a',\n 'ctrl+k': '\\x0b',\n 'ctrl+l': '\\x0c',\n 'ctrl+m': '\\x0d',\n 'ctrl+n': '\\x0e',\n 'ctrl+o': '\\x0f',\n 'ctrl+p': '\\x10',\n 'ctrl+q': '\\x11',\n 'ctrl+r': '\\x12',\n 'ctrl+s': '\\x13',\n 'ctrl+t': '\\x14',\n 'ctrl+u': '\\x15',\n 'ctrl+v': '\\x16',\n 'ctrl+w': '\\x17',\n 'ctrl+x': '\\x18',\n 'ctrl+y': '\\x19',\n 'ctrl+z': '\\x1a',\n 'ctrl+[': '\\x1b',\n 'ctrl+\\\\': '\\x1c',\n 'ctrl+]': '\\x1d',\n 'ctrl+^': '\\x1e',\n 'ctrl+_': '\\x1f',\n\n // Alt+letter (Meta key = ESC + letter)\n 'alt+a': '\\x1ba', 'alt+b': '\\x1bb', 'alt+c': '\\x1bc', 'alt+d': '\\x1bd',\n 'alt+e': '\\x1be', 'alt+f': '\\x1bf', 'alt+g': '\\x1bg', 'alt+h': '\\x1bh',\n 'alt+i': '\\x1bi', 'alt+j': '\\x1bj', 'alt+k': '\\x1bk', 'alt+l': '\\x1bl',\n 'alt+m': '\\x1bm', 'alt+n': '\\x1bn', 'alt+o': '\\x1bo', 'alt+p': '\\x1bp',\n 'alt+q': '\\x1bq', 'alt+r': '\\x1br', 'alt+s': '\\x1bs', 'alt+t': '\\x1bt',\n 'alt+u': '\\x1bu', 'alt+v': '\\x1bv', 'alt+w': '\\x1bw', 'alt+x': '\\x1bx',\n 'alt+y': '\\x1by', 'alt+z': '\\x1bz',\n 'alt+backspace': '\\x1b\\x7f', // Delete word backward\n\n // Navigation - plain\n 'up': '\\x1b[A',\n 'down': '\\x1b[B',\n 'right': '\\x1b[C',\n 'left': '\\x1b[D',\n 'home': '\\x1b[H',\n 'end': '\\x1b[F',\n 'pageup': '\\x1b[5~',\n 'pagedown': '\\x1b[6~',\n\n // Navigation - with Shift (modifier 2)\n 'shift+up': '\\x1b[1;2A',\n 'shift+down': '\\x1b[1;2B',\n 'shift+right': '\\x1b[1;2C',\n 'shift+left': '\\x1b[1;2D',\n 'shift+home': '\\x1b[1;2H',\n 'shift+end': '\\x1b[1;2F',\n 'shift+pageup': '\\x1b[5;2~',\n 'shift+pagedown': '\\x1b[6;2~',\n\n // Navigation - with Alt (modifier 3)\n 'alt+up': '\\x1b[1;3A',\n 'alt+down': '\\x1b[1;3B',\n 'alt+right': '\\x1b[1;3C', // Forward word\n 'alt+left': '\\x1b[1;3D', // Backward word\n\n // Navigation - with Ctrl (modifier 5)\n 'ctrl+up': '\\x1b[1;5A',\n 'ctrl+down': '\\x1b[1;5B',\n 'ctrl+right': '\\x1b[1;5C', // Forward word\n 'ctrl+left': '\\x1b[1;5D', // Backward word\n 'ctrl+home': '\\x1b[1;5H',\n 'ctrl+end': '\\x1b[1;5F',\n\n // Navigation - with Ctrl+Shift (modifier 6) - select word\n 'ctrl+shift+up': '\\x1b[1;6A',\n 'ctrl+shift+down': '\\x1b[1;6B',\n 'ctrl+shift+right': '\\x1b[1;6C',\n 'ctrl+shift+left': '\\x1b[1;6D',\n 'ctrl+shift+home': '\\x1b[1;6H',\n 'ctrl+shift+end': '\\x1b[1;6F',\n\n // Navigation - with Shift+Alt (modifier 4)\n 'shift+alt+up': '\\x1b[1;4A',\n 'shift+alt+down': '\\x1b[1;4B',\n 'shift+alt+right': '\\x1b[1;4C',\n 'shift+alt+left': '\\x1b[1;4D',\n\n // Editing\n 'enter': '\\r',\n 'return': '\\r',\n 'tab': '\\t',\n 'shift+tab': '\\x1b[Z', // Reverse tab\n 'backspace': '\\x7f',\n 'delete': '\\x1b[3~',\n 'shift+delete': '\\x1b[3;2~',\n 'ctrl+delete': '\\x1b[3;5~', // Delete word forward\n 'insert': '\\x1b[2~',\n 'escape': '\\x1b',\n 'esc': '\\x1b',\n 'space': ' ',\n\n // Function keys - plain\n 'f1': '\\x1bOP',\n 'f2': '\\x1bOQ',\n 'f3': '\\x1bOR',\n 'f4': '\\x1bOS',\n 'f5': '\\x1b[15~',\n 'f6': '\\x1b[17~',\n 'f7': '\\x1b[18~',\n 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~',\n 'f10': '\\x1b[21~',\n 'f11': '\\x1b[23~',\n 'f12': '\\x1b[24~',\n\n // Function keys - with Shift (modifier 2)\n 'shift+f1': '\\x1b[1;2P',\n 'shift+f2': '\\x1b[1;2Q',\n 'shift+f3': '\\x1b[1;2R',\n 'shift+f4': '\\x1b[1;2S',\n 'shift+f5': '\\x1b[15;2~',\n 'shift+f6': '\\x1b[17;2~',\n 'shift+f7': '\\x1b[18;2~',\n 'shift+f8': '\\x1b[19;2~',\n 'shift+f9': '\\x1b[20;2~',\n 'shift+f10': '\\x1b[21;2~',\n 'shift+f11': '\\x1b[23;2~',\n 'shift+f12': '\\x1b[24;2~',\n\n // Function keys - with Ctrl (modifier 5)\n 'ctrl+f1': '\\x1b[1;5P',\n 'ctrl+f2': '\\x1b[1;5Q',\n 'ctrl+f3': '\\x1b[1;5R',\n 'ctrl+f4': '\\x1b[1;5S',\n 'ctrl+f5': '\\x1b[15;5~',\n 'ctrl+f6': '\\x1b[17;5~',\n 'ctrl+f7': '\\x1b[18;5~',\n 'ctrl+f8': '\\x1b[19;5~',\n 'ctrl+f9': '\\x1b[20;5~',\n 'ctrl+f10': '\\x1b[21;5~',\n 'ctrl+f11': '\\x1b[23;5~',\n 'ctrl+f12': '\\x1b[24;5~',\n};\n\n/**\n * Bracketed paste mode escape sequences\n */\nconst BRACKETED_PASTE_START = '\\x1b[200~';\nconst BRACKETED_PASTE_END = '\\x1b[201~';\n\nexport class PTYSession extends EventEmitter {\n private ptyProcess: ptyModule.IPty | null = null;\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\n public readonly id: string;\n public readonly config: SpawnConfig;\n\n constructor(\n private adapter: CLIAdapter,\n config: SpawnConfig,\n logger?: Logger\n ) {\n super();\n this.id = config.id || generateId();\n this.config = { ...config, id: this.id };\n this.logger = logger || consoleLogger;\n }\n\n get status(): SessionStatus {\n return this._status;\n }\n\n get pid(): number | undefined {\n return this.ptyProcess?.pid;\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 * Start the PTY session\n */\n async start(): Promise<void> {\n if (this.ptyProcess) {\n throw new Error('Session already started');\n }\n\n const nodePty = loadPty();\n\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\n const env = {\n ...process.env,\n ...adapterEnv,\n ...this.config.env,\n // Force terminal settings\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n };\n\n this.logger.info(\n { sessionId: this.id, command, args: args.join(' ') },\n 'Starting PTY session'\n );\n\n try {\n this.ptyProcess = nodePty.spawn(command, args, {\n name: 'xterm-256color',\n cols: this.config.cols || 120,\n rows: this.config.rows || 40,\n cwd: this.config.workdir || process.cwd(),\n env: env as Record<string, string>,\n });\n\n this.setupEventHandlers();\n\n this.logger.info(\n { sessionId: this.id, pid: this.ptyProcess.pid },\n 'PTY session started'\n );\n } catch (error) {\n this._status = 'error';\n this.logger.error(\n { sessionId: this.id, error },\n 'Failed to start PTY session'\n );\n throw error;\n }\n }\n\n /**\n * Set up event handlers for the PTY\n */\n private setupEventHandlers(): void {\n if (!this.ptyProcess) return;\n\n this.ptyProcess.onData((data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n // Emit raw output\n this.emit('output', data);\n\n // Check for blocking prompts\n const blockingPrompt = this.detectAndHandleBlockingPrompt();\n if (blockingPrompt) {\n return;\n }\n\n // Fallback: Check for login required (legacy support)\n const loginDetection = this.adapter.detectLogin(this.outputBuffer);\n if (loginDetection.required && this._status !== 'authenticating') {\n this._status = 'authenticating';\n this.emit('login_required', loginDetection.instructions, loginDetection.url);\n this.logger.warn(\n { sessionId: this.id, loginType: loginDetection.type },\n 'Login required'\n );\n return;\n }\n\n // Check for ready state\n if (this._status === 'starting' && this.adapter.detectReady(this.outputBuffer)) {\n this._status = 'ready';\n this.emit('ready');\n this.logger.info({ sessionId: this.id }, 'Session ready');\n }\n\n // Check for exit\n const exitDetection = this.adapter.detectExit(this.outputBuffer);\n if (exitDetection.exited) {\n this._status = 'stopped';\n this.emit('exit', exitDetection.code || 0);\n }\n\n // Try to parse output into structured message\n this.tryParseOutput();\n });\n\n this.ptyProcess.onExit(({ exitCode, signal }) => {\n this._status = 'stopped';\n this.logger.info(\n { sessionId: this.id, exitCode, signal },\n 'PTY session exited'\n );\n this.emit('exit', exitCode);\n });\n }\n\n /**\n * Detect blocking prompts and handle them with auto-responses or user notification\n */\n private detectAndHandleBlockingPrompt(): boolean {\n // First, check adapter's auto-response rules\n const autoHandled = this.tryAutoResponse();\n if (autoHandled) {\n return true;\n }\n\n // Then check the adapter's detectBlockingPrompt method\n if (this.adapter.detectBlockingPrompt) {\n const detection = this.adapter.detectBlockingPrompt(this.outputBuffer);\n\n if (detection.detected) {\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 we can auto-respond and have a suggested response, do it\n if (detection.canAutoRespond && detection.suggestedResponse) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: detection.type,\n response: detection.suggestedResponse,\n },\n 'Auto-responding to blocking prompt'\n );\n\n this.writeRaw(detection.suggestedResponse + '\\r');\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n }\n\n // Otherwise, notify that user intervention is needed\n if (detection.type === 'login') {\n this._status = 'authenticating';\n }\n\n this.logger.warn(\n {\n sessionId: this.id,\n promptType: detection.type,\n prompt: detection.prompt,\n },\n 'Blocking prompt requires user intervention'\n );\n\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Try to match and apply auto-response rules\n */\n private tryAutoResponse(): boolean {\n const rules = this.adapter.autoResponseRules;\n if (!rules || rules.length === 0) {\n return false;\n }\n\n for (const rule of rules) {\n if (rule.pattern.test(this.outputBuffer)) {\n // Check if it's safe to auto-respond (default: true)\n const safe = rule.safe !== false;\n\n if (safe) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: rule.type,\n description: rule.description,\n response: rule.response,\n },\n 'Applying auto-response rule'\n );\n\n this.writeRaw(rule.response + '\\r');\n\n // Clear the matched portion from buffer to prevent re-matching\n this.outputBuffer = this.outputBuffer.replace(rule.pattern, '');\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 // Not safe to auto-respond, emit for user intervention\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\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Try to parse the output buffer into structured messages\n */\n private tryParseOutput(): void {\n const parsed = this.adapter.parseOutput(this.outputBuffer);\n\n if (parsed && parsed.isComplete) {\n // Clear the buffer for the parsed content\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 // Also emit specific event for questions\n if (parsed.isQuestion) {\n this.emit('question', parsed.content);\n }\n }\n }\n\n /**\n * Write data to the PTY (formatted by adapter)\n */\n write(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n const formatted = this.adapter.formatInput(data);\n this.ptyProcess.write(formatted + '\\r');\n\n this.logger.debug({ sessionId: this.id, input: data }, 'Sent input to session');\n }\n\n /**\n * Write raw data directly to the PTY (no formatting)\n */\n writeRaw(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n this.ptyProcess.write(data);\n }\n\n /**\n * Send a task/message to the session\n */\n send(message: string): SessionMessage {\n this._status = 'busy';\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 this.write(message);\n\n return msg;\n }\n\n /**\n * Resize the PTY terminal\n */\n resize(cols: number, rows: number): void {\n this.ptyProcess?.resize(cols, rows);\n }\n\n /**\n * Send special keys to the PTY\n *\n * Supported keys:\n * - Control: ctrl+c, ctrl+d, ctrl+z, ctrl+l, ctrl+a, ctrl+e, ctrl+k, ctrl+u, ctrl+w, ctrl+r\n * - Navigation: up, down, left, right, home, end, pageup, pagedown\n * - Editing: enter, tab, backspace, delete, insert, escape\n * - Function: f1-f12\n *\n * @param keys - Key name(s) to send, e.g. \"ctrl+c\" or [\"up\", \"up\", \"enter\"]\n */\n sendKeys(keys: string | string[]): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n const keyList = Array.isArray(keys) ? keys : [keys];\n\n for (const key of keyList) {\n const normalizedKey = key.toLowerCase().trim();\n const sequence = SPECIAL_KEYS[normalizedKey];\n\n if (sequence) {\n this._lastActivityAt = new Date();\n this.ptyProcess.write(sequence);\n this.logger.debug({ sessionId: this.id, key: normalizedKey }, 'Sent special key');\n } else {\n this.logger.warn(\n { sessionId: this.id, key: normalizedKey },\n 'Unknown special key, sending as literal'\n );\n this.ptyProcess.write(key);\n }\n }\n }\n\n /**\n * Paste text using bracketed paste mode\n *\n * Bracketed paste mode wraps the pasted text in escape sequences\n * that tell the terminal this is pasted content, not typed input.\n * This prevents issues with pasting text that contains special characters\n * or looks like commands.\n *\n * @param text - Text to paste\n * @param useBracketedPaste - Whether to use bracketed paste mode (default: true)\n */\n paste(text: string, useBracketedPaste: boolean = true): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n\n if (useBracketedPaste) {\n this.ptyProcess.write(BRACKETED_PASTE_START + text + BRACKETED_PASTE_END);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text with bracketed paste mode'\n );\n } else {\n this.ptyProcess.write(text);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text without bracketed paste'\n );\n }\n }\n\n /**\n * Kill the PTY process\n */\n kill(signal?: string): void {\n if (this.ptyProcess) {\n this._status = 'stopping';\n this.ptyProcess.kill(signal);\n this.logger.info({ sessionId: this.id, signal }, 'Killing PTY session');\n }\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 };\n }\n}\n","/**\n * Base CLI Adapter\n *\n * Abstract base class with common functionality for CLI adapters.\n */\n\nimport { spawn } from 'child_process';\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../types';\n\n/**\n * Abstract base class for CLI adapters with common functionality\n */\nexport abstract class BaseCLIAdapter implements CLIAdapter {\n abstract readonly adapterType: string;\n abstract readonly displayName: string;\n\n /**\n * Auto-response rules for handling known blocking prompts.\n * Subclasses should override this to add CLI-specific rules.\n */\n readonly autoResponseRules: AutoResponseRule[] = [];\n\n abstract getCommand(): string;\n abstract getArgs(config: SpawnConfig): string[];\n abstract getEnv(config: SpawnConfig): Record<string, string>;\n abstract detectLogin(output: string): LoginDetection;\n abstract detectReady(output: string): boolean;\n abstract parseOutput(output: string): ParsedOutput | null;\n abstract getPromptPattern(): RegExp;\n\n /**\n * Default exit detection - look for common exit patterns\n */\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n // Check for common exit/error patterns\n if (output.includes('Process exited with code')) {\n const match = output.match(/Process exited with code (\\d+)/);\n return {\n exited: true,\n code: match ? parseInt(match[1], 10) : 1,\n };\n }\n\n if (output.includes('Command not found') || output.includes('command not found')) {\n return {\n exited: true,\n code: 127,\n error: 'Command not found',\n };\n }\n\n return { exited: false };\n }\n\n /**\n * Default blocking prompt detection - looks for common prompt patterns.\n * Subclasses should override for CLI-specific detection.\n */\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n const stripped = this.stripAnsi(output);\n\n // Check for login/auth first (highest priority)\n const loginDetection = this.detectLogin(output);\n if (loginDetection.required) {\n return {\n detected: true,\n type: 'login',\n prompt: loginDetection.instructions,\n url: loginDetection.url,\n canAutoRespond: false,\n instructions: loginDetection.instructions,\n };\n }\n\n // Check for common update prompts\n if (/update (available|now|ready)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'update',\n prompt: 'Update available',\n options: ['y', 'n'],\n suggestedResponse: 'n',\n canAutoRespond: true,\n instructions: 'CLI update available - auto-declining to continue',\n };\n }\n\n // Check for terms of service / license acceptance\n if (/accept.*(terms|license|agreement)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'tos',\n prompt: 'Terms/license acceptance required',\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Please accept the terms of service manually',\n };\n }\n\n // Check for model/version selection\n if (/choose.*model|select.*model|which model/i.test(stripped)) {\n return {\n detected: true,\n type: 'model_select',\n prompt: 'Model selection required',\n canAutoRespond: false,\n instructions: 'Please select a model',\n };\n }\n\n // Check for project/workspace selection\n if (/choose.*(project|workspace)|select.*(project|workspace)/i.test(stripped)) {\n return {\n detected: true,\n type: 'project_select',\n prompt: 'Project/workspace selection required',\n canAutoRespond: false,\n instructions: 'Please select a project or workspace',\n };\n }\n\n // Check for generic y/n prompts that look like they're blocking\n if (/\\[y\\/n\\]|\\(y\\/n\\)|\\[Y\\/n\\]|\\[y\\/N\\]/i.test(stripped) && stripped.includes('?')) {\n return {\n detected: true,\n type: 'unknown',\n prompt: stripped.slice(-200), // Last 200 chars for context\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Unknown confirmation prompt detected',\n };\n }\n\n return { detected: false };\n }\n\n /**\n * Default input formatting - just return as-is\n */\n formatInput(message: string): string {\n return message;\n }\n\n /**\n * Validate CLI installation by running --version or --help\n */\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n return new Promise((resolve) => {\n const command = this.getCommand();\n\n try {\n const proc = spawn(command, ['--version'], {\n shell: true,\n timeout: 5000,\n });\n\n let output = '';\n\n proc.stdout?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.stderr?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n // Try to extract version from output\n const versionMatch = output.match(/(\\d+\\.\\d+\\.\\d+)/);\n resolve({\n installed: true,\n version: versionMatch ? versionMatch[1] : undefined,\n });\n } else {\n resolve({\n installed: false,\n error: `Command exited with code ${code}`,\n });\n }\n });\n\n proc.on('error', (err) => {\n resolve({\n installed: false,\n error: err.message,\n });\n });\n } catch (err) {\n resolve({\n installed: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n });\n }\n\n /**\n * Helper to check if output contains a question\n */\n protected containsQuestion(output: string): boolean {\n const questionPatterns = [\n /\\?$/m, // Ends with ?\n /would you like/i,\n /do you want/i,\n /should I/i,\n /shall I/i,\n /please (choose|select|confirm)/i,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /\\[Y\\/n\\]/i,\n ];\n\n return questionPatterns.some((pattern) => pattern.test(output));\n }\n\n /**\n * Helper to strip ANSI escape codes from output\n */\n protected stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n }\n}\n","/**\n * Adapter Factory\n *\n * Factory function for creating CLI adapters from configuration.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport { BaseCLIAdapter } from './base-adapter';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n AdapterFactoryConfig,\n} from '../types';\n\n/**\n * Creates a CLI adapter from configuration\n */\nexport function createAdapter(config: AdapterFactoryConfig): CLIAdapter {\n return new ConfiguredAdapter(config);\n}\n\n/**\n * Adapter implementation created from configuration\n */\nclass ConfiguredAdapter extends BaseCLIAdapter {\n readonly adapterType: string;\n readonly displayName: string;\n readonly autoResponseRules: AutoResponseRule[];\n\n constructor(private config: AdapterFactoryConfig) {\n super();\n this.adapterType = config.command.replace(/[^a-zA-Z0-9]/g, '-');\n this.displayName = config.command;\n this.autoResponseRules = this.buildAutoResponseRules();\n }\n\n private buildAutoResponseRules(): AutoResponseRule[] {\n if (!this.config.blockingPrompts) {\n return [];\n }\n\n return this.config.blockingPrompts\n .filter((p) => p.autoResponse !== undefined)\n .map((p) => ({\n pattern: p.pattern,\n type: p.type,\n response: p.autoResponse!,\n description: p.description || `Auto-respond to ${p.type} prompt`,\n safe: p.safe !== false,\n }));\n }\n\n getCommand(): string {\n return this.config.command;\n }\n\n getArgs(config: SpawnConfig): string[] {\n if (typeof this.config.args === 'function') {\n return this.config.args(config);\n }\n return this.config.args || [];\n }\n\n getEnv(config: SpawnConfig): Record<string, string> {\n if (typeof this.config.env === 'function') {\n return this.config.env(config);\n }\n return this.config.env || {};\n }\n\n detectLogin(output: string): LoginDetection {\n if (!this.config.loginDetection) {\n return { required: false };\n }\n\n const { patterns, extractUrl, extractInstructions } = this.config.loginDetection;\n const stripped = this.stripAnsi(output);\n\n for (const pattern of patterns) {\n if (pattern.test(stripped)) {\n return {\n required: true,\n type: 'browser',\n url: extractUrl?.(stripped) || undefined,\n instructions: extractInstructions?.(stripped) || 'Authentication required',\n };\n }\n }\n\n return { required: false };\n }\n\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n // First check config-defined blocking prompts\n if (this.config.blockingPrompts) {\n const stripped = this.stripAnsi(output);\n\n for (const prompt of this.config.blockingPrompts) {\n if (prompt.pattern.test(stripped)) {\n return {\n detected: true,\n type: prompt.type,\n prompt: stripped.slice(-200),\n suggestedResponse: prompt.autoResponse,\n canAutoRespond: prompt.autoResponse !== undefined && prompt.safe !== false,\n instructions: prompt.description,\n };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectBlockingPrompt(output);\n }\n\n detectReady(output: string): boolean {\n if (!this.config.readyIndicators || this.config.readyIndicators.length === 0) {\n // Default: ready after any output\n return output.length > 10;\n }\n\n const stripped = this.stripAnsi(output);\n return this.config.readyIndicators.some((pattern) => pattern.test(stripped));\n }\n\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n if (this.config.exitIndicators) {\n for (const indicator of this.config.exitIndicators) {\n const match = output.match(indicator.pattern);\n if (match) {\n const code = indicator.codeExtractor?.(match) ?? 1;\n return { exited: true, code };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectExit(output);\n }\n\n parseOutput(output: string): ParsedOutput | null {\n if (this.config.parseOutput) {\n return this.config.parseOutput(output);\n }\n\n // Default parsing\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: this.containsQuestion(cleaned),\n };\n }\n\n formatInput(message: string): string {\n if (this.config.formatInput) {\n return this.config.formatInput(message);\n }\n return message;\n }\n\n getPromptPattern(): RegExp {\n return this.config.promptPattern || /[\\$#>]\\s*$/m;\n }\n}\n","/**\n * Shell Adapter\n *\n * Built-in adapter for bash/zsh shell sessions.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../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 return [];\n }\n\n getEnv(_config: SpawnConfig): Record<string, string> {\n return {\n PS1: this.promptStr,\n };\n }\n\n detectLogin(_output: string): LoginDetection {\n // Shell doesn't need login\n return { required: false };\n }\n\n detectBlockingPrompt(_output: string): BlockingPromptDetection {\n // Shell typically doesn't have blocking prompts\n return { detected: false };\n }\n\n detectReady(output: string): boolean {\n // Ready when we see the prompt or any meaningful output\n return output.includes(this.promptStr) || output.includes('$') || output.length > 10;\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 // Match our custom prompt or standard shell prompts\n const escaped = this.promptStr.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:${escaped}|\\\\$|#|>)\\\\s*$`, 'm');\n }\n\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n // Shell is always installed\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","/**\n * Bun-Compatible PTY Manager\n *\n * A wrapper that spawns a Node.js worker process to handle PTY operations,\n * allowing pty-manager to work from Bun or other non-Node runtimes.\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport type { SpawnConfig } from './types';\n\nexport interface WorkerSessionHandle {\n id: string;\n name: string;\n type: string;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n pid: number | undefined;\n cols: number;\n rows: number;\n startedAt?: Date;\n lastActivityAt?: Date;\n error?: string;\n exitCode?: number;\n}\n\nexport interface BunPTYManagerOptions {\n /** Path to node executable (default: 'node') */\n nodePath?: string;\n /** Path to worker script (default: auto-detected) */\n workerPath?: string;\n /** Environment variables for worker process */\n env?: Record<string, string>;\n}\n\ninterface PendingOperation {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n}\n\n/**\n * PTY Manager that works with Bun and other non-Node runtimes\n * by spawning a Node.js worker process.\n */\nexport class BunCompatiblePTYManager extends EventEmitter {\n private worker: ChildProcess | null = null;\n private sessions: Map<string, WorkerSessionHandle> = new Map();\n private pending: Map<string, PendingOperation> = new Map();\n private ready = false;\n private readyPromise: Promise<void>;\n private readyResolve!: () => void;\n private nodePath: string;\n private workerPath: string;\n private env: Record<string, string>;\n\n constructor(options: BunPTYManagerOptions = {}) {\n super();\n\n this.nodePath = options.nodePath || 'node';\n this.workerPath = options.workerPath || this.findWorkerPath();\n this.env = options.env || {};\n\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n }\n\n private findWorkerPath(): string {\n // Try to find the worker script relative to this module\n const possiblePaths = [\n path.join(__dirname, 'pty-worker.js'),\n path.join(__dirname, '..', 'dist', 'pty-worker.js'),\n path.join(__dirname, '..', 'src', 'pty-worker.js'),\n ];\n\n // Return first path (we'll rely on Node to throw if it doesn't exist)\n return possiblePaths[0];\n }\n\n private startWorker(): void {\n this.worker = spawn(this.nodePath, [this.workerPath], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...this.env },\n });\n\n if (!this.worker.stdout || !this.worker.stdin) {\n throw new Error('Failed to create worker process pipes');\n }\n\n const rl = readline.createInterface({\n input: this.worker.stdout,\n terminal: false,\n });\n\n rl.on('line', (line) => this.handleWorkerMessage(line));\n\n this.worker.stderr?.on('data', (data) => {\n this.emit('worker_error', data.toString());\n });\n\n this.worker.on('exit', (code, signal) => {\n this.ready = false;\n this.worker = null;\n this.emit('worker_exit', { code, signal });\n\n // Reject all pending operations\n for (const [key, op] of this.pending) {\n clearTimeout(op.timeout);\n op.reject(new Error('Worker process exited'));\n this.pending.delete(key);\n }\n\n // Mark all sessions as stopped\n for (const session of this.sessions.values()) {\n session.status = 'stopped';\n }\n });\n\n this.worker.on('error', (err) => {\n this.emit('worker_error', err);\n });\n }\n\n private handleWorkerMessage(line: string): void {\n let event: Record<string, unknown>;\n\n try {\n event = JSON.parse(line);\n } catch {\n this.emit('worker_error', `Invalid JSON from worker: ${line}`);\n return;\n }\n\n const eventType = event.event as string;\n const id = event.id as string | undefined;\n\n switch (eventType) {\n case 'worker_ready':\n this.ready = true;\n this.readyResolve();\n this.emit('ready');\n break;\n\n case 'spawned': {\n // Get config from event (worker sends it back)\n const session: WorkerSessionHandle = {\n id: id!,\n name: (event.name as string) || id!,\n type: (event.type as string) || 'shell',\n status: 'starting',\n pid: event.pid as number,\n cols: (event.cols as number) || 80,\n rows: (event.rows as number) || 24,\n startedAt: new Date(),\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output': {\n const session = this.sessions.get(id!);\n if (session) {\n session.lastActivityAt = new Date();\n }\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n }\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\n session.lastActivityAt = new Date();\n this.emit('session_ready', session);\n }\n break;\n }\n\n case 'exit': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'stopped';\n session.exitCode = event.code as number;\n session.lastActivityAt = new Date();\n this.emit('session_stopped', session, event.code, event.signal);\n this.sessions.delete(id!);\n }\n break;\n }\n\n case 'error':\n if (id) {\n const session = this.sessions.get(id);\n if (session) {\n session.status = 'error';\n session.error = event.message as string;\n session.lastActivityAt = new Date();\n }\n this.emit('session_error', { id, error: event.message });\n } else {\n this.emit('worker_error', event.message);\n }\n break;\n\n case 'list': {\n // Convert date strings back to Date objects\n const sessions = (event.sessions as Record<string, unknown>[]).map((s) => ({\n ...s,\n startedAt: s.startedAt ? new Date(s.startedAt as string) : undefined,\n lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt as string) : undefined,\n })) as WorkerSessionHandle[];\n this.resolvePending('list', sessions);\n break;\n }\n\n case 'ack': {\n const cmd = event.cmd as string;\n const success = event.success as boolean;\n const pendingKey = id ? `${cmd}:${id}` : cmd;\n const pending = this.pending.get(pendingKey);\n\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(pendingKey);\n\n if (success) {\n pending.resolve(true);\n } else {\n pending.reject(new Error(event.error as string));\n }\n }\n break;\n }\n }\n }\n\n private sendCommand(cmd: Record<string, unknown>): void {\n if (!this.worker?.stdin) {\n throw new Error('Worker not available');\n }\n\n this.worker.stdin.write(JSON.stringify(cmd) + '\\n');\n }\n\n private createPending(key: string, timeoutMs = 30000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Operation ${key} timed out`));\n }, timeoutMs);\n\n this.pending.set(key, { resolve, reject, timeout });\n });\n }\n\n private resolvePending(key: string, value: unknown): void {\n const pending = this.pending.get(key);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(key);\n pending.resolve(value);\n }\n }\n\n /**\n * Wait for the worker to be ready\n */\n async waitForReady(): Promise<void> {\n return this.readyPromise;\n }\n\n /**\n * Check if worker is ready\n */\n isReady(): boolean {\n return this.ready;\n }\n\n /**\n * Spawn a new PTY session\n */\n async spawn(config: SpawnConfig & { id: string }): Promise<WorkerSessionHandle> {\n await this.waitForReady();\n\n const { id } = config;\n\n this.sendCommand({ cmd: 'spawn', id, config });\n\n await this.createPending(`spawn:${id}`);\n\n return this.sessions.get(id)!;\n }\n\n /**\n * Send data to a session\n */\n async send(id: string, data: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'send', id, data });\n\n await this.createPending(`send:${id}`);\n }\n\n /**\n * Send special keys to a session\n */\n async sendKeys(id: string, keys: string | string[]): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'sendKeys', id, keys });\n\n await this.createPending(`sendKeys:${id}`);\n }\n\n /**\n * Paste text to a session\n */\n async paste(id: string, text: string, bracketed = true): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'paste', id, text, bracketed });\n\n await this.createPending(`paste:${id}`);\n }\n\n /**\n * Resize a session\n */\n async resize(id: string, cols: number, rows: number): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'resize', id, cols, rows });\n\n const session = this.sessions.get(id);\n if (session) {\n session.cols = cols;\n session.rows = rows;\n }\n\n await this.createPending(`resize:${id}`);\n }\n\n /**\n * Kill a session\n */\n async kill(id: string, signal?: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'kill', id, signal });\n\n await this.createPending(`kill:${id}`);\n }\n\n /**\n * Get a session by ID\n */\n get(id: string): WorkerSessionHandle | undefined {\n return this.sessions.get(id);\n }\n\n /**\n * List all sessions\n */\n async list(): Promise<WorkerSessionHandle[]> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'list' });\n\n const sessions = (await this.createPending('list')) as WorkerSessionHandle[];\n return sessions;\n }\n\n /**\n * Check if a session exists\n */\n has(id: string): boolean {\n return this.sessions.has(id);\n }\n\n /**\n * Subscribe to output from a specific session\n */\n onSessionData(id: string, callback: (data: string) => void): () => void {\n const handler = (data: string) => callback(data);\n this.on(`data:${id}`, handler);\n return () => this.off(`data:${id}`, handler);\n }\n\n /**\n * Shutdown the worker and all sessions\n */\n async shutdown(): Promise<void> {\n if (!this.worker) return;\n\n this.sendCommand({ cmd: 'shutdown' });\n\n await this.createPending('shutdown', 10000).catch(() => {\n // Force kill if shutdown times out\n this.worker?.kill('SIGKILL');\n });\n }\n\n /**\n * Restart the worker process\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n this.sessions.clear();\n this.ready = false;\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n await this.waitForReady();\n }\n}\n\n/**\n * Detect if running in Bun\n */\nexport function isBun(): boolean {\n // Bun 1.1.24+ sets process.versions.bun (lowercase)\n return typeof process !== 'undefined' && 'bun' in process.versions;\n}\n\n/**\n * Create the appropriate PTY manager based on runtime\n */\nexport function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager {\n return new BunCompatiblePTYManager(options);\n}\n"],"mappings":"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","names":["import_events","consoleLogger","import_child_process","import_events"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/pty-manager.ts","../src/adapters/adapter-registry.ts","../src/pty-session.ts","../src/adapters/base-adapter.ts","../src/adapters/adapter-factory.ts","../src/adapters/shell-adapter.ts","../src/bun-compat.ts"],"sourcesContent":["/**\n * pty-manager\n *\n * PTY session manager with lifecycle management,\n * pluggable adapters, and blocking prompt detection.\n */\n\n// Core classes\nexport { PTYManager } from './pty-manager';\nexport { PTYSession, SPECIAL_KEYS } from './pty-session';\n\n// Adapter system\nexport {\n AdapterRegistry,\n BaseCLIAdapter,\n createAdapter,\n ShellAdapter,\n} from './adapters';\n\nexport type { CLIAdapter, ShellAdapterOptions } from './adapters';\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 BlockingPromptType,\n BlockingPromptDetection,\n AutoResponseRule,\n BlockingPromptInfo,\n\n // Manager types\n Logger,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n\n // Factory types\n AdapterFactoryConfig,\n} from './types';\n\n// Event types\nexport type { PTYManagerEvents } from './pty-manager';\nexport type { PTYSessionEvents } from './pty-session';\n\n// Bun compatibility layer\nexport {\n BunCompatiblePTYManager,\n createPTYManager,\n isBun,\n} from './bun-compat';\n\nexport type {\n WorkerSessionHandle,\n BunPTYManagerOptions,\n} from './bun-compat';\n","/**\n * PTY Manager\n *\n * Manages multiple PTY sessions for CLI tools.\n */\n\nimport { EventEmitter } from 'events';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport { AdapterRegistry } from './adapters/adapter-registry';\nimport { PTYSession } from './pty-session';\nimport type {\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n SessionStatus,\n BlockingPromptInfo,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n Logger,\n} from './types';\n\nexport interface PTYManagerEvents {\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 blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (session: SessionHandle, question: string) => void;\n}\n\n/**\n * Console-based logger fallback\n */\nconst 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\nexport class PTYManager extends EventEmitter {\n private sessions: Map<string, PTYSession> = new Map();\n private outputLogs: Map<string, string[]> = new Map();\n private maxLogLines: number;\n private logger: Logger;\n public readonly adapters: AdapterRegistry;\n\n constructor(config: PTYManagerConfig = {}) {\n super();\n this.adapters = new AdapterRegistry();\n this.logger = config.logger || consoleLogger;\n this.maxLogLines = config.maxLogLines || 1000;\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 PTY session\n */\n async spawn(config: SpawnConfig): Promise<SessionHandle> {\n // Get adapter for this type\n const adapter = this.adapters.get(config.type);\n if (!adapter) {\n throw new Error(`No adapter found for type: ${config.type}. Registered adapters: ${this.adapters.list().join(', ') || 'none'}`);\n }\n\n // Check if ID already exists\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 session'\n );\n\n // Create session\n const session = new PTYSession(adapter, config, this.logger);\n\n // Set up event forwarding\n this.setupSessionEvents(session);\n\n // Store session\n this.sessions.set(session.id, session);\n this.outputLogs.set(session.id, []);\n\n // Start the session\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: PTYSession): void {\n session.on('output', (data: string) => {\n // Store in log buffer\n const logs = this.outputLogs.get(session.id) || [];\n const lines = data.split('\\n');\n logs.push(...lines);\n\n // Trim to max lines\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('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\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 // Force kill if graceful shutdown times out\n session.kill('SIGKILL');\n resolve();\n }, timeout);\n\n session.once('exit', () => {\n clearTimeout(timer);\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n });\n\n // Send graceful signal\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 // Apply filters\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) {\n return null;\n }\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 sessions');\n\n await this.stopAll({ timeout: 3000 });\n\n this.sessions.clear();\n this.outputLogs.clear();\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) {\n return null;\n }\n\n return {\n /**\n * Subscribe to raw terminal output\n * Returns an unsubscribe function\n */\n onData: (callback: (data: string) => void) => {\n session.on('output', callback);\n return () => session.off('output', callback);\n },\n\n /**\n * Write raw data to terminal (no formatting applied)\n */\n write: (data: string) => {\n session.writeRaw(data);\n },\n\n /**\n * Resize the terminal\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 PTYSession (for advanced use)\n */\n getSession(sessionId: string): PTYSession | undefined {\n return this.sessions.get(sessionId);\n }\n}\n","/**\n * Adapter Registry\n *\n * Registry for managing CLI adapters.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\n\n/**\n * Registry of available CLI adapters\n */\nexport class AdapterRegistry {\n private adapters: Map<string, CLIAdapter> = new Map();\n\n /**\n * Register an adapter\n */\n register(adapter: CLIAdapter): void {\n this.adapters.set(adapter.adapterType, adapter);\n }\n\n /**\n * Get adapter for type\n */\n get(adapterType: string): CLIAdapter | undefined {\n return this.adapters.get(adapterType);\n }\n\n /**\n * Check if adapter exists for type\n */\n has(adapterType: string): boolean {\n return this.adapters.has(adapterType);\n }\n\n /**\n * Unregister an adapter\n */\n unregister(adapterType: string): boolean {\n return this.adapters.delete(adapterType);\n }\n\n /**\n * List all registered adapter types\n */\n list(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Get all adapters\n */\n all(): CLIAdapter[] {\n return Array.from(this.adapters.values());\n }\n\n /**\n * Clear all adapters\n */\n clear(): void {\n this.adapters.clear();\n }\n}\n","/**\n * PTY Session\n *\n * Manages a single pseudo-terminal session for a CLI tool.\n */\n\nimport { EventEmitter } from 'events';\nimport type * as ptyModule from 'node-pty';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport type {\n SpawnConfig,\n SessionStatus,\n SessionHandle,\n SessionMessage,\n BlockingPromptInfo,\n Logger,\n} from './types';\n\n// Lazy-load node-pty to avoid issues in environments where it's not installed\nlet ptyCache: typeof ptyModule | null = null;\nfunction loadPty(): typeof ptyModule {\n if (!ptyCache) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n ptyCache = require('node-pty') as typeof ptyModule;\n } catch {\n throw new Error(\n 'node-pty is required but not installed. Run: npm install node-pty'\n );\n }\n }\n return ptyCache!;\n}\n\nexport interface PTYSessionEvents {\n output: (data: string) => void;\n ready: () => void;\n login_required: (instructions?: string, url?: string) => 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}\n\n/**\n * Console-based logger fallback\n */\nconst 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/**\n * Generate a unique ID\n */\nfunction generateId(): string {\n return `pty-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Special key mappings to escape sequences\n *\n * Modifier codes for arrows/function keys:\n * 2 = Shift, 3 = Alt, 4 = Shift+Alt, 5 = Ctrl, 6 = Ctrl+Shift, 7 = Ctrl+Alt, 8 = Ctrl+Alt+Shift\n */\nexport const SPECIAL_KEYS: Record<string, string> = {\n // Control keys (Ctrl+letter = ASCII control code)\n 'ctrl+a': '\\x01',\n 'ctrl+b': '\\x02',\n 'ctrl+c': '\\x03',\n 'ctrl+d': '\\x04',\n 'ctrl+e': '\\x05',\n 'ctrl+f': '\\x06',\n 'ctrl+g': '\\x07',\n 'ctrl+h': '\\x08',\n 'ctrl+i': '\\x09',\n 'ctrl+j': '\\x0a',\n 'ctrl+k': '\\x0b',\n 'ctrl+l': '\\x0c',\n 'ctrl+m': '\\x0d',\n 'ctrl+n': '\\x0e',\n 'ctrl+o': '\\x0f',\n 'ctrl+p': '\\x10',\n 'ctrl+q': '\\x11',\n 'ctrl+r': '\\x12',\n 'ctrl+s': '\\x13',\n 'ctrl+t': '\\x14',\n 'ctrl+u': '\\x15',\n 'ctrl+v': '\\x16',\n 'ctrl+w': '\\x17',\n 'ctrl+x': '\\x18',\n 'ctrl+y': '\\x19',\n 'ctrl+z': '\\x1a',\n 'ctrl+[': '\\x1b',\n 'ctrl+\\\\': '\\x1c',\n 'ctrl+]': '\\x1d',\n 'ctrl+^': '\\x1e',\n 'ctrl+_': '\\x1f',\n\n // Alt+letter (Meta key = ESC + letter)\n 'alt+a': '\\x1ba', 'alt+b': '\\x1bb', 'alt+c': '\\x1bc', 'alt+d': '\\x1bd',\n 'alt+e': '\\x1be', 'alt+f': '\\x1bf', 'alt+g': '\\x1bg', 'alt+h': '\\x1bh',\n 'alt+i': '\\x1bi', 'alt+j': '\\x1bj', 'alt+k': '\\x1bk', 'alt+l': '\\x1bl',\n 'alt+m': '\\x1bm', 'alt+n': '\\x1bn', 'alt+o': '\\x1bo', 'alt+p': '\\x1bp',\n 'alt+q': '\\x1bq', 'alt+r': '\\x1br', 'alt+s': '\\x1bs', 'alt+t': '\\x1bt',\n 'alt+u': '\\x1bu', 'alt+v': '\\x1bv', 'alt+w': '\\x1bw', 'alt+x': '\\x1bx',\n 'alt+y': '\\x1by', 'alt+z': '\\x1bz',\n 'alt+backspace': '\\x1b\\x7f', // Delete word backward\n\n // Navigation - plain\n 'up': '\\x1b[A',\n 'down': '\\x1b[B',\n 'right': '\\x1b[C',\n 'left': '\\x1b[D',\n 'home': '\\x1b[H',\n 'end': '\\x1b[F',\n 'pageup': '\\x1b[5~',\n 'pagedown': '\\x1b[6~',\n\n // Navigation - with Shift (modifier 2)\n 'shift+up': '\\x1b[1;2A',\n 'shift+down': '\\x1b[1;2B',\n 'shift+right': '\\x1b[1;2C',\n 'shift+left': '\\x1b[1;2D',\n 'shift+home': '\\x1b[1;2H',\n 'shift+end': '\\x1b[1;2F',\n 'shift+pageup': '\\x1b[5;2~',\n 'shift+pagedown': '\\x1b[6;2~',\n\n // Navigation - with Alt (modifier 3)\n 'alt+up': '\\x1b[1;3A',\n 'alt+down': '\\x1b[1;3B',\n 'alt+right': '\\x1b[1;3C', // Forward word\n 'alt+left': '\\x1b[1;3D', // Backward word\n\n // Navigation - with Ctrl (modifier 5)\n 'ctrl+up': '\\x1b[1;5A',\n 'ctrl+down': '\\x1b[1;5B',\n 'ctrl+right': '\\x1b[1;5C', // Forward word\n 'ctrl+left': '\\x1b[1;5D', // Backward word\n 'ctrl+home': '\\x1b[1;5H',\n 'ctrl+end': '\\x1b[1;5F',\n\n // Navigation - with Ctrl+Shift (modifier 6) - select word\n 'ctrl+shift+up': '\\x1b[1;6A',\n 'ctrl+shift+down': '\\x1b[1;6B',\n 'ctrl+shift+right': '\\x1b[1;6C',\n 'ctrl+shift+left': '\\x1b[1;6D',\n 'ctrl+shift+home': '\\x1b[1;6H',\n 'ctrl+shift+end': '\\x1b[1;6F',\n\n // Navigation - with Shift+Alt (modifier 4)\n 'shift+alt+up': '\\x1b[1;4A',\n 'shift+alt+down': '\\x1b[1;4B',\n 'shift+alt+right': '\\x1b[1;4C',\n 'shift+alt+left': '\\x1b[1;4D',\n\n // Editing\n 'enter': '\\r',\n 'return': '\\r',\n 'tab': '\\t',\n 'shift+tab': '\\x1b[Z', // Reverse tab\n 'backspace': '\\x7f',\n 'delete': '\\x1b[3~',\n 'shift+delete': '\\x1b[3;2~',\n 'ctrl+delete': '\\x1b[3;5~', // Delete word forward\n 'insert': '\\x1b[2~',\n 'escape': '\\x1b',\n 'esc': '\\x1b',\n 'space': ' ',\n\n // Function keys - plain\n 'f1': '\\x1bOP',\n 'f2': '\\x1bOQ',\n 'f3': '\\x1bOR',\n 'f4': '\\x1bOS',\n 'f5': '\\x1b[15~',\n 'f6': '\\x1b[17~',\n 'f7': '\\x1b[18~',\n 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~',\n 'f10': '\\x1b[21~',\n 'f11': '\\x1b[23~',\n 'f12': '\\x1b[24~',\n\n // Function keys - with Shift (modifier 2)\n 'shift+f1': '\\x1b[1;2P',\n 'shift+f2': '\\x1b[1;2Q',\n 'shift+f3': '\\x1b[1;2R',\n 'shift+f4': '\\x1b[1;2S',\n 'shift+f5': '\\x1b[15;2~',\n 'shift+f6': '\\x1b[17;2~',\n 'shift+f7': '\\x1b[18;2~',\n 'shift+f8': '\\x1b[19;2~',\n 'shift+f9': '\\x1b[20;2~',\n 'shift+f10': '\\x1b[21;2~',\n 'shift+f11': '\\x1b[23;2~',\n 'shift+f12': '\\x1b[24;2~',\n\n // Function keys - with Ctrl (modifier 5)\n 'ctrl+f1': '\\x1b[1;5P',\n 'ctrl+f2': '\\x1b[1;5Q',\n 'ctrl+f3': '\\x1b[1;5R',\n 'ctrl+f4': '\\x1b[1;5S',\n 'ctrl+f5': '\\x1b[15;5~',\n 'ctrl+f6': '\\x1b[17;5~',\n 'ctrl+f7': '\\x1b[18;5~',\n 'ctrl+f8': '\\x1b[19;5~',\n 'ctrl+f9': '\\x1b[20;5~',\n 'ctrl+f10': '\\x1b[21;5~',\n 'ctrl+f11': '\\x1b[23;5~',\n 'ctrl+f12': '\\x1b[24;5~',\n};\n\n/**\n * Bracketed paste mode escape sequences\n */\nconst BRACKETED_PASTE_START = '\\x1b[200~';\nconst BRACKETED_PASTE_END = '\\x1b[201~';\n\nexport class PTYSession extends EventEmitter {\n private ptyProcess: ptyModule.IPty | null = null;\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\n public readonly id: string;\n public readonly config: SpawnConfig;\n\n constructor(\n private adapter: CLIAdapter,\n config: SpawnConfig,\n logger?: Logger\n ) {\n super();\n this.id = config.id || generateId();\n this.config = { ...config, id: this.id };\n this.logger = logger || consoleLogger;\n }\n\n get status(): SessionStatus {\n return this._status;\n }\n\n get pid(): number | undefined {\n return this.ptyProcess?.pid;\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 * Start the PTY session\n */\n async start(): Promise<void> {\n if (this.ptyProcess) {\n throw new Error('Session already started');\n }\n\n const nodePty = loadPty();\n\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\n const env = {\n ...process.env,\n ...adapterEnv,\n ...this.config.env,\n // Force terminal settings\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n };\n\n this.logger.info(\n { sessionId: this.id, command, args: args.join(' ') },\n 'Starting PTY session'\n );\n\n try {\n this.ptyProcess = nodePty.spawn(command, args, {\n name: 'xterm-256color',\n cols: this.config.cols || 120,\n rows: this.config.rows || 40,\n cwd: this.config.workdir || process.cwd(),\n env: env as Record<string, string>,\n });\n\n this.setupEventHandlers();\n\n this.logger.info(\n { sessionId: this.id, pid: this.ptyProcess.pid },\n 'PTY session started'\n );\n } catch (error) {\n this._status = 'error';\n this.logger.error(\n { sessionId: this.id, error },\n 'Failed to start PTY session'\n );\n throw error;\n }\n }\n\n /**\n * Set up event handlers for the PTY\n */\n private setupEventHandlers(): void {\n if (!this.ptyProcess) return;\n\n this.ptyProcess.onData((data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n // Emit raw output\n this.emit('output', data);\n\n // Check for blocking prompts\n const blockingPrompt = this.detectAndHandleBlockingPrompt();\n if (blockingPrompt) {\n return;\n }\n\n // Fallback: Check for login required (legacy support)\n const loginDetection = this.adapter.detectLogin(this.outputBuffer);\n if (loginDetection.required && this._status !== 'authenticating') {\n this._status = 'authenticating';\n this.emit('login_required', loginDetection.instructions, loginDetection.url);\n this.logger.warn(\n { sessionId: this.id, loginType: loginDetection.type },\n 'Login required'\n );\n return;\n }\n\n // Check for ready state\n if (this._status === 'starting' && this.adapter.detectReady(this.outputBuffer)) {\n this._status = 'ready';\n this.emit('ready');\n this.logger.info({ sessionId: this.id }, 'Session ready');\n }\n\n // Check for exit\n const exitDetection = this.adapter.detectExit(this.outputBuffer);\n if (exitDetection.exited) {\n this._status = 'stopped';\n this.emit('exit', exitDetection.code || 0);\n }\n\n // Try to parse output into structured message\n this.tryParseOutput();\n });\n\n this.ptyProcess.onExit(({ exitCode, signal }) => {\n this._status = 'stopped';\n this.logger.info(\n { sessionId: this.id, exitCode, signal },\n 'PTY session exited'\n );\n this.emit('exit', exitCode);\n });\n }\n\n /**\n * Detect blocking prompts and handle them with auto-responses or user notification\n */\n private detectAndHandleBlockingPrompt(): boolean {\n // First, check adapter's auto-response rules\n const autoHandled = this.tryAutoResponse();\n if (autoHandled) {\n return true;\n }\n\n // Then check the adapter's detectBlockingPrompt method\n if (this.adapter.detectBlockingPrompt) {\n const detection = this.adapter.detectBlockingPrompt(this.outputBuffer);\n\n if (detection.detected) {\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 we can auto-respond and have a suggested response, do it\n if (detection.canAutoRespond && detection.suggestedResponse) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: detection.type,\n response: detection.suggestedResponse,\n },\n 'Auto-responding to blocking prompt'\n );\n\n this.writeRaw(detection.suggestedResponse + '\\r');\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n }\n\n // Otherwise, notify that user intervention is needed\n if (detection.type === 'login') {\n this._status = 'authenticating';\n }\n\n this.logger.warn(\n {\n sessionId: this.id,\n promptType: detection.type,\n prompt: detection.prompt,\n },\n 'Blocking prompt requires user intervention'\n );\n\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Try to match and apply auto-response rules\n */\n private tryAutoResponse(): boolean {\n const rules = this.adapter.autoResponseRules;\n if (!rules || rules.length === 0) {\n return false;\n }\n\n for (const rule of rules) {\n if (rule.pattern.test(this.outputBuffer)) {\n // Check if it's safe to auto-respond (default: true)\n const safe = rule.safe !== false;\n\n if (safe) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: rule.type,\n description: rule.description,\n response: rule.response,\n },\n 'Applying auto-response rule'\n );\n\n this.writeRaw(rule.response + '\\r');\n\n // Clear the matched portion from buffer to prevent re-matching\n this.outputBuffer = this.outputBuffer.replace(rule.pattern, '');\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 // Not safe to auto-respond, emit for user intervention\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\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Try to parse the output buffer into structured messages\n */\n private tryParseOutput(): void {\n const parsed = this.adapter.parseOutput(this.outputBuffer);\n\n if (parsed && parsed.isComplete) {\n // Clear the buffer for the parsed content\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 // Also emit specific event for questions\n if (parsed.isQuestion) {\n this.emit('question', parsed.content);\n }\n }\n }\n\n /**\n * Write data to the PTY (formatted by adapter)\n */\n write(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n const formatted = this.adapter.formatInput(data);\n this.ptyProcess.write(formatted + '\\r');\n\n this.logger.debug({ sessionId: this.id, input: data }, 'Sent input to session');\n }\n\n /**\n * Write raw data directly to the PTY (no formatting)\n */\n writeRaw(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n this.ptyProcess.write(data);\n }\n\n /**\n * Send a task/message to the session\n */\n send(message: string): SessionMessage {\n this._status = 'busy';\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 this.write(message);\n\n return msg;\n }\n\n /**\n * Resize the PTY terminal\n */\n resize(cols: number, rows: number): void {\n this.ptyProcess?.resize(cols, rows);\n }\n\n /**\n * Send special keys to the PTY\n *\n * Supported keys:\n * - Control: ctrl+c, ctrl+d, ctrl+z, ctrl+l, ctrl+a, ctrl+e, ctrl+k, ctrl+u, ctrl+w, ctrl+r\n * - Navigation: up, down, left, right, home, end, pageup, pagedown\n * - Editing: enter, tab, backspace, delete, insert, escape\n * - Function: f1-f12\n *\n * @param keys - Key name(s) to send, e.g. \"ctrl+c\" or [\"up\", \"up\", \"enter\"]\n */\n sendKeys(keys: string | string[]): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n const keyList = Array.isArray(keys) ? keys : [keys];\n\n for (const key of keyList) {\n const normalizedKey = key.toLowerCase().trim();\n const sequence = SPECIAL_KEYS[normalizedKey];\n\n if (sequence) {\n this._lastActivityAt = new Date();\n this.ptyProcess.write(sequence);\n this.logger.debug({ sessionId: this.id, key: normalizedKey }, 'Sent special key');\n } else {\n this.logger.warn(\n { sessionId: this.id, key: normalizedKey },\n 'Unknown special key, sending as literal'\n );\n this.ptyProcess.write(key);\n }\n }\n }\n\n /**\n * Paste text using bracketed paste mode\n *\n * Bracketed paste mode wraps the pasted text in escape sequences\n * that tell the terminal this is pasted content, not typed input.\n * This prevents issues with pasting text that contains special characters\n * or looks like commands.\n *\n * @param text - Text to paste\n * @param useBracketedPaste - Whether to use bracketed paste mode (default: true)\n */\n paste(text: string, useBracketedPaste: boolean = true): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n\n if (useBracketedPaste) {\n this.ptyProcess.write(BRACKETED_PASTE_START + text + BRACKETED_PASTE_END);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text with bracketed paste mode'\n );\n } else {\n this.ptyProcess.write(text);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text without bracketed paste'\n );\n }\n }\n\n /**\n * Kill the PTY process\n */\n kill(signal?: string): void {\n if (this.ptyProcess) {\n this._status = 'stopping';\n this.ptyProcess.kill(signal);\n this.logger.info({ sessionId: this.id, signal }, 'Killing PTY session');\n }\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 };\n }\n}\n","/**\n * Base CLI Adapter\n *\n * Abstract base class with common functionality for CLI adapters.\n */\n\nimport { spawn } from 'child_process';\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../types';\n\n/**\n * Abstract base class for CLI adapters with common functionality\n */\nexport abstract class BaseCLIAdapter implements CLIAdapter {\n abstract readonly adapterType: string;\n abstract readonly displayName: string;\n\n /**\n * Auto-response rules for handling known blocking prompts.\n * Subclasses should override this to add CLI-specific rules.\n */\n readonly autoResponseRules: AutoResponseRule[] = [];\n\n abstract getCommand(): string;\n abstract getArgs(config: SpawnConfig): string[];\n abstract getEnv(config: SpawnConfig): Record<string, string>;\n abstract detectLogin(output: string): LoginDetection;\n abstract detectReady(output: string): boolean;\n abstract parseOutput(output: string): ParsedOutput | null;\n abstract getPromptPattern(): RegExp;\n\n /**\n * Default exit detection - look for common exit patterns\n */\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n // Check for common exit/error patterns\n if (output.includes('Process exited with code')) {\n const match = output.match(/Process exited with code (\\d+)/);\n return {\n exited: true,\n code: match ? parseInt(match[1], 10) : 1,\n };\n }\n\n if (output.includes('Command not found') || output.includes('command not found')) {\n return {\n exited: true,\n code: 127,\n error: 'Command not found',\n };\n }\n\n return { exited: false };\n }\n\n /**\n * Default blocking prompt detection - looks for common prompt patterns.\n * Subclasses should override for CLI-specific detection.\n */\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n const stripped = this.stripAnsi(output);\n\n // Check for login/auth first (highest priority)\n const loginDetection = this.detectLogin(output);\n if (loginDetection.required) {\n return {\n detected: true,\n type: 'login',\n prompt: loginDetection.instructions,\n url: loginDetection.url,\n canAutoRespond: false,\n instructions: loginDetection.instructions,\n };\n }\n\n // Check for common update prompts\n if (/update (available|now|ready)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'update',\n prompt: 'Update available',\n options: ['y', 'n'],\n suggestedResponse: 'n',\n canAutoRespond: true,\n instructions: 'CLI update available - auto-declining to continue',\n };\n }\n\n // Check for terms of service / license acceptance\n if (/accept.*(terms|license|agreement)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'tos',\n prompt: 'Terms/license acceptance required',\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Please accept the terms of service manually',\n };\n }\n\n // Check for model/version selection\n if (/choose.*model|select.*model|which model/i.test(stripped)) {\n return {\n detected: true,\n type: 'model_select',\n prompt: 'Model selection required',\n canAutoRespond: false,\n instructions: 'Please select a model',\n };\n }\n\n // Check for project/workspace selection\n if (/choose.*(project|workspace)|select.*(project|workspace)/i.test(stripped)) {\n return {\n detected: true,\n type: 'project_select',\n prompt: 'Project/workspace selection required',\n canAutoRespond: false,\n instructions: 'Please select a project or workspace',\n };\n }\n\n // Check for generic y/n prompts that look like they're blocking\n if (/\\[y\\/n\\]|\\(y\\/n\\)|\\[Y\\/n\\]|\\[y\\/N\\]/i.test(stripped) && stripped.includes('?')) {\n return {\n detected: true,\n type: 'unknown',\n prompt: stripped.slice(-200), // Last 200 chars for context\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Unknown confirmation prompt detected',\n };\n }\n\n return { detected: false };\n }\n\n /**\n * Default input formatting - just return as-is\n */\n formatInput(message: string): string {\n return message;\n }\n\n /**\n * Validate CLI installation by running --version or --help\n */\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n return new Promise((resolve) => {\n const command = this.getCommand();\n\n try {\n const proc = spawn(command, ['--version'], {\n shell: true,\n timeout: 5000,\n });\n\n let output = '';\n\n proc.stdout?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.stderr?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n // Try to extract version from output\n const versionMatch = output.match(/(\\d+\\.\\d+\\.\\d+)/);\n resolve({\n installed: true,\n version: versionMatch ? versionMatch[1] : undefined,\n });\n } else {\n resolve({\n installed: false,\n error: `Command exited with code ${code}`,\n });\n }\n });\n\n proc.on('error', (err) => {\n resolve({\n installed: false,\n error: err.message,\n });\n });\n } catch (err) {\n resolve({\n installed: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n });\n }\n\n /**\n * Helper to check if output contains a question\n */\n protected containsQuestion(output: string): boolean {\n const questionPatterns = [\n /\\?$/m, // Ends with ?\n /would you like/i,\n /do you want/i,\n /should I/i,\n /shall I/i,\n /please (choose|select|confirm)/i,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /\\[Y\\/n\\]/i,\n ];\n\n return questionPatterns.some((pattern) => pattern.test(output));\n }\n\n /**\n * Helper to strip ANSI escape codes from output\n */\n protected stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n }\n}\n","/**\n * Adapter Factory\n *\n * Factory function for creating CLI adapters from configuration.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport { BaseCLIAdapter } from './base-adapter';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n AdapterFactoryConfig,\n} from '../types';\n\n/**\n * Creates a CLI adapter from configuration\n */\nexport function createAdapter(config: AdapterFactoryConfig): CLIAdapter {\n return new ConfiguredAdapter(config);\n}\n\n/**\n * Adapter implementation created from configuration\n */\nclass ConfiguredAdapter extends BaseCLIAdapter {\n readonly adapterType: string;\n readonly displayName: string;\n readonly autoResponseRules: AutoResponseRule[];\n\n constructor(private config: AdapterFactoryConfig) {\n super();\n this.adapterType = config.command.replace(/[^a-zA-Z0-9]/g, '-');\n this.displayName = config.command;\n this.autoResponseRules = this.buildAutoResponseRules();\n }\n\n private buildAutoResponseRules(): AutoResponseRule[] {\n if (!this.config.blockingPrompts) {\n return [];\n }\n\n return this.config.blockingPrompts\n .filter((p) => p.autoResponse !== undefined)\n .map((p) => ({\n pattern: p.pattern,\n type: p.type,\n response: p.autoResponse!,\n description: p.description || `Auto-respond to ${p.type} prompt`,\n safe: p.safe !== false,\n }));\n }\n\n getCommand(): string {\n return this.config.command;\n }\n\n getArgs(config: SpawnConfig): string[] {\n if (typeof this.config.args === 'function') {\n return this.config.args(config);\n }\n return this.config.args || [];\n }\n\n getEnv(config: SpawnConfig): Record<string, string> {\n if (typeof this.config.env === 'function') {\n return this.config.env(config);\n }\n return this.config.env || {};\n }\n\n detectLogin(output: string): LoginDetection {\n if (!this.config.loginDetection) {\n return { required: false };\n }\n\n const { patterns, extractUrl, extractInstructions } = this.config.loginDetection;\n const stripped = this.stripAnsi(output);\n\n for (const pattern of patterns) {\n if (pattern.test(stripped)) {\n return {\n required: true,\n type: 'browser',\n url: extractUrl?.(stripped) || undefined,\n instructions: extractInstructions?.(stripped) || 'Authentication required',\n };\n }\n }\n\n return { required: false };\n }\n\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n // First check config-defined blocking prompts\n if (this.config.blockingPrompts) {\n const stripped = this.stripAnsi(output);\n\n for (const prompt of this.config.blockingPrompts) {\n if (prompt.pattern.test(stripped)) {\n return {\n detected: true,\n type: prompt.type,\n prompt: stripped.slice(-200),\n suggestedResponse: prompt.autoResponse,\n canAutoRespond: prompt.autoResponse !== undefined && prompt.safe !== false,\n instructions: prompt.description,\n };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectBlockingPrompt(output);\n }\n\n detectReady(output: string): boolean {\n if (!this.config.readyIndicators || this.config.readyIndicators.length === 0) {\n // Default: ready after any output\n return output.length > 10;\n }\n\n const stripped = this.stripAnsi(output);\n return this.config.readyIndicators.some((pattern) => pattern.test(stripped));\n }\n\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n if (this.config.exitIndicators) {\n for (const indicator of this.config.exitIndicators) {\n const match = output.match(indicator.pattern);\n if (match) {\n const code = indicator.codeExtractor?.(match) ?? 1;\n return { exited: true, code };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectExit(output);\n }\n\n parseOutput(output: string): ParsedOutput | null {\n if (this.config.parseOutput) {\n return this.config.parseOutput(output);\n }\n\n // Default parsing\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: this.containsQuestion(cleaned),\n };\n }\n\n formatInput(message: string): string {\n if (this.config.formatInput) {\n return this.config.formatInput(message);\n }\n return message;\n }\n\n getPromptPattern(): RegExp {\n return this.config.promptPattern || /[\\$#>]\\s*$/m;\n }\n}\n","/**\n * Shell Adapter\n *\n * Built-in adapter for bash/zsh shell sessions.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../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 return [];\n }\n\n getEnv(_config: SpawnConfig): Record<string, string> {\n return {\n PS1: this.promptStr,\n };\n }\n\n detectLogin(_output: string): LoginDetection {\n // Shell doesn't need login\n return { required: false };\n }\n\n detectBlockingPrompt(_output: string): BlockingPromptDetection {\n // Shell typically doesn't have blocking prompts\n return { detected: false };\n }\n\n detectReady(output: string): boolean {\n // Ready when we see the prompt or any meaningful output\n return output.includes(this.promptStr) || output.includes('$') || output.length > 10;\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 // Match our custom prompt or standard shell prompts\n const escaped = this.promptStr.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:${escaped}|\\\\$|#|>)\\\\s*$`, 'm');\n }\n\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n // Shell is always installed\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","/**\n * Bun-Compatible PTY Manager\n *\n * A wrapper that spawns a Node.js worker process to handle PTY operations,\n * allowing pty-manager to work from Bun or other non-Node runtimes.\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport type { SpawnConfig } from './types';\n\nexport interface WorkerSessionHandle {\n id: string;\n name: string;\n type: string;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n pid: number | undefined;\n cols: number;\n rows: number;\n startedAt?: Date;\n lastActivityAt?: Date;\n error?: string;\n exitCode?: number;\n}\n\nexport interface BunPTYManagerOptions {\n /** Path to node executable (default: 'node') */\n nodePath?: string;\n /** Path to worker script (default: auto-detected) */\n workerPath?: string;\n /** Environment variables for worker process */\n env?: Record<string, string>;\n}\n\ninterface PendingOperation {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n}\n\n/**\n * PTY Manager that works with Bun and other non-Node runtimes\n * by spawning a Node.js worker process.\n */\nexport class BunCompatiblePTYManager extends EventEmitter {\n private worker: ChildProcess | null = null;\n private sessions: Map<string, WorkerSessionHandle> = new Map();\n private pending: Map<string, PendingOperation> = new Map();\n private ready = false;\n private readyPromise: Promise<void>;\n private readyResolve!: () => void;\n private nodePath: string;\n private workerPath: string;\n private env: Record<string, string>;\n\n constructor(options: BunPTYManagerOptions = {}) {\n super();\n\n this.nodePath = options.nodePath || 'node';\n this.workerPath = options.workerPath || this.findWorkerPath();\n this.env = options.env || {};\n\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n }\n\n private findWorkerPath(): string {\n // Try to find the worker script relative to this module\n const possiblePaths = [\n path.join(__dirname, 'pty-worker.js'),\n path.join(__dirname, '..', 'dist', 'pty-worker.js'),\n path.join(__dirname, '..', 'src', 'pty-worker.js'),\n ];\n\n // Return first path (we'll rely on Node to throw if it doesn't exist)\n return possiblePaths[0];\n }\n\n private startWorker(): void {\n this.worker = spawn(this.nodePath, [this.workerPath], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...this.env },\n });\n\n if (!this.worker.stdout || !this.worker.stdin) {\n throw new Error('Failed to create worker process pipes');\n }\n\n const rl = readline.createInterface({\n input: this.worker.stdout,\n terminal: false,\n });\n\n rl.on('line', (line) => this.handleWorkerMessage(line));\n\n this.worker.stderr?.on('data', (data) => {\n this.emit('worker_error', data.toString());\n });\n\n this.worker.on('exit', (code, signal) => {\n this.ready = false;\n this.worker = null;\n this.emit('worker_exit', { code, signal });\n\n // Reject all pending operations\n for (const [key, op] of this.pending) {\n clearTimeout(op.timeout);\n op.reject(new Error('Worker process exited'));\n this.pending.delete(key);\n }\n\n // Mark all sessions as stopped\n for (const session of this.sessions.values()) {\n session.status = 'stopped';\n }\n });\n\n this.worker.on('error', (err) => {\n this.emit('worker_error', err);\n });\n }\n\n private handleWorkerMessage(line: string): void {\n let event: Record<string, unknown>;\n\n try {\n event = JSON.parse(line);\n } catch {\n this.emit('worker_error', `Invalid JSON from worker: ${line}`);\n return;\n }\n\n const eventType = event.event as string;\n const id = event.id as string | undefined;\n\n switch (eventType) {\n case 'worker_ready':\n this.ready = true;\n this.readyResolve();\n this.emit('ready');\n break;\n\n case 'spawned': {\n // Get config from event (worker sends it back)\n const session: WorkerSessionHandle = {\n id: id!,\n name: (event.name as string) || id!,\n type: (event.type as string) || 'shell',\n status: 'starting',\n pid: event.pid as number,\n cols: (event.cols as number) || 80,\n rows: (event.rows as number) || 24,\n startedAt: new Date(),\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output': {\n const session = this.sessions.get(id!);\n if (session) {\n session.lastActivityAt = new Date();\n }\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n }\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\n session.lastActivityAt = new Date();\n this.emit('session_ready', session);\n }\n break;\n }\n\n case 'exit': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'stopped';\n session.exitCode = event.code as number;\n session.lastActivityAt = new Date();\n this.emit('session_stopped', session, event.code, event.signal);\n this.sessions.delete(id!);\n }\n break;\n }\n\n case 'error':\n if (id) {\n const session = this.sessions.get(id);\n if (session) {\n session.status = 'error';\n session.error = event.message as string;\n session.lastActivityAt = new Date();\n }\n this.emit('session_error', { id, error: event.message });\n } else {\n this.emit('worker_error', event.message);\n }\n break;\n\n case 'blocking_prompt': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('blocking_prompt', session, event.promptInfo, event.autoResponded);\n }\n break;\n }\n\n case 'login_required': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('login_required', session, event.instructions, event.url);\n }\n break;\n }\n\n case 'message': {\n const msg = event.message as Record<string, unknown>;\n // Convert timestamp back to Date\n this.emit('message', {\n ...msg,\n timestamp: new Date(msg.timestamp as string),\n });\n break;\n }\n\n case 'question': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('question', session, event.question);\n }\n break;\n }\n\n case 'list': {\n // Convert date strings back to Date objects\n const sessions = (event.sessions as Record<string, unknown>[]).map((s) => ({\n ...s,\n startedAt: s.startedAt ? new Date(s.startedAt as string) : undefined,\n lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt as string) : undefined,\n })) as WorkerSessionHandle[];\n this.resolvePending('list', sessions);\n break;\n }\n\n case 'ack': {\n const cmd = event.cmd as string;\n const success = event.success as boolean;\n const pendingKey = id ? `${cmd}:${id}` : cmd;\n const pending = this.pending.get(pendingKey);\n\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(pendingKey);\n\n if (success) {\n pending.resolve(true);\n } else {\n pending.reject(new Error(event.error as string));\n }\n }\n break;\n }\n }\n }\n\n private sendCommand(cmd: Record<string, unknown>): void {\n if (!this.worker?.stdin) {\n throw new Error('Worker not available');\n }\n\n this.worker.stdin.write(JSON.stringify(cmd) + '\\n');\n }\n\n private createPending(key: string, timeoutMs = 30000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Operation ${key} timed out`));\n }, timeoutMs);\n\n this.pending.set(key, { resolve, reject, timeout });\n });\n }\n\n private resolvePending(key: string, value: unknown): void {\n const pending = this.pending.get(key);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(key);\n pending.resolve(value);\n }\n }\n\n /**\n * Wait for the worker to be ready\n */\n async waitForReady(): Promise<void> {\n return this.readyPromise;\n }\n\n /**\n * Check if worker is ready\n */\n isReady(): boolean {\n return this.ready;\n }\n\n /**\n * Spawn a new PTY session\n */\n async spawn(config: SpawnConfig & { id: string }): Promise<WorkerSessionHandle> {\n await this.waitForReady();\n\n const { id } = config;\n\n this.sendCommand({ cmd: 'spawn', id, config });\n\n await this.createPending(`spawn:${id}`);\n\n return this.sessions.get(id)!;\n }\n\n /**\n * Send data to a session\n */\n async send(id: string, data: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'send', id, data });\n\n await this.createPending(`send:${id}`);\n }\n\n /**\n * Send special keys to a session\n */\n async sendKeys(id: string, keys: string | string[]): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'sendKeys', id, keys });\n\n await this.createPending(`sendKeys:${id}`);\n }\n\n /**\n * Paste text to a session\n */\n async paste(id: string, text: string, bracketed = true): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'paste', id, text, bracketed });\n\n await this.createPending(`paste:${id}`);\n }\n\n /**\n * Resize a session\n */\n async resize(id: string, cols: number, rows: number): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'resize', id, cols, rows });\n\n const session = this.sessions.get(id);\n if (session) {\n session.cols = cols;\n session.rows = rows;\n }\n\n await this.createPending(`resize:${id}`);\n }\n\n /**\n * Kill a session\n */\n async kill(id: string, signal?: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'kill', id, signal });\n\n await this.createPending(`kill:${id}`);\n }\n\n /**\n * Get a session by ID\n */\n get(id: string): WorkerSessionHandle | undefined {\n return this.sessions.get(id);\n }\n\n /**\n * List all sessions\n */\n async list(): Promise<WorkerSessionHandle[]> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'list' });\n\n const sessions = (await this.createPending('list')) as WorkerSessionHandle[];\n return sessions;\n }\n\n /**\n * Check if a session exists\n */\n has(id: string): boolean {\n return this.sessions.has(id);\n }\n\n /**\n * Subscribe to output from a specific session\n */\n onSessionData(id: string, callback: (data: string) => void): () => void {\n const handler = (data: string) => callback(data);\n this.on(`data:${id}`, handler);\n return () => this.off(`data:${id}`, handler);\n }\n\n /**\n * Shutdown the worker and all sessions\n */\n async shutdown(): Promise<void> {\n if (!this.worker) return;\n\n this.sendCommand({ cmd: 'shutdown' });\n\n await this.createPending('shutdown', 10000).catch(() => {\n // Force kill if shutdown times out\n this.worker?.kill('SIGKILL');\n });\n }\n\n /**\n * Restart the worker process\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n this.sessions.clear();\n this.ready = false;\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n await this.waitForReady();\n }\n}\n\n/**\n * Detect if running in Bun\n */\nexport function isBun(): boolean {\n // Bun 1.1.24+ sets process.versions.bun (lowercase)\n return typeof process !== 'undefined' && 'bun' in process.versions;\n}\n\n/**\n * Create the appropriate PTY manager based on runtime\n */\nexport function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager {\n return new BunCompatiblePTYManager(options);\n}\n"],"mappings":"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","names":["import_events","consoleLogger","import_child_process","import_events"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1424,6 +1424,35 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
|
|
|
1424
1424
|
this.emit("worker_error", event.message);
|
|
1425
1425
|
}
|
|
1426
1426
|
break;
|
|
1427
|
+
case "blocking_prompt": {
|
|
1428
|
+
const session = this.sessions.get(id);
|
|
1429
|
+
if (session) {
|
|
1430
|
+
this.emit("blocking_prompt", session, event.promptInfo, event.autoResponded);
|
|
1431
|
+
}
|
|
1432
|
+
break;
|
|
1433
|
+
}
|
|
1434
|
+
case "login_required": {
|
|
1435
|
+
const session = this.sessions.get(id);
|
|
1436
|
+
if (session) {
|
|
1437
|
+
this.emit("login_required", session, event.instructions, event.url);
|
|
1438
|
+
}
|
|
1439
|
+
break;
|
|
1440
|
+
}
|
|
1441
|
+
case "message": {
|
|
1442
|
+
const msg = event.message;
|
|
1443
|
+
this.emit("message", {
|
|
1444
|
+
...msg,
|
|
1445
|
+
timestamp: new Date(msg.timestamp)
|
|
1446
|
+
});
|
|
1447
|
+
break;
|
|
1448
|
+
}
|
|
1449
|
+
case "question": {
|
|
1450
|
+
const session = this.sessions.get(id);
|
|
1451
|
+
if (session) {
|
|
1452
|
+
this.emit("question", session, event.question);
|
|
1453
|
+
}
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1427
1456
|
case "list": {
|
|
1428
1457
|
const sessions = event.sessions.map((s) => ({
|
|
1429
1458
|
...s,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pty-manager.ts","../src/adapters/adapter-registry.ts","../src/pty-session.ts","../src/adapters/base-adapter.ts","../src/adapters/adapter-factory.ts","../src/adapters/shell-adapter.ts","../src/bun-compat.ts"],"sourcesContent":["/**\n * PTY Manager\n *\n * Manages multiple PTY sessions for CLI tools.\n */\n\nimport { EventEmitter } from 'events';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport { AdapterRegistry } from './adapters/adapter-registry';\nimport { PTYSession } from './pty-session';\nimport type {\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n SessionStatus,\n BlockingPromptInfo,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n Logger,\n} from './types';\n\nexport interface PTYManagerEvents {\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 blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (session: SessionHandle, question: string) => void;\n}\n\n/**\n * Console-based logger fallback\n */\nconst 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\nexport class PTYManager extends EventEmitter {\n private sessions: Map<string, PTYSession> = new Map();\n private outputLogs: Map<string, string[]> = new Map();\n private maxLogLines: number;\n private logger: Logger;\n public readonly adapters: AdapterRegistry;\n\n constructor(config: PTYManagerConfig = {}) {\n super();\n this.adapters = new AdapterRegistry();\n this.logger = config.logger || consoleLogger;\n this.maxLogLines = config.maxLogLines || 1000;\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 PTY session\n */\n async spawn(config: SpawnConfig): Promise<SessionHandle> {\n // Get adapter for this type\n const adapter = this.adapters.get(config.type);\n if (!adapter) {\n throw new Error(`No adapter found for type: ${config.type}. Registered adapters: ${this.adapters.list().join(', ') || 'none'}`);\n }\n\n // Check if ID already exists\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 session'\n );\n\n // Create session\n const session = new PTYSession(adapter, config, this.logger);\n\n // Set up event forwarding\n this.setupSessionEvents(session);\n\n // Store session\n this.sessions.set(session.id, session);\n this.outputLogs.set(session.id, []);\n\n // Start the session\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: PTYSession): void {\n session.on('output', (data: string) => {\n // Store in log buffer\n const logs = this.outputLogs.get(session.id) || [];\n const lines = data.split('\\n');\n logs.push(...lines);\n\n // Trim to max lines\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('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\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 // Force kill if graceful shutdown times out\n session.kill('SIGKILL');\n resolve();\n }, timeout);\n\n session.once('exit', () => {\n clearTimeout(timer);\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n });\n\n // Send graceful signal\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 // Apply filters\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) {\n return null;\n }\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 sessions');\n\n await this.stopAll({ timeout: 3000 });\n\n this.sessions.clear();\n this.outputLogs.clear();\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) {\n return null;\n }\n\n return {\n /**\n * Subscribe to raw terminal output\n * Returns an unsubscribe function\n */\n onData: (callback: (data: string) => void) => {\n session.on('output', callback);\n return () => session.off('output', callback);\n },\n\n /**\n * Write raw data to terminal (no formatting applied)\n */\n write: (data: string) => {\n session.writeRaw(data);\n },\n\n /**\n * Resize the terminal\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 PTYSession (for advanced use)\n */\n getSession(sessionId: string): PTYSession | undefined {\n return this.sessions.get(sessionId);\n }\n}\n","/**\n * Adapter Registry\n *\n * Registry for managing CLI adapters.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\n\n/**\n * Registry of available CLI adapters\n */\nexport class AdapterRegistry {\n private adapters: Map<string, CLIAdapter> = new Map();\n\n /**\n * Register an adapter\n */\n register(adapter: CLIAdapter): void {\n this.adapters.set(adapter.adapterType, adapter);\n }\n\n /**\n * Get adapter for type\n */\n get(adapterType: string): CLIAdapter | undefined {\n return this.adapters.get(adapterType);\n }\n\n /**\n * Check if adapter exists for type\n */\n has(adapterType: string): boolean {\n return this.adapters.has(adapterType);\n }\n\n /**\n * Unregister an adapter\n */\n unregister(adapterType: string): boolean {\n return this.adapters.delete(adapterType);\n }\n\n /**\n * List all registered adapter types\n */\n list(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Get all adapters\n */\n all(): CLIAdapter[] {\n return Array.from(this.adapters.values());\n }\n\n /**\n * Clear all adapters\n */\n clear(): void {\n this.adapters.clear();\n }\n}\n","/**\n * PTY Session\n *\n * Manages a single pseudo-terminal session for a CLI tool.\n */\n\nimport { EventEmitter } from 'events';\nimport type * as ptyModule from 'node-pty';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport type {\n SpawnConfig,\n SessionStatus,\n SessionHandle,\n SessionMessage,\n BlockingPromptInfo,\n Logger,\n} from './types';\n\n// Lazy-load node-pty to avoid issues in environments where it's not installed\nlet ptyCache: typeof ptyModule | null = null;\nfunction loadPty(): typeof ptyModule {\n if (!ptyCache) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n ptyCache = require('node-pty') as typeof ptyModule;\n } catch {\n throw new Error(\n 'node-pty is required but not installed. Run: npm install node-pty'\n );\n }\n }\n return ptyCache!;\n}\n\nexport interface PTYSessionEvents {\n output: (data: string) => void;\n ready: () => void;\n login_required: (instructions?: string, url?: string) => 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}\n\n/**\n * Console-based logger fallback\n */\nconst 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/**\n * Generate a unique ID\n */\nfunction generateId(): string {\n return `pty-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Special key mappings to escape sequences\n *\n * Modifier codes for arrows/function keys:\n * 2 = Shift, 3 = Alt, 4 = Shift+Alt, 5 = Ctrl, 6 = Ctrl+Shift, 7 = Ctrl+Alt, 8 = Ctrl+Alt+Shift\n */\nexport const SPECIAL_KEYS: Record<string, string> = {\n // Control keys (Ctrl+letter = ASCII control code)\n 'ctrl+a': '\\x01',\n 'ctrl+b': '\\x02',\n 'ctrl+c': '\\x03',\n 'ctrl+d': '\\x04',\n 'ctrl+e': '\\x05',\n 'ctrl+f': '\\x06',\n 'ctrl+g': '\\x07',\n 'ctrl+h': '\\x08',\n 'ctrl+i': '\\x09',\n 'ctrl+j': '\\x0a',\n 'ctrl+k': '\\x0b',\n 'ctrl+l': '\\x0c',\n 'ctrl+m': '\\x0d',\n 'ctrl+n': '\\x0e',\n 'ctrl+o': '\\x0f',\n 'ctrl+p': '\\x10',\n 'ctrl+q': '\\x11',\n 'ctrl+r': '\\x12',\n 'ctrl+s': '\\x13',\n 'ctrl+t': '\\x14',\n 'ctrl+u': '\\x15',\n 'ctrl+v': '\\x16',\n 'ctrl+w': '\\x17',\n 'ctrl+x': '\\x18',\n 'ctrl+y': '\\x19',\n 'ctrl+z': '\\x1a',\n 'ctrl+[': '\\x1b',\n 'ctrl+\\\\': '\\x1c',\n 'ctrl+]': '\\x1d',\n 'ctrl+^': '\\x1e',\n 'ctrl+_': '\\x1f',\n\n // Alt+letter (Meta key = ESC + letter)\n 'alt+a': '\\x1ba', 'alt+b': '\\x1bb', 'alt+c': '\\x1bc', 'alt+d': '\\x1bd',\n 'alt+e': '\\x1be', 'alt+f': '\\x1bf', 'alt+g': '\\x1bg', 'alt+h': '\\x1bh',\n 'alt+i': '\\x1bi', 'alt+j': '\\x1bj', 'alt+k': '\\x1bk', 'alt+l': '\\x1bl',\n 'alt+m': '\\x1bm', 'alt+n': '\\x1bn', 'alt+o': '\\x1bo', 'alt+p': '\\x1bp',\n 'alt+q': '\\x1bq', 'alt+r': '\\x1br', 'alt+s': '\\x1bs', 'alt+t': '\\x1bt',\n 'alt+u': '\\x1bu', 'alt+v': '\\x1bv', 'alt+w': '\\x1bw', 'alt+x': '\\x1bx',\n 'alt+y': '\\x1by', 'alt+z': '\\x1bz',\n 'alt+backspace': '\\x1b\\x7f', // Delete word backward\n\n // Navigation - plain\n 'up': '\\x1b[A',\n 'down': '\\x1b[B',\n 'right': '\\x1b[C',\n 'left': '\\x1b[D',\n 'home': '\\x1b[H',\n 'end': '\\x1b[F',\n 'pageup': '\\x1b[5~',\n 'pagedown': '\\x1b[6~',\n\n // Navigation - with Shift (modifier 2)\n 'shift+up': '\\x1b[1;2A',\n 'shift+down': '\\x1b[1;2B',\n 'shift+right': '\\x1b[1;2C',\n 'shift+left': '\\x1b[1;2D',\n 'shift+home': '\\x1b[1;2H',\n 'shift+end': '\\x1b[1;2F',\n 'shift+pageup': '\\x1b[5;2~',\n 'shift+pagedown': '\\x1b[6;2~',\n\n // Navigation - with Alt (modifier 3)\n 'alt+up': '\\x1b[1;3A',\n 'alt+down': '\\x1b[1;3B',\n 'alt+right': '\\x1b[1;3C', // Forward word\n 'alt+left': '\\x1b[1;3D', // Backward word\n\n // Navigation - with Ctrl (modifier 5)\n 'ctrl+up': '\\x1b[1;5A',\n 'ctrl+down': '\\x1b[1;5B',\n 'ctrl+right': '\\x1b[1;5C', // Forward word\n 'ctrl+left': '\\x1b[1;5D', // Backward word\n 'ctrl+home': '\\x1b[1;5H',\n 'ctrl+end': '\\x1b[1;5F',\n\n // Navigation - with Ctrl+Shift (modifier 6) - select word\n 'ctrl+shift+up': '\\x1b[1;6A',\n 'ctrl+shift+down': '\\x1b[1;6B',\n 'ctrl+shift+right': '\\x1b[1;6C',\n 'ctrl+shift+left': '\\x1b[1;6D',\n 'ctrl+shift+home': '\\x1b[1;6H',\n 'ctrl+shift+end': '\\x1b[1;6F',\n\n // Navigation - with Shift+Alt (modifier 4)\n 'shift+alt+up': '\\x1b[1;4A',\n 'shift+alt+down': '\\x1b[1;4B',\n 'shift+alt+right': '\\x1b[1;4C',\n 'shift+alt+left': '\\x1b[1;4D',\n\n // Editing\n 'enter': '\\r',\n 'return': '\\r',\n 'tab': '\\t',\n 'shift+tab': '\\x1b[Z', // Reverse tab\n 'backspace': '\\x7f',\n 'delete': '\\x1b[3~',\n 'shift+delete': '\\x1b[3;2~',\n 'ctrl+delete': '\\x1b[3;5~', // Delete word forward\n 'insert': '\\x1b[2~',\n 'escape': '\\x1b',\n 'esc': '\\x1b',\n 'space': ' ',\n\n // Function keys - plain\n 'f1': '\\x1bOP',\n 'f2': '\\x1bOQ',\n 'f3': '\\x1bOR',\n 'f4': '\\x1bOS',\n 'f5': '\\x1b[15~',\n 'f6': '\\x1b[17~',\n 'f7': '\\x1b[18~',\n 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~',\n 'f10': '\\x1b[21~',\n 'f11': '\\x1b[23~',\n 'f12': '\\x1b[24~',\n\n // Function keys - with Shift (modifier 2)\n 'shift+f1': '\\x1b[1;2P',\n 'shift+f2': '\\x1b[1;2Q',\n 'shift+f3': '\\x1b[1;2R',\n 'shift+f4': '\\x1b[1;2S',\n 'shift+f5': '\\x1b[15;2~',\n 'shift+f6': '\\x1b[17;2~',\n 'shift+f7': '\\x1b[18;2~',\n 'shift+f8': '\\x1b[19;2~',\n 'shift+f9': '\\x1b[20;2~',\n 'shift+f10': '\\x1b[21;2~',\n 'shift+f11': '\\x1b[23;2~',\n 'shift+f12': '\\x1b[24;2~',\n\n // Function keys - with Ctrl (modifier 5)\n 'ctrl+f1': '\\x1b[1;5P',\n 'ctrl+f2': '\\x1b[1;5Q',\n 'ctrl+f3': '\\x1b[1;5R',\n 'ctrl+f4': '\\x1b[1;5S',\n 'ctrl+f5': '\\x1b[15;5~',\n 'ctrl+f6': '\\x1b[17;5~',\n 'ctrl+f7': '\\x1b[18;5~',\n 'ctrl+f8': '\\x1b[19;5~',\n 'ctrl+f9': '\\x1b[20;5~',\n 'ctrl+f10': '\\x1b[21;5~',\n 'ctrl+f11': '\\x1b[23;5~',\n 'ctrl+f12': '\\x1b[24;5~',\n};\n\n/**\n * Bracketed paste mode escape sequences\n */\nconst BRACKETED_PASTE_START = '\\x1b[200~';\nconst BRACKETED_PASTE_END = '\\x1b[201~';\n\nexport class PTYSession extends EventEmitter {\n private ptyProcess: ptyModule.IPty | null = null;\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\n public readonly id: string;\n public readonly config: SpawnConfig;\n\n constructor(\n private adapter: CLIAdapter,\n config: SpawnConfig,\n logger?: Logger\n ) {\n super();\n this.id = config.id || generateId();\n this.config = { ...config, id: this.id };\n this.logger = logger || consoleLogger;\n }\n\n get status(): SessionStatus {\n return this._status;\n }\n\n get pid(): number | undefined {\n return this.ptyProcess?.pid;\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 * Start the PTY session\n */\n async start(): Promise<void> {\n if (this.ptyProcess) {\n throw new Error('Session already started');\n }\n\n const nodePty = loadPty();\n\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\n const env = {\n ...process.env,\n ...adapterEnv,\n ...this.config.env,\n // Force terminal settings\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n };\n\n this.logger.info(\n { sessionId: this.id, command, args: args.join(' ') },\n 'Starting PTY session'\n );\n\n try {\n this.ptyProcess = nodePty.spawn(command, args, {\n name: 'xterm-256color',\n cols: this.config.cols || 120,\n rows: this.config.rows || 40,\n cwd: this.config.workdir || process.cwd(),\n env: env as Record<string, string>,\n });\n\n this.setupEventHandlers();\n\n this.logger.info(\n { sessionId: this.id, pid: this.ptyProcess.pid },\n 'PTY session started'\n );\n } catch (error) {\n this._status = 'error';\n this.logger.error(\n { sessionId: this.id, error },\n 'Failed to start PTY session'\n );\n throw error;\n }\n }\n\n /**\n * Set up event handlers for the PTY\n */\n private setupEventHandlers(): void {\n if (!this.ptyProcess) return;\n\n this.ptyProcess.onData((data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n // Emit raw output\n this.emit('output', data);\n\n // Check for blocking prompts\n const blockingPrompt = this.detectAndHandleBlockingPrompt();\n if (blockingPrompt) {\n return;\n }\n\n // Fallback: Check for login required (legacy support)\n const loginDetection = this.adapter.detectLogin(this.outputBuffer);\n if (loginDetection.required && this._status !== 'authenticating') {\n this._status = 'authenticating';\n this.emit('login_required', loginDetection.instructions, loginDetection.url);\n this.logger.warn(\n { sessionId: this.id, loginType: loginDetection.type },\n 'Login required'\n );\n return;\n }\n\n // Check for ready state\n if (this._status === 'starting' && this.adapter.detectReady(this.outputBuffer)) {\n this._status = 'ready';\n this.emit('ready');\n this.logger.info({ sessionId: this.id }, 'Session ready');\n }\n\n // Check for exit\n const exitDetection = this.adapter.detectExit(this.outputBuffer);\n if (exitDetection.exited) {\n this._status = 'stopped';\n this.emit('exit', exitDetection.code || 0);\n }\n\n // Try to parse output into structured message\n this.tryParseOutput();\n });\n\n this.ptyProcess.onExit(({ exitCode, signal }) => {\n this._status = 'stopped';\n this.logger.info(\n { sessionId: this.id, exitCode, signal },\n 'PTY session exited'\n );\n this.emit('exit', exitCode);\n });\n }\n\n /**\n * Detect blocking prompts and handle them with auto-responses or user notification\n */\n private detectAndHandleBlockingPrompt(): boolean {\n // First, check adapter's auto-response rules\n const autoHandled = this.tryAutoResponse();\n if (autoHandled) {\n return true;\n }\n\n // Then check the adapter's detectBlockingPrompt method\n if (this.adapter.detectBlockingPrompt) {\n const detection = this.adapter.detectBlockingPrompt(this.outputBuffer);\n\n if (detection.detected) {\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 we can auto-respond and have a suggested response, do it\n if (detection.canAutoRespond && detection.suggestedResponse) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: detection.type,\n response: detection.suggestedResponse,\n },\n 'Auto-responding to blocking prompt'\n );\n\n this.writeRaw(detection.suggestedResponse + '\\r');\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n }\n\n // Otherwise, notify that user intervention is needed\n if (detection.type === 'login') {\n this._status = 'authenticating';\n }\n\n this.logger.warn(\n {\n sessionId: this.id,\n promptType: detection.type,\n prompt: detection.prompt,\n },\n 'Blocking prompt requires user intervention'\n );\n\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Try to match and apply auto-response rules\n */\n private tryAutoResponse(): boolean {\n const rules = this.adapter.autoResponseRules;\n if (!rules || rules.length === 0) {\n return false;\n }\n\n for (const rule of rules) {\n if (rule.pattern.test(this.outputBuffer)) {\n // Check if it's safe to auto-respond (default: true)\n const safe = rule.safe !== false;\n\n if (safe) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: rule.type,\n description: rule.description,\n response: rule.response,\n },\n 'Applying auto-response rule'\n );\n\n this.writeRaw(rule.response + '\\r');\n\n // Clear the matched portion from buffer to prevent re-matching\n this.outputBuffer = this.outputBuffer.replace(rule.pattern, '');\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 // Not safe to auto-respond, emit for user intervention\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\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Try to parse the output buffer into structured messages\n */\n private tryParseOutput(): void {\n const parsed = this.adapter.parseOutput(this.outputBuffer);\n\n if (parsed && parsed.isComplete) {\n // Clear the buffer for the parsed content\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 // Also emit specific event for questions\n if (parsed.isQuestion) {\n this.emit('question', parsed.content);\n }\n }\n }\n\n /**\n * Write data to the PTY (formatted by adapter)\n */\n write(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n const formatted = this.adapter.formatInput(data);\n this.ptyProcess.write(formatted + '\\r');\n\n this.logger.debug({ sessionId: this.id, input: data }, 'Sent input to session');\n }\n\n /**\n * Write raw data directly to the PTY (no formatting)\n */\n writeRaw(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n this.ptyProcess.write(data);\n }\n\n /**\n * Send a task/message to the session\n */\n send(message: string): SessionMessage {\n this._status = 'busy';\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 this.write(message);\n\n return msg;\n }\n\n /**\n * Resize the PTY terminal\n */\n resize(cols: number, rows: number): void {\n this.ptyProcess?.resize(cols, rows);\n }\n\n /**\n * Send special keys to the PTY\n *\n * Supported keys:\n * - Control: ctrl+c, ctrl+d, ctrl+z, ctrl+l, ctrl+a, ctrl+e, ctrl+k, ctrl+u, ctrl+w, ctrl+r\n * - Navigation: up, down, left, right, home, end, pageup, pagedown\n * - Editing: enter, tab, backspace, delete, insert, escape\n * - Function: f1-f12\n *\n * @param keys - Key name(s) to send, e.g. \"ctrl+c\" or [\"up\", \"up\", \"enter\"]\n */\n sendKeys(keys: string | string[]): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n const keyList = Array.isArray(keys) ? keys : [keys];\n\n for (const key of keyList) {\n const normalizedKey = key.toLowerCase().trim();\n const sequence = SPECIAL_KEYS[normalizedKey];\n\n if (sequence) {\n this._lastActivityAt = new Date();\n this.ptyProcess.write(sequence);\n this.logger.debug({ sessionId: this.id, key: normalizedKey }, 'Sent special key');\n } else {\n this.logger.warn(\n { sessionId: this.id, key: normalizedKey },\n 'Unknown special key, sending as literal'\n );\n this.ptyProcess.write(key);\n }\n }\n }\n\n /**\n * Paste text using bracketed paste mode\n *\n * Bracketed paste mode wraps the pasted text in escape sequences\n * that tell the terminal this is pasted content, not typed input.\n * This prevents issues with pasting text that contains special characters\n * or looks like commands.\n *\n * @param text - Text to paste\n * @param useBracketedPaste - Whether to use bracketed paste mode (default: true)\n */\n paste(text: string, useBracketedPaste: boolean = true): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n\n if (useBracketedPaste) {\n this.ptyProcess.write(BRACKETED_PASTE_START + text + BRACKETED_PASTE_END);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text with bracketed paste mode'\n );\n } else {\n this.ptyProcess.write(text);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text without bracketed paste'\n );\n }\n }\n\n /**\n * Kill the PTY process\n */\n kill(signal?: string): void {\n if (this.ptyProcess) {\n this._status = 'stopping';\n this.ptyProcess.kill(signal);\n this.logger.info({ sessionId: this.id, signal }, 'Killing PTY session');\n }\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 };\n }\n}\n","/**\n * Base CLI Adapter\n *\n * Abstract base class with common functionality for CLI adapters.\n */\n\nimport { spawn } from 'child_process';\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../types';\n\n/**\n * Abstract base class for CLI adapters with common functionality\n */\nexport abstract class BaseCLIAdapter implements CLIAdapter {\n abstract readonly adapterType: string;\n abstract readonly displayName: string;\n\n /**\n * Auto-response rules for handling known blocking prompts.\n * Subclasses should override this to add CLI-specific rules.\n */\n readonly autoResponseRules: AutoResponseRule[] = [];\n\n abstract getCommand(): string;\n abstract getArgs(config: SpawnConfig): string[];\n abstract getEnv(config: SpawnConfig): Record<string, string>;\n abstract detectLogin(output: string): LoginDetection;\n abstract detectReady(output: string): boolean;\n abstract parseOutput(output: string): ParsedOutput | null;\n abstract getPromptPattern(): RegExp;\n\n /**\n * Default exit detection - look for common exit patterns\n */\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n // Check for common exit/error patterns\n if (output.includes('Process exited with code')) {\n const match = output.match(/Process exited with code (\\d+)/);\n return {\n exited: true,\n code: match ? parseInt(match[1], 10) : 1,\n };\n }\n\n if (output.includes('Command not found') || output.includes('command not found')) {\n return {\n exited: true,\n code: 127,\n error: 'Command not found',\n };\n }\n\n return { exited: false };\n }\n\n /**\n * Default blocking prompt detection - looks for common prompt patterns.\n * Subclasses should override for CLI-specific detection.\n */\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n const stripped = this.stripAnsi(output);\n\n // Check for login/auth first (highest priority)\n const loginDetection = this.detectLogin(output);\n if (loginDetection.required) {\n return {\n detected: true,\n type: 'login',\n prompt: loginDetection.instructions,\n url: loginDetection.url,\n canAutoRespond: false,\n instructions: loginDetection.instructions,\n };\n }\n\n // Check for common update prompts\n if (/update (available|now|ready)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'update',\n prompt: 'Update available',\n options: ['y', 'n'],\n suggestedResponse: 'n',\n canAutoRespond: true,\n instructions: 'CLI update available - auto-declining to continue',\n };\n }\n\n // Check for terms of service / license acceptance\n if (/accept.*(terms|license|agreement)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'tos',\n prompt: 'Terms/license acceptance required',\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Please accept the terms of service manually',\n };\n }\n\n // Check for model/version selection\n if (/choose.*model|select.*model|which model/i.test(stripped)) {\n return {\n detected: true,\n type: 'model_select',\n prompt: 'Model selection required',\n canAutoRespond: false,\n instructions: 'Please select a model',\n };\n }\n\n // Check for project/workspace selection\n if (/choose.*(project|workspace)|select.*(project|workspace)/i.test(stripped)) {\n return {\n detected: true,\n type: 'project_select',\n prompt: 'Project/workspace selection required',\n canAutoRespond: false,\n instructions: 'Please select a project or workspace',\n };\n }\n\n // Check for generic y/n prompts that look like they're blocking\n if (/\\[y\\/n\\]|\\(y\\/n\\)|\\[Y\\/n\\]|\\[y\\/N\\]/i.test(stripped) && stripped.includes('?')) {\n return {\n detected: true,\n type: 'unknown',\n prompt: stripped.slice(-200), // Last 200 chars for context\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Unknown confirmation prompt detected',\n };\n }\n\n return { detected: false };\n }\n\n /**\n * Default input formatting - just return as-is\n */\n formatInput(message: string): string {\n return message;\n }\n\n /**\n * Validate CLI installation by running --version or --help\n */\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n return new Promise((resolve) => {\n const command = this.getCommand();\n\n try {\n const proc = spawn(command, ['--version'], {\n shell: true,\n timeout: 5000,\n });\n\n let output = '';\n\n proc.stdout?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.stderr?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n // Try to extract version from output\n const versionMatch = output.match(/(\\d+\\.\\d+\\.\\d+)/);\n resolve({\n installed: true,\n version: versionMatch ? versionMatch[1] : undefined,\n });\n } else {\n resolve({\n installed: false,\n error: `Command exited with code ${code}`,\n });\n }\n });\n\n proc.on('error', (err) => {\n resolve({\n installed: false,\n error: err.message,\n });\n });\n } catch (err) {\n resolve({\n installed: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n });\n }\n\n /**\n * Helper to check if output contains a question\n */\n protected containsQuestion(output: string): boolean {\n const questionPatterns = [\n /\\?$/m, // Ends with ?\n /would you like/i,\n /do you want/i,\n /should I/i,\n /shall I/i,\n /please (choose|select|confirm)/i,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /\\[Y\\/n\\]/i,\n ];\n\n return questionPatterns.some((pattern) => pattern.test(output));\n }\n\n /**\n * Helper to strip ANSI escape codes from output\n */\n protected stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n }\n}\n","/**\n * Adapter Factory\n *\n * Factory function for creating CLI adapters from configuration.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport { BaseCLIAdapter } from './base-adapter';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n AdapterFactoryConfig,\n} from '../types';\n\n/**\n * Creates a CLI adapter from configuration\n */\nexport function createAdapter(config: AdapterFactoryConfig): CLIAdapter {\n return new ConfiguredAdapter(config);\n}\n\n/**\n * Adapter implementation created from configuration\n */\nclass ConfiguredAdapter extends BaseCLIAdapter {\n readonly adapterType: string;\n readonly displayName: string;\n readonly autoResponseRules: AutoResponseRule[];\n\n constructor(private config: AdapterFactoryConfig) {\n super();\n this.adapterType = config.command.replace(/[^a-zA-Z0-9]/g, '-');\n this.displayName = config.command;\n this.autoResponseRules = this.buildAutoResponseRules();\n }\n\n private buildAutoResponseRules(): AutoResponseRule[] {\n if (!this.config.blockingPrompts) {\n return [];\n }\n\n return this.config.blockingPrompts\n .filter((p) => p.autoResponse !== undefined)\n .map((p) => ({\n pattern: p.pattern,\n type: p.type,\n response: p.autoResponse!,\n description: p.description || `Auto-respond to ${p.type} prompt`,\n safe: p.safe !== false,\n }));\n }\n\n getCommand(): string {\n return this.config.command;\n }\n\n getArgs(config: SpawnConfig): string[] {\n if (typeof this.config.args === 'function') {\n return this.config.args(config);\n }\n return this.config.args || [];\n }\n\n getEnv(config: SpawnConfig): Record<string, string> {\n if (typeof this.config.env === 'function') {\n return this.config.env(config);\n }\n return this.config.env || {};\n }\n\n detectLogin(output: string): LoginDetection {\n if (!this.config.loginDetection) {\n return { required: false };\n }\n\n const { patterns, extractUrl, extractInstructions } = this.config.loginDetection;\n const stripped = this.stripAnsi(output);\n\n for (const pattern of patterns) {\n if (pattern.test(stripped)) {\n return {\n required: true,\n type: 'browser',\n url: extractUrl?.(stripped) || undefined,\n instructions: extractInstructions?.(stripped) || 'Authentication required',\n };\n }\n }\n\n return { required: false };\n }\n\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n // First check config-defined blocking prompts\n if (this.config.blockingPrompts) {\n const stripped = this.stripAnsi(output);\n\n for (const prompt of this.config.blockingPrompts) {\n if (prompt.pattern.test(stripped)) {\n return {\n detected: true,\n type: prompt.type,\n prompt: stripped.slice(-200),\n suggestedResponse: prompt.autoResponse,\n canAutoRespond: prompt.autoResponse !== undefined && prompt.safe !== false,\n instructions: prompt.description,\n };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectBlockingPrompt(output);\n }\n\n detectReady(output: string): boolean {\n if (!this.config.readyIndicators || this.config.readyIndicators.length === 0) {\n // Default: ready after any output\n return output.length > 10;\n }\n\n const stripped = this.stripAnsi(output);\n return this.config.readyIndicators.some((pattern) => pattern.test(stripped));\n }\n\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n if (this.config.exitIndicators) {\n for (const indicator of this.config.exitIndicators) {\n const match = output.match(indicator.pattern);\n if (match) {\n const code = indicator.codeExtractor?.(match) ?? 1;\n return { exited: true, code };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectExit(output);\n }\n\n parseOutput(output: string): ParsedOutput | null {\n if (this.config.parseOutput) {\n return this.config.parseOutput(output);\n }\n\n // Default parsing\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: this.containsQuestion(cleaned),\n };\n }\n\n formatInput(message: string): string {\n if (this.config.formatInput) {\n return this.config.formatInput(message);\n }\n return message;\n }\n\n getPromptPattern(): RegExp {\n return this.config.promptPattern || /[\\$#>]\\s*$/m;\n }\n}\n","/**\n * Shell Adapter\n *\n * Built-in adapter for bash/zsh shell sessions.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../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 return [];\n }\n\n getEnv(_config: SpawnConfig): Record<string, string> {\n return {\n PS1: this.promptStr,\n };\n }\n\n detectLogin(_output: string): LoginDetection {\n // Shell doesn't need login\n return { required: false };\n }\n\n detectBlockingPrompt(_output: string): BlockingPromptDetection {\n // Shell typically doesn't have blocking prompts\n return { detected: false };\n }\n\n detectReady(output: string): boolean {\n // Ready when we see the prompt or any meaningful output\n return output.includes(this.promptStr) || output.includes('$') || output.length > 10;\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 // Match our custom prompt or standard shell prompts\n const escaped = this.promptStr.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:${escaped}|\\\\$|#|>)\\\\s*$`, 'm');\n }\n\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n // Shell is always installed\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","/**\n * Bun-Compatible PTY Manager\n *\n * A wrapper that spawns a Node.js worker process to handle PTY operations,\n * allowing pty-manager to work from Bun or other non-Node runtimes.\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport type { SpawnConfig } from './types';\n\nexport interface WorkerSessionHandle {\n id: string;\n name: string;\n type: string;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n pid: number | undefined;\n cols: number;\n rows: number;\n startedAt?: Date;\n lastActivityAt?: Date;\n error?: string;\n exitCode?: number;\n}\n\nexport interface BunPTYManagerOptions {\n /** Path to node executable (default: 'node') */\n nodePath?: string;\n /** Path to worker script (default: auto-detected) */\n workerPath?: string;\n /** Environment variables for worker process */\n env?: Record<string, string>;\n}\n\ninterface PendingOperation {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n}\n\n/**\n * PTY Manager that works with Bun and other non-Node runtimes\n * by spawning a Node.js worker process.\n */\nexport class BunCompatiblePTYManager extends EventEmitter {\n private worker: ChildProcess | null = null;\n private sessions: Map<string, WorkerSessionHandle> = new Map();\n private pending: Map<string, PendingOperation> = new Map();\n private ready = false;\n private readyPromise: Promise<void>;\n private readyResolve!: () => void;\n private nodePath: string;\n private workerPath: string;\n private env: Record<string, string>;\n\n constructor(options: BunPTYManagerOptions = {}) {\n super();\n\n this.nodePath = options.nodePath || 'node';\n this.workerPath = options.workerPath || this.findWorkerPath();\n this.env = options.env || {};\n\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n }\n\n private findWorkerPath(): string {\n // Try to find the worker script relative to this module\n const possiblePaths = [\n path.join(__dirname, 'pty-worker.js'),\n path.join(__dirname, '..', 'dist', 'pty-worker.js'),\n path.join(__dirname, '..', 'src', 'pty-worker.js'),\n ];\n\n // Return first path (we'll rely on Node to throw if it doesn't exist)\n return possiblePaths[0];\n }\n\n private startWorker(): void {\n this.worker = spawn(this.nodePath, [this.workerPath], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...this.env },\n });\n\n if (!this.worker.stdout || !this.worker.stdin) {\n throw new Error('Failed to create worker process pipes');\n }\n\n const rl = readline.createInterface({\n input: this.worker.stdout,\n terminal: false,\n });\n\n rl.on('line', (line) => this.handleWorkerMessage(line));\n\n this.worker.stderr?.on('data', (data) => {\n this.emit('worker_error', data.toString());\n });\n\n this.worker.on('exit', (code, signal) => {\n this.ready = false;\n this.worker = null;\n this.emit('worker_exit', { code, signal });\n\n // Reject all pending operations\n for (const [key, op] of this.pending) {\n clearTimeout(op.timeout);\n op.reject(new Error('Worker process exited'));\n this.pending.delete(key);\n }\n\n // Mark all sessions as stopped\n for (const session of this.sessions.values()) {\n session.status = 'stopped';\n }\n });\n\n this.worker.on('error', (err) => {\n this.emit('worker_error', err);\n });\n }\n\n private handleWorkerMessage(line: string): void {\n let event: Record<string, unknown>;\n\n try {\n event = JSON.parse(line);\n } catch {\n this.emit('worker_error', `Invalid JSON from worker: ${line}`);\n return;\n }\n\n const eventType = event.event as string;\n const id = event.id as string | undefined;\n\n switch (eventType) {\n case 'worker_ready':\n this.ready = true;\n this.readyResolve();\n this.emit('ready');\n break;\n\n case 'spawned': {\n // Get config from event (worker sends it back)\n const session: WorkerSessionHandle = {\n id: id!,\n name: (event.name as string) || id!,\n type: (event.type as string) || 'shell',\n status: 'starting',\n pid: event.pid as number,\n cols: (event.cols as number) || 80,\n rows: (event.rows as number) || 24,\n startedAt: new Date(),\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output': {\n const session = this.sessions.get(id!);\n if (session) {\n session.lastActivityAt = new Date();\n }\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n }\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\n session.lastActivityAt = new Date();\n this.emit('session_ready', session);\n }\n break;\n }\n\n case 'exit': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'stopped';\n session.exitCode = event.code as number;\n session.lastActivityAt = new Date();\n this.emit('session_stopped', session, event.code, event.signal);\n this.sessions.delete(id!);\n }\n break;\n }\n\n case 'error':\n if (id) {\n const session = this.sessions.get(id);\n if (session) {\n session.status = 'error';\n session.error = event.message as string;\n session.lastActivityAt = new Date();\n }\n this.emit('session_error', { id, error: event.message });\n } else {\n this.emit('worker_error', event.message);\n }\n break;\n\n case 'list': {\n // Convert date strings back to Date objects\n const sessions = (event.sessions as Record<string, unknown>[]).map((s) => ({\n ...s,\n startedAt: s.startedAt ? new Date(s.startedAt as string) : undefined,\n lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt as string) : undefined,\n })) as WorkerSessionHandle[];\n this.resolvePending('list', sessions);\n break;\n }\n\n case 'ack': {\n const cmd = event.cmd as string;\n const success = event.success as boolean;\n const pendingKey = id ? `${cmd}:${id}` : cmd;\n const pending = this.pending.get(pendingKey);\n\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(pendingKey);\n\n if (success) {\n pending.resolve(true);\n } else {\n pending.reject(new Error(event.error as string));\n }\n }\n break;\n }\n }\n }\n\n private sendCommand(cmd: Record<string, unknown>): void {\n if (!this.worker?.stdin) {\n throw new Error('Worker not available');\n }\n\n this.worker.stdin.write(JSON.stringify(cmd) + '\\n');\n }\n\n private createPending(key: string, timeoutMs = 30000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Operation ${key} timed out`));\n }, timeoutMs);\n\n this.pending.set(key, { resolve, reject, timeout });\n });\n }\n\n private resolvePending(key: string, value: unknown): void {\n const pending = this.pending.get(key);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(key);\n pending.resolve(value);\n }\n }\n\n /**\n * Wait for the worker to be ready\n */\n async waitForReady(): Promise<void> {\n return this.readyPromise;\n }\n\n /**\n * Check if worker is ready\n */\n isReady(): boolean {\n return this.ready;\n }\n\n /**\n * Spawn a new PTY session\n */\n async spawn(config: SpawnConfig & { id: string }): Promise<WorkerSessionHandle> {\n await this.waitForReady();\n\n const { id } = config;\n\n this.sendCommand({ cmd: 'spawn', id, config });\n\n await this.createPending(`spawn:${id}`);\n\n return this.sessions.get(id)!;\n }\n\n /**\n * Send data to a session\n */\n async send(id: string, data: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'send', id, data });\n\n await this.createPending(`send:${id}`);\n }\n\n /**\n * Send special keys to a session\n */\n async sendKeys(id: string, keys: string | string[]): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'sendKeys', id, keys });\n\n await this.createPending(`sendKeys:${id}`);\n }\n\n /**\n * Paste text to a session\n */\n async paste(id: string, text: string, bracketed = true): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'paste', id, text, bracketed });\n\n await this.createPending(`paste:${id}`);\n }\n\n /**\n * Resize a session\n */\n async resize(id: string, cols: number, rows: number): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'resize', id, cols, rows });\n\n const session = this.sessions.get(id);\n if (session) {\n session.cols = cols;\n session.rows = rows;\n }\n\n await this.createPending(`resize:${id}`);\n }\n\n /**\n * Kill a session\n */\n async kill(id: string, signal?: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'kill', id, signal });\n\n await this.createPending(`kill:${id}`);\n }\n\n /**\n * Get a session by ID\n */\n get(id: string): WorkerSessionHandle | undefined {\n return this.sessions.get(id);\n }\n\n /**\n * List all sessions\n */\n async list(): Promise<WorkerSessionHandle[]> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'list' });\n\n const sessions = (await this.createPending('list')) as WorkerSessionHandle[];\n return sessions;\n }\n\n /**\n * Check if a session exists\n */\n has(id: string): boolean {\n return this.sessions.has(id);\n }\n\n /**\n * Subscribe to output from a specific session\n */\n onSessionData(id: string, callback: (data: string) => void): () => void {\n const handler = (data: string) => callback(data);\n this.on(`data:${id}`, handler);\n return () => this.off(`data:${id}`, handler);\n }\n\n /**\n * Shutdown the worker and all sessions\n */\n async shutdown(): Promise<void> {\n if (!this.worker) return;\n\n this.sendCommand({ cmd: 'shutdown' });\n\n await this.createPending('shutdown', 10000).catch(() => {\n // Force kill if shutdown times out\n this.worker?.kill('SIGKILL');\n });\n }\n\n /**\n * Restart the worker process\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n this.sessions.clear();\n this.ready = false;\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n await this.waitForReady();\n }\n}\n\n/**\n * Detect if running in Bun\n */\nexport function isBun(): boolean {\n // Bun 1.1.24+ sets process.versions.bun (lowercase)\n return typeof process !== 'undefined' && 'bun' in process.versions;\n}\n\n/**\n * Create the appropriate PTY manager based on runtime\n */\nexport function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager {\n return new BunCompatiblePTYManager(options);\n}\n"],"mappings":"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","names":["EventEmitter","consoleLogger","EventEmitter","spawn","EventEmitter"]}
|
|
1
|
+
{"version":3,"sources":["../src/pty-manager.ts","../src/adapters/adapter-registry.ts","../src/pty-session.ts","../src/adapters/base-adapter.ts","../src/adapters/adapter-factory.ts","../src/adapters/shell-adapter.ts","../src/bun-compat.ts"],"sourcesContent":["/**\n * PTY Manager\n *\n * Manages multiple PTY sessions for CLI tools.\n */\n\nimport { EventEmitter } from 'events';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport { AdapterRegistry } from './adapters/adapter-registry';\nimport { PTYSession } from './pty-session';\nimport type {\n SpawnConfig,\n SessionHandle,\n SessionMessage,\n SessionFilter,\n SessionStatus,\n BlockingPromptInfo,\n StopOptions,\n LogOptions,\n TerminalAttachment,\n PTYManagerConfig,\n Logger,\n} from './types';\n\nexport interface PTYManagerEvents {\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 blocking_prompt: (session: SessionHandle, promptInfo: BlockingPromptInfo, autoResponded: boolean) => void;\n message: (message: SessionMessage) => void;\n question: (session: SessionHandle, question: string) => void;\n}\n\n/**\n * Console-based logger fallback\n */\nconst 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\nexport class PTYManager extends EventEmitter {\n private sessions: Map<string, PTYSession> = new Map();\n private outputLogs: Map<string, string[]> = new Map();\n private maxLogLines: number;\n private logger: Logger;\n public readonly adapters: AdapterRegistry;\n\n constructor(config: PTYManagerConfig = {}) {\n super();\n this.adapters = new AdapterRegistry();\n this.logger = config.logger || consoleLogger;\n this.maxLogLines = config.maxLogLines || 1000;\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 PTY session\n */\n async spawn(config: SpawnConfig): Promise<SessionHandle> {\n // Get adapter for this type\n const adapter = this.adapters.get(config.type);\n if (!adapter) {\n throw new Error(`No adapter found for type: ${config.type}. Registered adapters: ${this.adapters.list().join(', ') || 'none'}`);\n }\n\n // Check if ID already exists\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 session'\n );\n\n // Create session\n const session = new PTYSession(adapter, config, this.logger);\n\n // Set up event forwarding\n this.setupSessionEvents(session);\n\n // Store session\n this.sessions.set(session.id, session);\n this.outputLogs.set(session.id, []);\n\n // Start the session\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: PTYSession): void {\n session.on('output', (data: string) => {\n // Store in log buffer\n const logs = this.outputLogs.get(session.id) || [];\n const lines = data.split('\\n');\n logs.push(...lines);\n\n // Trim to max lines\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('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\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 // Force kill if graceful shutdown times out\n session.kill('SIGKILL');\n resolve();\n }, timeout);\n\n session.once('exit', () => {\n clearTimeout(timer);\n this.sessions.delete(sessionId);\n this.outputLogs.delete(sessionId);\n resolve();\n });\n\n // Send graceful signal\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 // Apply filters\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) {\n return null;\n }\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 sessions');\n\n await this.stopAll({ timeout: 3000 });\n\n this.sessions.clear();\n this.outputLogs.clear();\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) {\n return null;\n }\n\n return {\n /**\n * Subscribe to raw terminal output\n * Returns an unsubscribe function\n */\n onData: (callback: (data: string) => void) => {\n session.on('output', callback);\n return () => session.off('output', callback);\n },\n\n /**\n * Write raw data to terminal (no formatting applied)\n */\n write: (data: string) => {\n session.writeRaw(data);\n },\n\n /**\n * Resize the terminal\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 PTYSession (for advanced use)\n */\n getSession(sessionId: string): PTYSession | undefined {\n return this.sessions.get(sessionId);\n }\n}\n","/**\n * Adapter Registry\n *\n * Registry for managing CLI adapters.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\n\n/**\n * Registry of available CLI adapters\n */\nexport class AdapterRegistry {\n private adapters: Map<string, CLIAdapter> = new Map();\n\n /**\n * Register an adapter\n */\n register(adapter: CLIAdapter): void {\n this.adapters.set(adapter.adapterType, adapter);\n }\n\n /**\n * Get adapter for type\n */\n get(adapterType: string): CLIAdapter | undefined {\n return this.adapters.get(adapterType);\n }\n\n /**\n * Check if adapter exists for type\n */\n has(adapterType: string): boolean {\n return this.adapters.has(adapterType);\n }\n\n /**\n * Unregister an adapter\n */\n unregister(adapterType: string): boolean {\n return this.adapters.delete(adapterType);\n }\n\n /**\n * List all registered adapter types\n */\n list(): string[] {\n return Array.from(this.adapters.keys());\n }\n\n /**\n * Get all adapters\n */\n all(): CLIAdapter[] {\n return Array.from(this.adapters.values());\n }\n\n /**\n * Clear all adapters\n */\n clear(): void {\n this.adapters.clear();\n }\n}\n","/**\n * PTY Session\n *\n * Manages a single pseudo-terminal session for a CLI tool.\n */\n\nimport { EventEmitter } from 'events';\nimport type * as ptyModule from 'node-pty';\nimport type { CLIAdapter } from './adapters/adapter-interface';\nimport type {\n SpawnConfig,\n SessionStatus,\n SessionHandle,\n SessionMessage,\n BlockingPromptInfo,\n Logger,\n} from './types';\n\n// Lazy-load node-pty to avoid issues in environments where it's not installed\nlet ptyCache: typeof ptyModule | null = null;\nfunction loadPty(): typeof ptyModule {\n if (!ptyCache) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n ptyCache = require('node-pty') as typeof ptyModule;\n } catch {\n throw new Error(\n 'node-pty is required but not installed. Run: npm install node-pty'\n );\n }\n }\n return ptyCache!;\n}\n\nexport interface PTYSessionEvents {\n output: (data: string) => void;\n ready: () => void;\n login_required: (instructions?: string, url?: string) => 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}\n\n/**\n * Console-based logger fallback\n */\nconst 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/**\n * Generate a unique ID\n */\nfunction generateId(): string {\n return `pty-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * Special key mappings to escape sequences\n *\n * Modifier codes for arrows/function keys:\n * 2 = Shift, 3 = Alt, 4 = Shift+Alt, 5 = Ctrl, 6 = Ctrl+Shift, 7 = Ctrl+Alt, 8 = Ctrl+Alt+Shift\n */\nexport const SPECIAL_KEYS: Record<string, string> = {\n // Control keys (Ctrl+letter = ASCII control code)\n 'ctrl+a': '\\x01',\n 'ctrl+b': '\\x02',\n 'ctrl+c': '\\x03',\n 'ctrl+d': '\\x04',\n 'ctrl+e': '\\x05',\n 'ctrl+f': '\\x06',\n 'ctrl+g': '\\x07',\n 'ctrl+h': '\\x08',\n 'ctrl+i': '\\x09',\n 'ctrl+j': '\\x0a',\n 'ctrl+k': '\\x0b',\n 'ctrl+l': '\\x0c',\n 'ctrl+m': '\\x0d',\n 'ctrl+n': '\\x0e',\n 'ctrl+o': '\\x0f',\n 'ctrl+p': '\\x10',\n 'ctrl+q': '\\x11',\n 'ctrl+r': '\\x12',\n 'ctrl+s': '\\x13',\n 'ctrl+t': '\\x14',\n 'ctrl+u': '\\x15',\n 'ctrl+v': '\\x16',\n 'ctrl+w': '\\x17',\n 'ctrl+x': '\\x18',\n 'ctrl+y': '\\x19',\n 'ctrl+z': '\\x1a',\n 'ctrl+[': '\\x1b',\n 'ctrl+\\\\': '\\x1c',\n 'ctrl+]': '\\x1d',\n 'ctrl+^': '\\x1e',\n 'ctrl+_': '\\x1f',\n\n // Alt+letter (Meta key = ESC + letter)\n 'alt+a': '\\x1ba', 'alt+b': '\\x1bb', 'alt+c': '\\x1bc', 'alt+d': '\\x1bd',\n 'alt+e': '\\x1be', 'alt+f': '\\x1bf', 'alt+g': '\\x1bg', 'alt+h': '\\x1bh',\n 'alt+i': '\\x1bi', 'alt+j': '\\x1bj', 'alt+k': '\\x1bk', 'alt+l': '\\x1bl',\n 'alt+m': '\\x1bm', 'alt+n': '\\x1bn', 'alt+o': '\\x1bo', 'alt+p': '\\x1bp',\n 'alt+q': '\\x1bq', 'alt+r': '\\x1br', 'alt+s': '\\x1bs', 'alt+t': '\\x1bt',\n 'alt+u': '\\x1bu', 'alt+v': '\\x1bv', 'alt+w': '\\x1bw', 'alt+x': '\\x1bx',\n 'alt+y': '\\x1by', 'alt+z': '\\x1bz',\n 'alt+backspace': '\\x1b\\x7f', // Delete word backward\n\n // Navigation - plain\n 'up': '\\x1b[A',\n 'down': '\\x1b[B',\n 'right': '\\x1b[C',\n 'left': '\\x1b[D',\n 'home': '\\x1b[H',\n 'end': '\\x1b[F',\n 'pageup': '\\x1b[5~',\n 'pagedown': '\\x1b[6~',\n\n // Navigation - with Shift (modifier 2)\n 'shift+up': '\\x1b[1;2A',\n 'shift+down': '\\x1b[1;2B',\n 'shift+right': '\\x1b[1;2C',\n 'shift+left': '\\x1b[1;2D',\n 'shift+home': '\\x1b[1;2H',\n 'shift+end': '\\x1b[1;2F',\n 'shift+pageup': '\\x1b[5;2~',\n 'shift+pagedown': '\\x1b[6;2~',\n\n // Navigation - with Alt (modifier 3)\n 'alt+up': '\\x1b[1;3A',\n 'alt+down': '\\x1b[1;3B',\n 'alt+right': '\\x1b[1;3C', // Forward word\n 'alt+left': '\\x1b[1;3D', // Backward word\n\n // Navigation - with Ctrl (modifier 5)\n 'ctrl+up': '\\x1b[1;5A',\n 'ctrl+down': '\\x1b[1;5B',\n 'ctrl+right': '\\x1b[1;5C', // Forward word\n 'ctrl+left': '\\x1b[1;5D', // Backward word\n 'ctrl+home': '\\x1b[1;5H',\n 'ctrl+end': '\\x1b[1;5F',\n\n // Navigation - with Ctrl+Shift (modifier 6) - select word\n 'ctrl+shift+up': '\\x1b[1;6A',\n 'ctrl+shift+down': '\\x1b[1;6B',\n 'ctrl+shift+right': '\\x1b[1;6C',\n 'ctrl+shift+left': '\\x1b[1;6D',\n 'ctrl+shift+home': '\\x1b[1;6H',\n 'ctrl+shift+end': '\\x1b[1;6F',\n\n // Navigation - with Shift+Alt (modifier 4)\n 'shift+alt+up': '\\x1b[1;4A',\n 'shift+alt+down': '\\x1b[1;4B',\n 'shift+alt+right': '\\x1b[1;4C',\n 'shift+alt+left': '\\x1b[1;4D',\n\n // Editing\n 'enter': '\\r',\n 'return': '\\r',\n 'tab': '\\t',\n 'shift+tab': '\\x1b[Z', // Reverse tab\n 'backspace': '\\x7f',\n 'delete': '\\x1b[3~',\n 'shift+delete': '\\x1b[3;2~',\n 'ctrl+delete': '\\x1b[3;5~', // Delete word forward\n 'insert': '\\x1b[2~',\n 'escape': '\\x1b',\n 'esc': '\\x1b',\n 'space': ' ',\n\n // Function keys - plain\n 'f1': '\\x1bOP',\n 'f2': '\\x1bOQ',\n 'f3': '\\x1bOR',\n 'f4': '\\x1bOS',\n 'f5': '\\x1b[15~',\n 'f6': '\\x1b[17~',\n 'f7': '\\x1b[18~',\n 'f8': '\\x1b[19~',\n 'f9': '\\x1b[20~',\n 'f10': '\\x1b[21~',\n 'f11': '\\x1b[23~',\n 'f12': '\\x1b[24~',\n\n // Function keys - with Shift (modifier 2)\n 'shift+f1': '\\x1b[1;2P',\n 'shift+f2': '\\x1b[1;2Q',\n 'shift+f3': '\\x1b[1;2R',\n 'shift+f4': '\\x1b[1;2S',\n 'shift+f5': '\\x1b[15;2~',\n 'shift+f6': '\\x1b[17;2~',\n 'shift+f7': '\\x1b[18;2~',\n 'shift+f8': '\\x1b[19;2~',\n 'shift+f9': '\\x1b[20;2~',\n 'shift+f10': '\\x1b[21;2~',\n 'shift+f11': '\\x1b[23;2~',\n 'shift+f12': '\\x1b[24;2~',\n\n // Function keys - with Ctrl (modifier 5)\n 'ctrl+f1': '\\x1b[1;5P',\n 'ctrl+f2': '\\x1b[1;5Q',\n 'ctrl+f3': '\\x1b[1;5R',\n 'ctrl+f4': '\\x1b[1;5S',\n 'ctrl+f5': '\\x1b[15;5~',\n 'ctrl+f6': '\\x1b[17;5~',\n 'ctrl+f7': '\\x1b[18;5~',\n 'ctrl+f8': '\\x1b[19;5~',\n 'ctrl+f9': '\\x1b[20;5~',\n 'ctrl+f10': '\\x1b[21;5~',\n 'ctrl+f11': '\\x1b[23;5~',\n 'ctrl+f12': '\\x1b[24;5~',\n};\n\n/**\n * Bracketed paste mode escape sequences\n */\nconst BRACKETED_PASTE_START = '\\x1b[200~';\nconst BRACKETED_PASTE_END = '\\x1b[201~';\n\nexport class PTYSession extends EventEmitter {\n private ptyProcess: ptyModule.IPty | null = null;\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\n public readonly id: string;\n public readonly config: SpawnConfig;\n\n constructor(\n private adapter: CLIAdapter,\n config: SpawnConfig,\n logger?: Logger\n ) {\n super();\n this.id = config.id || generateId();\n this.config = { ...config, id: this.id };\n this.logger = logger || consoleLogger;\n }\n\n get status(): SessionStatus {\n return this._status;\n }\n\n get pid(): number | undefined {\n return this.ptyProcess?.pid;\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 * Start the PTY session\n */\n async start(): Promise<void> {\n if (this.ptyProcess) {\n throw new Error('Session already started');\n }\n\n const nodePty = loadPty();\n\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\n const env = {\n ...process.env,\n ...adapterEnv,\n ...this.config.env,\n // Force terminal settings\n TERM: 'xterm-256color',\n COLORTERM: 'truecolor',\n };\n\n this.logger.info(\n { sessionId: this.id, command, args: args.join(' ') },\n 'Starting PTY session'\n );\n\n try {\n this.ptyProcess = nodePty.spawn(command, args, {\n name: 'xterm-256color',\n cols: this.config.cols || 120,\n rows: this.config.rows || 40,\n cwd: this.config.workdir || process.cwd(),\n env: env as Record<string, string>,\n });\n\n this.setupEventHandlers();\n\n this.logger.info(\n { sessionId: this.id, pid: this.ptyProcess.pid },\n 'PTY session started'\n );\n } catch (error) {\n this._status = 'error';\n this.logger.error(\n { sessionId: this.id, error },\n 'Failed to start PTY session'\n );\n throw error;\n }\n }\n\n /**\n * Set up event handlers for the PTY\n */\n private setupEventHandlers(): void {\n if (!this.ptyProcess) return;\n\n this.ptyProcess.onData((data) => {\n this._lastActivityAt = new Date();\n this.outputBuffer += data;\n\n // Emit raw output\n this.emit('output', data);\n\n // Check for blocking prompts\n const blockingPrompt = this.detectAndHandleBlockingPrompt();\n if (blockingPrompt) {\n return;\n }\n\n // Fallback: Check for login required (legacy support)\n const loginDetection = this.adapter.detectLogin(this.outputBuffer);\n if (loginDetection.required && this._status !== 'authenticating') {\n this._status = 'authenticating';\n this.emit('login_required', loginDetection.instructions, loginDetection.url);\n this.logger.warn(\n { sessionId: this.id, loginType: loginDetection.type },\n 'Login required'\n );\n return;\n }\n\n // Check for ready state\n if (this._status === 'starting' && this.adapter.detectReady(this.outputBuffer)) {\n this._status = 'ready';\n this.emit('ready');\n this.logger.info({ sessionId: this.id }, 'Session ready');\n }\n\n // Check for exit\n const exitDetection = this.adapter.detectExit(this.outputBuffer);\n if (exitDetection.exited) {\n this._status = 'stopped';\n this.emit('exit', exitDetection.code || 0);\n }\n\n // Try to parse output into structured message\n this.tryParseOutput();\n });\n\n this.ptyProcess.onExit(({ exitCode, signal }) => {\n this._status = 'stopped';\n this.logger.info(\n { sessionId: this.id, exitCode, signal },\n 'PTY session exited'\n );\n this.emit('exit', exitCode);\n });\n }\n\n /**\n * Detect blocking prompts and handle them with auto-responses or user notification\n */\n private detectAndHandleBlockingPrompt(): boolean {\n // First, check adapter's auto-response rules\n const autoHandled = this.tryAutoResponse();\n if (autoHandled) {\n return true;\n }\n\n // Then check the adapter's detectBlockingPrompt method\n if (this.adapter.detectBlockingPrompt) {\n const detection = this.adapter.detectBlockingPrompt(this.outputBuffer);\n\n if (detection.detected) {\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 we can auto-respond and have a suggested response, do it\n if (detection.canAutoRespond && detection.suggestedResponse) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: detection.type,\n response: detection.suggestedResponse,\n },\n 'Auto-responding to blocking prompt'\n );\n\n this.writeRaw(detection.suggestedResponse + '\\r');\n this.emit('blocking_prompt', promptInfo, true);\n return true;\n }\n\n // Otherwise, notify that user intervention is needed\n if (detection.type === 'login') {\n this._status = 'authenticating';\n }\n\n this.logger.warn(\n {\n sessionId: this.id,\n promptType: detection.type,\n prompt: detection.prompt,\n },\n 'Blocking prompt requires user intervention'\n );\n\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Try to match and apply auto-response rules\n */\n private tryAutoResponse(): boolean {\n const rules = this.adapter.autoResponseRules;\n if (!rules || rules.length === 0) {\n return false;\n }\n\n for (const rule of rules) {\n if (rule.pattern.test(this.outputBuffer)) {\n // Check if it's safe to auto-respond (default: true)\n const safe = rule.safe !== false;\n\n if (safe) {\n this.logger.info(\n {\n sessionId: this.id,\n promptType: rule.type,\n description: rule.description,\n response: rule.response,\n },\n 'Applying auto-response rule'\n );\n\n this.writeRaw(rule.response + '\\r');\n\n // Clear the matched portion from buffer to prevent re-matching\n this.outputBuffer = this.outputBuffer.replace(rule.pattern, '');\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 // Not safe to auto-respond, emit for user intervention\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\n this.emit('blocking_prompt', promptInfo, false);\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Try to parse the output buffer into structured messages\n */\n private tryParseOutput(): void {\n const parsed = this.adapter.parseOutput(this.outputBuffer);\n\n if (parsed && parsed.isComplete) {\n // Clear the buffer for the parsed content\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 // Also emit specific event for questions\n if (parsed.isQuestion) {\n this.emit('question', parsed.content);\n }\n }\n }\n\n /**\n * Write data to the PTY (formatted by adapter)\n */\n write(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n const formatted = this.adapter.formatInput(data);\n this.ptyProcess.write(formatted + '\\r');\n\n this.logger.debug({ sessionId: this.id, input: data }, 'Sent input to session');\n }\n\n /**\n * Write raw data directly to the PTY (no formatting)\n */\n writeRaw(data: string): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n this.ptyProcess.write(data);\n }\n\n /**\n * Send a task/message to the session\n */\n send(message: string): SessionMessage {\n this._status = 'busy';\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 this.write(message);\n\n return msg;\n }\n\n /**\n * Resize the PTY terminal\n */\n resize(cols: number, rows: number): void {\n this.ptyProcess?.resize(cols, rows);\n }\n\n /**\n * Send special keys to the PTY\n *\n * Supported keys:\n * - Control: ctrl+c, ctrl+d, ctrl+z, ctrl+l, ctrl+a, ctrl+e, ctrl+k, ctrl+u, ctrl+w, ctrl+r\n * - Navigation: up, down, left, right, home, end, pageup, pagedown\n * - Editing: enter, tab, backspace, delete, insert, escape\n * - Function: f1-f12\n *\n * @param keys - Key name(s) to send, e.g. \"ctrl+c\" or [\"up\", \"up\", \"enter\"]\n */\n sendKeys(keys: string | string[]): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n const keyList = Array.isArray(keys) ? keys : [keys];\n\n for (const key of keyList) {\n const normalizedKey = key.toLowerCase().trim();\n const sequence = SPECIAL_KEYS[normalizedKey];\n\n if (sequence) {\n this._lastActivityAt = new Date();\n this.ptyProcess.write(sequence);\n this.logger.debug({ sessionId: this.id, key: normalizedKey }, 'Sent special key');\n } else {\n this.logger.warn(\n { sessionId: this.id, key: normalizedKey },\n 'Unknown special key, sending as literal'\n );\n this.ptyProcess.write(key);\n }\n }\n }\n\n /**\n * Paste text using bracketed paste mode\n *\n * Bracketed paste mode wraps the pasted text in escape sequences\n * that tell the terminal this is pasted content, not typed input.\n * This prevents issues with pasting text that contains special characters\n * or looks like commands.\n *\n * @param text - Text to paste\n * @param useBracketedPaste - Whether to use bracketed paste mode (default: true)\n */\n paste(text: string, useBracketedPaste: boolean = true): void {\n if (!this.ptyProcess) {\n throw new Error('Session not started');\n }\n\n this._lastActivityAt = new Date();\n\n if (useBracketedPaste) {\n this.ptyProcess.write(BRACKETED_PASTE_START + text + BRACKETED_PASTE_END);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text with bracketed paste mode'\n );\n } else {\n this.ptyProcess.write(text);\n this.logger.debug(\n { sessionId: this.id, length: text.length },\n 'Pasted text without bracketed paste'\n );\n }\n }\n\n /**\n * Kill the PTY process\n */\n kill(signal?: string): void {\n if (this.ptyProcess) {\n this._status = 'stopping';\n this.ptyProcess.kill(signal);\n this.logger.info({ sessionId: this.id, signal }, 'Killing PTY session');\n }\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 };\n }\n}\n","/**\n * Base CLI Adapter\n *\n * Abstract base class with common functionality for CLI adapters.\n */\n\nimport { spawn } from 'child_process';\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../types';\n\n/**\n * Abstract base class for CLI adapters with common functionality\n */\nexport abstract class BaseCLIAdapter implements CLIAdapter {\n abstract readonly adapterType: string;\n abstract readonly displayName: string;\n\n /**\n * Auto-response rules for handling known blocking prompts.\n * Subclasses should override this to add CLI-specific rules.\n */\n readonly autoResponseRules: AutoResponseRule[] = [];\n\n abstract getCommand(): string;\n abstract getArgs(config: SpawnConfig): string[];\n abstract getEnv(config: SpawnConfig): Record<string, string>;\n abstract detectLogin(output: string): LoginDetection;\n abstract detectReady(output: string): boolean;\n abstract parseOutput(output: string): ParsedOutput | null;\n abstract getPromptPattern(): RegExp;\n\n /**\n * Default exit detection - look for common exit patterns\n */\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n // Check for common exit/error patterns\n if (output.includes('Process exited with code')) {\n const match = output.match(/Process exited with code (\\d+)/);\n return {\n exited: true,\n code: match ? parseInt(match[1], 10) : 1,\n };\n }\n\n if (output.includes('Command not found') || output.includes('command not found')) {\n return {\n exited: true,\n code: 127,\n error: 'Command not found',\n };\n }\n\n return { exited: false };\n }\n\n /**\n * Default blocking prompt detection - looks for common prompt patterns.\n * Subclasses should override for CLI-specific detection.\n */\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n const stripped = this.stripAnsi(output);\n\n // Check for login/auth first (highest priority)\n const loginDetection = this.detectLogin(output);\n if (loginDetection.required) {\n return {\n detected: true,\n type: 'login',\n prompt: loginDetection.instructions,\n url: loginDetection.url,\n canAutoRespond: false,\n instructions: loginDetection.instructions,\n };\n }\n\n // Check for common update prompts\n if (/update (available|now|ready)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'update',\n prompt: 'Update available',\n options: ['y', 'n'],\n suggestedResponse: 'n',\n canAutoRespond: true,\n instructions: 'CLI update available - auto-declining to continue',\n };\n }\n\n // Check for terms of service / license acceptance\n if (/accept.*(terms|license|agreement)/i.test(stripped) && /\\[y\\/n\\]/i.test(stripped)) {\n return {\n detected: true,\n type: 'tos',\n prompt: 'Terms/license acceptance required',\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Please accept the terms of service manually',\n };\n }\n\n // Check for model/version selection\n if (/choose.*model|select.*model|which model/i.test(stripped)) {\n return {\n detected: true,\n type: 'model_select',\n prompt: 'Model selection required',\n canAutoRespond: false,\n instructions: 'Please select a model',\n };\n }\n\n // Check for project/workspace selection\n if (/choose.*(project|workspace)|select.*(project|workspace)/i.test(stripped)) {\n return {\n detected: true,\n type: 'project_select',\n prompt: 'Project/workspace selection required',\n canAutoRespond: false,\n instructions: 'Please select a project or workspace',\n };\n }\n\n // Check for generic y/n prompts that look like they're blocking\n if (/\\[y\\/n\\]|\\(y\\/n\\)|\\[Y\\/n\\]|\\[y\\/N\\]/i.test(stripped) && stripped.includes('?')) {\n return {\n detected: true,\n type: 'unknown',\n prompt: stripped.slice(-200), // Last 200 chars for context\n options: ['y', 'n'],\n canAutoRespond: false,\n instructions: 'Unknown confirmation prompt detected',\n };\n }\n\n return { detected: false };\n }\n\n /**\n * Default input formatting - just return as-is\n */\n formatInput(message: string): string {\n return message;\n }\n\n /**\n * Validate CLI installation by running --version or --help\n */\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n return new Promise((resolve) => {\n const command = this.getCommand();\n\n try {\n const proc = spawn(command, ['--version'], {\n shell: true,\n timeout: 5000,\n });\n\n let output = '';\n\n proc.stdout?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.stderr?.on('data', (data) => {\n output += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n // Try to extract version from output\n const versionMatch = output.match(/(\\d+\\.\\d+\\.\\d+)/);\n resolve({\n installed: true,\n version: versionMatch ? versionMatch[1] : undefined,\n });\n } else {\n resolve({\n installed: false,\n error: `Command exited with code ${code}`,\n });\n }\n });\n\n proc.on('error', (err) => {\n resolve({\n installed: false,\n error: err.message,\n });\n });\n } catch (err) {\n resolve({\n installed: false,\n error: err instanceof Error ? err.message : 'Unknown error',\n });\n }\n });\n }\n\n /**\n * Helper to check if output contains a question\n */\n protected containsQuestion(output: string): boolean {\n const questionPatterns = [\n /\\?$/m, // Ends with ?\n /would you like/i,\n /do you want/i,\n /should I/i,\n /shall I/i,\n /please (choose|select|confirm)/i,\n /\\(y\\/n\\)/i,\n /\\[y\\/N\\]/i,\n /\\[Y\\/n\\]/i,\n ];\n\n return questionPatterns.some((pattern) => pattern.test(output));\n }\n\n /**\n * Helper to strip ANSI escape codes from output\n */\n protected stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1B(?:[@-Z\\\\-_]|\\[[0-?]*[ -/]*[@-~])/g, '');\n }\n}\n","/**\n * Adapter Factory\n *\n * Factory function for creating CLI adapters from configuration.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport { BaseCLIAdapter } from './base-adapter';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n AdapterFactoryConfig,\n} from '../types';\n\n/**\n * Creates a CLI adapter from configuration\n */\nexport function createAdapter(config: AdapterFactoryConfig): CLIAdapter {\n return new ConfiguredAdapter(config);\n}\n\n/**\n * Adapter implementation created from configuration\n */\nclass ConfiguredAdapter extends BaseCLIAdapter {\n readonly adapterType: string;\n readonly displayName: string;\n readonly autoResponseRules: AutoResponseRule[];\n\n constructor(private config: AdapterFactoryConfig) {\n super();\n this.adapterType = config.command.replace(/[^a-zA-Z0-9]/g, '-');\n this.displayName = config.command;\n this.autoResponseRules = this.buildAutoResponseRules();\n }\n\n private buildAutoResponseRules(): AutoResponseRule[] {\n if (!this.config.blockingPrompts) {\n return [];\n }\n\n return this.config.blockingPrompts\n .filter((p) => p.autoResponse !== undefined)\n .map((p) => ({\n pattern: p.pattern,\n type: p.type,\n response: p.autoResponse!,\n description: p.description || `Auto-respond to ${p.type} prompt`,\n safe: p.safe !== false,\n }));\n }\n\n getCommand(): string {\n return this.config.command;\n }\n\n getArgs(config: SpawnConfig): string[] {\n if (typeof this.config.args === 'function') {\n return this.config.args(config);\n }\n return this.config.args || [];\n }\n\n getEnv(config: SpawnConfig): Record<string, string> {\n if (typeof this.config.env === 'function') {\n return this.config.env(config);\n }\n return this.config.env || {};\n }\n\n detectLogin(output: string): LoginDetection {\n if (!this.config.loginDetection) {\n return { required: false };\n }\n\n const { patterns, extractUrl, extractInstructions } = this.config.loginDetection;\n const stripped = this.stripAnsi(output);\n\n for (const pattern of patterns) {\n if (pattern.test(stripped)) {\n return {\n required: true,\n type: 'browser',\n url: extractUrl?.(stripped) || undefined,\n instructions: extractInstructions?.(stripped) || 'Authentication required',\n };\n }\n }\n\n return { required: false };\n }\n\n detectBlockingPrompt(output: string): BlockingPromptDetection {\n // First check config-defined blocking prompts\n if (this.config.blockingPrompts) {\n const stripped = this.stripAnsi(output);\n\n for (const prompt of this.config.blockingPrompts) {\n if (prompt.pattern.test(stripped)) {\n return {\n detected: true,\n type: prompt.type,\n prompt: stripped.slice(-200),\n suggestedResponse: prompt.autoResponse,\n canAutoRespond: prompt.autoResponse !== undefined && prompt.safe !== false,\n instructions: prompt.description,\n };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectBlockingPrompt(output);\n }\n\n detectReady(output: string): boolean {\n if (!this.config.readyIndicators || this.config.readyIndicators.length === 0) {\n // Default: ready after any output\n return output.length > 10;\n }\n\n const stripped = this.stripAnsi(output);\n return this.config.readyIndicators.some((pattern) => pattern.test(stripped));\n }\n\n detectExit(output: string): { exited: boolean; code?: number; error?: string } {\n if (this.config.exitIndicators) {\n for (const indicator of this.config.exitIndicators) {\n const match = output.match(indicator.pattern);\n if (match) {\n const code = indicator.codeExtractor?.(match) ?? 1;\n return { exited: true, code };\n }\n }\n }\n\n // Fall back to base implementation\n return super.detectExit(output);\n }\n\n parseOutput(output: string): ParsedOutput | null {\n if (this.config.parseOutput) {\n return this.config.parseOutput(output);\n }\n\n // Default parsing\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: this.containsQuestion(cleaned),\n };\n }\n\n formatInput(message: string): string {\n if (this.config.formatInput) {\n return this.config.formatInput(message);\n }\n return message;\n }\n\n getPromptPattern(): RegExp {\n return this.config.promptPattern || /[\\$#>]\\s*$/m;\n }\n}\n","/**\n * Shell Adapter\n *\n * Built-in adapter for bash/zsh shell sessions.\n */\n\nimport type { CLIAdapter } from './adapter-interface';\nimport type {\n SpawnConfig,\n ParsedOutput,\n LoginDetection,\n BlockingPromptDetection,\n AutoResponseRule,\n} from '../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 return [];\n }\n\n getEnv(_config: SpawnConfig): Record<string, string> {\n return {\n PS1: this.promptStr,\n };\n }\n\n detectLogin(_output: string): LoginDetection {\n // Shell doesn't need login\n return { required: false };\n }\n\n detectBlockingPrompt(_output: string): BlockingPromptDetection {\n // Shell typically doesn't have blocking prompts\n return { detected: false };\n }\n\n detectReady(output: string): boolean {\n // Ready when we see the prompt or any meaningful output\n return output.includes(this.promptStr) || output.includes('$') || output.length > 10;\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 // Match our custom prompt or standard shell prompts\n const escaped = this.promptStr.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:${escaped}|\\\\$|#|>)\\\\s*$`, 'm');\n }\n\n async validateInstallation(): Promise<{ installed: boolean; version?: string; error?: string }> {\n // Shell is always installed\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","/**\n * Bun-Compatible PTY Manager\n *\n * A wrapper that spawns a Node.js worker process to handle PTY operations,\n * allowing pty-manager to work from Bun or other non-Node runtimes.\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport * as path from 'path';\nimport * as readline from 'readline';\nimport type { SpawnConfig } from './types';\n\nexport interface WorkerSessionHandle {\n id: string;\n name: string;\n type: string;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n pid: number | undefined;\n cols: number;\n rows: number;\n startedAt?: Date;\n lastActivityAt?: Date;\n error?: string;\n exitCode?: number;\n}\n\nexport interface BunPTYManagerOptions {\n /** Path to node executable (default: 'node') */\n nodePath?: string;\n /** Path to worker script (default: auto-detected) */\n workerPath?: string;\n /** Environment variables for worker process */\n env?: Record<string, string>;\n}\n\ninterface PendingOperation {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: NodeJS.Timeout;\n}\n\n/**\n * PTY Manager that works with Bun and other non-Node runtimes\n * by spawning a Node.js worker process.\n */\nexport class BunCompatiblePTYManager extends EventEmitter {\n private worker: ChildProcess | null = null;\n private sessions: Map<string, WorkerSessionHandle> = new Map();\n private pending: Map<string, PendingOperation> = new Map();\n private ready = false;\n private readyPromise: Promise<void>;\n private readyResolve!: () => void;\n private nodePath: string;\n private workerPath: string;\n private env: Record<string, string>;\n\n constructor(options: BunPTYManagerOptions = {}) {\n super();\n\n this.nodePath = options.nodePath || 'node';\n this.workerPath = options.workerPath || this.findWorkerPath();\n this.env = options.env || {};\n\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n }\n\n private findWorkerPath(): string {\n // Try to find the worker script relative to this module\n const possiblePaths = [\n path.join(__dirname, 'pty-worker.js'),\n path.join(__dirname, '..', 'dist', 'pty-worker.js'),\n path.join(__dirname, '..', 'src', 'pty-worker.js'),\n ];\n\n // Return first path (we'll rely on Node to throw if it doesn't exist)\n return possiblePaths[0];\n }\n\n private startWorker(): void {\n this.worker = spawn(this.nodePath, [this.workerPath], {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...this.env },\n });\n\n if (!this.worker.stdout || !this.worker.stdin) {\n throw new Error('Failed to create worker process pipes');\n }\n\n const rl = readline.createInterface({\n input: this.worker.stdout,\n terminal: false,\n });\n\n rl.on('line', (line) => this.handleWorkerMessage(line));\n\n this.worker.stderr?.on('data', (data) => {\n this.emit('worker_error', data.toString());\n });\n\n this.worker.on('exit', (code, signal) => {\n this.ready = false;\n this.worker = null;\n this.emit('worker_exit', { code, signal });\n\n // Reject all pending operations\n for (const [key, op] of this.pending) {\n clearTimeout(op.timeout);\n op.reject(new Error('Worker process exited'));\n this.pending.delete(key);\n }\n\n // Mark all sessions as stopped\n for (const session of this.sessions.values()) {\n session.status = 'stopped';\n }\n });\n\n this.worker.on('error', (err) => {\n this.emit('worker_error', err);\n });\n }\n\n private handleWorkerMessage(line: string): void {\n let event: Record<string, unknown>;\n\n try {\n event = JSON.parse(line);\n } catch {\n this.emit('worker_error', `Invalid JSON from worker: ${line}`);\n return;\n }\n\n const eventType = event.event as string;\n const id = event.id as string | undefined;\n\n switch (eventType) {\n case 'worker_ready':\n this.ready = true;\n this.readyResolve();\n this.emit('ready');\n break;\n\n case 'spawned': {\n // Get config from event (worker sends it back)\n const session: WorkerSessionHandle = {\n id: id!,\n name: (event.name as string) || id!,\n type: (event.type as string) || 'shell',\n status: 'starting',\n pid: event.pid as number,\n cols: (event.cols as number) || 80,\n rows: (event.rows as number) || 24,\n startedAt: new Date(),\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output': {\n const session = this.sessions.get(id!);\n if (session) {\n session.lastActivityAt = new Date();\n }\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n }\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\n session.lastActivityAt = new Date();\n this.emit('session_ready', session);\n }\n break;\n }\n\n case 'exit': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'stopped';\n session.exitCode = event.code as number;\n session.lastActivityAt = new Date();\n this.emit('session_stopped', session, event.code, event.signal);\n this.sessions.delete(id!);\n }\n break;\n }\n\n case 'error':\n if (id) {\n const session = this.sessions.get(id);\n if (session) {\n session.status = 'error';\n session.error = event.message as string;\n session.lastActivityAt = new Date();\n }\n this.emit('session_error', { id, error: event.message });\n } else {\n this.emit('worker_error', event.message);\n }\n break;\n\n case 'blocking_prompt': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('blocking_prompt', session, event.promptInfo, event.autoResponded);\n }\n break;\n }\n\n case 'login_required': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('login_required', session, event.instructions, event.url);\n }\n break;\n }\n\n case 'message': {\n const msg = event.message as Record<string, unknown>;\n // Convert timestamp back to Date\n this.emit('message', {\n ...msg,\n timestamp: new Date(msg.timestamp as string),\n });\n break;\n }\n\n case 'question': {\n const session = this.sessions.get(id!);\n if (session) {\n this.emit('question', session, event.question);\n }\n break;\n }\n\n case 'list': {\n // Convert date strings back to Date objects\n const sessions = (event.sessions as Record<string, unknown>[]).map((s) => ({\n ...s,\n startedAt: s.startedAt ? new Date(s.startedAt as string) : undefined,\n lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt as string) : undefined,\n })) as WorkerSessionHandle[];\n this.resolvePending('list', sessions);\n break;\n }\n\n case 'ack': {\n const cmd = event.cmd as string;\n const success = event.success as boolean;\n const pendingKey = id ? `${cmd}:${id}` : cmd;\n const pending = this.pending.get(pendingKey);\n\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(pendingKey);\n\n if (success) {\n pending.resolve(true);\n } else {\n pending.reject(new Error(event.error as string));\n }\n }\n break;\n }\n }\n }\n\n private sendCommand(cmd: Record<string, unknown>): void {\n if (!this.worker?.stdin) {\n throw new Error('Worker not available');\n }\n\n this.worker.stdin.write(JSON.stringify(cmd) + '\\n');\n }\n\n private createPending(key: string, timeoutMs = 30000): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Operation ${key} timed out`));\n }, timeoutMs);\n\n this.pending.set(key, { resolve, reject, timeout });\n });\n }\n\n private resolvePending(key: string, value: unknown): void {\n const pending = this.pending.get(key);\n if (pending) {\n clearTimeout(pending.timeout);\n this.pending.delete(key);\n pending.resolve(value);\n }\n }\n\n /**\n * Wait for the worker to be ready\n */\n async waitForReady(): Promise<void> {\n return this.readyPromise;\n }\n\n /**\n * Check if worker is ready\n */\n isReady(): boolean {\n return this.ready;\n }\n\n /**\n * Spawn a new PTY session\n */\n async spawn(config: SpawnConfig & { id: string }): Promise<WorkerSessionHandle> {\n await this.waitForReady();\n\n const { id } = config;\n\n this.sendCommand({ cmd: 'spawn', id, config });\n\n await this.createPending(`spawn:${id}`);\n\n return this.sessions.get(id)!;\n }\n\n /**\n * Send data to a session\n */\n async send(id: string, data: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'send', id, data });\n\n await this.createPending(`send:${id}`);\n }\n\n /**\n * Send special keys to a session\n */\n async sendKeys(id: string, keys: string | string[]): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'sendKeys', id, keys });\n\n await this.createPending(`sendKeys:${id}`);\n }\n\n /**\n * Paste text to a session\n */\n async paste(id: string, text: string, bracketed = true): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'paste', id, text, bracketed });\n\n await this.createPending(`paste:${id}`);\n }\n\n /**\n * Resize a session\n */\n async resize(id: string, cols: number, rows: number): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'resize', id, cols, rows });\n\n const session = this.sessions.get(id);\n if (session) {\n session.cols = cols;\n session.rows = rows;\n }\n\n await this.createPending(`resize:${id}`);\n }\n\n /**\n * Kill a session\n */\n async kill(id: string, signal?: string): Promise<void> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'kill', id, signal });\n\n await this.createPending(`kill:${id}`);\n }\n\n /**\n * Get a session by ID\n */\n get(id: string): WorkerSessionHandle | undefined {\n return this.sessions.get(id);\n }\n\n /**\n * List all sessions\n */\n async list(): Promise<WorkerSessionHandle[]> {\n await this.waitForReady();\n\n this.sendCommand({ cmd: 'list' });\n\n const sessions = (await this.createPending('list')) as WorkerSessionHandle[];\n return sessions;\n }\n\n /**\n * Check if a session exists\n */\n has(id: string): boolean {\n return this.sessions.has(id);\n }\n\n /**\n * Subscribe to output from a specific session\n */\n onSessionData(id: string, callback: (data: string) => void): () => void {\n const handler = (data: string) => callback(data);\n this.on(`data:${id}`, handler);\n return () => this.off(`data:${id}`, handler);\n }\n\n /**\n * Shutdown the worker and all sessions\n */\n async shutdown(): Promise<void> {\n if (!this.worker) return;\n\n this.sendCommand({ cmd: 'shutdown' });\n\n await this.createPending('shutdown', 10000).catch(() => {\n // Force kill if shutdown times out\n this.worker?.kill('SIGKILL');\n });\n }\n\n /**\n * Restart the worker process\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n this.sessions.clear();\n this.ready = false;\n this.readyPromise = new Promise((resolve) => {\n this.readyResolve = resolve;\n });\n\n this.startWorker();\n await this.waitForReady();\n }\n}\n\n/**\n * Detect if running in Bun\n */\nexport function isBun(): boolean {\n // Bun 1.1.24+ sets process.versions.bun (lowercase)\n return typeof process !== 'undefined' && 'bun' in process.versions;\n}\n\n/**\n * Create the appropriate PTY manager based on runtime\n */\nexport function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager {\n return new BunCompatiblePTYManager(options);\n}\n"],"mappings":"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","names":["EventEmitter","consoleLogger","EventEmitter","spawn","EventEmitter"]}
|
package/dist/pty-worker.js
CHANGED
|
@@ -1049,6 +1049,38 @@ manager.on("session_stopped", (handle, reason) => {
|
|
|
1049
1049
|
manager.on("session_error", (handle, error) => {
|
|
1050
1050
|
emit({ event: "error", id: handle.id, message: error });
|
|
1051
1051
|
});
|
|
1052
|
+
manager.on("blocking_prompt", (handle, promptInfo, autoResponded) => {
|
|
1053
|
+
emit({
|
|
1054
|
+
event: "blocking_prompt",
|
|
1055
|
+
id: handle.id,
|
|
1056
|
+
promptInfo,
|
|
1057
|
+
autoResponded
|
|
1058
|
+
});
|
|
1059
|
+
});
|
|
1060
|
+
manager.on("login_required", (handle, instructions, url) => {
|
|
1061
|
+
emit({
|
|
1062
|
+
event: "login_required",
|
|
1063
|
+
id: handle.id,
|
|
1064
|
+
instructions,
|
|
1065
|
+
url
|
|
1066
|
+
});
|
|
1067
|
+
});
|
|
1068
|
+
manager.on("message", (message) => {
|
|
1069
|
+
emit({
|
|
1070
|
+
event: "message",
|
|
1071
|
+
message: {
|
|
1072
|
+
...message,
|
|
1073
|
+
timestamp: message.timestamp.toISOString()
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
});
|
|
1077
|
+
manager.on("question", (handle, question) => {
|
|
1078
|
+
emit({
|
|
1079
|
+
event: "question",
|
|
1080
|
+
id: handle.id,
|
|
1081
|
+
question
|
|
1082
|
+
});
|
|
1083
|
+
});
|
|
1052
1084
|
async function handleSpawn(id, config) {
|
|
1053
1085
|
try {
|
|
1054
1086
|
if (manager.has(id)) {
|
package/package.json
CHANGED