@f5xc-salesdemos/pi-tui 19.29.3 → 19.29.5

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/pi-tui",
4
- "version": "19.29.3",
4
+ "version": "19.29.5",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://github.com/f5xc-salesdemos/xcsh",
7
7
  "author": "Can Boluk",
@@ -37,8 +37,8 @@
37
37
  "fmt": "biome format --write ."
38
38
  },
39
39
  "dependencies": {
40
- "@f5xc-salesdemos/pi-natives": "19.29.3",
41
- "@f5xc-salesdemos/pi-utils": "19.29.3",
40
+ "@f5xc-salesdemos/pi-natives": "19.29.5",
41
+ "@f5xc-salesdemos/pi-utils": "19.29.5",
42
42
  "marked": "^17.0"
43
43
  },
44
44
  "devDependencies": {
@@ -224,8 +224,15 @@ function extractCompleteSequences(buffer: string): { sequences: string[]; remain
224
224
 
225
225
  export type StdinBufferOptions = {
226
226
  /**
227
- * Maximum time to wait for sequence completion (default: 10ms)
228
- * After this time, the buffer is flushed even if incomplete
227
+ * Maximum time to wait for sequence completion (default: 50ms)
228
+ * After this time, the buffer is flushed even if incomplete.
229
+ *
230
+ * This is effectively the "ESC hold" window: a lone ESC (the Escape key)
231
+ * registers after this delay, and a multi-byte escape sequence fragmented
232
+ * across stdin reads (common under heavy render load) has this long to
233
+ * reassemble before its tail would leak as individual printable characters.
234
+ * 50ms is the standard ESC timeout — long enough to survive multi-frame
235
+ * stalls, short enough to feel instant.
229
236
  */
230
237
  timeout?: number;
231
238
  };
@@ -248,7 +255,7 @@ export class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
248
255
 
249
256
  constructor(options: StdinBufferOptions = {}) {
250
257
  super();
251
- this.#timeoutMs = options.timeout ?? 10;
258
+ this.#timeoutMs = options.timeout ?? 50;
252
259
  }
253
260
 
254
261
  process(data: string | Buffer): void {
package/src/terminal.ts CHANGED
@@ -274,7 +274,10 @@ export class ProcessTerminal implements Terminal {
274
274
  * to handle the case where the response arrives split across multiple events.
275
275
  */
276
276
  #setupStdinBuffer(): void {
277
- this.#stdinBuffer = new StdinBuffer({ timeout: 10 });
277
+ // Use the default ESC-hold window (50ms) so escape sequences fragmented
278
+ // across stdin reads under render load reassemble instead of leaking their
279
+ // tail as editor text (e.g. modifyOtherKeys Ctrl+C \x1b[27;5;99~).
280
+ this.#stdinBuffer = new StdinBuffer();
278
281
 
279
282
  // Kitty protocol response pattern: \x1b[?<flags>u
280
283
  const kittyResponsePattern = /^\x1b\[\?(\d+)u$/;
@@ -503,6 +506,10 @@ export class ProcessTerminal implements Terminal {
503
506
  }
504
507
 
505
508
  async drainInput(maxMs = 1000, idleMs = 50): Promise<void> {
509
+ // Stop the periodic OSC 11 poll first. drainInput precedes relinquishing
510
+ // the TTY (exit, or a cooked-mode subprocess); a poll query fired now would
511
+ // have its response echoed as gibberish once raw mode is gone.
512
+ this.#stopOsc11Poll();
506
513
  if (this.#kittyProtocolActive) {
507
514
  // Disable Kitty keyboard protocol first so any late key releases
508
515
  // do not generate new Kitty escape sequences.
package/src/tui.ts CHANGED
@@ -580,6 +580,18 @@ export class TUI extends Container {
580
580
  this.terminal.stop();
581
581
  }
582
582
 
583
+ /**
584
+ * Suspend the UI to hand the TTY to a cooked-mode subprocess (e.g. an
585
+ * interactive `aws sso login`). Drains pending terminal input while still in
586
+ * raw mode, then stops — so a late capability-probe response (notably the
587
+ * periodic OSC 11 poll) cannot be echoed as gibberish during the cooked-mode
588
+ * window. Pair with start() once the subprocess exits.
589
+ */
590
+ async suspendForSubprocess(maxDrainMs = 150): Promise<void> {
591
+ await this.terminal.drainInput(maxDrainMs);
592
+ this.stop();
593
+ }
594
+
583
595
  requestRender(force = false): void {
584
596
  if (force) {
585
597
  this.#previousLines = [];