pty-manager 1.10.1 → 1.11.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/dist/index.d.mts CHANGED
@@ -1,32 +1,7 @@
1
- import { EventEmitter } from 'events';
2
1
  import * as adapter_types from 'adapter-types';
3
- import { SpawnConfig, CLIAdapter, AutoResponseRule, ToolRunningInfo, AdapterRegistry, LoginDetection, BlockingPromptDetection, ParsedOutput } from 'adapter-types';
2
+ import { CLIAdapter, AutoResponseRule, SpawnConfig, LoginDetection, BlockingPromptDetection, ParsedOutput, ToolRunningInfo, AdapterRegistry } from 'adapter-types';
4
3
  export { AdapterFactoryConfig, AdapterRegistry, AutoResponseRule, BaseCLIAdapter, BlockingPromptDetection, BlockingPromptType, CLIAdapter, LoginDetection, MessageType, ParsedOutput, SpawnConfig, ToolRunningInfo, createAdapter } from 'adapter-types';
5
-
6
- /**
7
- * Lazy runtime check for node-pty native addon.
8
- *
9
- * Called once before the first PTY spawn. Ensures the native binary is
10
- * loadable and spawn-helper permissions are correct.
11
- *
12
- * 1. Finds the binary — checks for prebuilt pty.node under
13
- * prebuilds/<platform>-<arch>/ (node-pty >=1.0), then falls back to
14
- * checking for a node-gyp compiled build/Release/pty.node
15
- * 2. Fixes spawn-helper permissions — bun install can strip execute
16
- * bits from the spawn-helper Mach-O binary, causing posix_spawnp
17
- * failed at runtime. The script chmod 755s all spawn-helpers under
18
- * prebuilds/
19
- * 3. Rebuilds if missing — if no binary is found at all, runs
20
- * node-gyp rebuild as a last resort (with a 2-minute timeout)
21
- */
22
- /**
23
- * Ensure node-pty is usable. Called once before first spawn.
24
- * Idempotent — subsequent calls are no-ops.
25
- *
26
- * @param log - logger function (defaults to console.log)
27
- * @throws Error if no native binary can be found or built
28
- */
29
- declare function ensurePty(log?: (msg: string) => void): void;
4
+ import { EventEmitter } from 'node:events';
30
5
 
