pty-manager 1.2.0 → 1.2.2

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.d.mts CHANGED
@@ -678,10 +678,16 @@ declare class ShellAdapter implements CLIAdapter {
678
678
 
679
679
  interface WorkerSessionHandle {
680
680
  id: string;
681
- pid: number | undefined;
681
+ name: string;
682
+ type: string;
682
683
  status: 'starting' | 'ready' | 'stopped' | 'error';
684
+ pid: number | undefined;
683
685
  cols: number;
684
686
  rows: number;
687
+ startedAt?: Date;
688
+ lastActivityAt?: Date;
689
+ error?: string;
690
+ exitCode?: number;
685
691
  }
686
692
  interface BunPTYManagerOptions {
687
693
  /** Path to node executable (default: 'node') */
package/dist/index.d.ts CHANGED
@@ -678,10 +678,16 @@ declare class ShellAdapter implements CLIAdapter {
678
678
 
679
679
  interface WorkerSessionHandle {
680
680
  id: string;
681
- pid: number | undefined;
681
+ name: string;
682
+ type: string;
682
683
  status: 'starting' | 'ready' | 'stopped' | 'error';
684
+ pid: number | undefined;
683
685
  cols: number;
684
686
  rows: number;
687
+ startedAt?: Date;
688
+ lastActivityAt?: Date;
689
+ error?: string;
690
+ exitCode?: number;
685
691
  }
686
692
  interface BunPTYManagerOptions {
687
693
  /** Path to node executable (default: 'node') */
package/dist/index.js CHANGED
@@ -1408,23 +1408,32 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
1408
1408
  case "spawned": {
1409
1409
  const session = {
1410
1410
  id,
1411
- pid: event.pid,
1411
+ name: event.name || id,
1412
+ type: event.type || "shell",
1412
1413
  status: "starting",
1413
- cols: 80,
1414
- rows: 24
1414
+ pid: event.pid,
1415
+ cols: event.cols || 80,
1416
+ rows: event.rows || 24,
1417
+ startedAt: /* @__PURE__ */ new Date()
1415
1418
  };
1416
1419
  this.sessions.set(id, session);
1417
1420
  this.emit("session_started", session);
1418
1421
  break;
1419
1422
  }
1420
- case "output":
1423
+ case "output": {
1424
+ const session = this.sessions.get(id);
1425
+ if (session) {
1426
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1427
+ }
1421
1428
  this.emit("data", { id, data: event.data });
1422
1429
  this.emit(`data:${id}`, event.data);
1423
1430
  break;
1431
+ }
1424
1432
  case "ready": {
1425
1433
  const session = this.sessions.get(id);
1426
1434
  if (session) {
1427
1435
  session.status = "ready";
1436
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1428
1437
  this.emit("session_ready", session);
1429
1438
  }
1430
1439
  break;
@@ -1433,6 +1442,8 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
1433
1442
  const session = this.sessions.get(id);
1434
1443
  if (session) {
1435
1444
  session.status = "stopped";
1445
+ session.exitCode = event.code;
1446
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1436
1447
  this.emit("session_stopped", session, event.code, event.signal);
1437
1448
  this.sessions.delete(id);
1438
1449
  }
@@ -1443,15 +1454,23 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
1443
1454
  const session = this.sessions.get(id);
1444
1455
  if (session) {
1445
1456
  session.status = "error";
1457
+ session.error = event.message;
1458
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1446
1459
  }
1447
1460
  this.emit("session_error", { id, error: event.message });
1448
1461
  } else {
1449
1462
  this.emit("worker_error", event.message);
1450
1463
  }
1451
1464
  break;
1452
- case "list":
1453
- this.resolvePending("list", event.sessions);
1465
+ case "list": {
1466
+ const sessions = event.sessions.map((s) => ({
1467
+ ...s,
1468
+ startedAt: s.startedAt ? new Date(s.startedAt) : void 0,
1469
+ lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt) : void 0
1470
+ }));
1471
+ this.resolvePending("list", sessions);
1454
1472
  break;
1473
+ }
1455
1474
  case "ack": {
1456
1475
  const cmd = event.cmd;
1457
1476
  const success = event.success;
@@ -1614,7 +1633,7 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
1614
1633
  }
1615
1634
  };
1616
1635
  function isBun() {
1617
- return typeof process !== "undefined" && "Bun" in process.versions;
1636
+ return typeof process !== "undefined" && "bun" in process.versions;
1618
1637
  }
1619
1638
  function createPTYManager(options) {
1620
1639
  return new BunCompatiblePTYManager(options);
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 pid: number | undefined;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n cols: number;\n rows: 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 const session: WorkerSessionHandle = {\n id: id!,\n pid: event.pid as number,\n status: 'starting',\n cols: 80,\n rows: 24,\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output':\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\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 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 }\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 this.resolvePending('list', event.sessions);\n break;\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 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 '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
@@ -1370,23 +1370,32 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
1370
1370
  case "spawned": {
1371
1371
  const session = {
1372
1372
  id,
1373
- pid: event.pid,
1373
+ name: event.name || id,
1374
+ type: event.type || "shell",
1374
1375
  status: "starting",
1375
- cols: 80,
1376
- rows: 24
1376
+ pid: event.pid,
1377
+ cols: event.cols || 80,
1378
+ rows: event.rows || 24,
1379
+ startedAt: /* @__PURE__ */ new Date()
1377
1380
  };
1378
1381
  this.sessions.set(id, session);
1379
1382
  this.emit("session_started", session);
1380
1383
  break;
1381
1384
  }
1382
- case "output":
1385
+ case "output": {
1386
+ const session = this.sessions.get(id);
1387
+ if (session) {
1388
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1389
+ }
1383
1390
  this.emit("data", { id, data: event.data });
1384
1391
  this.emit(`data:${id}`, event.data);
1385
1392
  break;
1393
+ }
1386
1394
  case "ready": {
1387
1395
  const session = this.sessions.get(id);
1388
1396
  if (session) {
1389
1397
  session.status = "ready";
1398
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1390
1399
  this.emit("session_ready", session);
1391
1400
  }
1392
1401
  break;
@@ -1395,6 +1404,8 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
1395
1404
  const session = this.sessions.get(id);
1396
1405
  if (session) {
1397
1406
  session.status = "stopped";
1407
+ session.exitCode = event.code;
1408
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1398
1409
  this.emit("session_stopped", session, event.code, event.signal);
1399
1410
  this.sessions.delete(id);
1400
1411
  }
@@ -1405,15 +1416,23 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
1405
1416
  const session = this.sessions.get(id);
1406
1417
  if (session) {
1407
1418
  session.status = "error";
1419
+ session.error = event.message;
1420
+ session.lastActivityAt = /* @__PURE__ */ new Date();
1408
1421
  }
1409
1422
  this.emit("session_error", { id, error: event.message });
1410
1423
  } else {
1411
1424
  this.emit("worker_error", event.message);
1412
1425
  }
1413
1426
  break;
1414
- case "list":
1415
- this.resolvePending("list", event.sessions);
1427
+ case "list": {
1428
+ const sessions = event.sessions.map((s) => ({
1429
+ ...s,
1430
+ startedAt: s.startedAt ? new Date(s.startedAt) : void 0,
1431
+ lastActivityAt: s.lastActivityAt ? new Date(s.lastActivityAt) : void 0
1432
+ }));
1433
+ this.resolvePending("list", sessions);
1416
1434
  break;
1435
+ }
1417
1436
  case "ack": {
1418
1437
  const cmd = event.cmd;
1419
1438
  const success = event.success;
@@ -1576,7 +1595,7 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
1576
1595
  }
1577
1596
  };
1578
1597
  function isBun() {
1579
- return typeof process !== "undefined" && "Bun" in process.versions;
1598
+ return typeof process !== "undefined" && "bun" in process.versions;
1580
1599
  }
1581
1600
  function createPTYManager(options) {
1582
1601
  return new BunCompatiblePTYManager(options);
@@ -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 pid: number | undefined;\n status: 'starting' | 'ready' | 'stopped' | 'error';\n cols: number;\n rows: 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 const session: WorkerSessionHandle = {\n id: id!,\n pid: event.pid as number,\n status: 'starting',\n cols: 80,\n rows: 24,\n };\n this.sessions.set(id!, session);\n this.emit('session_started', session);\n break;\n }\n\n case 'output':\n this.emit('data', { id, data: event.data });\n this.emit(`data:${id}`, event.data);\n break;\n\n case 'ready': {\n const session = this.sessions.get(id!);\n if (session) {\n session.status = 'ready';\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 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 }\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 this.resolvePending('list', event.sessions);\n break;\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 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 '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"]}
@@ -1022,13 +1022,28 @@ function ack(cmd, id, success = true, error) {
1022
1022
  emit({ event: "ack", cmd, id, success, error });
1023
1023
  }
1024
1024
  manager.on("session_started", (handle) => {
1025
- emit({ event: "spawned", id: handle.id, pid: handle.pid });
1025
+ emit({
1026
+ event: "spawned",
1027
+ id: handle.id,
1028
+ name: handle.name,
1029
+ type: handle.type,
1030
+ pid: handle.pid,
1031
+ cols: 120,
1032
+ // Default cols
1033
+ rows: 40
1034
+ // Default rows
1035
+ });
1026
1036
  });
1027
1037
  manager.on("session_ready", (handle) => {
1028
1038
  emit({ event: "ready", id: handle.id });
1029
1039
  });
1030
1040
  manager.on("session_stopped", (handle, reason) => {
1031
- emit({ event: "exit", id: handle.id, code: handle.exitCode || 0, reason });
1041
+ emit({
1042
+ event: "exit",
1043
+ id: handle.id,
1044
+ code: handle.exitCode || 0,
1045
+ reason
1046
+ });
1032
1047
  attachments.delete(handle.id);
1033
1048
  });
1034
1049
  manager.on("session_error", (handle, error) => {
@@ -1117,8 +1132,16 @@ function handleList() {
1117
1132
  const sessions = manager.list();
1118
1133
  const sessionList = sessions.map((s) => ({
1119
1134
  id: s.id,
1135
+ name: s.name,
1136
+ type: s.type,
1137
+ status: s.status,
1120
1138
  pid: s.pid,
1121
- status: s.status
1139
+ cols: 120,
1140
+ rows: 40,
1141
+ startedAt: s.startedAt?.toISOString() || (/* @__PURE__ */ new Date()).toISOString(),
1142
+ lastActivityAt: s.lastActivityAt?.toISOString(),
1143
+ error: s.error,
1144
+ exitCode: s.exitCode
1122
1145
  }));
1123
1146
  emit({ event: "list", sessions: sessionList });
1124
1147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pty-manager",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "PTY session manager with lifecycle management, pluggable adapters, and blocking prompt detection",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",