pty-manager 1.2.16 → 1.2.18
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 +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.js +48 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +48 -10
- package/dist/index.mjs.map +1 -1
- package/dist/pty-worker.js +47 -10
- package/package.json +1 -1
package/dist/pty-worker.js
CHANGED
|
@@ -307,6 +307,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
307
307
|
messageCounter = 0;
|
|
308
308
|
logger;
|
|
309
309
|
sessionRules = [];
|
|
310
|
+
_firedOnceRules = /* @__PURE__ */ new Set();
|
|
310
311
|
_lastBlockingPromptHash = null;
|
|
311
312
|
// Stall detection
|
|
312
313
|
_stallTimer = null;
|
|
@@ -314,6 +315,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
314
315
|
_stallDetectionEnabled;
|
|
315
316
|
_lastStallHash = null;
|
|
316
317
|
_stallStartedAt = null;
|
|
318
|
+
_lastContentHash = null;
|
|
317
319
|
id;
|
|
318
320
|
config;
|
|
319
321
|
get status() {
|
|
@@ -400,12 +402,28 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
400
402
|
/**
|
|
401
403
|
* Start or reset the stall detection timer.
|
|
402
404
|
* Active when status is "busy" or "authenticating" and stall detection is enabled.
|
|
405
|
+
*
|
|
406
|
+
* Content-based: hashes the ANSI-stripped buffer tail and only resets the
|
|
407
|
+
* timer when visible content actually changes. This prevents TUI spinners
|
|
408
|
+
* (which produce new ANSI sequences but no new visible text) from endlessly
|
|
409
|
+
* resetting the timer.
|
|
403
410
|
*/
|
|
404
411
|
resetStallTimer() {
|
|
405
|
-
this.clearStallTimer();
|
|
406
412
|
if (!this._stallDetectionEnabled || this._status !== "busy" && this._status !== "authenticating") {
|
|
413
|
+
this.clearStallTimer();
|
|
407
414
|
return;
|
|
408
415
|
}
|
|
416
|
+
const tail = this.outputBuffer.slice(-500);
|
|
417
|
+
const stripped = this.stripAnsiForStall(tail).trim();
|
|
418
|
+
const hash = this.simpleHash(stripped);
|
|
419
|
+
if (hash === this._lastContentHash) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
this._lastContentHash = hash;
|
|
423
|
+
if (this._stallTimer) {
|
|
424
|
+
clearTimeout(this._stallTimer);
|
|
425
|
+
this._stallTimer = null;
|
|
426
|
+
}
|
|
409
427
|
this._stallStartedAt = Date.now();
|
|
410
428
|
this._lastStallHash = null;
|
|
411
429
|
this._stallTimer = setTimeout(() => {
|
|
@@ -421,6 +439,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
421
439
|
this._stallTimer = null;
|
|
422
440
|
}
|
|
423
441
|
this._stallStartedAt = null;
|
|
442
|
+
this._lastContentHash = null;
|
|
424
443
|
}
|
|
425
444
|
/**
|
|
426
445
|
* Called when the stall timer fires (no output for stallTimeoutMs).
|
|
@@ -465,12 +484,19 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
465
484
|
return hash.toString(36);
|
|
466
485
|
}
|
|
467
486
|
/**
|
|
468
|
-
* Strip ANSI codes
|
|
469
|
-
*
|
|
487
|
+
* Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
|
|
488
|
+
* Used for stall detection hashing and auto-response pattern matching.
|
|
489
|
+
*
|
|
490
|
+
* Cursor movement codes are replaced with spaces (not removed) to preserve
|
|
491
|
+
* word boundaries — e.g. "Do\x1b[5Cyou" becomes "Do you", not "Doyou".
|
|
470
492
|
*/
|
|
471
493
|
stripAnsiForStall(str) {
|
|
472
|
-
|
|
473
|
-
|
|
494
|
+
let result = str.replace(/\x1b\[\d*[CDABG]/g, " ");
|
|
495
|
+
result = result.replace(/\x1b\[\d*(?:;\d+)?[Hf]/g, " ");
|
|
496
|
+
result = result.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
497
|
+
result = result.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷✻✶✳✢⏺←→↑↓]/g, " ");
|
|
498
|
+
result = result.replace(/ {2,}/g, " ");
|
|
499
|
+
return result;
|
|
474
500
|
}
|
|
475
501
|
/**
|
|
476
502
|
* Handle external stall classification result.
|
|
@@ -481,6 +507,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
481
507
|
return;
|
|
482
508
|
}
|
|
483
509
|
if (!classification || classification.state === "still_working") {
|
|
510
|
+
this._lastContentHash = null;
|
|
484
511
|
this.resetStallTimer();
|
|
485
512
|
return;
|
|
486
513
|
}
|
|
@@ -705,10 +732,14 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
705
732
|
if (allRules.length === 0) {
|
|
706
733
|
return false;
|
|
707
734
|
}
|
|
708
|
-
|
|
709
|
-
stripped = stripped.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⏺←→↑↓]/g, " ");
|
|
710
|
-
stripped = stripped.replace(/ {2,}/g, " ");
|
|
735
|
+
const stripped = this.stripAnsiForStall(this.outputBuffer);
|
|
711
736
|
for (const rule of allRules) {
|
|
737
|
+
if (rule.once) {
|
|
738
|
+
const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;
|
|
739
|
+
if (this._firedOnceRules.has(ruleKey)) {
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
712
743
|
if (rule.pattern.test(stripped)) {
|
|
713
744
|
const safe = rule.safe !== false;
|
|
714
745
|
const isSessionRule = this.sessionRules.includes(rule);
|
|
@@ -732,6 +763,10 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
732
763
|
} else {
|
|
733
764
|
this.writeRaw(rule.response + "\r");
|
|
734
765
|
}
|
|
766
|
+
if (rule.once) {
|
|
767
|
+
const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;
|
|
768
|
+
this._firedOnceRules.add(ruleKey);
|
|
769
|
+
}
|
|
735
770
|
this.outputBuffer = this.outputBuffer.replace(rule.pattern, "");
|
|
736
771
|
const promptInfo = {
|
|
737
772
|
type: rule.type,
|
|
@@ -1601,7 +1636,8 @@ function deserializeRule(serialized) {
|
|
|
1601
1636
|
responseType: serialized.responseType,
|
|
1602
1637
|
keys: serialized.keys,
|
|
1603
1638
|
description: serialized.description,
|
|
1604
|
-
safe: serialized.safe
|
|
1639
|
+
safe: serialized.safe,
|
|
1640
|
+
once: serialized.once
|
|
1605
1641
|
};
|
|
1606
1642
|
}
|
|
1607
1643
|
function serializeRule(rule) {
|
|
@@ -1613,7 +1649,8 @@ function serializeRule(rule) {
|
|
|
1613
1649
|
responseType: rule.responseType,
|
|
1614
1650
|
keys: rule.keys,
|
|
1615
1651
|
description: rule.description,
|
|
1616
|
-
safe: rule.safe
|
|
1652
|
+
safe: rule.safe,
|
|
1653
|
+
once: rule.once
|
|
1617
1654
|
};
|
|
1618
1655
|
}
|
|
1619
1656
|
function handleAddRule(id, serializedRule) {
|
package/package.json
CHANGED