31
6
  /**
32
7
  * Session lifecycle states
@@ -163,6 +138,269 @@ interface PTYManagerConfig {
163
138
  onStallClassify?: (sessionId: string, recentOutput: string, stallDurationMs: number) => Promise<StallClassification | null>;
164
139
  }
165
140
 
141
+ /**
142
+ * Shell Adapter
143
+ *
144
+ * Built-in adapter for bash/zsh shell sessions.
145
+ */
146
+
147
+ /**
148
+ * Options for the shell adapter
149
+ */
150
+ interface ShellAdapterOptions {
151
+ /** Shell to use (default: $SHELL or /bin/bash) */
152
+ shell?: string;
153
+ /** Custom prompt string (default: 'pty> ') */
154
+ prompt?: string;
155
+ }
156
+ /**
157
+ * Built-in adapter for shell sessions (bash/zsh)
158
+ */
159
+ declare class ShellAdapter implements CLIAdapter {
160
+ readonly adapterType = "shell";
161
+ readonly displayName = "Shell";
162
+ readonly autoResponseRules: AutoResponseRule[];
163
+ private shell;
164
+ private promptStr;
165
+ constructor(options?: ShellAdapterOptions);
166
+ getCommand(): string;
167
+ getArgs(_config: SpawnConfig): string[];
168
+ getEnv(_config: SpawnConfig): Record<string, string>;
169
+ detectLogin(_output: string): LoginDetection;
170
+ detectBlockingPrompt(_output: string): BlockingPromptDetection;
171
+ detectReady(output: string): boolean;
172
+ /**
173
+ * Detect shell continuation prompts that indicate the shell is NOT ready
174
+ * for a new command (e.g., unclosed quote, heredoc, backtick).
175
+ */
176
+ private isContinuationPrompt;
177
+ detectExit(output: string): {
178
+ exited: boolean;
179
+ code?: number;
180
+ error?: string;
181
+ };
182
+ parseOutput(output: string): ParsedOutput | null;
183
+ formatInput(message: string): string;
184
+ getPromptPattern(): RegExp;
185
+ validateInstallation(): Promise<{
186
+ installed: boolean;
187
+ version?: string;
188
+ error?: string;
189
+ }>;
190
+ private stripAnsi;
191
+ }
192
+
193
+ /**
194
+ * Bun-Compatible PTY Manager
195
+ *
196
+ * A wrapper that spawns a Node.js worker process to handle PTY operations,
197
+ * allowing pty-manager to work from Bun or other non-Node runtimes.
198
+ */
199
+
200
+ interface WorkerSessionHandle {
201
+ id: string;
202
+ name: string;
203
+ type: string;
204
+ status: SessionStatus;
205
+ pid: number | undefined;
206
+ cols: number;
207
+ rows: number;
208
+ startedAt?: Date;
209
+ lastActivityAt?: Date;
210
+ error?: string;
211
+ exitCode?: number;
212
+ }
213
+ interface BunPTYManagerOptions {
214
+ /** Path to node executable (default: 'node') */
215
+ nodePath?: string;
216
+ /** Path to worker script (default: auto-detected) */
217
+ workerPath?: string;
218
+ /** Environment variables for worker process */
219
+ env?: Record<string, string>;
220
+ /**
221
+ * Adapter modules to load in the worker process.
222
+ * Each module should export a `createAllAdapters()` function that returns an array of adapters.
223
+ * Example: ['coding-agent-adapters']
224
+ */
225
+ adapterModules?: string[];
226
+ /** Enable stall detection (default: false) */
227
+ stallDetectionEnabled?: boolean;
228
+ /** Default stall timeout in ms (default: 8000) */
229
+ stallTimeoutMs?: number;
230
+ /**
231
+ * External classification callback invoked when a stall is detected.
232
+ * The worker emits stall_detected; this callback runs on the parent side.
233
+ */
234
+ onStallClassify?: (sessionId: string, recentOutput: string, stallDurationMs: number) => Promise<StallClassification | null>;
235
+ }
236
+ /**
237
+ * PTY Manager that works with Bun and other non-Node runtimes
238
+ * by spawning a Node.js worker process.
239
+ */
240
+ declare class BunCompatiblePTYManager extends EventEmitter {
241
+ private worker;
242
+ private sessions;
243
+ private pending;
244
+ private ready;
245
+ private readyPromise;
246
+ private readyResolve;
247
+ private nodePath;
248
+ private workerPath;
249
+ private env;
250
+ private adapterModules;
251
+ private _stallDetectionEnabled;
252
+ private _stallTimeoutMs;
253
+ private _onStallClassify?;
254
+ constructor(options?: BunPTYManagerOptions);
255
+ private findWorkerPath;
256
+ private startWorker;
257
+ private handleWorkerMessage;
258
+ private sendCommand;
259
+ private createPending;
260
+ private resolvePending;
261
+ /**
262
+ * Wait for the worker to be ready
263
+ */
264
+ waitForReady(): Promise<void>;
265
+ /**
266
+ * Check if worker is ready
267
+ */
268
+ isReady(): boolean;
269
+ /**
270
+ * Spawn a new PTY session
271
+ */
272
+ spawn(config: SpawnConfig & {
273
+ id: string;
274
+ }): Promise<WorkerSessionHandle>;
275
+ /**
276
+ * Send data to a session
277
+ */
278
+ send(id: string, data: string): Promise<void>;
279
+ /**
280
+ * Send special keys to a session
281
+ */
282
+ sendKeys(id: string, keys: string | string[]): Promise<void>;
283
+ /**
284
+ * Notify a session of an external hook event (resets stall timer, updates status).
285
+ */
286
+ notifyHookEvent(id: string, hookEvent: string): Promise<void>;
287
+ /**
288
+ * Write raw data to a session (bypasses adapter formatting)
289
+ */
290
+ writeRaw(id: string, data: string): Promise<void>;
291
+ /**
292
+ * Paste text to a session
293
+ */
294
+ paste(id: string, text: string, bracketed?: boolean): Promise<void>;
295
+ /**
296
+ * Resize a session
297
+ */
298
+ resize(id: string, cols: number, rows: number): Promise<void>;
299
+ /**
300
+ * Kill a session
301
+ */
302
+ kill(id: string, signal?: string): Promise<void>;
303
+ /**
304
+ * Get a session by ID
305
+ */
306
+ get(id: string): WorkerSessionHandle | undefined;
307
+ /**
308
+ * List all sessions
309
+ */
310
+ list(): Promise<WorkerSessionHandle[]>;
311
+ /**
312
+ * Check if a session exists
313
+ */
314
+ has(id: string): boolean;
315
+ /**
316
+ * Whether the adapter currently classifies the session as actively
317
+ * processing work.
318
+ *
319
+ * This round-trips to the worker since the adapter lives in the
320
+ * worker process. Orchestrators (like milady's swarm idle watchdog)
321
+ * should consult this before assuming a session is idle based on
322
+ * output byte diffs — TUIs that redraw their status row in place
323
+ * (Codex's "Working… esc to interrupt") can fool a raw text diff
324
+ * even while the model is actively reasoning.
325
+ *
326
+ * Returns `false` for unknown sessions, adapters that don't
327
+ * implement `detectLoading`, or on IPC errors.
328
+ */
329
+ isSessionLoading(id: string): Promise<boolean>;
330
+ /**
331
+ * Subscribe to output from a specific session
332
+ */
333
+ onSessionData(id: string, callback: (data: string) => void): () => void;
334
+ private serializeRule;
335
+ /**
336
+ * Add an auto-response rule to a session.
337
+ * Session rules are checked before adapter rules.
338
+ */
339
+ addAutoResponseRule(sessionId: string, rule: AutoResponseRule): Promise<void>;
340
+ /**
341
+ * Remove an auto-response rule from a session by pattern.
342
+ * Returns true if a rule was removed.
343
+ */
344
+ removeAutoResponseRule(sessionId: string, pattern: RegExp): Promise<boolean>;
345
+ /**
346
+ * Set all auto-response rules for a session, replacing existing ones.
347
+ */
348
+ setAutoResponseRules(sessionId: string, rules: AutoResponseRule[]): Promise<void>;
349
+ /**
350
+ * Get all auto-response rules for a session.
351
+ */
352
+ getAutoResponseRules(sessionId: string): Promise<AutoResponseRule[]>;
353
+ /**
354
+ * Select a TUI menu option by index (0-based) in a session.
355
+ */
356
+ selectMenuOption(id: string, optionIndex: number): Promise<void>;
357
+ /**
358
+ * Clear all auto-response rules for a session.
359
+ */
360
+ clearAutoResponseRules(sessionId: string): Promise<void>;
361
+ /**
362
+ * Shutdown the worker and all sessions
363
+ */
364
+ shutdown(): Promise<void>;
365
+ /**
366
+ * Restart the worker process
367
+ */
368
+ restart(): Promise<void>;
369
+ }
370
+ /**
371
+ * Detect if running in Bun
372
+ */
373
+ declare function isBun(): boolean;
374
+ /**
375
+ * Create the appropriate PTY manager based on runtime
376
+ */
377
+ declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
378
+
379
+ /**
380
+ * Lazy runtime check for node-pty native addon.
381
+ *
382
+ * Called once before the first PTY spawn. Ensures the native binary is
383
+ * loadable and spawn-helper permissions are correct.
384
+ *
385
+ * 1. Finds the binary — checks for prebuilt pty.node under
386
+ * prebuilds/<platform>-<arch>/ (node-pty >=1.0), then falls back to
387
+ * checking for a node-gyp compiled build/Release/pty.node
388
+ * 2. Fixes spawn-helper permissions — bun install can strip execute
389
+ * bits from the spawn-helper Mach-O binary, causing posix_spawnp
390
+ * failed at runtime. The script chmod 755s all spawn-helpers under
391
+ * prebuilds/
392
+ * 3. Rebuilds if missing — if no binary is found at all, runs
393
+ * node-gyp rebuild as a last resort (with a 2-minute timeout)
394
+ */
395
+ /**
396
+ * Ensure node-pty is usable. Called once before first spawn.
397
+ * Idempotent — subsequent calls are no-ops.
398
+ *
399
+ * @param log - logger function (defaults to console.log)
400
+ * @throws Error if no native binary can be found or built
401
+ */
402
+ declare function ensurePty(log?: (msg: string) => void): void;
403
+
166
404
  /**
167
405
  * PTY Session
168
406
  *
@@ -203,6 +441,8 @@ declare class PTYSession extends EventEmitter {
203
441
  private sessionRules;
204
442
  private _firedOnceRules;
205
443
  private _lastBlockingPromptHash;
444
+ private _lastBlockingPromptEmitAt;
445
+ private static readonly BLOCKING_PROMPT_DEBOUNCE_MS;
206
446
  private _ruleOverrides;
207
447
  private _disabledRulePatterns;
208
448
  private _stallTimer;
@@ -311,6 +551,18 @@ declare class PTYSession extends EventEmitter {
311
551
  * signal before transitioning, so stale triggers are safe.
312
552
  */
