pty-manager 1.2.14 → 1.2.16
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 +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +75 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +75 -12
- package/dist/index.mjs.map +1 -1
- package/dist/pty-worker.js +77 -12
- package/package.json +13 -14
package/dist/index.mjs
CHANGED
|
@@ -378,11 +378,11 @@ var PTYSession = class extends EventEmitter {
|
|
|
378
378
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
379
379
|
/**
|
|
380
380
|
* Start or reset the stall detection timer.
|
|
381
|
-
*
|
|
381
|
+
* Active when status is "busy" or "authenticating" and stall detection is enabled.
|
|
382
382
|
*/
|
|
383
383
|
resetStallTimer() {
|
|
384
384
|
this.clearStallTimer();
|
|
385
|
-
if (!this._stallDetectionEnabled || this._status !== "busy") {
|
|
385
|
+
if (!this._stallDetectionEnabled || this._status !== "busy" && this._status !== "authenticating") {
|
|
386
386
|
return;
|
|
387
387
|
}
|
|
388
388
|
this._stallStartedAt = Date.now();
|
|
@@ -405,7 +405,7 @@ var PTYSession = class extends EventEmitter {
|
|
|
405
405
|
* Called when the stall timer fires (no output for stallTimeoutMs).
|
|
406
406
|
*/
|
|
407
407
|
onStallTimerFired() {
|
|
408
|
-
if (this._status !== "busy") {
|
|
408
|
+
if (this._status !== "busy" && this._status !== "authenticating") {
|
|
409
409
|
return;
|
|
410
410
|
}
|
|
411
411
|
const tail = this.outputBuffer.slice(-500);
|
|
@@ -425,6 +425,12 @@ var PTYSession = class extends EventEmitter {
|
|
|
425
425
|
this.emit("stall_detected", recentOutput, stallDurationMs);
|
|
426
426
|
this._stallTimer = setTimeout(() => this.onStallTimerFired(), this._stallTimeoutMs);
|
|
427
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Promise-based delay helper.
|
|
430
|
+
*/
|
|
431
|
+
delay(ms) {
|
|
432
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
433
|
+
}
|
|
428
434
|
/**
|
|
429
435
|
* Simple string hash for deduplication.
|
|
430
436
|
*/
|
|
@@ -450,7 +456,7 @@ var PTYSession = class extends EventEmitter {
|
|
|
450
456
|
* Called by the manager after onStallClassify resolves.
|
|
451
457
|
*/
|
|
452
458
|
handleStallClassification(classification) {
|
|
453
|
-
if (this._status !== "busy") {
|
|
459
|
+
if (this._status !== "busy" && this._status !== "authenticating") {
|
|
454
460
|
return;
|
|
455
461
|
}
|
|
456
462
|
if (!classification || classification.state === "still_working") {
|
|
@@ -469,7 +475,13 @@ var PTYSession = class extends EventEmitter {
|
|
|
469
475
|
{ sessionId: this.id, response: classification.suggestedResponse },
|
|
470
476
|
"Auto-responding to stall-classified prompt"
|
|
471
477
|
);
|
|
472
|
-
|
|
478
|
+
const resp = classification.suggestedResponse;
|
|
479
|
+
if (resp.startsWith("keys:")) {
|
|
480
|
+
const keys = resp.slice(5).split(",").map((k) => k.trim());
|
|
481
|
+
this.sendKeySequence(keys);
|
|
482
|
+
} else {
|
|
483
|
+
this.writeRaw(resp + "\r");
|
|
484
|
+
}
|
|
473
485
|
this.emit("blocking_prompt", promptInfo, true);
|
|
474
486
|
} else {
|
|
475
487
|
this.emit("blocking_prompt", promptInfo, false);
|
|
@@ -548,10 +560,14 @@ var PTYSession = class extends EventEmitter {
|
|
|
548
560
|
this.ptyProcess.onData((data) => {
|
|
549
561
|
this._lastActivityAt = /* @__PURE__ */ new Date();
|
|
550
562
|
this.outputBuffer += data;
|
|
551
|
-
if (this._status === "busy") {
|
|
563
|
+
if (this._status === "busy" || this._status === "authenticating") {
|
|
552
564
|
this.resetStallTimer();
|
|
553
565
|
}
|
|
554
566
|
this.emit("output", data);
|
|
567
|
+
const blockingPrompt = this.detectAndHandleBlockingPrompt();
|
|
568
|
+
if (blockingPrompt) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
555
571
|
if ((this._status === "starting" || this._status === "authenticating") && this.adapter.detectReady(this.outputBuffer)) {
|
|
556
572
|
this._status = "ready";
|
|
557
573
|
this._lastBlockingPromptHash = null;
|
|
@@ -561,10 +577,6 @@ var PTYSession = class extends EventEmitter {
|
|
|
561
577
|
this.logger.info({ sessionId: this.id }, "Session ready");
|
|
562
578
|
return;
|
|
563
579
|
}
|
|
564
|
-
const blockingPrompt = this.detectAndHandleBlockingPrompt();
|
|
565
|
-
if (blockingPrompt) {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
580
|
if (this._status !== "ready" && this._status !== "busy") {
|
|
569
581
|
const loginDetection = this.adapter.detectLogin(this.outputBuffer);
|
|
570
582
|
if (loginDetection.required && this._status !== "authenticating") {
|
|
@@ -632,7 +644,13 @@ var PTYSession = class extends EventEmitter {
|
|
|
632
644
|
},
|
|
633
645
|
"Auto-responding to blocking prompt"
|
|
634
646
|
);
|
|
635
|
-
|
|
647
|
+
const resp = detection.suggestedResponse;
|
|
648
|
+
if (resp.startsWith("keys:")) {
|
|
649
|
+
const keys = resp.slice(5).split(",").map((k) => k.trim());
|
|
650
|
+
this.sendKeySequence(keys);
|
|
651
|
+
} else {
|
|
652
|
+
this.writeRaw(resp + "\r");
|
|
653
|
+
}
|
|
636
654
|
this._lastBlockingPromptHash = null;
|
|
637
655
|
this.emit("blocking_prompt", promptInfo, true);
|
|
638
656
|
return true;
|
|
@@ -684,7 +702,15 @@ var PTYSession = class extends EventEmitter {
|
|
|
684
702
|
},
|
|
685
703
|
"Applying auto-response rule"
|
|
686
704
|
);
|
|
687
|
-
|
|
705
|
+
const useKeys = rule.keys && rule.keys.length > 0;
|
|
706
|
+
const isTuiDefault = !rule.responseType && !rule.keys && this.adapter.usesTuiMenus;
|
|
707
|
+
if (useKeys) {
|
|
708
|
+
this.sendKeySequence(rule.keys);
|
|
709
|
+
} else if (isTuiDefault) {
|
|
710
|
+
this.sendKeys("enter");
|
|
711
|
+
} else {
|
|
712
|
+
this.writeRaw(rule.response + "\r");
|
|
713
|
+
}
|
|
688
714
|
this.outputBuffer = this.outputBuffer.replace(rule.pattern, "");
|
|
689
715
|
const promptInfo = {
|
|
690
716
|
type: rule.type,
|
|
@@ -814,6 +840,26 @@ var PTYSession = class extends EventEmitter {
|
|
|
814
840
|
}
|
|
815
841
|
}
|
|
816
842
|
}
|
|
843
|
+
/**
|
|
844
|
+
* Select a TUI menu option by index (0-based).
|
|
845
|
+
* Sends Down arrow `optionIndex` times, then Enter, with 50ms delays.
|
|
846
|
+
*/
|
|
847
|
+
async selectMenuOption(optionIndex) {
|
|
848
|
+
for (let i = 0; i < optionIndex; i++) {
|
|
849
|
+
this.sendKeys("down");
|
|
850
|
+
await this.delay(50);
|
|
851
|
+
}
|
|
852
|
+
this.sendKeys("enter");
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Send a sequence of keys with staggered timing.
|
|
856
|
+
* Each key is sent 50ms apart using setTimeout to keep the caller synchronous.
|
|
857
|
+
*/
|
|
858
|
+
sendKeySequence(keys) {
|
|
859
|
+
keys.forEach((key, i) => {
|
|
860
|
+
setTimeout(() => this.sendKeys(key), i * 50);
|
|
861
|
+
});
|
|
862
|
+
}
|
|
817
863
|
/**
|
|
818
864
|
* Paste text using bracketed paste mode
|
|
819
865
|
*
|
|
@@ -1270,6 +1316,11 @@ var BaseCLIAdapter = class {
|
|
|
1270
1316
|
* Subclasses should override this to add CLI-specific rules.
|
|
1271
1317
|
*/
|
|
1272
1318
|
autoResponseRules = [];
|
|
1319
|
+
/**
|
|
1320
|
+
* Whether this CLI uses TUI menus requiring arrow-key navigation.
|
|
1321
|
+
* Defaults to false; coding agent adapters override to true.
|
|
1322
|
+
*/
|
|
1323
|
+
usesTuiMenus = false;
|
|
1273
1324
|
/**
|
|
1274
1325
|
* Default exit detection - look for common exit patterns
|
|
1275
1326
|
*/
|
|
@@ -1890,6 +1941,8 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
|
|
|
1890
1941
|
pattern: new RegExp(r.pattern, r.flags || ""),
|
|
1891
1942
|
type: r.type,
|
|
1892
1943
|
response: r.response,
|
|
1944
|
+
responseType: r.responseType,
|
|
1945
|
+
keys: r.keys,
|
|
1893
1946
|
description: r.description,
|
|
1894
1947
|
safe: r.safe
|
|
1895
1948
|
}));
|
|
@@ -2042,6 +2095,8 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
|
|
|
2042
2095
|
flags: rule.pattern.flags || void 0,
|
|
2043
2096
|
type: rule.type,
|
|
2044
2097
|
response: rule.response,
|
|
2098
|
+
responseType: rule.responseType,
|
|
2099
|
+
keys: rule.keys,
|
|
2045
2100
|
description: rule.description,
|
|
2046
2101
|
safe: rule.safe
|
|
2047
2102
|
};
|
|
@@ -2093,6 +2148,14 @@ var BunCompatiblePTYManager = class extends EventEmitter3 {
|
|
|
2093
2148
|
const rules = await this.createPending(`getRules:${sessionId}`);
|
|
2094
2149
|
return rules;
|
|
2095
2150
|
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Select a TUI menu option by index (0-based) in a session.
|
|
2153
|
+
*/
|
|
2154
|
+
async selectMenuOption(id, optionIndex) {
|
|
2155
|
+
await this.waitForReady();
|
|
2156
|
+
this.sendCommand({ cmd: "selectMenuOption", id, optionIndex });
|
|
2157
|
+
await this.createPending(`selectMenuOption:${id}`);
|
|
2158
|
+
}
|
|
2096
2159
|
/**
|
|
2097
2160
|
* Clear all auto-response rules for a session.
|
|
2098
2161
|
*/
|