@chengchenccc/tui 0.1.1-rc.2 → 0.2.0-rc.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 (57) hide show
  1. package/dist/components/ansi-console.d.ts +32 -0
  2. package/dist/components/ansi-console.d.ts.map +1 -0
  3. package/dist/components/ansi-console.js +75 -0
  4. package/dist/components/ansi-console.test.d.ts +2 -0
  5. package/dist/components/ansi-console.test.d.ts.map +1 -0
  6. package/dist/components/ansi-console.test.js +36 -0
  7. package/dist/components/loader.d.ts +21 -1
  8. package/dist/components/loader.d.ts.map +1 -1
  9. package/dist/components/loader.js +39 -15
  10. package/dist/components/markdown.d.ts +5 -0
  11. package/dist/components/markdown.d.ts.map +1 -1
  12. package/dist/components/markdown.js +47 -2
  13. package/dist/components/markdown.test.js +30 -1
  14. package/dist/components/select-list.d.ts +6 -0
  15. package/dist/components/select-list.d.ts.map +1 -1
  16. package/dist/components/select-list.js +18 -0
  17. package/dist/components/select-list.test.d.ts +2 -0
  18. package/dist/components/select-list.test.d.ts.map +1 -0
  19. package/dist/components/select-list.test.js +53 -0
  20. package/dist/index.d.ts +4 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -2
  23. package/dist/keybindings.d.ts +5 -0
  24. package/dist/keybindings.d.ts.map +1 -1
  25. package/dist/keybindings.js +7 -0
  26. package/dist/loader-sweep.test.d.ts +2 -0
  27. package/dist/loader-sweep.test.d.ts.map +1 -0
  28. package/dist/loader-sweep.test.js +67 -0
  29. package/dist/stdin-buffer.d.ts +1 -0
  30. package/dist/stdin-buffer.d.ts.map +1 -1
  31. package/dist/stdin-buffer.js +19 -0
  32. package/dist/stdin-buffer.test.d.ts +2 -0
  33. package/dist/stdin-buffer.test.d.ts.map +1 -0
  34. package/dist/stdin-buffer.test.js +38 -0
  35. package/dist/terminal-reassert.test.d.ts +2 -0
  36. package/dist/terminal-reassert.test.d.ts.map +1 -0
  37. package/dist/terminal-reassert.test.js +18 -0
  38. package/dist/terminal.d.ts +14 -0
  39. package/dist/terminal.d.ts.map +1 -1
  40. package/dist/terminal.js +18 -0
  41. package/dist/text-sizing.d.ts +7 -0
  42. package/dist/text-sizing.d.ts.map +1 -0
  43. package/dist/text-sizing.js +34 -0
  44. package/dist/text-sizing.test.d.ts +2 -0
  45. package/dist/text-sizing.test.d.ts.map +1 -0
  46. package/dist/text-sizing.test.js +43 -0
  47. package/dist/tui-scrollback.test.js +36 -0
  48. package/dist/tui.d.ts +8 -0
  49. package/dist/tui.d.ts.map +1 -1
  50. package/dist/tui.js +73 -7
  51. package/dist/utils.d.ts +1 -3
  52. package/dist/utils.d.ts.map +1 -1
  53. package/dist/utils.js +28 -0
  54. package/dist/virtual-terminal.d.ts +1 -0
  55. package/dist/virtual-terminal.d.ts.map +1 -1
  56. package/dist/virtual-terminal.js +3 -0
  57. package/package.json +2 -2
@@ -35,6 +35,7 @@ export interface Keybindings {
35
35
  "tui.select.pageDown": true;
36
36
  "tui.select.confirm": true;
37
37
  "tui.select.cancel": true;
38
+ "tui.select.delete": true;
38
39
  }
39
40
  export type Keybinding = keyof Keybindings;