313
553
  private scheduleTaskComplete;
554
+ /**
555
+ * Whether the adapter's `detectLoading()` currently classifies the
556
+ * session as actively processing work.
557
+ *
558
+ * This wraps `adapter.detectLoading(outputBuffer)` for consumers outside
559
+ * the PTY layer (e.g. milady's swarm idle watchdog) that need a
560
+ * reliable "is the agent busy right now?" signal without reimplementing
561
+ * heuristics over raw terminal output.
562
+ *
563
+ * Returns `false` if the adapter does not implement `detectLoading`.
564
+ */
565
+ isLoading(): boolean;
314
566
  /**
315
567
  * Adapter-level task completion check with compatibility fallback.
316
568
  * Prefer detectTaskComplete() because detectReady() may be broad for TUIs.
@@ -555,6 +807,18 @@ declare class PTYManager extends EventEmitter {
555
807
  * Get the underlying PTYSession (for advanced use)
556
808
  */
557
809
  getSession(sessionId: string): PTYSession | undefined;
810
+ /**
811
+ * Whether the adapter currently classifies the session as actively
812
+ * processing work (e.g. Codex's "esc to interrupt" status row).
813
+ *
814
+ * Orchestrators (like milady's swarm idle watchdog) should consult
815
+ * this before assuming a session is idle based on output byte diffs,
816
+ * which are fooled by TUIs that redraw the same status row in place.
817
+ *
818
+ * Returns `false` for unknown sessions or adapters that don't
819
+ * implement `detectLoading`.
820
+ */
821
+ isSessionLoading(sessionId: string): boolean;
558
822
  /**
559
823
  * Configure stall detection at runtime.
560
824
  * Affects newly spawned sessions only — existing sessions keep their config.
@@ -643,227 +907,4 @@ declare function extractTaskCompletionTraceRecords(entries: Array<string | Recor
643
907
  */
