pty-manager 1.2.17 → 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 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,6 +418,7 @@ 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;
@@ -479,8 +482,11 @@ declare class PTYSession extends EventEmitter {
479
482
  */
480
483
  private simpleHash;
481
484
  /**
482
- * Strip ANSI codes for stall detection output.
483
- * Replaces cursor-forward sequences with spaces first.
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".
484
490
  */
485
491
  private stripAnsiForStall;
486
492
  /**
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,6 +418,7 @@ 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;
@@ -479,8 +482,11 @@ declare class PTYSession extends EventEmitter {
479
482
  */
480
483
  private simpleHash;
481
484
  /**
482
- * Strip ANSI codes for stall detection output.
483
- * Replaces cursor-forward sequences with spaces first.
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".
484
490
  */
485
491
  private stripAnsiForStall;
486
492
  /**
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;
@@ -430,7 +431,7 @@ var PTYSession = class extends import_events.EventEmitter {
430
431
  return;
431
432
  }
432
433
  const tail = this.outputBuffer.slice(-500);
433
- const stripped = this.stripAnsiForStall(tail);
434
+ const stripped = this.stripAnsiForStall(tail).trim();
434
435
  const hash = this.simpleHash(stripped);
435
436
  if (hash === this._lastContentHash) {
436
437
  return;
@@ -500,12 +501,19 @@ var PTYSession = class extends import_events.EventEmitter {
500
501
  return hash.toString(36);
501
502
  }
502
503
  /**
503
- * Strip ANSI codes for stall detection output.
504
- * Replaces cursor-forward sequences with spaces first.
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".
505
509
  */
506
510
  stripAnsiForStall(str) {
507
- const withSpaces = str.replace(/\x1b\[\d*C/g, " ");
508
- return withSpaces.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "");
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;
509
517
  }
510
518
  /**
511
519
  * Handle external stall classification result.
@@ -741,10 +749,14 @@ var PTYSession = class extends import_events.EventEmitter {
741
749
  if (allRules.length === 0) {
742
750
  return false;
743
751
  }
744
- let stripped = this.stripAnsiForStall(this.outputBuffer);
745
- stripped = stripped.replace(/[│╭╰╮╯─═╌║╔╗╚╝╠╣╦╩╬┌┐└┘├┤┬┴┼●○❯❮▶◀⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏⏺←→↑↓]/g, " ");
746
- stripped = stripped.replace(/ {2,}/g, " ");
752
+ const stripped = this.stripAnsiForStall(this.outputBuffer);
747
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
+ }
748
760
  if (rule.pattern.test(stripped)) {
749
761
  const safe = rule.safe !== false;
750
762
  const isSessionRule = this.sessionRules.includes(rule);
@@ -768,6 +780,10 @@ var PTYSession = class extends import_events.EventEmitter {
768
780
  } else {
769
781
  this.writeRaw(rule.response + "\r");
770
782
  }
783
+ if (rule.once) {
784
+ const ruleKey = `${rule.pattern.source}:${rule.pattern.flags}`;
785
+ this._firedOnceRules.add(ruleKey);
786
+ }
771
787
  this.outputBuffer = this.outputBuffer.replace(rule.pattern, "");
772
788
  const promptInfo = {
773
789
  type: rule.type,
@@ -2002,7 +2018,8 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
2002
2018
  responseType: r.responseType,
2003
2019
  keys: r.keys,
2004
2020
  description: r.description,
2005
- safe: r.safe
2021
+ safe: r.safe,
2022
+ once: r.once
2006
2023
  }));
2007
2024
  this.resolvePending(`getRules:${id}`, rules);
2008
2025
  break;
@@ -2156,7 +2173,8 @@ var BunCompatiblePTYManager = class extends import_events3.EventEmitter {
2156
2173
  responseType: rule.responseType,
2157
2174
  keys: rule.keys,
2158
2175
  description: rule.description,
2159
- safe: rule.safe
2176
+ safe: rule.safe,
2177
+ once: rule.once
2160
2178
  };
2161
2179
  }
2162
2180
  /**