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/index.d.mts
CHANGED
|
@@ -133,6 +133,8 @@ interface AutoResponseRule {
|
|
|
133
133
|
description: string;
|
|
134
134
|
/** Whether this is safe to auto-respond (default: true) */
|
|
135
135
|
safe?: boolean;
|
|
136
|
+
/** Fire this rule at most once per session (prevents thrashing on TUI re-renders) */
|
|
137
|
+
once?: boolean;
|
|
136
138
|
}
|
|
137
139
|
/**
|
|
138
140
|
* Blocking prompt info for events
|
|
@@ -416,12 +418,14 @@ declare class PTYSession extends EventEmitter {
|
|
|
416
418
|
private messageCounter;
|
|
417
419
|
private logger;
|
|
418
420
|
private sessionRules;
|
|
421
|
+
private _firedOnceRules;
|
|
419
422
|
private _lastBlockingPromptHash;
|
|
420
423
|
private _stallTimer;
|
|
421
424
|
private _stallTimeoutMs;
|
|
422
425
|
private _stallDetectionEnabled;
|
|
423
426
|
private _lastStallHash;
|
|
424
427
|
private _stallStartedAt;
|
|
428
|
+
private _lastContentHash;
|
|
425
429
|
readonly id: string;
|
|
426
430
|
readonly config: SpawnConfig;
|
|
427
431
|
constructor(adapter: CLIAdapter, config: SpawnConfig, logger?: Logger, stallDetectionEnabled?: boolean, defaultStallTimeoutMs?: number);
|
|
@@ -454,6 +458,11 @@ declare class PTYSession extends EventEmitter {
|
|
|
454
458
|
/**
|
|
455
459
|
* Start or reset the stall detection timer.
|
|
456
460
|
* Active when status is "busy" or "authenticating" and stall detection is enabled.
|
|
461
|
+
*
|
|
462
|
+
* Content-based: hashes the ANSI-stripped buffer tail and only resets the
|
|
463
|
+
* timer when visible content actually changes. This prevents TUI spinners
|
|
464
|
+
* (which produce new ANSI sequences but no new visible text) from endlessly
|
|
465
|
+
* resetting the timer.
|
|
457
466
|
*/
|
|
458
467
|
private resetStallTimer;
|
|
459
468
|
/**
|
|
@@ -473,8 +482,11 @@ declare class PTYSession extends EventEmitter {
|
|
|
473
482
|
*/
|
|
474
483
|
private simpleHash;
|
|
475
484
|
/**
|
|
476
|
-
* Strip ANSI codes
|
|
477
|
-
*
|
|
485
|
+
* Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
|
|
486
|
+
* Used for stall detection hashing and auto-response pattern matching.
|
|
487
|
+
*
|
|
488
|
+
* Cursor movement codes are replaced with spaces (not removed) to preserve
|
|
489
|
+
* word boundaries — e.g. "Do\x1b[5Cyou" becomes "Do you", not "Doyou".
|
|
478
490
|
*/
|
|
479
491
|
private stripAnsiForStall;
|
|
480
492
|
/**
|
|
@@ -829,7 +841,7 @@ interface WorkerSessionHandle {
|
|
|
829
841
|
id: string;
|
|
830
842
|
name: string;
|
|
831
843
|
type: string;
|
|
832
|
-
status:
|
|
844
|
+
status: SessionStatus;
|
|
833
845
|
pid: number | undefined;
|
|
834
846
|
cols: number;
|
|
835
847
|
rows: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -133,6 +133,8 @@ interface AutoResponseRule {
|
|
|
133
133
|
description: string;
|
|
134
134
|
/** Whether this is safe to auto-respond (default: true) */
|
|
135
135
|
safe?: boolean;
|
|
136
|
+
/** Fire this rule at most once per session (prevents thrashing on TUI re-renders) */
|
|
137
|
+
once?: boolean;
|
|
136
138
|
}
|
|
137
139
|
/**
|
|
138
140
|
* Blocking prompt info for events
|
|
@@ -416,12 +418,14 @@ declare class PTYSession extends EventEmitter {
|
|
|
416
418
|
private messageCounter;
|
|
417
419
|
private logger;
|
|
418
420
|
private sessionRules;
|
|
421
|
+
private _firedOnceRules;
|
|
419
422
|
private _lastBlockingPromptHash;
|
|
420
423
|
private _stallTimer;
|
|
421
424
|
private _stallTimeoutMs;
|
|
422
425
|
private _stallDetectionEnabled;
|
|
423
426
|
private _lastStallHash;
|
|
424
427
|
private _stallStartedAt;
|
|
428
|
+
private _lastContentHash;
|
|
425
429
|
readonly id: string;
|
|
426
430
|
readonly config: SpawnConfig;
|
|
427
431
|
constructor(adapter: CLIAdapter, config: SpawnConfig, logger?: Logger, stallDetectionEnabled?: boolean, defaultStallTimeoutMs?: number);
|
|
@@ -454,6 +458,11 @@ declare class PTYSession extends EventEmitter {
|
|
|
454
458
|
/**
|
|
455
459
|
* Start or reset the stall detection timer.
|
|
456
460
|
* Active when status is "busy" or "authenticating" and stall detection is enabled.
|
|
461
|
+
*
|
|
462
|
+
* Content-based: hashes the ANSI-stripped buffer tail and only resets the
|
|
463
|
+
* timer when visible content actually changes. This prevents TUI spinners
|
|
464
|
+
* (which produce new ANSI sequences but no new visible text) from endlessly
|
|
465
|
+
* resetting the timer.
|
|
457
466
|
*/
|
|
458
467
|
private resetStallTimer;
|
|
459
468
|
/**
|
|
@@ -473,8 +482,11 @@ declare class PTYSession extends EventEmitter {
|
|
|
473
482
|
*/
|
|
474
483
|
private simpleHash;
|
|
475
484
|
/**
|
|
476
|
-
* Strip ANSI codes
|
|
477
|
-
*
|
|
485
|
+
* Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
|
|
486
|
+
* Used for stall detection hashing and auto-response pattern matching.
|
|
487
|
+
*
|
|
488
|
+
* Cursor movement codes are replaced with spaces (not removed) to preserve
|
|
489
|
+
* word boundaries — e.g. "Do\x1b[5Cyou" becomes "Do you", not "Doyou".
|
|
478
490
|
*/
|
|
479
491
|
private stripAnsiForStall;
|
|
480
492
|
/**
|
|
@@ -829,7 +841,7 @@ interface WorkerSessionHandle {
|
|
|
829
841
|
id: string;
|
|
830
842
|
name: string;
|
|
831
843
|
type: string;
|
|
832
|
-
status:
|
|
844
|
+
status: SessionStatus;
|
|
833
845
|
pid: number | undefined;
|
|
834
846
|
cols: number;
|
|
835
847
|
rows: number;
|
package/dist/index.js
CHANGED
|
@@ -324,6 +324,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
324
324
|
messageCounter = 0;
|
|
325
325
|
logger;
|
|
326
326
|
sessionRules = [];
|
|
327
|
+
_firedOnceRules = /* @__PURE__ */ new Set();
|
|
327
328
|
_lastBlockingPromptHash = null;
|
|
328
329
|
// Stall detection
|
|
329
330
|
_stallTimer = null;
|
|
@@ -331,6 +332,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
331
332
|
_stallDetectionEnabled;
|
|
332
333
|
_lastStallHash = null;
|
|
333
334
|
_stallStartedAt = null;
|
|
335
|
+
_lastContentHash = null;
|
|
334
336
|
id;
|
|
335
337
|
config;
|
|
336
338
|
get status() {
|
|
@@ -417,12 +419,28 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
417
419
|
/**
|
|
418
420
|
* Start or reset the stall detection timer.
|
|
419
421
|
* Active when status is "busy" or "authenticating" and stall detection is enabled.
|
|
422
|
+
*
|
|
423
|
+
* Content-based: hashes the ANSI-stripped buffer tail and only resets the
|
|
424
|
+
* timer when visible content actually changes. This prevents TUI spinners
|
|
425
|
+
* (which produce new ANSI sequences but no new visible text) from endlessly
|
|
426
|
+
* resetting the timer.
|
|
420
427
|
*/
|
|
421
428
|
resetStallTimer() {
|
|
422
|
-
this.clearStallTimer();
|
|
423
429
|
if (!this._stallDetectionEnabled || this._status !== "busy" && this._status !== "authenticating") {
|
|
430
|
+
this.clearStallTimer();
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const tail = this.outputBuffer.slice(-500);
|
|
434
|
+
const stripped = this.stripAnsiForStall(tail).trim();
|
|
435
|
+
const hash = this.simpleHash(stripped);
|
|
436
|
+
if (hash === this._lastContentHash) {
|
|
424
437
|
return;
|
|
425
438
|
}
|
|
439
|
+
this._lastContentHash = hash;
|
|
440
|
+
if (this._stallTimer) {
|
|
441
|
+
clearTimeout(this._stallTimer);
|
|
442
|
+
this._stallTimer = null;
|
|
443
|
+
}
|
|
426
444
|
this._stallStartedAt = Date.now();
|
|
427
445
|
this._lastStallHash = null;
|
|
428
446
|
this._stallTimer = setTimeout(() => {
|
|
@@ -438,6 +456,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
438
456
|
this._stallTimer = null;
|
|
439
457
|
}
|
|
440
458
|
this._stallStartedAt = null;
|
|
459
|
+
this._lastContentHash = null;
|
|
441
460
|
}
|
|
442
461
|
/**
|
|
443
462
|
* Called when the stall timer fires (no output for stallTimeoutMs).
|
|
@@ -482,12 +501,19 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
482
501
|
return hash.toString(36);
|
|
483
502
|
}
|
|
484
503
|
/**
|
|
485
|
-
* Strip ANSI codes
|
|
486
|
-
*
|
|
504
|
+
* Strip ANSI codes, cursor movement, box-drawing, and spinner characters.
|
|
505
|
+
* Used for stall detection hashing and auto-response pattern matching.
|
|
506
|
+
*
|
|
507
|
+
* Cursor movement codes are replaced with spaces (not removed) to preserve
|
|
508
|
+
* word boundaries — e.g. "Do\x1b[5Cyou" becomes "Do you", not "Doyou".
|
|
487
509
|
*/
|
|
488
510
|
stripAnsiForStall(str) {
|
|
489
|
-
|
|
490
|
-
|
|
511
|
+
let result = str.replace(/\x1b\[\d*[CDABG]/g, " ");
|
|
512
|
+
result = result.replace(/\x1b\[\d*(?:;\d+)?[Hf]/g, " ");
|
|
513
|
+
result = result.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
|
|
514
|
+
result = result.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⣾⣽⣻⢿⡿⣟⣯⣷✻✶✳✢⏺←→↑↓]/g, " ");
|
|
515
|
+
result = result.replace(/ {2,}/g, " ");
|
|
516
|
+
return result;
|
|
491
517
|
}
|
|
492
518
|
/**
|
|
493
519
|
* Handle external stall classification result.
|
|
@@ -498,6 +524,7 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
498
524
|
return;
|
|
499
525
|
}
|
|
500
526
|
if (!classification || classification.state === "still_working") {
|
|
527
|
+
this._lastContentHash = null;
|
|
501
528
|
this.resetStallTimer();
|
|
502
529
|
return;
|
|
503
530
|
}
|
|
@@ -722,10 +749,14 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
722
749
|
if (allRules.length === 0) {
|
|
723
750
|
return false;
|
|
724
751
|
}
|
|
725
|
-
|
|
726
|
-
stripped = stripped.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⏺←→↑↓]/g, " ");
|
|
727
|
-
stripped = stripped.replace(/ {2,}/g, " ");
|
|
752
|
+
const stripped = this.stripAnsiForStall(this.outputBuffer);
|
|
728
753
|
for (const rule of allRules) {
|
|
754
|
+
if (rule.once) {
|
|
755
|
+
const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;
|
|
756
|
+
if (this._firedOnceRules.has(ruleKey)) {
|
|
757
|
+
continue;
|
|
758
|
+
}
|
|
759
|
+
}
|
|
729
760
|
if (rule.pattern.test(stripped)) {
|
|
730
761
|
const safe = rule.safe !== false;
|
|
731
762
|
const isSessionRule = this.sessionRules.includes(rule);
|
|
@@ -749,6 +780,10 @@ var PTYSession = class extends import_events.EventEmitter {
|
|
|
749
780
|
} else {
|
|
750
781
|
this.writeRaw(rule.response + "\r");
|
|
751
782
|
}
|
|
783
|
+
if (rule.once) {
|
|
784
|
+
const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;
|
|
785
|
+
this._firedOnceRules.add(ruleKey);
|
|
786
|
+
}
|
|
752
787
|
this.outputBuffer = this.outputBuffer.replace(rule.pattern, "");
|
|
753
788
|
const promptInfo = {
|
|
754
789
|
type: rule.type,
|
|
@@ -1921,6 +1956,7 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
|
|
|
1921
1956
|
case "login_required": {
|
|
1922
1957
|
const session = this.sessions.get(id);
|
|
1923
1958
|
if (session) {
|
|
1959
|
+
session.status = "authenticating";
|
|
1924
1960
|
this.emit("login_required", session, event.instructions, event.url);
|
|
1925
1961
|
}
|
|
1926
1962
|
break;
|
|
@@ -1982,7 +2018,8 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
|
|
|
1982
2018
|
responseType: r.responseType,
|
|
1983
2019
|
keys: r.keys,
|
|
1984
2020
|
description: r.description,
|
|
1985
|
-
safe: r.safe
|
|
2021
|
+
safe: r.safe,
|
|
2022
|
+
once: r.once
|
|
1986
2023
|
}));
|
|
1987
2024
|
this.resolvePending(`getRules:${id}`, rules);
|
|
1988
2025
|
break;
|
|
@@ -2136,7 +2173,8 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
|
|
|
2136
2173
|
responseType: rule.responseType,
|
|
2137
2174
|
keys: rule.keys,
|
|
2138
2175
|
description: rule.description,
|
|
2139
|
-
safe: rule.safe
|
|
2176
|
+
safe: rule.safe,
|
|
2177
|
+
once: rule.once
|
|
2140
2178
|
};
|
|
2141
2179
|
}
|
|
2142
2180
|
/**
|