@f5xc-salesdemos/pi-tui 19.27.1 → 19.28.1

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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/terminal.ts +36 -26
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5xc-salesdemos/pi-tui",
4
- "version": "19.27.1",
4
+ "version": "19.28.1",
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.27.1",
41
- "@f5xc-salesdemos/pi-utils": "19.27.1",
40
+ "@f5xc-salesdemos/pi-natives": "19.28.1",
41
+ "@f5xc-salesdemos/pi-utils": "19.28.1",
42
42
  "marked": "^17.0"
43
43
  },
44
44
  "devDependencies": {
package/src/terminal.ts CHANGED
@@ -134,7 +134,6 @@ export class ProcessTerminal implements Terminal {
134
134
  }
135
135
 
136
136
  start(onInput: (data: string) => void, onResize: () => void): void {
137
- this.#inputHandler = onInput;
138
137
  this.#resizeHandler = onResize;
139
138
 
140
139
  // Register for emergency cleanup
@@ -186,6 +185,13 @@ export class ProcessTerminal implements Terminal {
186
185
  // Start periodic OSC 11 re-query for terminals without Mode 2031
187
186
  // (Warp, Alacritty, WezTerm, iTerm2). Self-disables once Mode 2031 fires.
188
187
  this.#startOsc11Poll();
188
+
189
+ // Defer activating the user input handler until terminal capability
190
+ // queries have settled. Without this, query responses (Kitty, DA1,
191
+ // OSC 11) race into the editor as typed text.
192
+ setTimeout(() => {
193
+ this.#inputHandler = onInput;
194
+ }, 50);
189
195
  }
190
196
 
191
197
  /**
@@ -264,41 +270,33 @@ export class ProcessTerminal implements Terminal {
264
270
 
265
271
  // Forward individual sequences to the input handler
266
272
  this.#stdinBuffer.on("data", (sequence: string) => {
267
- // Check for Kitty protocol response (only if not already enabled)
268
- if (!this.#kittyProtocolActive) {
269
- const match = sequence.match(kittyResponsePattern);
270
- if (match) {
273
+ // Kitty protocol response always swallow, enable protocol on first match
274
+ const kittyMatch = sequence.match(kittyResponsePattern);
275
+ if (kittyMatch) {
276
+ if (!this.#kittyProtocolActive) {
271
277
  if (this.#modifyOtherKeysTimeout) {
272
278
  clearTimeout(this.#modifyOtherKeysTimeout);
273
279
  this.#modifyOtherKeysTimeout = undefined;
274
280
  }
275
281
  this.#kittyProtocolActive = true;
276
282
  setKittyProtocolActive(true);
277
-
278
- // Enable Kitty keyboard protocol (push flags)
279
- // Flag 1 = disambiguate escape codes
280
- // Flag 2 = report event types (press/repeat/release)
281
- // Flag 4 = report alternate keys
282
283
  this.#safeWrite("\x1b[>7u");
283
- return; // Don't forward protocol response to TUI
284
284
  }
285
+ return;
285
286
  }
286
287
 
287
- // DA1 response: swallow our sentinel reply regardless of whether OSC 11
288
- // already succeeded. Other terminal probes should never see these replies.
289
- if (da1ResponsePattern.test(sequence) && this.#pendingDa1Sentinels > 0) {
290
- this.#pendingDa1Sentinels--;
291
- if (this.#osc11Pending) {
292
- // DA1 arrived before OSC 11 response: terminal does not support
293
- // OSC 11. Clear the pending state without starting a queued query
294
- // (queued query is started below, after sentinel is consumed).
295
- this.#osc11Pending = false;
296
- this.#osc11ResponseBuffer = "";
297
- }
298
- // Now that this DA1 cycle is complete, start any queued query.
299
- if (this.#osc11QueryQueued && !this.#dead) {
300
- this.#osc11QueryQueued = false;
301
- this.#startOsc11Query();
288
+ // DA1 response — always swallow; manage sentinel count if pending
289
+ if (da1ResponsePattern.test(sequence)) {
290
+ if (this.#pendingDa1Sentinels > 0) {
291
+ this.#pendingDa1Sentinels--;
292
+ if (this.#osc11Pending) {
293
+ this.#osc11Pending = false;
294
+ this.#osc11ResponseBuffer = "";
295
+ }
296
+ if (this.#osc11QueryQueued && !this.#dead) {
297
+ this.#osc11QueryQueued = false;
298
+ this.#startOsc11Query();
299
+ }
302
300
  }
303
301
  return;
304
302
  }
@@ -339,6 +337,18 @@ export class ProcessTerminal implements Terminal {
339
337
  }, 100);
340
338
  return;
341
339
  }
340
+ // Drop stale terminal responses that leaked through the stdin buffer
341
+ // timeout flush. These are incomplete DA1/DA2 replies, OSC 11
342
+ // fragments, or Kitty protocol responses that arrived split across
343
+ // data events and were flushed before their terminator arrived.
344
+ if (
345
+ /^\x1b\[\?[\d;]*[a-z]?$/i.test(sequence) || // DA1/Kitty responses: ESC[?...
346
+ /^\x1b\](?:11|10|4);/.test(sequence) || // OSC color responses without terminator
347
+ /^\x1b\[>[\d;]*[a-z]?$/i.test(sequence) // DA2 responses: ESC[>...
348
+ ) {
349
+ return;
350
+ }
351
+
342
352
  if (this.#inputHandler) {
343
353
  this.#inputHandler(sequence);
344
354
  }