40
41
  export interface KeybindingDefinition {
@@ -164,6 +165,10 @@ export declare const TUI_KEYBINDINGS: {
164
165
  readonly defaultKeys: "enter";
165
166
  readonly description: "Confirm selection";
166
167
  };
168
+ readonly "tui.select.delete": {
169
+ readonly defaultKeys: "ctrl+d";
170
+ readonly description: "Delete selection";
171
+ };
167
172
  readonly "tui.select.cancel": {
168
173
  readonly defaultKeys: ["escape", "ctrl+c"];
169
174
  readonly description: "Cancel selection";
@@ -1 +1 @@
1
- {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../src/keybindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAc,MAAM,WAAW,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAE1B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,uBAAuB,EAAE,IAAI,CAAC;IAC9B,uBAAuB,EAAE,IAAI,CAAC;IAC9B,wBAAwB,EAAE,IAAI,CAAC;IAC/B,2BAA2B,EAAE,IAAI,CAAC;IAClC,4BAA4B,EAAE,IAAI,CAAC;IACnC,4BAA4B,EAAE,IAAI,CAAC;IACnC,0BAA0B,EAAE,IAAI,CAAC;IACjC,wBAAwB,EAAE,IAAI,CAAC;IAC/B,yBAAyB,EAAE,IAAI,CAAC;IAChC,mBAAmB,EAAE,IAAI,CAAC;IAC1B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,+BAA+B,EAAE,IAAI,CAAC;IACtC,8BAA8B,EAAE,IAAI,CAAC;IACrC,+BAA+B,EAAE,IAAI,CAAC;IACtC,8BAA8B,EAAE,IAAI,CAAC;IACrC,8BAA8B,EAAE,IAAI,CAAC;IACrC,4BAA4B,EAAE,IAAI,CAAC;IACnC,iBAAiB,EAAE,IAAI,CAAC;IACxB,oBAAoB,EAAE,IAAI,CAAC;IAC3B,iBAAiB,EAAE,IAAI,CAAC;IAExB,mBAAmB,EAAE,IAAI,CAAC;IAC1B,kBAAkB,EAAE,IAAI,CAAC;IACzB,eAAe,EAAE,IAAI,CAAC;IACtB,gBAAgB,EAAE,IAAI,CAAC;IAEvB,eAAe,EAAE,IAAI,CAAC;IACtB,iBAAiB,EAAE,IAAI,CAAC;IACxB,mBAAmB,EAAE,IAAI,CAAC;IAC1B,qBAAqB,EAAE,IAAI,CAAC;IAC5B,oBAAoB,EAAE,IAAI,CAAC;IAC3B,mBAAmB,EAAE,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AACzE,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,GAAG,SAAS,CAAC,CAAC;AAE5E,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Fc,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,KAAK,CAAC;IACX,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAgBD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,SAAS,CAA4B;gBAEjC,WAAW,EAAE,qBAAqB,EAAE,YAAY,GAAE,iBAAsB;IAMpF,OAAO,CAAC,OAAO;IA4Bf,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO;IAQtD,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,KAAK,EAAE;IAIxC,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,oBAAoB;IAI3D,YAAY,IAAI,kBAAkB,EAAE;IAOpC,eAAe,CAAC,YAAY,EAAE,iBAAiB,GAAG,IAAI;IAKtD,eAAe,IAAI,iBAAiB;IAIpC,mBAAmB,IAAI,iBAAiB;CAQzC;AAID,wBAAgB,cAAc,CAAC,WAAW,EAAE,kBAAkB,GAAG,IAAI,CAEpE;AAED,wBAAgB,cAAc,IAAI,kBAAkB,CAKnD"}
1
+ {"version":3,"file":"keybindings.d.ts","sourceRoot":"","sources":["../src/keybindings.ts"],"names":[],"mappings":"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"}
@@ -90,6 +90,13 @@ export const TUI_KEYBINDINGS = {
90
90
  defaultKeys: "enter",
91
91
  description: "Confirm selection",
92
92
  },
93
+ "tui.select.delete": {
94
+ // An explicit chord, not a bare letter: the picker's list is the only
95
+ // thing on screen, but deletion is unrecoverable, so it should never
96
+ // come from a stray keypress.
97
+ defaultKeys: "ctrl+d",
98
+ description: "Delete selection",
99
+ },
93
100
  "tui.select.cancel": {
94
101
  defaultKeys: ["escape", "ctrl+c"],
95
102
  description: "Cancel selection",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=loader-sweep.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-sweep.test.d.ts","sourceRoot":"","sources":["../src/loader-sweep.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import { describe, expect, test, vi } from "bun:test";
2
+ import { Loader } from "./components/loader.js";
3
+ const ESC = String.fromCharCode(27);
4
+ /** Cell index of the bright (bold) sweep tier on the rendered line, or -1. */
5
+ function bandCell(line) {
6
+ return visibleIndex(line, `${ESC}[1m${ESC}[36m`);
7
+ }
8
+ /** The message row: Loader.render pads with a blank row above and below. */
9
+ function messageRow(loader) {
10
+ return loader.render(80)[1] ?? "";
11
+ }
12
+ /** Index (in visible cells) where `marker` starts in an ANSI string. */
13
+ function visibleIndex(line, marker) {
14
+ const at = line.indexOf(marker);
15
+ if (at === -1)
16
+ return -1;
17
+ const before = line.slice(0, at).replace(new RegExp(`${ESC}\\[[0-9;]*m`, "g"), "");
18
+ return [...before].length;
19
+ }
20
+ describe("Loader light sweep covers the whole line", () => {
21
+ test("the band travels past the spinner's 10-frame window", () => {
22
+ vi.useFakeTimers();
23
+ try {
24
+ const stub = { requestRender: () => { } };
25
+ const message = "bash · a fairly long command line that keeps working";
26
+ const loader = new Loader(stub, (s) => s, (s) => s, message);
27
+ loader.start();
28
+ const seen = [];
29
+ // 40 ticks × 80ms: well past the 10-frame modulo the bug was capped at.
30
+ for (let tick = 0; tick < 40; tick++) {
31
+ vi.advanceTimersByTime(80);
32
+ seen.push(bandCell(messageRow(loader)));
33
+ }
34
+ const lit = seen.filter((i) => i >= 0);
35
+ expect(lit.length).toBeGreaterThan(0);
36
+ // Pre-fix the band never left cells 0..9.
37
+ expect(Math.max(...lit)).toBeGreaterThan(12);
38
+ }
39
+ finally {
40
+ vi.useRealTimers();
41
+ }
42
+ });
43
+ test("over one full period every cell is lit at least once", () => {
44
+ vi.useFakeTimers();
45
+ try {
46
+ const stub = { requestRender: () => { } };
47
+ const message = "abcdefghijklmnopqrstuvwxyz0123456789"; // 36 cells
48
+ const loader = new Loader(stub, (s) => s, (s) => s, message);
49
+ loader.start();
50
+ const litCells = new Set();
51
+ for (let tick = 0; tick < 36 + 12 + 2; tick++) {
52
+ vi.advanceTimersByTime(80);
53
+ const line = messageRow(loader);
54
+ const idx = bandCell(line);
55
+ if (idx >= 0)
56
+ litCells.add(idx);
57
+ }
58
+ // The band enters from the left padding and leaves on the right, so
59
+ // the entire message gets lit over one pass.
60
+ const covered = [...litCells].filter((i) => i < message.length);
61
+ expect(covered.length).toBeGreaterThan(message.length - 4);
62
+ }
63
+ finally {
64
+ vi.useRealTimers();
65
+ }
66
+ });
67
+ });
@@ -39,6 +39,7 @@ export declare class StdinBuffer extends EventEmitter<StdinBufferEventMap> {
39
39
  private pasteMode;
40
40
  private pasteBuffer;
41
41
  private pendingKittyPrintableCodepoint;
42
+ private extendedEscFlush;
42
43
  constructor(options?: StdinBufferOptions);
43
44
  process(data: string | Buffer): void;
44
45
  private emitDataSequence;
@@ -1 +1 @@
1
- {"version":3,"file":"stdin-buffer.d.ts","sourceRoot":"","sources":["../src/stdin-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAgPtC,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;IACf,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,qBAAa,WAAY,SAAQ,YAAY,CAAC,mBAAmB,CAAC;IAChE,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAA8C;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,8BAA8B,CAAqB;gBAE/C,OAAO,GAAE,kBAAuB;IAKrC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAsG3C,OAAO,CAAC,gBAAgB;IAWxB,KAAK,IAAI,MAAM,EAAE;IAgBjB,KAAK,IAAI,IAAI;IAWb,SAAS,IAAI,MAAM;IAInB,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"stdin-buffer.d.ts","sourceRoot":"","sources":["../src/stdin-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAgPtC,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;IACf,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,qBAAa,WAAY,SAAQ,YAAY,CAAC,mBAAmB,CAAC;IAChE,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAA8C;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,GAAE,kBAAuB;IAKrC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAwH3C,OAAO,CAAC,gBAAgB;IAWxB,KAAK,IAAI,MAAM,EAAE;IAgBjB,KAAK,IAAI,IAAI;IAWb,SAAS,IAAI,MAAM;IAInB,OAAO,IAAI,IAAI;CAGhB"}
@@ -230,6 +230,7 @@ export class StdinBuffer extends EventEmitter {
230
230
  pasteMode = false;
231
231
  pasteBuffer = "";
232
232
  pendingKittyPrintableCodepoint;
233
+ extendedEscFlush = false;
233
234
  constructor(options = {}) {
234
235
  super();
235
236
  this.timeoutMs = options.timeout ?? 10;
@@ -312,6 +313,24 @@ export class StdinBuffer extends EventEmitter {
312
313
  }
313
314
  if (this.buffer.length > 0) {
314
315
  this.timeout = setTimeout(() => {
316
+ // A bare ESC flushed by timeout may be the first byte of a Kitty
317
+ // CSI-u sequence whose tail is still in flight: when the event loop
318
+ // was blocked (a long render frame), the timer fires BEFORE the
319
+ // pending stdin read, splitting the sequence — the tail then leaks
320
+ // into the editor as printable text ("[99;1:3u"). Re-arm ONCE so a
321
+ // straggler tail merges; a real Esc press costs one extra window.
322
+ if (this.buffer === "\x1b" && !this.extendedEscFlush) {
323
+ this.extendedEscFlush = true;
324
+ this.timeout = setTimeout(() => {
325
+ this.extendedEscFlush = false;
326
+ const flushed = this.flush();
327
+ for (const sequence of flushed) {
328
+ this.emitDataSequence(sequence);
329
+ }
330
+ }, this.timeoutMs);
331
+ return;
332
+ }
333
+ this.extendedEscFlush = false;
315
334
  const flushed = this.flush();
316
335
  for (const sequence of flushed) {
317
336
  this.emitDataSequence(sequence);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stdin-buffer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin-buffer.test.d.ts","sourceRoot":"","sources":["../src/stdin-buffer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { StdinBuffer } from "./stdin-buffer.js";
3
+ const wait = (ms) => {
4
+ const { promise, resolve } = Promise.withResolvers();
5
+ setTimeout(resolve, ms);
6
+ return promise;
7
+ };
8
+ describe("StdinBuffer bare-ESC flush extension", () => {
9
+ test("split CSI-u sequence merges: tail in the second window joins the ESC", async () => {
10
+ const buf = new StdinBuffer({ timeout: 10 });
11
+ const emitted = [];
12
+ buf.on("data", (s) => emitted.push(s));
13
+ // Event-loop-blocked split: ESC read lands, timer fires before the tail
14
+ // read is processed, tail arrives inside the extended window.
15
+ buf.process("\x1b");
16
+ await wait(15);
17
+ expect(emitted).toEqual([]); // NOT flushed as a lone Esc yet
18
+ buf.process("[99;1:3u");
19
+ await wait(40);
20
+ expect(emitted).toEqual(["\x1b[99;1:3u"]);
21
+ });
22
+ test("a real lone Esc still flushes after the extended window", async () => {
23
+ const buf = new StdinBuffer({ timeout: 10 });
24
+ const emitted = [];
25
+ buf.on("data", (s) => emitted.push(s));
26
+ buf.process("\x1b");
27
+ await wait(60);
28
+ expect(emitted).toEqual(["\x1b"]);
29
+ });
30
+ test("whole CSI-u sequence in one chunk is emitted immediately", async () => {
31
+ const buf = new StdinBuffer({ timeout: 10 });
32
+ const emitted = [];
33
+ buf.on("data", (s) => emitted.push(s));
34
+ buf.process("\x1b[99;1:3u");
35
+ await wait(30);
36
+ expect(emitted).toEqual(["\x1b[99;1:3u"]);
37
+ });
38
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=terminal-reassert.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-reassert.test.d.ts","sourceRoot":"","sources":["../src/terminal-reassert.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { KITTY_KEYBOARD_SET_FLAGS, VirtualTerminal } from "./index.js";
3
+ /** Terminal re-assert contract: after a child process (pty console, shell
4
+ * escape, an interactive command) hands the terminal back, the app owns
5
+ * the modes again. A real session leaked raw CSI-u tails into the editor
6
+ * because the child had changed them. */
7
+ describe("terminal re-assert", () => {
8
+ test("the kitty re-assert uses the SET form, never a second push", () => {
9
+ expect(KITTY_KEYBOARD_SET_FLAGS).toBe("\u001b[=7u");
10
+ // Push form (CSI > flags u) grows the terminal's flag stack per call.
11
+ expect(KITTY_KEYBOARD_SET_FLAGS.includes(">")).toBe(false);
12
+ });
13
+ test("VirtualTerminal satisfies the contract as a no-op", () => {
14
+ const vt = new VirtualTerminal(80, 24);
15
+ expect(typeof vt.reassertTerminalState).toBe("function");
16
+ vt.reassertTerminalState();
17
+ });
18
+ });
@@ -1,3 +1,7 @@
1
+ /** Re-assert form of the Kitty keyboard flags: CSI = flags u SETS them.
2
+ * (The startup query uses the PUSH form `CSI > flags u`; repeating a push
3
+ * on every re-assert would grow the terminal's flag stack.) */
4
+ export declare const KITTY_KEYBOARD_SET_FLAGS = "\u001B[=7u";
1
5
  export type KeyboardProtocolNegotiationSequence = {
2
6
  type: "kitty-flags";
3
7
  flags: number;
@@ -27,6 +31,15 @@ export interface Terminal {
27
31
  moveBy(lines: number): void;
28
32
  hideCursor(): void;
29
33
  showCursor(): void;
34
+ /**
35
+ * Re-assert the terminal modes this app owns: raw mode, the Kitty
36
+ * keyboard-protocol flags, and the hidden cursor. A child process (pty
37
+ * console, shell escape, an interactive command that grabbed /dev/tty)
38
+ * may leave any of them modified; callers re-assert after such a child
39
+ * exits so the user's next keystroke decodes normally instead of leaking
40
+ * raw escape bytes into the editor.
41
+ */
42
+ reassertTerminalState(): void;
30
43
  clearLine(): void;
31
44
  clearFromCursor(): void;
32
45
  clearScreen(): void;
@@ -98,6 +111,7 @@ export declare class ProcessTerminal implements Terminal {
98
111
  get columns(): number;
99
112
  get rows(): number;
100
113
  moveBy(lines: number): void;
114
+ reassertTerminalState(): void;
101
115
  hideCursor(): void;
102
116
  showCursor(): void;
103
117
  clearLine(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
package/dist/terminal.js CHANGED
@@ -11,6 +11,10 @@ const TERMINAL_PROGRESS_ACTIVE_SEQUENCE = "\x1b]9;4;3\x07";
11
11
  const TERMINAL_PROGRESS_CLEAR_SEQUENCE = "\x1b]9;4;0;\x07";
12
12
  const APPLE_TERMINAL_SHIFT_ENTER_SEQUENCE = "\x1b[13;2u";
13
13
  const DESIRED_KITTY_KEYBOARD_PROTOCOL_FLAGS = 7;
14
+ /** Re-assert form of the Kitty keyboard flags: CSI = flags u SETS them.
15
+ * (The startup query uses the PUSH form `CSI > flags u`; repeating a push
16
+ * on every re-assert would grow the terminal's flag stack.) */
17
+ export const KITTY_KEYBOARD_SET_FLAGS = `\x1b[=${DESIRED_KITTY_KEYBOARD_PROTOCOL_FLAGS}u`;
14
18
  const KEYBOARD_PROTOCOL_RESPONSE_FRAGMENT_TIMEOUT_MS = 150;
15
19
  const KITTY_KEYBOARD_PROTOCOL_QUERY = `\x1b[>${DESIRED_KITTY_KEYBOARD_PROTOCOL_FLAGS}u\x1b[?u\x1b[c`;
16
20
  export function parseKeyboardProtocolNegotiationSequence(sequence) {
@@ -387,6 +391,20 @@ export class ProcessTerminal {
387
391
  }
388
392
  // lines === 0: no movement
389
393
  }
394
+ reassertTerminalState() {
395
+ // Raw mode: children routinely flip it back to cooked (echo on).
396
+ if (process.stdin.setRawMode) {
397
+ process.stdin.setRawMode(true);
398
+ }
399
+ // Kitty keyboard flags: re-SET (CSI = flags u) rather than push, so
400
+ // repeated re-asserts cannot grow the terminal's flag stack. A child
401
+ // that cleared them would otherwise leave every keystroke as a legacy
402
+ // byte while the app keeps parsing CSI-u.
403
+ if (this._kittyProtocolActive) {
404
+ process.stdout.write(KITTY_KEYBOARD_SET_FLAGS);
405
+ }
406
+ this.hideCursor();
407
+ }
390
408
  hideCursor() {
391
409
  process.stdout.write("\x1b[?25l");
392
410
  }
@@ -0,0 +1,7 @@
1
+ /** Whether this terminal is known to implement OSC 66. */
2
+ export declare function textSizingSupported(env?: NodeJS.ProcessEnv): boolean;
3
+ export declare function textSizingEnabled(): boolean;
4
+ /** Force the capability on/off (tests, an explicit host setting, `undefined`
5
+ * to fall back to detection). */
6
+ export declare function setTextSizingEnabled(next: boolean | undefined): void;
7
+ //# sourceMappingURL=text-sizing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-sizing.d.ts","sourceRoot":"","sources":["../src/text-sizing.ts"],"names":[],"mappings":"AAaA,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CASjF;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;kCACkC;AAClC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAEpE"}
@@ -0,0 +1,34 @@
1
+ /** OSC 66 text sizing (Kitty ≥0.33, Ghostty): `\x1b]66;s=<n>;<payload>\x1b\\`
2
+ * makes the terminal paint the payload at `n`× the cell size while it still
3
+ * occupies its natural cell width. omp uses it to draw h1 headings double
4
+ * size — the one visual-hierarchy cue a terminal otherwise cannot express.
5
+ *
6
+ * Support is DETECTED but never assumed: a terminal that does not implement
7
+ * OSC 66 swallows the whole sequence, payload included, so the heading would
8
+ * render as a BLANK line. Unknown terminals therefore stay off and only the
9
+ * known implementations opt in; OMA_TEXT_SIZING=1/0 overrides either way. */
10
+ const SUPPORTING_TERM_PROGRAMS = new Set(["ghostty", "kitty", "wezterm"]);
11
+ let override;
12
+ /** Whether this terminal is known to implement OSC 66. */
13
+ export function textSizingSupported(env = process.env) {
14
+ const forced = env.OMA_TEXT_SIZING;
15
+ if (forced === "1")
16
+ return true;
17
+ if (forced === "0")
18
+ return false;
19
+ if (env.KITTY_WINDOW_ID || env.GHOSTTY_RESOURCES_DIR || env.WEZTERM_EXECUTABLE)
20
+ return true;
21
+ const term = env.TERM ?? "";
22
+ if (term.includes("kitty") || term.includes("ghostty") || term.includes("wezterm"))
23
+ return true;
24
+ const program = (env.TERM_PROGRAM ?? "").toLowerCase();
25
+ return SUPPORTING_TERM_PROGRAMS.has(program);
26
+ }
27
+ export function textSizingEnabled() {
28
+ return override ?? textSizingSupported();
29
+ }
30
+ /** Force the capability on/off (tests, an explicit host setting, `undefined`
31
+ * to fall back to detection). */
32
+ export function setTextSizingEnabled(next) {
33
+ override = next;
34
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=text-sizing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-sizing.test.d.ts","sourceRoot":"","sources":["../src/text-sizing.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { afterEach, describe, expect, test } from "bun:test";
2
+ import { setTextSizingEnabled, textSizingEnabled, textSizingSupported } from "./text-sizing.js";
3
+ import { encodeTextSized, visibleWidth } from "./utils.js";
4
+ const ESC = String.fromCharCode(27);
5
+ afterEach(() => setTextSizingEnabled(undefined));
6
+ /** OSC 66 (Kitty ≥0.33 / Ghostty) is the only way a terminal can render a
7
+ * heading larger than body text. An unsupported terminal swallows the whole
8
+ * sequence — payload included — so it must never be sent by accident. */
9
+ describe("OSC 66 text sizing", () => {
10
+ test("an unsupported terminal keeps the capability off", () => {
11
+ expect(textSizingSupported({ TERM: "xterm-256color" })).toBe(false);
12
+ expect(textSizingSupported({ TERM: "screen" })).toBe(false);
13
+ expect(textSizingSupported({})).toBe(false);
14
+ });
15
+ test("known implementations are detected from the environment", () => {
16
+ expect(textSizingSupported({ TERM: "xterm-kitty" })).toBe(true);
17
+ expect(textSizingSupported({ TERM_PROGRAM: "ghostty" })).toBe(true);
18
+ expect(textSizingSupported({ KITTY_WINDOW_ID: "1" })).toBe(true);
19
+ expect(textSizingSupported({ TERM: "xterm-256color", OMA_TEXT_SIZING: "1" })).toBe(true);
20
+ expect(textSizingSupported({ TERM: "xterm-kitty", OMA_TEXT_SIZING: "0" })).toBe(false);
21
+ });
22
+ test("the runtime flag follows detection and can be forced", () => {
23
+ setTextSizingEnabled(true);
24
+ expect(textSizingEnabled()).toBe(true);
25
+ setTextSizingEnabled(false);
26
+ expect(textSizingEnabled()).toBe(false);
27
+ });
28
+ test("a sized span measures at its scale, not zero", () => {
29
+ const sized = encodeTextSized("Report", 2);
30
+ expect(sized.startsWith(`${ESC}]66;s=2;`)).toBe(true);
31
+ expect(sized.endsWith(`${ESC}\\`)).toBe(true);
32
+ // A zero-width reading would let the frame pad over the sized glyphs.
33
+ expect(visibleWidth(sized)).toBe(12);
34
+ expect(visibleWidth(sized)).toBe(visibleWidth(encodeTextSized("Report", 2)));
35
+ // Unscaled text keeps its normal width.
36
+ expect(visibleWidth("Report")).toBe(6);
37
+ expect(encodeTextSized("Report", 1)).toBe("Report");
38
+ });
39
+ test("control bytes cannot break out of the payload", () => {
40
+ const sized = encodeTextSized(`bad${ESC}[31mred`, 2);
41
+ expect(sized.slice(0, -2)).not.toContain(`${ESC}[31m`);
42
+ });
43
+ });
@@ -49,3 +49,39 @@ describe("TUI provider native scrollback", () => {
49
49
  expect(vt.getViewport().slice(-5)).toEqual(["V0", "V1", "V2", "V3", "V4"]);
50
50
  });
51
51
  });
52
+ describe("adaptive render backpressure (omp #4145 port)", () => {
53
+ test("a slow frame pushes the next ordinary paint out proportionally", async () => {
54
+ const vt = new VirtualTerminal(40, 8);
55
+ const tui = new TUI(vt);
56
+ let frames = 0;
57
+ tui.setFrameProvider({
58
+ renderFrame({ rows }) {
59
+ frames++;
60
+ // EVERY frame is expensive — the long-markdown-tail regime the
61
+ // backpressure exists for (~80ms of work per paint).
62
+ const end = performance.now() + 80;
63
+ while (performance.now() < end) {
64
+ /* spin */
65
+ }
66
+ return { viewport: Array.from({ length: rows }, (_, i) => `row ${i} #${frames}`) };
67
+ },
68
+ acknowledgeHistory: () => { },
69
+ });
70
+ tui.requestRender();
71
+ await new Promise((r) => setTimeout(r, 200));
72
+ const afterFirst = frames;
73
+ // Hammer ordinary requests for 300ms: with adaptive backpressure the
74
+ // first (120ms) frame forces the following paint to wait ~240ms, so
75
+ // only a couple more frames land instead of one per request.
76
+ const until = Date.now() + 300;
77
+ while (Date.now() < until) {
78
+ tui.requestRender();
79
+ await new Promise((r) => setTimeout(r, 5));
80
+ }
81
+ const total = frames - afterFirst;
82
+ expect(afterFirst).toBeGreaterThanOrEqual(1);
83
+ // Adaptive floor = 2 × 80ms = 160ms per frame; 300ms of hammering must
84
+ // yield a handful of frames, not one per request (~60 without it).
85
+ expect(total).toBeLessThanOrEqual(4);
86
+ }, 20_000);
87
+ });
package/dist/tui.d.ts CHANGED
@@ -195,9 +195,17 @@ export declare class TUI extends Container {
195
195
  /** Global callback for debug key (Shift+Ctrl+D). Called before input is forwarded to focused component. */
196
196
  onDebug?: () => void;
197
197
  private renderRequested;
198
+ /** Duration of the previous frame (drives adaptive backpressure). */
199
+ private lastFrameCostMs;
198
200
  private renderTimer;
199
201
  private lastRenderAt;
200
202
  private static readonly MIN_RENDER_INTERVAL_MS;
203
+ /** Adaptive backpressure (omp #4145): the next frame starts no sooner than
204
+ * last_frame_start + 2 × last_frame_cost, targeting a ~50% render duty
205
+ * cycle so a heavy frame (long markdown tail) cannot saturate the loop and
206
+ * starve input/loader paints. Capped so a one-off spike cannot lock the
207
+ * UI. */
208
+ private static readonly MAX_ADAPTIVE_RENDER_MS;
201
209
  private cursorRow;
202
210
  private hardwareCursorRow;
203
211
  private showHardwareCursor;
package/dist/tui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.ts"],"names":[],"mappings":"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"}