pty-manager 1.3.3 → 1.5.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.
@@ -330,6 +330,9 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
330
330
  // Task completion detection (idle detection when busy)
331
331
  _taskCompleteTimer = null;
332
332
  static TASK_COMPLETE_DEBOUNCE_MS = 1500;
333
+ // Ready detection settle delay — defers session_ready until output goes quiet
334
+ _readySettleTimer = null;
335
+ _readySettlePending = false;
333
336
  // Deferred output processing — prevents node-pty's synchronous data
334
337
  // delivery from starving the event loop (timers, I/O callbacks, etc.)
335
338
  _processScheduled = false;
@@ -621,6 +624,45 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
621
624
  }
622
625
  }
623
626
  // ─────────────────────────────────────────────────────────────────────────────
627
+ // Ready Detection Settle Delay
628
+ // ─────────────────────────────────────────────────────────────────────────────
629
+ /**
630
+ * Schedule or reset the ready-settle timer.
631
+ * Defers emitting session_ready until output goes quiet for readySettleMs
632
+ * after detectReady first matches. This prevents sending input while
633
+ * TUI agents are still rendering (status bar, shortcuts, update notices).
634
+ */
635
+ scheduleReadySettle() {
636
+ this._readySettlePending = true;
637
+ if (this._readySettleTimer) {
638
+ clearTimeout(this._readySettleTimer);
639
+ }
640
+ const settleMs = this.adapter.readySettleMs ?? 100;
641
+ this._readySettleTimer = setTimeout(() => {
642
+ this._readySettleTimer = null;
643
+ this._readySettlePending = false;
644
+ if (this._status !== "starting" && this._status !== "authenticating") return;
645
+ if (!this.adapter.detectReady(this.outputBuffer)) return;
646
+ this._status = "ready";
647
+ this._lastBlockingPromptHash = null;
648
+ this.outputBuffer = "";
649
+ this.clearStallTimer();
650
+ this.emit("ready");
651
+ this.logger.info({ sessionId: this.id }, "Session ready (after settle)");
652
+ }, settleMs);
653
+ }
654
+ /**
655
+ * Cancel a pending ready-settle timer (ready indicator disappeared
656
+ * or session status changed).
657
+ */
658
+ cancelReadySettle() {
659
+ if (this._readySettleTimer) {
660
+ clearTimeout(this._readySettleTimer);
661
+ this._readySettleTimer = null;
662
+ }
663
+ this._readySettlePending = false;
664
+ }
665
+ // ─────────────────────────────────────────────────────────────────────────────
624
666
  // Lifecycle
625
667
  // ─────────────────────────────────────────────────────────────────────────────
626
668
  /**
@@ -709,13 +751,16 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
709
751
  if (this._status === "busy" || this._status === "authenticating") {
710
752
  this.resetStallTimer();
711
753
  }
754
+ if (this._readySettlePending) {
755
+ if ((this._status === "starting" || this._status === "authenticating") && this.adapter.detectReady(this.outputBuffer)) {
756
+ this.scheduleReadySettle();
757
+ } else {
758
+ this.cancelReadySettle();
759
+ }
760
+ return;
761
+ }
712
762
  if ((this._status === "starting" || this._status === "authenticating") && this.adapter.detectReady(this.outputBuffer)) {
713
- this._status = "ready";
714
- this._lastBlockingPromptHash = null;
715
- this.outputBuffer = "";
716
- this.clearStallTimer();
717
- this.emit("ready");
718
- this.logger.info({ sessionId: this.id }, "Session ready");
763
+ this.scheduleReadySettle();
719
764
  return;
720
765
  }
721
766
  if (this._status === "busy" && this.adapter.detectReady(this.outputBuffer)) {
@@ -1051,6 +1096,7 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
1051
1096
  this._status = "stopping";
1052
1097
  this.clearStallTimer();
1053
1098
  this.cancelTaskComplete();
1099
+ this.cancelReadySettle();
1054
1100
  this.ptyProcess.kill(signal);
1055
1101
  this.logger.info({ sessionId: this.id, signal }, "Killing PTY session");
1056
1102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pty-manager",
3
- "version": "1.3.3",
3
+ "version": "1.5.0",
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",