pty-manager 1.8.0 → 1.9.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
@@ -188,6 +188,17 @@ interface StallClassification {
188
188
  /** Suggested response to send (for waiting_for_input with auto-respond) */
189
189
  suggestedResponse?: string;
190
190
  }
191
+ /**
192
+ * Information about an external tool/process running within a session.
193
+ * Emitted when the adapter detects a tool is actively executing (e.g. browser,
194
+ * bash command, Node process). Suppresses stall detection while active.
195
+ */
196
+ interface ToolRunningInfo {
197
+ /** Name of the tool (e.g. "Chrome", "bash", "node", "python") */
198
+ toolName: string;
199
+ /** Optional description of what the tool is doing */
200
+ description?: string;
201
+ }
191
202
  /**
192
203
  * Logger interface (bring your own logger)
193
204
  */
@@ -387,6 +398,17 @@ interface CLIAdapter {
387
398
  * "Reading N files", "Waiting for LLM", etc.
388
399
  */
389
400
  detectLoading?(output: string): boolean;
401
+ /**
402
+ * Optional: Detect if an external tool/process is currently running within
403
+ * the session (e.g. browser, bash command, Node server, Python script).
404
+ *
405
+ * When a tool is detected, stall detection is suppressed (the agent is
406
+ * working, just through an external process) and a `tool_running` event
407
+ * is emitted so the UI can display the active tool.
408
+ *
409
+ * Return null when no tool is detected.
410
+ */
411
+ detectToolRunning?(output: string): ToolRunningInfo | null;
390
412
  /**
391
413
  * Optional: Get health check command
392
414
  */
@@ -453,6 +475,7 @@ interface PTYSessionEvents {
453
475
  stall_detected: (recentOutput: string, stallDurationMs: number) => void;
454
476
  status_changed: (status: SessionStatus) => void;
455
477
  task_complete: () => void;
478
+ tool_running: (info: ToolRunningInfo) => void;
456
479
  }
457
480
  /**
458
481
  * Special key mappings to escape sequences
@@ -490,6 +513,7 @@ declare class PTYSession extends EventEmitter {
490
513
  private static readonly TASK_COMPLETE_DEBOUNCE_MS;
491
514
  private _readySettleTimer;
492
515
  private _readySettlePending;
516
+ private _lastToolRunningName;
493
517
  private _processScheduled;
494
518
  private static readonly MAX_OUTPUT_BUFFER;
495
519
  readonly id: string;
@@ -737,6 +761,7 @@ interface PTYManagerEvents {
737
761
  stall_detected: (session: SessionHandle, recentOutput: string, stallDurationMs: number) => void;
738
762
  session_status_changed: (session: SessionHandle) => void;
739
763
  task_complete: (session: SessionHandle) => void;
764
+ tool_running: (session: SessionHandle, info: ToolRunningInfo) => void;
740
765
  }
741
766
  declare class PTYManager extends EventEmitter {
742
767
  private sessions;
@@ -1199,4 +1224,4 @@ declare function isBun(): boolean;
1199
1224
  */
1200
1225
  declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
1201
1226
 
1202
- export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, 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 StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
1227
+ export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, 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 StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type ToolRunningInfo, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
package/dist/index.d.ts CHANGED
@@ -188,6 +188,17 @@ interface StallClassification {
188
188
  /** Suggested response to send (for waiting_for_input with auto-respond) */
189
189
  suggestedResponse?: string;
190
190
  }
191
+ /**
192
+ * Information about an external tool/process running within a session.
193
+ * Emitted when the adapter detects a tool is actively executing (e.g. browser,
194
+ * bash command, Node process). Suppresses stall detection while active.
195
+ */
196
+ interface ToolRunningInfo {
197
+ /** Name of the tool (e.g. "Chrome", "bash", "node", "python") */
198
+ toolName: string;
199
+ /** Optional description of what the tool is doing */
200
+ description?: string;
201
+ }
191
202
  /**
192
203
  * Logger interface (bring your own logger)
193
204
  */
@@ -387,6 +398,17 @@ interface CLIAdapter {
387
398
  * "Reading N files", "Waiting for LLM", etc.
388
399
  */
389
400
  detectLoading?(output: string): boolean;
401
+ /**
402
+ * Optional: Detect if an external tool/process is currently running within
403
+ * the session (e.g. browser, bash command, Node server, Python script).
404
+ *
405
+ * When a tool is detected, stall detection is suppressed (the agent is
406
+ * working, just through an external process) and a `tool_running` event
407
+ * is emitted so the UI can display the active tool.
408
+ *
409
+ * Return null when no tool is detected.
410
+ */
411
+ detectToolRunning?(output: string): ToolRunningInfo | null;
390
412
  /**
391
413
  * Optional: Get health check command
392
414
  */
@@ -453,6 +475,7 @@ interface PTYSessionEvents {
453
475
  stall_detected: (recentOutput: string, stallDurationMs: number) => void;
454
476
  status_changed: (status: SessionStatus) => void;
455
477
  task_complete: () => void;
478
+ tool_running: (info: ToolRunningInfo) => void;
456
479
  }
457
480
  /**
458
481
  * Special key mappings to escape sequences
@@ -490,6 +513,7 @@ declare class PTYSession extends EventEmitter {
490
513
  private static readonly TASK_COMPLETE_DEBOUNCE_MS;
491
514
  private _readySettleTimer;
492
515
  private _readySettlePending;
516
+ private _lastToolRunningName;
493
517
  private _processScheduled;
494
518
  private static readonly MAX_OUTPUT_BUFFER;
495
519
  readonly id: string;
@@ -737,6 +761,7 @@ interface PTYManagerEvents {
737
761
  stall_detected: (session: SessionHandle, recentOutput: string, stallDurationMs: number) => void;
738
762
  session_status_changed: (session: SessionHandle) => void;
739
763
  task_complete: (session: SessionHandle) => void;
764
+ tool_running: (session: SessionHandle, info: ToolRunningInfo) => void;
740
765
  }
741
766
  declare class PTYManager extends EventEmitter {
742
767
  private sessions;
@@ -1199,4 +1224,4 @@ declare function isBun(): boolean;
1199
1224
  */
1200
1225
  declare function createPTYManager(options?: BunPTYManagerOptions): BunCompatiblePTYManager;
1201
1226
 
1202
- export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, 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 StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
1227
+ export { type AdapterFactoryConfig, AdapterRegistry, type AuthRequiredInfo, type AuthRequiredMethod, type AutoResponseRule, BaseCLIAdapter, type BlockingPromptDetection, type BlockingPromptInfo, type BlockingPromptType, type BuildTimelineOptions, 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 StallClassification, type StopOptions, type TaskCompletionTimelineResult, type TaskCompletionTimelineStep, type TaskCompletionTraceRecord, type TaskCompletionTurnTimeline, type TerminalAttachment, type ToolRunningInfo, type WorkerSessionHandle, buildTaskCompletionTimeline, createAdapter, createPTYManager, extractTaskCompletionTraceRecords, isBun };
package/dist/index.js CHANGED
@@ -364,6 +364,8 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
364
364
  // Ready detection settle delay — defers session_ready until output goes quiet
365
365
  _readySettleTimer = null;
366
366
  _readySettlePending = false;
367
+ // Tool running deduplication — only emit when tool changes
368
+ _lastToolRunningName = null;
367
369
  // Deferred output processing — prevents node-pty's synchronous data
368
370
  // delivery from starving the event loop (timers, I/O callbacks, etc.)
369
371
  _processScheduled = false;
@@ -529,6 +531,22 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
529
531
  this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);
530
532
  return;
531
533
  }