644
908
  declare function buildTaskCompletionTimeline(records: TaskCompletionTraceRecord[], options?: BuildTimelineOptions): TaskCompletionTimelineResult;
645
909
 
646
- /**
647
- * Shell Adapter
648
- *
649
- * Built-in adapter for bash/zsh shell sessions.
650
- */
651
-
652
- /**
653
- * Options for the shell adapter
654
- */
655
- interface ShellAdapterOptions {
656
- /** Shell to use (default: $SHELL or /bin/bash) */
657
- shell?: string;
658
- /** Custom prompt string (default: 'pty> ') */
659
- prompt?: string;
660
- }
661
- /**
662
- * Built-in adapter for shell sessions (bash/zsh)
663
- */
664
- declare class ShellAdapter implements CLIAdapter {
665
- readonly adapterType = "shell";
666
- readonly displayName = "Shell";
667
- readonly autoResponseRules: AutoResponseRule[];
668
- private shell;
669
- private promptStr;
670
- constructor(options?: ShellAdapterOptions);
671
- getCommand(): string;
672
- getArgs(_config: SpawnConfig): string[];
673
- getEnv(_config: SpawnConfig): Record<string, string>;
674
- detectLogin(_output: string): LoginDetection;
675
- detectBlockingPrompt(_output: string): BlockingPromptDetection;
676
- detectReady(output: string): boolean;
677
- /**
678
- * Detect shell continuation prompts that indicate the shell is NOT ready
679
- * for a new command (e.g., unclosed quote, heredoc, backtick).
680
- */
681
- private isContinuationPrompt;
682
- detectExit(output: string): {
683
- exited: boolean;
684
- code?: number;
685
- error?: string;
686
- };
687
- parseOutput(output: string): ParsedOutput | null;
688
- formatInput(message: string): string;
689
- getPromptPattern(): RegExp;
690
- validateInstallation(): Promise<{
691
- installed: boolean;
692
- version?: string;
693
- error?: string;
694
- }>;
695
- private stripAnsi;
696
- }
697
-
698
- /**
699
- * Bun-Compatible PTY Manager
700
- *
701
- * A wrapper that spawns a Node.js worker process to handle PTY operations,
702
- * allowing pty-manager to work from Bun or other non-Node runtimes.
703
- */
704
-
705
- interface WorkerSessionHandle {
706
- id: string;
707
- name: string;
708
- type: string;
709
- status: SessionStatus;
710
- pid: number | undefined;
711
- cols: number;
712
- rows: number;
713
- startedAt?: Date;
714
- lastActivityAt?: Date;
715
- error?: string;
716
- exitCode?: number;
717
- }
718
- interface BunPTYManagerOptions {
719
- /** Path to node executable (default: 'node') */
720
- nodePath?: string;
721
- /** Path to worker script (default: auto-detected) */
722
- workerPath?: string;
723
- /** Environment variables for worker process */
724
- env?: Record<string, string>;
725
- /**
726
- * Adapter modules to load in the worker process.
727
- * Each module should export a `createAllAdapters()` function that returns an array of adapters.
728
- * Example: ['coding-agent-adapters']
729
- */
730
- adapterModules?: string[];
731
- /** Enable stall detection (default: false) */
732
- stallDetectionEnabled?: boolean;
733
- /** Default stall timeout in ms (default: 8000) */
734
- stallTimeoutMs?: number;
735
- /**
736
- * External classification callback invoked when a stall is detected.
737
- * The worker emits stall_detected; this callback runs on the parent side.
738
- */
739
- onStallClassify?: (sessionId: string, recentOutput: string, stallDurationMs: number) => Promise<StallClassification | null>;
740
- }
741
- /**
742
- * PTY Manager that works with Bun and other non-Node runtimes
743
- * by spawning a Node.js worker process.
744
- */
745
- declare class BunCompatiblePTYManager extends EventEmitter {
746
- private worker;
747
- private sessions;
748
- private pending;
749
- private ready;
750
- private readyPromise;
751
- private readyResolve;
752
- private nodePath;
753
- private workerPath;
754
- private env;
755
- private adapterModules;
756
- private _stallDetectionEnabled;
757
- private _stallTimeoutMs;
758
- private _onStallClassify?;
759
- constructor(options?: BunPTYManagerOptions);
760
- private findWorkerPath;
761
- private startWorker;
762
- private handleWorkerMessage;
763
- private sendCommand;
764
- private createPending;
765
- private resolvePending;
766
- /**
767
- * Wait for the worker to be ready
768
- */
769
- waitForReady(): Promise<void>;
770
- /**
771
- * Check if worker is ready
772
- */
773
- isReady(): boolean;
774
- /**
775
- * Spawn a new PTY session
776
- */
777
- spawn(config: SpawnConfig & {
778
- id: string;
779
- }): Promise<WorkerSessionHandle>;
780
- /**
781
- * Send data to a session
782
- */
783
- send(id: string, data: string): Promise<void>;
784
- /**
785
- * Send special keys to a session
786
- */
787
- sendKeys(id: string, keys: string | string[]): Promise<void>;
788
- /**
789
- * Notify a session of an external hook event (resets stall timer, updates status).
790
- */
791
- notifyHookEvent(id: string, hookEvent: string): Promise<void>;
792
- /**
793
- * Write raw data to a session (bypasses adapter formatting)
794
- */
795
- writeRaw(id: string, data: string): Promise<void>;
796
- /**
797
- * Paste text to a session
798
- */
799
- paste(id: string, text: string, bracketed?: boolean): Promise<void>;
800
- /**
801
- * Resize a session
802
- */
803
- resize(id: string, cols: number, rows: number): Promise<void>;
804
- /**
805
- * Kill a session
806
- */
807
- kill(id: string, signal?: string): Promise<void>;
808
- /**
809
- * Get a session by ID
810
- */
811
- get(id: string): WorkerSessionHandle | undefined;
812
- /**
813
- * List all sessions
814
- */
815
- list(): Promise<WorkerSessionHandle[]>;
816
- /**
817
- * Check if a session exists
818
- */
819
- has(id: string): boolean;
820
- /**
821
- * Subscribe to output from a specific session
822
- */
823
- onSessionData(id: string, callback: (data: string) => void): () => void;
824
- private serializeRule;
825
- /**
826
- * Add an auto-response rule to a session.
827
- * Session rules are checked before adapter rules.
828
- */
829
- addAutoResponseRule(sessionId: string, rule: AutoResponseRule): Promise<void>;
830
- /**
831
- * Remove an auto-response rule from a session by pattern.
832
- * Returns true if a rule was removed.
833
- */
834
- removeAutoResponseRule(sessionId: string, pattern: RegExp): Promise<boolean>;
835
- /**
836
- * Set all auto-response rules for a session, replacing existing ones.
837
- */
838
- setAutoResponseRules(sessionId: string, rules: AutoResponseRule[]): Promise<void>;
839
- /**
840
- * Get all auto-response rules for a session.
841
- */
842
- getAutoResponseRules(sessionId: string): Promise<AutoResponseRule[]>;
843
- /**
844
- * Select a TUI menu option by index (0-based) in a session.
845
- */
846
- selectMenuOption(id: string, optionIndex: number): Promise<void>;
847
- /**
848
- * Clear all auto-response rules for a session.
849
- */
850
- clearAutoResponseRules(sessionId: string): Promise<void>;
851
- /**
852
- * Shutdown the worker and all sessions
853
- */
854
- shutdown(): Promise<void>;
855
- /**
856
- * Restart the worker process
857
- */
858
- restart(): Promise<void>;
859
- }
860
- /**
861
- * Detect if running in Bun
862
- */
863
- declare function isBun(): boolean;
864
- /**
865
- * Create the appropriate PTY manager based on runtime
866
- */
867
- declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
868
-
869
910
  export { type AuthRequiredInfo, type AuthRequiredMethod, type BlockingPromptInfo, type BuildTimelineOptions, BunCompatiblePTYManager, type BunPTYManagerOptions, type LogOptions, type Logger, PTYManager, type PTYManagerConfig, type PTYManagerEvents, PTYSession, type PTYSessionEvents, SPECIAL_KEYS, type SessionFilter, type SessionHandle, type SessionMessage, type SessionStatus, ShellAdapter, type ShellAdapterOptions, type StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createPTYManager, ensurePty, extractTaskCompletionTraceRecords, isBun };