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.
package/dist/index.mjs CHANGED
@@ -309,6 +309,9 @@ var PTYSession = class _PTYSession extends EventEmitter {
309
309
  // Task completion detection (idle detection when busy)
310
310
  _taskCompleteTimer = null;
311
311
  static TASK_COMPLETE_DEBOUNCE_MS = 1500;
312
+ // Ready detection settle delay — defers session_ready until output goes quiet
313
+ _readySettleTimer = null;
314
+ _readySettlePending = false;
312
315
  // Deferred output processing — prevents node-pty's synchronous data
313
316
  // delivery from starving the event loop (timers, I/O callbacks, etc.)
314
317
  _processScheduled = false;
@@ -600,6 +603,45 @@ var PTYSession = class _PTYSession extends EventEmitter {
600
603
  }
601
604
  }
602
605
  // ─────────────────────────────────────────────────────────────────────────────
606
+ // Ready Detection Settle Delay
607
+ // ─────────────────────────────────────────────────────────────────────────────
608
+ /**
609
+ * Schedule or reset the ready-settle timer.
610
+ * Defers emitting session_ready until output goes quiet for readySettleMs
611
+ * after detectReady first matches. This prevents sending input while
612
+ * TUI agents are still rendering (status bar, shortcuts, update notices).
613
+ */
614
+ scheduleReadySettle() {
615
+ this._readySettlePending = true;
616
+ if (this._readySettleTimer) {
617
+ clearTimeout(this._readySettleTimer);
618
+ }
619
+ const settleMs = this.adapter.readySettleMs ?? 100;
620
+ this._readySettleTimer = setTimeout(() => {
621
+ this._readySettleTimer = null;
622
+ this._readySettlePending = false;
623
+ if (this._status !== "starting" && this._status !== "authenticating") return;
624
+ if (!this.adapter.detectReady(this.outputBuffer)) return;
625
+ this._status = "ready";
626
+ this._lastBlockingPromptHash = null;
627
+ this.outputBuffer = "";
628
+ this.clearStallTimer();
629
+ this.emit("ready");
630
+ this.logger.info({ sessionId: this.id }, "Session ready (after settle)");
631
+ }, settleMs);
632
+ }
633
+ /**
634
+ * Cancel a pending ready-settle timer (ready indicator disappeared
635
+ * or session status changed).
636
+ */
637
+ cancelReadySettle() {
638
+ if (this._readySettleTimer) {
639
+ clearTimeout(this._readySettleTimer);
640
+ this._readySettleTimer = null;
641
+ }
642
+ this._readySettlePending = false;
643
+ }
644
+ // ─────────────────────────────────────────────────────────────────────────────
603
645
  // Lifecycle
604
646
  // ─────────────────────────────────────────────────────────────────────────────
605
647
  /**
@@ -688,13 +730,16 @@ var PTYSession = class _PTYSession extends EventEmitter {
688
730
  if (this._status === "busy" || this._status === "authenticating") {
689
731
  this.resetStallTimer();
690
732
  }
733
+ if (this._readySettlePending) {
734
+ if ((this._status === "starting" || this._status === "authenticating") && this.adapter.detectReady(this.outputBuffer)) {
735
+ this.scheduleReadySettle();
736
+ } else {
737
+ this.cancelReadySettle();
738
+ }
739
+ return;
740
+ }
691
741
  if ((this._status === "starting" || this._status === "authenticating") && this.adapter.detectReady(this.outputBuffer)) {
692
- this._status = "ready";
693
- this._lastBlockingPromptHash = null;
694
- this.outputBuffer = "";
695
- this.clearStallTimer();
696
- this.emit("ready");
697
- this.logger.info({ sessionId: this.id }, "Session ready");
742
+ this.scheduleReadySettle();
698
743
  return;
699
744
  }
700
745
  if (this._status === "busy" && this.adapter.detectReady(this.outputBuffer)) {
@@ -1030,6 +1075,7 @@ var PTYSession = class _PTYSession extends EventEmitter {
1030
1075
  this._status = "stopping";
1031
1076
  this.clearStallTimer();
1032
1077
  this.cancelTaskComplete();
1078
+ this.cancelReadySettle();
1033
1079
  this.ptyProcess.kill(signal);
1034
1080
  this.logger.info({ sessionId: this.id, signal }, "Killing PTY session");
1035
1081
  }