pty-manager 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,6 +11,7 @@ PTY session manager with lifecycle management, pluggable adapters, and blocking
11
11
  - **Terminal attachment** - Attach to sessions for raw I/O streaming
12
12
  - **Special key support** - Send Ctrl, Alt, Shift, and function key combinations via `sendKeys()`
13
13
  - **Bracketed paste** - Proper paste handling with bracketed paste mode support
14
+ - **Bun compatible** - Worker-based adapter for non-Node runtimes like Bun
14
15
  - **Event-driven** - Rich event system for session lifecycle
15
16
  - **TypeScript-first** - Full type definitions included
16
17
 
@@ -310,6 +311,70 @@ console.log(SPECIAL_KEYS['up']); // '\x1b[A'
310
311
  console.log(Object.keys(SPECIAL_KEYS).length); // 130+
311
312
  ```
312
313
 
314
+ ## Bun Compatibility
315
+
316
+ Since Bun doesn't fully support Node.js native addons like `node-pty`, this package includes a worker-based solution that spawns a Node.js child process to handle PTY operations.
317
+
318
+ ### BunCompatiblePTYManager
319
+
320
+ ```typescript
321
+ import { BunCompatiblePTYManager, isBun } from 'pty-manager';
322
+
323
+ // Create manager (works from Bun or Node.js)
324
+ const manager = new BunCompatiblePTYManager({
325
+ nodePath: 'node', // Path to Node.js executable
326
+ });
327
+
328
+ // Wait for worker to be ready
329
+ await manager.waitForReady();
330
+
331
+ // Spawn a session
332
+ const session = await manager.spawn({
333
+ id: 'my-session',
334
+ name: 'shell',
335
+ type: 'shell',
336
+ });
337
+
338
+ // Listen for output
339
+ manager.onSessionData('my-session', (data) => {
340
+ console.log('Output:', data);
341
+ });
342
+
343
+ // Send commands
344
+ await manager.send('my-session', 'echo "Hello from Bun!"\n');
345
+
346
+ // Send special keys
347
+ await manager.sendKeys('my-session', 'ctrl+c');
348
+
349
+ // Paste with bracketed paste mode
350
+ await manager.paste('my-session', 'some text');
351
+
352
+ // Shutdown
353
+ await manager.shutdown();
354
+ ```
355
+
356
+ ### How it works
357
+
358
+ 1. `BunCompatiblePTYManager` spawns a Node.js child process running `pty-worker.js`
359
+ 2. Commands are sent as JSON over stdin
360
+ 3. Events (output, ready, exit) come back as JSON over stdout
361
+ 4. The worker uses the full `PTYManager` internally
362
+
363
+ ### Worker Protocol
364
+
365
+ Commands (stdin → worker):
366
+ - `{ "cmd": "spawn", "id": "...", "config": {...} }`
367
+ - `{ "cmd": "send", "id": "...", "data": "..." }`
368
+ - `{ "cmd": "sendKeys", "id": "...", "keys": ["ctrl+c"] }`
369
+ - `{ "cmd": "kill", "id": "..." }`
370
+ - `{ "cmd": "list" }`
371
+ - `{ "cmd": "shutdown" }`
372
+
373
+ Events (worker → stdout):
374
+ - `{ "event": "output", "id": "...", "data": "..." }`
375
+ - `{ "event": "ready", "id": "..." }`
376
+ - `{ "event": "exit", "id": "...", "code": 0 }`
377
+
313
378
  ## Built-in Adapters
314
379
 
315
380
  ### ShellAdapter
package/dist/index.d.mts CHANGED
@@ -669,4 +669,115 @@ declare class ShellAdapter implements CLIAdapter {
669
669
  private stripAnsi;
670
670
  }
671
671
 
672
- export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StopOptions, type TerminalAttachment, createAdapter };
672
+ /**
673
+ * Bun-Compatible PTY Manager
674
+ *
675
+ * A wrapper that spawns a Node.js worker process to handle PTY operations,
676
+ * allowing pty-manager to work from Bun or other non-Node runtimes.
677
+ */
678
+
679
+ interface WorkerSessionHandle {
680
+ id: string;
681
+ pid: number | undefined;
682
+ status: 'starting' | 'ready' | 'stopped' | 'error';
683
+ cols: number;
684
+ rows: number;
685
+ }
686
+ interface BunPTYManagerOptions {
687
+ /** Path to node executable (default: 'node') */
688
+ nodePath?: string;
689
+ /** Path to worker script (default: auto-detected) */
690
+ workerPath?: string;
691
+ /** Environment variables for worker process */
692
+ env?: Record<string, string>;
693
+ }
694
+ /**
695
+ * PTY Manager that works with Bun and other non-Node runtimes
696
+ * by spawning a Node.js worker process.
697
+ */
698
+ declare class BunCompatiblePTYManager extends EventEmitter {
699
+ private worker;
700
+ private sessions;
701
+ private pending;
702
+ private ready;
703
+ private readyPromise;
704
+ private readyResolve;
705
+ private nodePath;
706
+ private workerPath;
707
+ private env;
708
+ constructor(options?: BunPTYManagerOptions);
709
+ private findWorkerPath;
710
+ private startWorker;
711
+ private handleWorkerMessage;
712
+ private sendCommand;
713
+ private createPending;
714
+ private resolvePending;
715
+ /**
716
+ * Wait for the worker to be ready
717
+ */
718
+ waitForReady(): Promise<void>;
719
+ /**
720
+ * Check if worker is ready
721
+ */
722
+ isReady(): boolean;
723
+ /**
724
+ * Spawn a new PTY session
725
+ */
726
+ spawn(config: SpawnConfig & {
727
+ id: string;
728
+ }): Promise<WorkerSessionHandle>;
729
+ /**
730
+ * Send data to a session
731
+ */
732
+ send(id: string, data: string): Promise<void>;
733
+ /**
734
+ * Send special keys to a session
735
+ */
736
+ sendKeys(id: string, keys: string | string[]): Promise<void>;
737
+ /**
738
+ * Paste text to a session
739
+ */
740
+ paste(id: string, text: string, bracketed?: boolean): Promise<void>;
741
+ /**
742
+ * Resize a session
743
+ */
744
+ resize(id: string, cols: number, rows: number): Promise<void>;
745
+ /**
746
+ * Kill a session
747
+ */
748
+ kill(id: string, signal?: string): Promise<void>;
749
+ /**
750
+ * Get a session by ID
751
+ */
752
+ get(id: string): WorkerSessionHandle | undefined;
753
+ /**
754
+ * List all sessions
755
+ */
756
+ list(): Promise<WorkerSessionHandle[]>;
757
+ /**
758
+ * Check if a session exists
759
+ */
760
+ has(id: string): boolean;
761
+ /**
762
+ * Subscribe to output from a specific session
763
+ */
764
+ onSessionData(id: string, callback: (data: string) => void): () => void;
765
+ /**
766
+ * Shutdown the worker and all sessions
767
+ */
768
+ shutdown(): Promise<void>;
769
+ /**
770
+ * Restart the worker process
771
+ */
772
+ restart(): Promise<void>;
773
+ }
774
+ /**
775
+ * Detect if running in Bun
776
+ */
777
+ declare function isBun(): boolean;
778
+ /**
779
+ * Create the appropriate PTY manager based on runtime
780
+ */
781
+ declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
782
+
783
+ export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StopOptions, type TerminalAttachment, type WorkerSessionHandle, createAdapter, createPTYManager, isBun };
package/dist/index.d.ts CHANGED
@@ -669,4 +669,115 @@ declare class ShellAdapter implements CLIAdapter {
669
669
  private stripAnsi;
670
670
  }
671
671
 
672
- export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StopOptions, type TerminalAttachment, createAdapter };
672
+ /**
673
+ * Bun-Compatible PTY Manager
674
+ *
675
+ * A wrapper that spawns a Node.js worker process to handle PTY operations,
676
+ * allowing pty-manager to work from Bun or other non-Node runtimes.
677
+ */
678
+
679
+ interface WorkerSessionHandle {
680
+ id: string;
681
+ pid: number | undefined;
682
+ status: 'starting' | 'ready' | 'stopped' | 'error';
683
+ cols: number;
684
+ rows: number;
685
+ }
686
+ interface BunPTYManagerOptions {
687
+ /** Path to node executable (default: 'node') */
688
+ nodePath?: string;
689
+ /** Path to worker script (default: auto-detected) */
690
+ workerPath?: string;
691
+ /** Environment variables for worker process */
692
+ env?: Record<string, string>;
693
+ }
694
+ /**
695
+ * PTY Manager that works with Bun and other non-Node runtimes
696
+ * by spawning a Node.js worker process.
697
+ */
698
+ declare class BunCompatiblePTYManager extends EventEmitter {
699
+ private worker;
700
+ private sessions;
701
+ private pending;
702
+ private ready;
703
+ private readyPromise;
704
+ private readyResolve;
705
+ private nodePath;
706
+ private workerPath;
707
+ private env;
708
+ constructor(options?: BunPTYManagerOptions);
709
+ private findWorkerPath;
710
+ private startWorker;
711
+ private handleWorkerMessage;
712
+ private sendCommand;
713
+ private createPending;
714
+ private resolvePending;
715
+ /**
716
+ * Wait for the worker to be ready
717
+ */
718
+ waitForReady(): Promise<void>;
719
+ /**
720
+ * Check if worker is ready
721
+ */
722
+ isReady(): boolean;
723
+ /**
724
+ * Spawn a new PTY session
725
+ */
726
+ spawn(config: SpawnConfig & {
727
+ id: string;
728
+ }): Promise<WorkerSessionHandle>;
729
+ /**
730
+ * Send data to a session
731
+ */
732
+ send(id: string, data: string): Promise<void>;
733
+ /**
734
+ * Send special keys to a session
735
+ */
736
+ sendKeys(id: string, keys: string | string[]): Promise<void>;
737
+ /**
738
+ * Paste text to a session
739
+ */
740
+ paste(id: string, text: string, bracketed?: boolean): Promise<void>;
741
+ /**
742
+ * Resize a session
743
+ */
744
+ resize(id: string, cols: number, rows: number): Promise<void>;
745
+ /**
746
+ * Kill a session
747
+ */
748
+ kill(id: string, signal?: string): Promise<void>;
749
+ /**
750
+ * Get a session by ID
751
+ */
752
+ get(id: string): WorkerSessionHandle | undefined;
753
+ /**
754
+ * List all sessions
755
+ */
756
+ list(): Promise<WorkerSessionHandle[]>;
757
+ /**
758
+ * Check if a session exists
759
+ */
760
+ has(id: string): boolean;
761
+ /**
762
+ * Subscribe to output from a specific session
763
+ */
764
+ onSessionData(id: string, callback: (data: string) => void): () => void;
765
+ /**
766
+ * Shutdown the worker and all sessions
767
+ */
768
+ shutdown(): Promise<void>;
769
+ /**
770
+ * Restart the worker process
771
+ */
772
+ restart(): Promise<void>;
773
+ }
774
+ /**
775
+ * Detect if running in Bun
776
+ */
777
+ declare function isBun(): boolean;
778
+ /**
779
+ * Create the appropriate PTY manager based on runtime
780
+ */
781
+ declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
782
+
783
+ export { type AdapterFactoryConfig, AdapterRegistry, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, BunCompatiblePTYManager, type BunPTYManagerOptions, type CLIAdapter, type LogOptions, type Logger, type LoginDetection, type MessageType, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, type ParsedOutput, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type SpawnConfig, type StopOptions, type TerminalAttachment, type WorkerSessionHandle, createAdapter, createPTYManager, isBun };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -22,11 +32,14 @@ var index_exports = {};
22
32
  __export(index_exports, {
23
33
  AdapterRegistry: () => AdapterRegistry,
24
34
  BaseCLIAdapter: () => BaseCLIAdapter,
35
+ BunCompatiblePTYManager: () => BunCompatiblePTYManager,
25
36
  PTYManager: () => PTYManager,
26
37
  PTYSession: () => PTYSession,
27
38
  SPECIAL_KEYS: () => SPECIAL_KEYS,
28
39
  ShellAdapter: () => ShellAdapter,
29
- createAdapter: () => createAdapter
40
+ createAdapter: () => createAdapter,
41
+ createPTYManager: () => createPTYManager,
42
+ isBun: () => isBun
30
43
  });
31
44
  module.exports = __toCommonJS(index_exports);
32
45
 
@@ -1309,14 +1322,314 @@ var ShellAdapter = class {
1309
1322
  return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
1310
1323
  }
1311
1324
  };
1325
+
1326
+ // src/bun-compat.ts
1327
+ var import_child_process2 = require("child_process");
1328
+ var import_events3 = require("events");
1329
+ var path = __toESM(require("path"));
1330
+ var readline = __toESM(require("readline"));
1331
+ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
1332
+ worker = null;
1333
+ sessions = /* @__PURE__ */ new Map();
1334
+ pending = /* @__PURE__ */ new Map();
1335
+ ready = false;
1336
+ readyPromise;
1337
+ readyResolve;
1338
+ nodePath;
1339
+ workerPath;
1340
+ env;
1341
+ constructor(options = {}) {
1342
+ super();
1343
+ this.nodePath = options.nodePath || "node";
1344
+ this.workerPath = options.workerPath || this.findWorkerPath();
1345
+ this.env = options.env || {};
1346
+ this.readyPromise = new Promise((resolve) => {
1347
+ this.readyResolve = resolve;
1348
+ });
1349
+ this.startWorker();
1350
+ }
1351
+ findWorkerPath() {
1352
+ const possiblePaths = [
1353
+ path.join(__dirname, "pty-worker.js"),
1354
+ path.join(__dirname, "..", "dist", "pty-worker.js"),
1355
+ path.join(__dirname, "..", "src", "pty-worker.js")
1356
+ ];
1357
+ return possiblePaths[0];
1358
+ }
1359
+ startWorker() {
1360
+ this.worker = (0, import_child_process2.spawn)(this.nodePath, [this.workerPath], {
1361
+ stdio: ["pipe", "pipe", "pipe"],
1362
+ env: { ...process.env, ...this.env }
1363
+ });
1364
+ if (!this.worker.stdout || !this.worker.stdin) {
1365
+ throw new Error("Failed to create worker process pipes");
1366
+ }
1367
+ const rl = readline.createInterface({
1368
+ input: this.worker.stdout,
1369
+ terminal: false
1370
+ });
1371
+ rl.on("line", (line) => this.handleWorkerMessage(line));
1372
+ this.worker.stderr?.on("data", (data) => {
1373
+ this.emit("worker_error", data.toString());
1374
+ });
1375
+ this.worker.on("exit", (code, signal) => {
1376
+ this.ready = false;
1377
+ this.worker = null;
1378
+ this.emit("worker_exit", { code, signal });
1379
+ for (const [key, op] of this.pending) {
1380
+ clearTimeout(op.timeout);
1381
+ op.reject(new Error("Worker process exited"));
1382
+ this.pending.delete(key);
1383
+ }
1384
+ for (const session of this.sessions.values()) {
1385
+ session.status = "stopped";
1386
+ }
1387
+ });
1388
+ this.worker.on("error", (err) => {
1389
+ this.emit("worker_error", err);
1390
+ });
1391
+ }
1392
+ handleWorkerMessage(line) {
1393
+ let event;
1394
+ try {
1395
+ event = JSON.parse(line);
1396
+ } catch {
1397
+ this.emit("worker_error", `Invalid JSON from worker: ${line}`);
1398
+ return;
1399
+ }
1400
+ const eventType = event.event;
1401
+ const id = event.id;
1402
+ switch (eventType) {
1403
+ case "worker_ready":
1404
+ this.ready = true;
1405
+ this.readyResolve();
1406
+ this.emit("ready");
1407
+ break;
1408
+ case "spawned": {
1409
+ const session = {
1410
+ id,
1411
+ pid: event.pid,
1412
+ status: "starting",
1413
+ cols: 80,
1414
+ rows: 24
1415
+ };
1416
+ this.sessions.set(id, session);
1417
+ this.emit("session_started", session);
1418
+ break;
1419
+ }
1420
+ case "output":
1421
+ this.emit("data", { id, data: event.data });
1422
+ this.emit(`data:${id}`, event.data);
1423
+ break;
1424
+ case "ready": {
1425
+ const session = this.sessions.get(id);
1426
+ if (session) {
1427
+ session.status = "ready";
1428
+ this.emit("session_ready", session);
1429
+ }
1430
+ break;
1431
+ }
1432
+ case "exit": {
1433
+ const session = this.sessions.get(id);
1434
+ if (session) {
1435
+ session.status = "stopped";
1436
+ this.emit("session_stopped", session, event.code, event.signal);
1437
+ this.sessions.delete(id);
1438
+ }
1439
+ break;
1440
+ }
1441
+ case "error":
1442
+ if (id) {
1443
+ const session = this.sessions.get(id);
1444
+ if (session) {
1445
+ session.status = "error";
1446
+ }
1447
+ this.emit("session_error", { id, error: event.message });
1448
+ } else {
1449
+ this.emit("worker_error", event.message);
1450
+ }
1451
+ break;
1452
+ case "list":
1453
+ this.resolvePending("list", event.sessions);
1454
+ break;
1455
+ case "ack": {
1456
+ const cmd = event.cmd;
1457
+ const success = event.success;
1458
+ const pendingKey = id ? `${cmd}:${id}` : cmd;
1459
+ const pending = this.pending.get(pendingKey);
1460
+ if (pending) {
1461
+ clearTimeout(pending.timeout);
1462
+ this.pending.delete(pendingKey);
1463
+ if (success) {
1464
+ pending.resolve(true);
1465
+ } else {
1466
+ pending.reject(new Error(event.error));
1467
+ }
1468
+ }
1469
+ break;
1470
+ }
1471
+ }
1472
+ }
1473
+ sendCommand(cmd) {
1474
+ if (!this.worker?.stdin) {
1475
+ throw new Error("Worker not available");
1476
+ }
1477
+ this.worker.stdin.write(JSON.stringify(cmd) + "\n");
1478
+ }
1479
+ createPending(key, timeoutMs = 3e4) {
1480
+ return new Promise((resolve, reject) => {
1481
+ const timeout = setTimeout(() => {
1482
+ this.pending.delete(key);
1483
+ reject(new Error(`Operation ${key} timed out`));
1484
+ }, timeoutMs);
1485
+ this.pending.set(key, { resolve, reject, timeout });
1486
+ });
1487
+ }
1488
+ resolvePending(key, value) {
1489
+ const pending = this.pending.get(key);
1490
+ if (pending) {
1491
+ clearTimeout(pending.timeout);
1492
+ this.pending.delete(key);
1493
+ pending.resolve(value);
1494
+ }
1495
+ }
1496
+ /**
1497
+ * Wait for the worker to be ready
1498
+ */
1499
+ async waitForReady() {
1500
+ return this.readyPromise;
1501
+ }
1502
+ /**
1503
+ * Check if worker is ready
1504
+ */
1505
+ isReady() {
1506
+ return this.ready;
1507
+ }
1508
+ /**
1509
+ * Spawn a new PTY session
1510
+ */
1511
+ async spawn(config) {
1512
+ await this.waitForReady();
1513
+ const { id } = config;
1514
+ this.sendCommand({ cmd: "spawn", id, config });
1515
+ await this.createPending(`spawn:${id}`);
1516
+ return this.sessions.get(id);
1517
+ }
1518
+ /**
1519
+ * Send data to a session
1520
+ */
1521
+ async send(id, data) {
1522
+ await this.waitForReady();
1523
+ this.sendCommand({ cmd: "send", id, data });
1524
+ await this.createPending(`send:${id}`);
1525
+ }
1526
+ /**
1527
+ * Send special keys to a session
1528
+ */
1529
+ async sendKeys(id, keys) {
1530
+ await this.waitForReady();
1531
+ this.sendCommand({ cmd: "sendKeys", id, keys });
1532
+ await this.createPending(`sendKeys:${id}`);
1533
+ }
1534
+ /**
1535
+ * Paste text to a session
1536
+ */
1537
+ async paste(id, text, bracketed = true) {
1538
+ await this.waitForReady();
1539
+ this.sendCommand({ cmd: "paste", id, text, bracketed });
1540
+ await this.createPending(`paste:${id}`);
1541
+ }
1542
+ /**
1543
+ * Resize a session
1544
+ */
1545
+ async resize(id, cols, rows) {
1546
+ await this.waitForReady();
1547
+ this.sendCommand({ cmd: "resize", id, cols, rows });
1548
+ const session = this.sessions.get(id);
1549
+ if (session) {
1550
+ session.cols = cols;
1551
+ session.rows = rows;
1552
+ }
1553
+ await this.createPending(`resize:${id}`);
1554
+ }
1555
+ /**
1556
+ * Kill a session
1557
+ */
1558
+ async kill(id, signal) {
1559
+ await this.waitForReady();
1560
+ this.sendCommand({ cmd: "kill", id, signal });
1561
+ await this.createPending(`kill:${id}`);
1562
+ }
1563
+ /**
1564
+ * Get a session by ID
1565
+ */
1566
+ get(id) {
1567
+ return this.sessions.get(id);
1568
+ }
1569
+ /**
1570
+ * List all sessions
1571
+ */
1572
+ async list() {
1573
+ await this.waitForReady();
1574
+ this.sendCommand({ cmd: "list" });
1575
+ const sessions = await this.createPending("list");
1576
+ return sessions;
1577
+ }
1578
+ /**
1579
+ * Check if a session exists
1580
+ */
1581
+ has(id) {
1582
+ return this.sessions.has(id);
1583
+ }
1584
+ /**
1585
+ * Subscribe to output from a specific session
1586
+ */
1587
+ onSessionData(id, callback) {
1588
+ const handler = (data) => callback(data);
1589
+ this.on(`data:${id}`, handler);
1590
+ return () => this.off(`data:${id}`, handler);
1591
+ }
1592
+ /**
1593
+ * Shutdown the worker and all sessions
1594
+ */
1595
+ async shutdown() {
1596
+ if (!this.worker) return;
1597
+ this.sendCommand({ cmd: "shutdown" });
1598
+ await this.createPending("shutdown", 1e4).catch(() => {
1599
+ this.worker?.kill("SIGKILL");
1600
+ });
1601
+ }
1602
+ /**
1603
+ * Restart the worker process
1604
+ */
1605
+ async restart() {
1606
+ await this.shutdown();
1607
+ this.sessions.clear();
1608
+ this.ready = false;
1609
+ this.readyPromise = new Promise((resolve) => {
1610
+ this.readyResolve = resolve;
1611
+ });
1612
+ this.startWorker();
1613
+ await this.waitForReady();
1614
+ }
1615
+ };
1616
+ function isBun() {
1617
+ return typeof process !== "undefined" && "Bun" in process.versions;
1618
+ }
1619
+ function createPTYManager(options) {
1620
+ return new BunCompatiblePTYManager(options);
1621
+ }
1312
1622
  // Annotate the CommonJS export names for ESM import in node:
1313
1623
  0 && (module.exports = {
1314
1624
  AdapterRegistry,
1315
1625
  BaseCLIAdapter,
1626
+ BunCompatiblePTYManager,
1316
1627
  PTYManager,
1317
1628
  PTYSession,
1318
1629
  SPECIAL_KEYS,
1319
1630
  ShellAdapter,
1320
- createAdapter
1631
+ createAdapter,
1632
+ createPTYManager,
1633
+ isBun
1321
1634
  });
1322
1635
  //# sourceMappingURL=index.js.map