pty-manager 1.3.1 → 1.3.2
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 +3 -1
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +64 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +64 -41
- package/dist/index.mjs.map +1 -1
- package/dist/pty-worker.js +64 -41
- package/package.json +1 -1
package/dist/pty-worker.js
CHANGED
|
@@ -330,6 +330,12 @@ 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
|
+
// Deferred output processing — prevents node-pty's synchronous data
|
|
334
|
+
// delivery from starving the event loop (timers, I/O callbacks, etc.)
|
|
335
|
+
_processScheduled = false;
|
|
336
|
+
// Output buffer cap — prevents unbounded growth during long tasks
|
|
337
|
+
static MAX_OUTPUT_BUFFER = 1e5;
|
|
338
|
+
// 100 KB
|
|
333
339
|
id;
|
|
334
340
|
config;
|
|
335
341
|
get status() {
|
|
@@ -672,49 +678,16 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
|
|
|
672
678
|
this.ptyProcess.onData((data) => {
|
|
673
679
|
this._lastActivityAt = /* @__PURE__ */ new Date();
|
|
674
680
|
this.outputBuffer += data;
|
|
675
|
-
if (this.
|
|
676
|
-
this.
|
|
681
|
+
if (this.outputBuffer.length > _PTYSession.MAX_OUTPUT_BUFFER) {
|
|
682
|
+
this.outputBuffer = this.outputBuffer.slice(-_PTYSession.MAX_OUTPUT_BUFFER);
|
|
677
683
|
}
|
|
678
684
|
this.emit("output", data);
|
|
679
|
-
if (
|
|
680
|
-
this.
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
this.logger.info({ sessionId: this.id }, "Session ready");
|
|
686
|
-
return;
|
|
687
|
-
}
|
|
688
|
-
if (this._status === "busy" && this.adapter.detectReady(this.outputBuffer)) {
|
|
689
|
-
this.scheduleTaskComplete();
|
|
690
|
-
} else {
|
|
691
|
-
this.cancelTaskComplete();
|
|
692
|
-
}
|
|
693
|
-
const blockingPrompt = this.detectAndHandleBlockingPrompt();
|
|
694
|
-
if (blockingPrompt) {
|
|
695
|
-
return;
|
|
696
|
-
}
|
|
697
|
-
if (this._status !== "ready" && this._status !== "busy") {
|
|
698
|
-
const loginDetection = this.adapter.detectLogin(this.outputBuffer);
|
|
699
|
-
if (loginDetection.required && this._status !== "authenticating") {
|
|
700
|
-
this._status = "authenticating";
|
|
701
|
-
this.clearStallTimer();
|
|
702
|
-
this.emit("login_required", loginDetection.instructions, loginDetection.url);
|
|
703
|
-
this.logger.warn(
|
|
704
|
-
{ sessionId: this.id, loginType: loginDetection.type },
|
|
705
|
-
"Login required"
|
|
706
|
-
);
|
|
707
|
-
return;
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
const exitDetection = this.adapter.detectExit(this.outputBuffer);
|
|
711
|
-
if (exitDetection.exited) {
|
|
712
|
-
this._status = "stopped";
|
|
713
|
-
this.clearStallTimer();
|
|
714
|
-
this.emit("exit", exitDetection.code || 0);
|
|
715
|
-
}
|
|
716
|
-
if (this._status !== "starting" && this._status !== "authenticating") {
|
|
717
|
-
this.tryParseOutput();
|
|
685
|
+
if (!this._processScheduled) {
|
|
686
|
+
this._processScheduled = true;
|
|
687
|
+
setImmediate(() => {
|
|
688
|
+
this._processScheduled = false;
|
|
689
|
+
this.processOutputBuffer();
|
|
690
|
+
});
|
|
718
691
|
}
|
|
719
692
|
});
|
|
720
693
|
this.ptyProcess.onExit(({ exitCode, signal }) => {
|
|
@@ -727,6 +700,56 @@ var PTYSession = class _PTYSession extends import_events.EventEmitter {
|
|
|
727
700
|
this.emit("exit", exitCode);
|
|
728
701
|
});
|
|
729
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* Process the accumulated output buffer.
|
|
705
|
+
* Called via setImmediate() from the onData handler so that heavy regex
|
|
706
|
+
* work runs in its own event-loop tick, not inside node-pty's native callback.
|
|
707
|
+
*/
|
|
708
|
+
processOutputBuffer() {
|
|
709
|
+
if (this._status === "busy" || this._status === "authenticating") {
|
|
710
|
+
this.resetStallTimer();
|
|
711
|
+
}
|
|
712
|
+
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");
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
if (this._status === "busy" && this.adapter.detectReady(this.outputBuffer)) {
|
|
722
|
+
this.scheduleTaskComplete();
|
|
723
|
+
} else {
|
|
724
|
+
this.cancelTaskComplete();
|
|
725
|
+
}
|
|
726
|
+
const blockingPrompt = this.detectAndHandleBlockingPrompt();
|
|
727
|
+
if (blockingPrompt) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
if (this._status !== "ready" && this._status !== "busy") {
|
|
731
|
+
const loginDetection = this.adapter.detectLogin(this.outputBuffer);
|
|
732
|
+
if (loginDetection.required && this._status !== "authenticating") {
|
|
733
|
+
this._status = "authenticating";
|
|
734
|
+
this.clearStallTimer();
|
|
735
|
+
this.emit("login_required", loginDetection.instructions, loginDetection.url);
|
|
736
|
+
this.logger.warn(
|
|
737
|
+
{ sessionId: this.id, loginType: loginDetection.type },
|
|
738
|
+
"Login required"
|
|
739
|
+
);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
const exitDetection = this.adapter.detectExit(this.outputBuffer);
|
|
744
|
+
if (exitDetection.exited) {
|
|
745
|
+
this._status = "stopped";
|
|
746
|
+
this.clearStallTimer();
|
|
747
|
+
this.emit("exit", exitDetection.code || 0);
|
|
748
|
+
}
|
|
749
|
+
if (this._status !== "starting" && this._status !== "authenticating") {
|
|
750
|
+
this.tryParseOutput();
|
|
751
|
+
}
|
|
752
|
+
}
|
|
730
753
|
/**
|
|
731
754
|
* Detect blocking prompts and handle them with auto-responses or user notification.
|
|
732
755
|
* Deduplicates emissions - won't re-emit the same blocking prompt repeatedly.
|
package/package.json
CHANGED