534
+ const toolInfo = this.adapter.detectToolRunning?.(this.outputBuffer);
535
+ if (toolInfo) {
536
+ if (toolInfo.toolName !== this._lastToolRunningName) {
537
+ this._lastToolRunningName = toolInfo.toolName;
538
+ this.emit("tool_running", toolInfo);
539
+ }
540
+ this.logger.debug(
541
+ { sessionId: this.id, tool: toolInfo.toolName },
542
+ "Tool running \u2014 suppressing stall emission"
543
+ );
544
+ this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallBackoffMs);
545
+ return;
546
+ }
547
+ if (this._lastToolRunningName) {
548
+ this._lastToolRunningName = null;
549
+ }
532
550
  const tail = this.outputBuffer.slice(-500);
533
551
  const hash = this.simpleHash(tail);
534
552
  if (hash === this._lastStallHash) {
@@ -967,6 +985,17 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
967
985
  this.scheduleReadySettle();
968
986
  return;
969
987
  }
988
+ if (this._status === "busy") {
989
+ const toolInfo = this.adapter.detectToolRunning?.(this.outputBuffer);
990
+ if (toolInfo) {
991
+ if (toolInfo.toolName !== this._lastToolRunningName) {
992
+ this._lastToolRunningName = toolInfo.toolName;
993
+ this.emit("tool_running", toolInfo);
994
+ }
995
+ } else if (this._lastToolRunningName) {
996
+ this._lastToolRunningName = null;
997
+ }
998
+ }
970
999
  if (this._status === "busy") {
971
1000
  const signal = this.isTaskCompleteSignal(this.outputBuffer);
972
1001
  if (this._taskCompletePending || signal) {
@@ -1498,6 +1527,9 @@ var PTYManager = class extends import_events2.EventEmitter {
1498
1527
  session.on("task_complete", () => {
1499
1528
  this.emit("task_complete", session.toHandle());
1500
1529
  });
1530
+ session.on("tool_running", (info) => {
1531
+ this.emit("tool_running", session.toHandle(), info);
1532
+ });
1501
1533
  session.on("stall_detected", (recentOutput, stallDurationMs) => {
1502
1534
  const handle = session.toHandle();
1503
1535
  this.emit("stall_detected", handle, recentOutput, stallDurationMs);
@@ -2576,6 +2608,13 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
2576
2608
  }
2577
2609
  break;
2578
2610
  }
2611
+ case "tool_running": {
2612
+ const session = this.sessions.get(id);
2613
+ if (session) {
2614
+ this.emit("tool_running", session, event.info);
2615
+ }
2616
+ break;
2617
+ }
2579
2618
  case "stall_detected": {
2580
2619
  const session = this.sessions.get(id);
2581
2620
  if (session) {