@mudah-cli/terminal 0.2.0 → 0.4.0

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.
@@ -18,6 +18,21 @@ export interface TerminalCapabilities {
18
18
  readonly osc9: boolean;
19
19
  /** OSC 133 semantic prompt markers (Kitty, WezTerm, iTerm2, VS Code, foot). */
20
20
  readonly osc133: boolean;
21
+ /**
22
+ * The terminal answers OSC 10/11 color queries, so its theme can be read
23
+ * at runtime. Everything modern does; dumb terminals and CI do not.
24
+ */
25
+ readonly themeQuery: boolean;
26
+ /**
27
+ * Kitty graphics protocol (APC `_G`): pixel images in the terminal.
28
+ * Ghostty, Kitty, and WezTerm.
29
+ */
30
+ readonly kittyGraphics: boolean;
31
+ /**
32
+ * Kitty keyboard protocol (CSI u), including key-up when enabled.
33
+ * Ghostty, Kitty, and WezTerm.
34
+ */
35
+ readonly kittyKeyboard: boolean;
21
36
  /** Cursor show/hide is safe. */
22
37
  readonly cursorControl: boolean;
23
38
  /** Best-guess terminal theme. */
@@ -19,6 +19,9 @@ export function detectCapabilities(options = {}) {
19
19
  reducedMotion,
20
20
  osc9: brand === 'ghostty' || brand === 'wezterm',
21
21
  osc133: brand === 'kitty' || brand === 'wezterm' || brand === 'iterm' || brand === 'vscode' || brand === 'foot',
22
+ themeQuery: isTty && brand !== 'apple-terminal' && env['TERM'] !== 'dumb',
23
+ kittyGraphics: isTty && (brand === 'ghostty' || brand === 'kitty' || brand === 'wezterm'),
24
+ kittyKeyboard: isTty && (brand === 'ghostty' || brand === 'kitty' || brand === 'wezterm'),
22
25
  cursorControl: isTty,
23
26
  theme: overrides.theme ?? 'unknown',
24
27
  width: options.width ?? process.stdout.columns ?? 80,
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { OscWriter } from './osc.js';
2
+ /**
3
+ * Kitty graphics protocol (APC `_G`): transmit raw pixels and place them
4
+ * in the terminal. Ghostty, Kitty, and WezTerm speak this. Other terminals
5
+ * ignore APC, so a write is safe anywhere.
6
+ *
7
+ * Quiet mode (`q=2`) is always on: the terminal must not reply, so the
8
+ * key parser never sees an APC acknowledgement.
9
+ */
10
+ export type PixelFormat = 'rgb' | 'rgba';
11
+ export interface KittyImageOptions {
12
+ /** Pixel bytes, tightly packed, row-major, top-left origin. */
13
+ readonly pixels: Uint8Array;
14
+ readonly width: number;
15
+ readonly height: number;
16
+ /** Default `rgba`. */
17
+ readonly format?: PixelFormat;
18
+ /** Image id (1–4294967295). Reusing an id replaces the previous image. */
19
+ readonly id?: number;
20
+ /** Placement id. Pair with `id` so a later frame replaces this one. */
21
+ readonly placementId?: number;
22
+ /** Compress with zlib before base64. Default true. */
23
+ readonly compress?: boolean;
24
+ /** Scale to this many columns. Kitty preserves aspect if `rows` is omitted. */
25
+ readonly columns?: number;
26
+ /** Scale to this many rows. */
27
+ readonly rows?: number;
28
+ /** Do not move the cursor after placing the image. Default true. */
29
+ readonly stay?: boolean;
30
+ }
31
+ /**
32
+ * Encode a framebuffer as one or more Kitty graphics sequences.
33
+ * Chunks stay at most 4096 base64 bytes, as the protocol requires.
34
+ */
35
+ export declare function encodeKittyImage(options: KittyImageOptions): string;
36
+ /**
37
+ * Delete images. `all` wipes every placement. A numeric `id` deletes that
38
+ * image and its placements.
39
+ */
40
+ export declare function encodeKittyDelete(target?: 'all' | {
41
+ id: number;
42
+ }): string;
43
+ /**
44
+ * Place a framebuffer through the Kitty protocol. Reuses `id`/`placementId`
45
+ * so the next call replaces the frame without flicker.
46
+ */
47
+ export declare class KittyGraphics {
48
+ private readonly writer;
49
+ readonly id: number;
50
+ readonly placementId: number;
51
+ constructor(writer: OscWriter, options?: {
52
+ id?: number;
53
+ placementId?: number;
54
+ });
55
+ draw(pixels: Uint8Array, width: number, height: number, options?: Omit<KittyImageOptions, 'pixels' | 'width' | 'height' | 'id' | 'placementId'>): void;
56
+ /** Remove this image (or every image, when `all` is true). */
57
+ delete(all?: boolean): void;
58
+ }
59
+ /**
60
+ * Encode an RGBA/RGB framebuffer as unicode half-blocks (`▀`). Each cell
61
+ * holds two vertical pixels (foreground = top, background = bottom).
62
+ * Works in any truecolor terminal, including those without Kitty graphics.
63
+ */
64
+ export declare function encodeHalfBlocks(pixels: Uint8Array, width: number, height: number, format?: PixelFormat): string[];
@@ -0,0 +1,135 @@
1
+ import { deflateSync } from 'node:zlib';
2
+ const CHUNK = 4096;
3
+ const ST = '\x1b\\';
4
+ function bytesPerPixel(format) {
5
+ return format === 'rgb' ? 3 : 4;
6
+ }
7
+ /** APC wrapper: `ESC _ G <control> ; <payload> ESC \`. */
8
+ function apc(control, payload = '') {
9
+ return `\x1b_G${control};${payload}${ST}`;
10
+ }
11
+ /**
12
+ * Encode a framebuffer as one or more Kitty graphics sequences.
13
+ * Chunks stay at most 4096 base64 bytes, as the protocol requires.
14
+ */
15
+ export function encodeKittyImage(options) {
16
+ const format = options.format ?? 'rgba';
17
+ const bpp = bytesPerPixel(format);
18
+ const expected = options.width * options.height * bpp;
19
+ if (options.pixels.byteLength < expected) {
20
+ throw new Error(`[terminal] Kitty image payload is ${options.pixels.byteLength} bytes, need ${expected} for ${options.width}x${options.height} ${format}.`);
21
+ }
22
+ const raw = options.pixels.subarray(0, expected);
23
+ const compress = options.compress !== false;
24
+ const body = compress ? deflateSync(raw) : Buffer.from(raw);
25
+ const encoded = body.toString('base64');
26
+ const keys = [
27
+ 'a=T',
28
+ `f=${format === 'rgb' ? 24 : 32}`,
29
+ `s=${options.width}`,
30
+ `v=${options.height}`,
31
+ 'q=2',
32
+ ];
33
+ if (compress)
34
+ keys.push('o=z');
35
+ if (options.id !== undefined && options.id > 0)
36
+ keys.push(`i=${options.id}`);
37
+ if (options.placementId !== undefined && options.placementId > 0) {
38
+ keys.push(`p=${options.placementId}`);
39
+ }
40
+ if (options.columns !== undefined)
41
+ keys.push(`c=${options.columns}`);
42
+ if (options.rows !== undefined)
43
+ keys.push(`r=${options.rows}`);
44
+ if (options.stay !== false)
45
+ keys.push('C=1');
46
+ if (encoded.length <= CHUNK) {
47
+ return apc(keys.join(','), encoded);
48
+ }
49
+ const chunks = [];
50
+ for (let offset = 0; offset < encoded.length; offset += CHUNK) {
51
+ const slice = encoded.slice(offset, offset + CHUNK);
52
+ const last = offset + CHUNK >= encoded.length;
53
+ if (offset === 0) {
54
+ chunks.push(apc(`${keys.join(',')},m=1`, slice));
55
+ }
56
+ else {
57
+ chunks.push(apc(`m=${last ? 0 : 1}`, slice));
58
+ }
59
+ }
60
+ // The loop always emits m=1 on the first chunk. If the payload spanned
61
+ // more than two chunks, the last iteration already set m=0. If it spanned
62
+ // exactly two, the second iteration is last and also sets m=0.
63
+ return chunks.join('');
64
+ }
65
+ /**
66
+ * Delete images. `all` wipes every placement. A numeric `id` deletes that
67
+ * image and its placements.
68
+ */
69
+ export function encodeKittyDelete(target = 'all') {
70
+ if (target === 'all')
71
+ return apc('a=d,d=A,q=2');
72
+ return apc(`a=d,d=i,i=${target.id},q=2`);
73
+ }
74
+ /**
75
+ * Place a framebuffer through the Kitty protocol. Reuses `id`/`placementId`
76
+ * so the next call replaces the frame without flicker.
77
+ */
78
+ export class KittyGraphics {
79
+ writer;
80
+ id;
81
+ placementId;
82
+ constructor(writer, options = {}) {
83
+ this.writer = writer;
84
+ this.id = options.id ?? 1;
85
+ this.placementId = options.placementId ?? 1;
86
+ }
87
+ draw(pixels, width, height, options = {}) {
88
+ this.writer.write(encodeKittyImage({
89
+ pixels,
90
+ width,
91
+ height,
92
+ id: this.id,
93
+ placementId: this.placementId,
94
+ ...options,
95
+ }));
96
+ }
97
+ /** Remove this image (or every image, when `all` is true). */
98
+ delete(all = false) {
99
+ this.writer.write(encodeKittyDelete(all ? 'all' : { id: this.id }));
100
+ }
101
+ }
102
+ /**
103
+ * Encode an RGBA/RGB framebuffer as unicode half-blocks (`▀`). Each cell
104
+ * holds two vertical pixels (foreground = top, background = bottom).
105
+ * Works in any truecolor terminal, including those without Kitty graphics.
106
+ */
107
+ export function encodeHalfBlocks(pixels, width, height, format = 'rgba') {
108
+ const bpp = bytesPerPixel(format);
109
+ const lines = [];
110
+ const rows = Math.ceil(height / 2);
111
+ for (let cy = 0; cy < rows; cy++) {
112
+ let line = '';
113
+ const yTop = cy * 2;
114
+ const yBot = yTop + 1;
115
+ for (let x = 0; x < width; x++) {
116
+ const top = sample(pixels, width, height, x, yTop, bpp);
117
+ const bot = yBot < height ? sample(pixels, width, height, x, yBot, bpp) : top;
118
+ line += `\x1b[38;2;${top.r};${top.g};${top.b}m\x1b[48;2;${bot.r};${bot.g};${bot.b}m▀`;
119
+ }
120
+ line += '\x1b[0m';
121
+ lines.push(line);
122
+ }
123
+ return lines;
124
+ }
125
+ function sample(pixels, width, height, x, y, bpp) {
126
+ if (y >= height)
127
+ y = height - 1;
128
+ const i = (y * width + x) * bpp;
129
+ return {
130
+ r: pixels[i] ?? 0,
131
+ g: pixels[i + 1] ?? 0,
132
+ b: pixels[i + 2] ?? 0,
133
+ };
134
+ }
135
+ //# sourceMappingURL=graphics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphics.js","sourceRoot":"","sources":["../src/graphics.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export { ansi } from './ansi.js';
2
2
  export { detectCapabilities, type CapabilityOverrides, type ColorLevel, type DetectCapabilitiesOptions, type TerminalBrand, type TerminalCapabilities, } from './capabilities.js';
3
3
  export { guardedOsc, osc, type OscWriter } from './osc.js';
4
- export { enterRawMode, KeyParser, parseKeys, type KeyEvent, type KeyName } from './keys.js';
4
+ export { parseOscColor, parseThemeResponses, queryTerminalTheme, relativeLuminance, themeFromBackground, type Rgb, type TerminalTheme, type ThemeQueryFailure, type ThemeQueryInput, type ThemeQueryOptions, type ThemeQueryResult, } from './theme-query.js';
5
+ export { enterRawMode, KeyParser, parseKeys, enableKittyKeyboard, disableKittyKeyboard, KITTY_KEYBOARD, KITTY_KEYBOARD_KEYUP, type KeyEvent, type KeyKind, type KeyName } from './keys.js';
6
+ export { KittyGraphics, encodeHalfBlocks, encodeKittyDelete, encodeKittyImage, type KittyImageOptions, type PixelFormat, } from './graphics.js';
7
+ export { disableMouse, enableMouse, isMouseEvent, parseMouseEvents, type MouseButtons, type MouseEvent, type MouseModeOptions, } from './mouse.js';
5
8
  export { Ticker, type TickerOptions } from './ticker.js';
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  export { ansi } from './ansi.js';
2
2
  export { detectCapabilities, } from './capabilities.js';
3
3
  export { guardedOsc, osc } from './osc.js';
4
- export { enterRawMode, KeyParser, parseKeys } from './keys.js';
4
+ export { parseOscColor, parseThemeResponses, queryTerminalTheme, relativeLuminance, themeFromBackground, } from './theme-query.js';
5
+ export { enterRawMode, KeyParser, parseKeys, enableKittyKeyboard, disableKittyKeyboard, KITTY_KEYBOARD, KITTY_KEYBOARD_KEYUP } from './keys.js';
6
+ export { KittyGraphics, encodeHalfBlocks, encodeKittyDelete, encodeKittyImage, } from './graphics.js';
7
+ export { disableMouse, enableMouse, isMouseEvent, parseMouseEvents, } from './mouse.js';
5
8
  export { Ticker } from './ticker.js';
6
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,kBAAkB,GAMnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,GAAG,EAAkB,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAA+B,MAAM,WAAW,CAAC;AAC5F,OAAO,EAAE,MAAM,EAAsB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,kBAAkB,GAMnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,GAAG,EAAkB,MAAM,UAAU,CAAC;AAC3D,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GAOpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,cAAc,EAAE,oBAAoB,EAA6C,MAAM,WAAW,CAAC;AAC3L,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,gBAAgB,GAIjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAsB,MAAM,aAAa,CAAC"}
package/dist/keys.d.ts CHANGED
@@ -1,14 +1,47 @@
1
1
  import type { ReadStream } from 'node:tty';
2
2
  export type KeyName = 'up' | 'down' | 'left' | 'right' | 'home' | 'end' | 'page-up' | 'page-down' | 'enter' | 'escape' | 'backspace' | 'delete' | 'tab' | 'shift-tab' | 'space' | `ctrl+${string}` | `alt+${string}` | string;
3
+ export type KeyKind = 'press' | 'repeat' | 'release';
3
4
  export interface KeyEvent {
4
5
  name: KeyName;
5
6
  /** Raw character for printable keys. */
6
7
  ch?: string;
8
+ /**
9
+ * How the key moved. Legacy terminals only ever send `press` (and treat
10
+ * auto-repeat as another press). Kitty's keyboard protocol can also send
11
+ * `repeat` and `release`. Omitted means `press`.
12
+ */
13
+ kind?: KeyKind;
14
+ readonly shift?: boolean;
15
+ readonly alt?: boolean;
16
+ readonly ctrl?: boolean;
7
17
  }
18
+ /** Progressive-enhancement bits for the Kitty keyboard protocol. */
19
+ export declare const KITTY_KEYBOARD: {
20
+ /** Disambiguate Esc / alt / ctrl so they never collide with CSI. */
21
+ readonly disambiguate: 1;
22
+ /** Report press, repeat, and release as separate events. */
23
+ readonly eventTypes: 2;
24
+ /** Report shifted / base-layout alternate key codes. */
25
+ readonly alternateKeys: 4;
26
+ /** Send every key (including letters) as a CSI u event. Needed for key-up. */
27
+ readonly allKeys: 8;
28
+ /** Embed associated text in the CSI u sequence. */
29
+ readonly associatedText: 16;
30
+ };
31
+ /**
32
+ * Flags that give games real key-up: disambiguate + event types + all keys.
33
+ * Letter keys otherwise never produce a release event.
34
+ */
35
+ export declare const KITTY_KEYBOARD_KEYUP: number;
36
+ /** Push the Kitty keyboard protocol with `flags`. Default enables key-up. */
37
+ export declare function enableKittyKeyboard(flags?: number): string;
38
+ /** Pop the Kitty keyboard protocol (restore whatever was in force before). */
39
+ export declare function disableKittyKeyboard(): string;
8
40
  /**
9
41
  * Parse a raw input buffer into key events. Pure and synchronous.
10
- * Handles CSI sequences (arrows, home/end, paging, delete), bare escape,
11
- * alt+char, control characters, and printable text.
42
+ * Handles CSI sequences (arrows, home/end, paging, delete, CSI u), Kitty
43
+ * keyboard releases, bare escape, alt+char, control characters, and
44
+ * printable text. APC (Kitty graphics replies) is skipped.
12
45
  */
13
46
  export declare function parseKeys(buffer: string): KeyEvent[];
14
47
  /**
package/dist/keys.js CHANGED
@@ -1,17 +1,55 @@
1
+ import { isMouseEvent } from './mouse.js';
2
+ /** Progressive-enhancement bits for the Kitty keyboard protocol. */
3
+ export const KITTY_KEYBOARD = {
4
+ /** Disambiguate Esc / alt / ctrl so they never collide with CSI. */
5
+ disambiguate: 1,
6
+ /** Report press, repeat, and release as separate events. */
7
+ eventTypes: 2,
8
+ /** Report shifted / base-layout alternate key codes. */
9
+ alternateKeys: 4,
10
+ /** Send every key (including letters) as a CSI u event. Needed for key-up. */
11
+ allKeys: 8,
12
+ /** Embed associated text in the CSI u sequence. */
13
+ associatedText: 16,
14
+ };
15
+ /**
16
+ * Flags that give games real key-up: disambiguate + event types + all keys.
17
+ * Letter keys otherwise never produce a release event.
18
+ */
19
+ export const KITTY_KEYBOARD_KEYUP = KITTY_KEYBOARD.disambiguate | KITTY_KEYBOARD.eventTypes | KITTY_KEYBOARD.allKeys;
20
+ /** Push the Kitty keyboard protocol with `flags`. Default enables key-up. */
21
+ export function enableKittyKeyboard(flags = KITTY_KEYBOARD_KEYUP) {
22
+ return `\x1b[>${flags}u`;
23
+ }
24
+ /** Pop the Kitty keyboard protocol (restore whatever was in force before). */
25
+ export function disableKittyKeyboard() {
26
+ return '\x1b[<u';
27
+ }
1
28
  /**
2
29
  * Parse a raw input buffer into key events. Pure and synchronous.
3
- * Handles CSI sequences (arrows, home/end, paging, delete), bare escape,
4
- * alt+char, control characters, and printable text.
30
+ * Handles CSI sequences (arrows, home/end, paging, delete, CSI u), Kitty
31
+ * keyboard releases, bare escape, alt+char, control characters, and
32
+ * printable text. APC (Kitty graphics replies) is skipped.
5
33
  */
6
34
  export function parseKeys(buffer) {
7
35
  const events = [];
36
+ if (isMouseEvent(buffer))
37
+ return events;
8
38
  let i = 0;
9
39
  while (i < buffer.length) {
10
40
  const char = buffer[i];
11
41
  if (char === '\x1b') {
12
42
  const rest = buffer.slice(i + 1);
43
+ // APC (Kitty graphics): ESC _ ... ST (ESC \). Skip, never a key.
44
+ if (rest.startsWith('_')) {
45
+ const st = rest.indexOf('\x1b\\');
46
+ if (st < 0)
47
+ break;
48
+ i += 1 + st + 2;
49
+ continue;
50
+ }
13
51
  if (rest.startsWith('[') || rest.startsWith('O')) {
14
- const matcher = /^\[([0-9;?]*)([\x40-\x7e])/.exec(rest) ?? /^O([\x40-\x7e])/.exec(rest);
52
+ const matcher = /^\[([0-9;:?]*)([\x40-\x7e])/.exec(rest) ?? /^O([\x40-\x7e])/.exec(rest);
15
53
  if (matcher) {
16
54
  const event = escapeSequence(matcher[1] ?? '', (matcher[2] ?? matcher[1]));
17
55
  if (event)
@@ -19,38 +57,36 @@ export function parseKeys(buffer) {
19
57
  i += 1 + matcher[0].length;
20
58
  continue;
21
59
  }
22
- // Incomplete sequence (should not happen for complete buffers).
23
60
  break;
24
61
  }
25
62
  if (rest.startsWith(' ')) {
26
63
  const ch = rest.slice(1, 2);
27
- events.push({ name: `alt+${ch}`, ch });
64
+ events.push({ name: `alt+${ch}`, ch, alt: true, kind: 'press' });
28
65
  i += 2;
29
66
  continue;
30
67
  }
31
- events.push({ name: 'escape' });
68
+ events.push({ name: 'escape', kind: 'press' });
32
69
  i += 1;
33
70
  continue;
34
71
  }
35
72
  if (char === '\r' || char === '\n') {
36
- events.push({ name: 'enter', ch: '\r' });
73
+ events.push({ name: 'enter', ch: '\r', kind: 'press' });
37
74
  i += 1;
38
75
  continue;
39
76
  }
40
77
  if (char === '\x7f' || char === '\x08') {
41
- events.push({ name: 'backspace' });
78
+ events.push({ name: 'backspace', kind: 'press' });
42
79
  i += 1;
43
80
  continue;
44
81
  }
45
82
  if (char === '\t') {
46
- events.push({ name: 'tab' });
83
+ events.push({ name: 'tab', kind: 'press' });
47
84
  i += 1;
48
85
  continue;
49
86
  }
50
87
  if (char >= '\x01' && char <= '\x1a') {
51
- // ctrl+a .. ctrl+z
52
88
  const letter = String.fromCharCode(char.charCodeAt(0) + 96);
53
- events.push({ name: `ctrl+${letter}` });
89
+ events.push({ name: `ctrl+${letter}`, ctrl: true, kind: 'press' });
54
90
  i += 1;
55
91
  continue;
56
92
  }
@@ -59,48 +95,119 @@ export function parseKeys(buffer) {
59
95
  continue;
60
96
  }
61
97
  if (char === ' ') {
62
- events.push({ name: 'space', ch: ' ' });
98
+ events.push({ name: 'space', ch: ' ', kind: 'press' });
63
99
  i += 1;
64
100
  continue;
65
101
  }
66
- events.push({ name: char, ch: char });
102
+ events.push({ name: char, ch: char, kind: 'press' });
67
103
  i += 1;
68
104
  }
69
105
  return events;
70
106
  }
107
+ function parseModField(field) {
108
+ const [modRaw, typeRaw] = (field ?? '1').split(':');
109
+ const mod = Math.max(0, Number(modRaw ?? '1') - 1);
110
+ const typeNum = typeRaw === undefined || typeRaw === '' ? 1 : Number(typeRaw);
111
+ const kind = typeNum === 3 ? 'release' : typeNum === 2 ? 'repeat' : 'press';
112
+ return {
113
+ shift: (mod & 1) !== 0,
114
+ alt: (mod & 2) !== 0,
115
+ ctrl: (mod & 4) !== 0,
116
+ kind,
117
+ };
118
+ }
119
+ function namedKey(base, mods, ch) {
120
+ let name = base;
121
+ if (mods.ctrl && mods.alt)
122
+ name = `ctrl+alt+${base}`;
123
+ else if (mods.ctrl)
124
+ name = `ctrl+${base}`;
125
+ else if (mods.alt)
126
+ name = `alt+${base}`;
127
+ return { name, ch, kind: mods.kind, shift: mods.shift, alt: mods.alt, ctrl: mods.ctrl };
128
+ }
129
+ /** CSI u / functional-key mapping for the Kitty keyboard protocol. */
130
+ function fromKeyCode(code, mods) {
131
+ switch (code) {
132
+ case 27:
133
+ return { name: 'escape', kind: mods.kind, shift: mods.shift, alt: mods.alt, ctrl: mods.ctrl };
134
+ case 13:
135
+ return { name: 'enter', ch: '\r', kind: mods.kind, shift: mods.shift, alt: mods.alt, ctrl: mods.ctrl };
136
+ case 9:
137
+ return mods.shift
138
+ ? { name: 'shift-tab', kind: mods.kind, shift: true, alt: mods.alt, ctrl: mods.ctrl }
139
+ : { name: 'tab', kind: mods.kind, shift: mods.shift, alt: mods.alt, ctrl: mods.ctrl };
140
+ case 127:
141
+ case 8:
142
+ return { name: 'backspace', kind: mods.kind, shift: mods.shift, alt: mods.alt, ctrl: mods.ctrl };
143
+ case 32:
144
+ return namedKey('space', mods, ' ');
145
+ default:
146
+ break;
147
+ }
148
+ if (code >= 32 && code <= 126) {
149
+ const ch = String.fromCharCode(code);
150
+ const base = ch === ' ' ? 'space' : ch;
151
+ return namedKey(base, mods, ch);
152
+ }
153
+ return null;
154
+ }
71
155
  function escapeSequence(code, letter) {
72
- const param = code.split(';')[0] ?? '';
156
+ const fields = code.split(';');
157
+ const first = fields[0] ?? '';
158
+ const mods = parseModField(fields[1]);
159
+ if (letter === 'u') {
160
+ // CSI ? flags u is a keyboard-flags query reply, not a key.
161
+ if (first.startsWith('?'))
162
+ return null;
163
+ const keyCode = Number((first.split(':')[0] ?? '').replace('?', ''));
164
+ if (!Number.isFinite(keyCode))
165
+ return null;
166
+ return fromKeyCode(keyCode, mods);
167
+ }
168
+ const nav = (name) => ({
169
+ name,
170
+ kind: mods.kind,
171
+ shift: mods.shift,
172
+ alt: mods.alt,
173
+ ctrl: mods.ctrl,
174
+ });
73
175
  switch (letter) {
74
176
  case 'A':
75
- return { name: 'up' };
177
+ return nav('up');
76
178
  case 'B':
77
- return { name: 'down' };
179
+ return nav('down');
78
180
  case 'C':
79
- return { name: 'right' };
181
+ return nav('right');
80
182
  case 'D':
81
- return { name: 'left' };
183
+ return nav('left');
82
184
  case 'H':
83
- return { name: 'home' };
185
+ return nav('home');
84
186
  case 'F':
85
- return { name: 'end' };
187
+ return nav('end');
86
188
  case 'Z':
87
- return { name: 'shift-tab' };
88
- case '~':
189
+ return { name: 'shift-tab', kind: mods.kind, shift: true, alt: mods.alt, ctrl: mods.ctrl };
190
+ case '~': {
191
+ const param = first.split(':')[0] ?? '';
89
192
  switch (param) {
90
193
  case '1':
91
- return { name: 'home' };
194
+ case '7':
195
+ return nav('home');
92
196
  case '2':
197
+ return nav('delete');
93
198
  case '3':
94
- return { name: 'delete' };
199
+ return nav('delete');
95
200
  case '4':
96
- return { name: 'end' };
201
+ case '8':
202
+ return nav('end');
97
203
  case '5':
98
- return { name: 'page-up' };
204
+ return nav('page-up');
99
205
  case '6':
100
- return { name: 'page-down' };
206
+ return nav('page-down');
101
207
  default:
102
208
  return null;
103
209
  }
210
+ }
104
211
  default:
105
212
  return null;
106
213
  }
@@ -118,6 +225,8 @@ export class KeyParser {
118
225
  return [];
119
226
  const ready = this.pending.slice(0, safe);
120
227
  this.pending = this.pending.slice(safe);
228
+ if (isMouseEvent(ready))
229
+ return [];
121
230
  return parseKeys(ready);
122
231
  }
123
232
  /** Index up to which the buffer can be split without cutting a sequence. */
@@ -126,14 +235,26 @@ export class KeyParser {
126
235
  if (esc < 0)
127
236
  return text.length;
128
237
  const rest = text.slice(esc + 1);
238
+ // ST (ESC \): terminator of an APC. The sequence ends two bytes later.
239
+ if (rest.startsWith('\\'))
240
+ return esc + 2;
241
+ if (rest.startsWith('_')) {
242
+ return rest.includes('\x1b\\') ? text.length : -1;
243
+ }
244
+ if (rest.startsWith('[<')) {
245
+ return /^\[<\d+;\d+;\d+[Mm]$/.test(rest) ? text.length : -1;
246
+ }
247
+ if (rest.startsWith('[') && /\d+;\d+;\d+M$/.test(rest)) {
248
+ return text.length;
249
+ }
250
+ if (rest.startsWith('M')) {
251
+ return /^M[\x20-\x7f]{3}$/.test(rest) ? text.length : -1;
252
+ }
129
253
  if (rest.length === 0) {
130
- // Trailing lone ESC at a chunk boundary: terminals deliver CSI
131
- // sequences as single reads, so a bare ESC here IS the escape key.
132
254
  return esc + 1;
133
255
  }
134
256
  if (rest[0] === '[') {
135
- // Complete only when a final byte (0x40–0x7e) terminates the sequence.
136
- return /^\[[0-9;?]*[\x40-\x7e]$/.test(rest) ? text.length : -1;
257
+ return /^\[[0-9;:?]*[\x40-\x7e]$/.test(rest) ? text.length : -1;
137
258
  }
138
259
  if (rest[0] === 'O') {
139
260
  return /^O[\x40-\x7e]$/.test(rest) ? text.length : -1;
@@ -141,7 +262,6 @@ export class KeyParser {
141
262
  if (rest[0] === ' ') {
142
263
  return rest.length >= 2 ? text.length : -1;
143
264
  }
144
- // Bare escape followed by other data: the escape itself is complete.
145
265
  return esc + 1;
146
266
  }
147
267
  }
package/dist/keys.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Mouse input parsing for modern terminals.
3
+ *
4
+ * Terminals report clicks as CSI sequences. Three encodings are in use:
5
+ *
6
+ * - **X10** (`\x1b[Mbxy`) — press only, coordinates capped at 223.
7
+ * - **SGR 1006** (`\x1b[<b;x;yM/m`) — unlimited coordinates, press *and*
8
+ * release. Every terminal worth supporting speaks this.
9
+ * - **Urxvt 1015** (`\x1b[b;x;yM`) — rare; handled for completeness.
10
+ *
11
+ * Programs enable reporting by writing the corresponding mode (see
12
+ * {@link enableMouse} / {@link disableMouse}) and feed raw stdin through
13
+ * {@link parseMouseEvents}. Coordinates arrive 1-based and are normalized
14
+ * to 0-based here, matching how renderers address cells.
15
+ */
16
+ /** Which buttons are held. */
17
+ export interface MouseButtons {
18
+ readonly left: boolean;
19
+ readonly middle: boolean;
20
+ readonly right: boolean;
21
+ /** Fourth button, or wheel-up in some encodings. */
22
+ readonly extra: boolean;
23
+ }
24
+ /** A single mouse event on a cell. */
25
+ export interface MouseEvent {
26
+ /** 0-based column. */
27
+ readonly x: number;
28
+ /** 0-based row. */
29
+ readonly y: number;
30
+ readonly buttons: MouseButtons;
31
+ /** True when no button is pressed (a move or a release). */
32
+ readonly hover: boolean;
33
+ /** True for a button release rather than a press. */
34
+ readonly release: boolean;
35
+ readonly drag: boolean;
36
+ /** Mouse wheel direction, when this event came from a wheel. */
37
+ readonly wheel?: 'up' | 'down';
38
+ /** Set of modifiers held during the event. */
39
+ readonly shift: boolean;
40
+ readonly alt: boolean;
41
+ readonly ctrl: boolean;
42
+ }
43
+ /**
44
+ * Decode a raw input chunk into mouse events. Terminals that don't report
45
+ * the mouse simply never match, so this is safe to run on every keystroke.
46
+ *
47
+ * A terminal speaks one encoding at a time. SGR is tried first, and when it
48
+ * matches the chunk, the older encodings are skipped — otherwise an SGR
49
+ * report can also look like a stray X10 one.
50
+ */
51
+ export declare function parseMouseEvents(buffer: string): MouseEvent[];
52
+ /** True when the buffer looks like a mouse report. */
53
+ export declare function isMouseEvent(buffer: string): boolean;
54
+ export interface MouseModeOptions {
55
+ /** Report motion only while a button is held. */
56
+ drag?: boolean;
57
+ /** Report all motion, even with no button held. */
58
+ motion?: boolean;
59
+ }
60
+ /**
61
+ * The escape sequence that turns mouse reporting on. `1006` (SGR) is always
62
+ * included: it's the only encoding that survives large terminals.
63
+ */
64
+ export declare function enableMouse(options?: MouseModeOptions): string;
65
+ /** The escape sequence that turns mouse reporting off. */
66
+ export declare function disableMouse(options?: MouseModeOptions): string;
package/dist/mouse.js ADDED
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Mouse input parsing for modern terminals.
3
+ *
4
+ * Terminals report clicks as CSI sequences. Three encodings are in use:
5
+ *
6
+ * - **X10** (`\x1b[Mbxy`) — press only, coordinates capped at 223.
7
+ * - **SGR 1006** (`\x1b[<b;x;yM/m`) — unlimited coordinates, press *and*
8
+ * release. Every terminal worth supporting speaks this.
9
+ * - **Urxvt 1015** (`\x1b[b;x;yM`) — rare; handled for completeness.
10
+ *
11
+ * Programs enable reporting by writing the corresponding mode (see
12
+ * {@link enableMouse} / {@link disableMouse}) and feed raw stdin through
13
+ * {@link parseMouseEvents}. Coordinates arrive 1-based and are normalized
14
+ * to 0-based here, matching how renderers address cells.
15
+ */
16
+ const NO_BUTTONS = { left: false, middle: false, right: false, extra: false };
17
+ // \x1b[M<b><x><y> — X10 / 1000 mode, coordinates offset by 32.
18
+ const X10 = /\x1b\[M([\x20-\x7f])([\x20-\x7f])([\x20-\x7f])/g;
19
+ // \x1b[<0;1;2M — SGR 1006: params then a final M (press) or m (release).
20
+ const SGR = /\x1b\[<(\d+);(\d+);(\d+)([Mm])/g;
21
+ // \x1b[0;1;2M — urxvt 1015.
22
+ const URXVT = /\x1b\[(\d+);(\d+);(\d+)M/g;
23
+ /**
24
+ * Decode a raw input chunk into mouse events. Terminals that don't report
25
+ * the mouse simply never match, so this is safe to run on every keystroke.
26
+ *
27
+ * A terminal speaks one encoding at a time. SGR is tried first, and when it
28
+ * matches the chunk, the older encodings are skipped — otherwise an SGR
29
+ * report can also look like a stray X10 one.
30
+ */
31
+ export function parseMouseEvents(buffer) {
32
+ const sgr = [...buffer.matchAll(SGR)];
33
+ if (sgr.length > 0) {
34
+ return sgr.map((match) => decode(Number(match[1]), Number(match[2]) - 1, Number(match[3]) - 1, match[4] === 'm'));
35
+ }
36
+ const x10 = [...buffer.matchAll(X10)];
37
+ if (x10.length > 0) {
38
+ return x10.map((match) => decode(match[1].charCodeAt(0) - 32, match[2].charCodeAt(0) - 33, match[3].charCodeAt(0) - 33, false));
39
+ }
40
+ return [...buffer.matchAll(URXVT)].map((match) => decode(Number(match[1]) - 32, Number(match[2]) - 1, Number(match[3]) - 1, false));
41
+ }
42
+ /** True when the buffer looks like a mouse report. */
43
+ export function isMouseEvent(buffer) {
44
+ return /\x1b\[(M[\x20-\x7f]{3}|<\d+;\d+;\d+[Mm]|\d+;\d+;\d+M)/.test(buffer);
45
+ }
46
+ /**
47
+ * Turn a protocol button code into an event.
48
+ *
49
+ * Layout of the low bits: `0b11` is the button (0 left, 1 middle, 2 right,
50
+ * 3 none), `0b100000` marks motion, `0b100`/`0b1000`/`0b10000` are the
51
+ * shift/alt/ctrl modifiers, and 64/65 are the wheel.
52
+ */
53
+ function decode(code, x, y, release) {
54
+ const wheel = wheelDirection(code);
55
+ const button = code & 0b11;
56
+ const motion = (code & 0b100000) !== 0;
57
+ return {
58
+ x,
59
+ y,
60
+ buttons: wheel === undefined ? buttonsFrom(button, release) : NO_BUTTONS,
61
+ // "No button reported" covers both hover and release; SGR distinguishes
62
+ // them by its final byte, which is what `release` carries.
63
+ hover: wheel === undefined && button === 3 && motion,
64
+ release: wheel === undefined && (release || (button === 3 && !motion)),
65
+ drag: wheel === undefined && motion && button !== 3,
66
+ ...(wheel === undefined ? {} : { wheel }),
67
+ shift: (code & 0b100) !== 0,
68
+ alt: (code & 0b1000) !== 0,
69
+ ctrl: (code & 0b10000) !== 0,
70
+ };
71
+ }
72
+ function wheelDirection(code) {
73
+ // 64 = wheel up, 65 = wheel down (button codes 4 and 5).
74
+ if (code === 64)
75
+ return 'up';
76
+ if (code === 65)
77
+ return 'down';
78
+ return undefined;
79
+ }
80
+ function buttonsFrom(button, release) {
81
+ if (release || button === 3)
82
+ return NO_BUTTONS;
83
+ return {
84
+ left: button === 0,
85
+ middle: button === 1,
86
+ right: button === 2,
87
+ extra: false,
88
+ };
89
+ }
90
+ /**
91
+ * The escape sequence that turns mouse reporting on. `1006` (SGR) is always
92
+ * included: it's the only encoding that survives large terminals.
93
+ */
94
+ export function enableMouse(options = {}) {
95
+ const modes = ['1000', '1006'];
96
+ if (options.drag === true)
97
+ modes.unshift('1002');
98
+ if (options.motion === true)
99
+ modes.unshift('1003');
100
+ return modes.map((mode) => `\x1b[?${mode}h`).join('');
101
+ }
102
+ /** The escape sequence that turns mouse reporting off. */
103
+ export function disableMouse(options = {}) {
104
+ const modes = ['1000', '1006'];
105
+ if (options.drag === true)
106
+ modes.unshift('1002');
107
+ if (options.motion === true)
108
+ modes.unshift('1003');
109
+ return modes.map((mode) => `\x1b[?${mode}l`).join('');
110
+ }
111
+ //# sourceMappingURL=mouse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mouse.js","sourceRoot":"","sources":["../src/mouse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ import type { OscWriter } from './osc.js';
2
+ /** An 8-bit-per-channel sRGB color. */
3
+ export interface Rgb {
4
+ readonly r: number;
5
+ readonly g: number;
6
+ readonly b: number;
7
+ }
8
+ export type TerminalTheme = 'dark' | 'light';
9
+ export type ThemeQueryFailure = 'not-a-tty' | 'timeout' | 'unsupported';
10
+ export interface ThemeQueryResult {
11
+ /** True when at least one color came back from the terminal. */
12
+ readonly ok: boolean;
13
+ /** Reported background (OSC 11), when the terminal answered. */
14
+ readonly background?: Rgb;
15
+ /** Reported foreground (OSC 10), when the terminal answered. */
16
+ readonly foreground?: Rgb;
17
+ /** Theme inferred from the reported colors. */
18
+ readonly theme: TerminalTheme | 'unknown';
19
+ /** Why nothing came back, when `ok` is false. */
20
+ readonly reason?: ThemeQueryFailure;
21
+ }
22
+ /** The subset of a readable stream the query needs. `process.stdin` fits. */
23
+ export interface ThemeQueryInput {
24
+ readonly isTTY?: boolean;
25
+ readonly isRaw?: boolean;
26
+ setRawMode?(enabled: boolean): unknown;
27
+ resume?(): unknown;
28
+ pause?(): unknown;
29
+ on(event: string, listener: (chunk: Buffer | string) => void): unknown;
30
+ off(event: string, listener: (chunk: Buffer | string) => void): unknown;
31
+ }
32
+ export interface ThemeQueryOptions {
33
+ /** Stream the query is written to (default `process.stdout`). */
34
+ stdout?: OscWriter;
35
+ /** Stream the answer is read from (default `process.stdin`). */
36
+ stdin?: ThemeQueryInput;
37
+ /** How long to wait for an answer before giving up. */
38
+ timeoutMs?: number;
39
+ /** Also ask for the foreground color (OSC 10). Default true. */
40
+ includeForeground?: boolean;
41
+ }
42
+ /**
43
+ * Parse a single OSC color payload. Accepts the X11 `rgb:rr/gg/bb` form
44
+ * (1–4 hex digits per channel, scaled to 8 bits) and plain `#rrggbb`.
45
+ * Returns null for anything else.
46
+ */
47
+ export declare function parseOscColor(value: string): Rgb | null;
48
+ /**
49
+ * Pull every OSC 10/11 answer out of a raw input buffer. Input that arrives
50
+ * mid-response is kept by the caller, so this is safe to re-run per chunk.
51
+ */
52
+ export declare function parseThemeResponses(buffer: string): {
53
+ background?: Rgb;
54
+ foreground?: Rgb;
55
+ };
56
+ /** WCAG relative luminance, 0 (black) to 1 (white). */
57
+ export declare function relativeLuminance(color: Rgb): number;
58
+ /**
59
+ * Classify a background as light or dark. `threshold` is the relative
60
+ * luminance that separates the two (default 0.5).
61
+ */
62
+ export declare function themeFromBackground(background: Rgb, threshold?: number): TerminalTheme;
63
+ /**
64
+ * Ask the terminal for its colors with OSC 10 (foreground) and OSC 11
65
+ * (background), then infer light/dark from the answer.
66
+ *
67
+ * Resolves fast on the paths that can't work: no TTY, or a terminal that
68
+ * never answers (timeout). Terminal state (raw mode, flow, listeners) is
69
+ * always restored before this returns.
70
+ */
71
+ export declare function queryTerminalTheme(options?: ThemeQueryOptions): Promise<ThemeQueryResult>;
@@ -0,0 +1,142 @@
1
+ const DEFAULT_TIMEOUT_MS = 150;
2
+ // Terminals answer with either `\x1b]11;rgb:…\x1b\\` (ST) or `\x1b]11;rgb:…\x07` (BEL).
3
+ const RESPONSE = /\x1b\](10|11);([^\x07\x1b]*)(?:\x07|\x1b\\)/g;
4
+ const RGB_FORM = /^rgb:([0-9a-f]{1,4})\/([0-9a-f]{1,4})\/([0-9a-f]{1,4})$/i;
5
+ const HEX_FORM = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;
6
+ /**
7
+ * Parse a single OSC color payload. Accepts the X11 `rgb:rr/gg/bb` form
8
+ * (1–4 hex digits per channel, scaled to 8 bits) and plain `#rrggbb`.
9
+ * Returns null for anything else.
10
+ */
11
+ export function parseOscColor(value) {
12
+ const text = value.trim();
13
+ const rgb = RGB_FORM.exec(text);
14
+ if (rgb) {
15
+ return {
16
+ r: scaleChannel(rgb[1]),
17
+ g: scaleChannel(rgb[2]),
18
+ b: scaleChannel(rgb[3]),
19
+ };
20
+ }
21
+ const hex = HEX_FORM.exec(text);
22
+ if (hex) {
23
+ return {
24
+ r: parseInt(hex[1], 16),
25
+ g: parseInt(hex[2], 16),
26
+ b: parseInt(hex[3], 16),
27
+ };
28
+ }
29
+ return null;
30
+ }
31
+ /** Scale a 1–4 digit hex channel up to the 0–255 range. */
32
+ function scaleChannel(hex) {
33
+ const max = 2 ** (hex.length * 4) - 1;
34
+ return Math.round((parseInt(hex, 16) / max) * 255);
35
+ }
36
+ /**
37
+ * Pull every OSC 10/11 answer out of a raw input buffer. Input that arrives
38
+ * mid-response is kept by the caller, so this is safe to re-run per chunk.
39
+ */
40
+ export function parseThemeResponses(buffer) {
41
+ const found = {};
42
+ for (const match of buffer.matchAll(RESPONSE)) {
43
+ const code = match[1];
44
+ const color = parseOscColor(match[2] ?? '');
45
+ if (color === null)
46
+ continue;
47
+ if (code === '11')
48
+ found.background = color;
49
+ if (code === '10')
50
+ found.foreground = color;
51
+ }
52
+ return found;
53
+ }
54
+ /** WCAG relative luminance, 0 (black) to 1 (white). */
55
+ export function relativeLuminance(color) {
56
+ const channel = (raw) => {
57
+ const c = raw / 255;
58
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
59
+ };
60
+ return (0.2126 * channel(color.r) + 0.7152 * channel(color.g) + 0.0722 * channel(color.b));
61
+ }
62
+ /**
63
+ * Classify a background as light or dark. `threshold` is the relative
64
+ * luminance that separates the two (default 0.5).
65
+ */
66
+ export function themeFromBackground(background, threshold = 0.5) {
67
+ return relativeLuminance(background) >= threshold ? 'light' : 'dark';
68
+ }
69
+ /**
70
+ * Ask the terminal for its colors with OSC 10 (foreground) and OSC 11
71
+ * (background), then infer light/dark from the answer.
72
+ *
73
+ * Resolves fast on the paths that can't work: no TTY, or a terminal that
74
+ * never answers (timeout). Terminal state (raw mode, flow, listeners) is
75
+ * always restored before this returns.
76
+ */
77
+ export async function queryTerminalTheme(options = {}) {
78
+ const stdout = options.stdout ?? process.stdout;
79
+ const stdin = options.stdin ?? process.stdin;
80
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
81
+ const includeForeground = options.includeForeground ?? true;
82
+ if (stdin.isTTY !== true) {
83
+ return { ok: false, theme: 'unknown', reason: 'not-a-tty' };
84
+ }
85
+ let buffer = '';
86
+ let found = {};
87
+ const isSettled = () => found.background !== undefined &&
88
+ (!includeForeground || found.foreground !== undefined);
89
+ let done;
90
+ const finished = new Promise((resolve) => {
91
+ done = resolve;
92
+ });
93
+ const settle = () => {
94
+ clearTimeout(timer);
95
+ stdin.off?.('data', listener);
96
+ if (canRaw && stdin.isRaw !== wasRaw)
97
+ stdin.setRawMode?.(wasRaw);
98
+ if (didResume)
99
+ stdin.pause?.();
100
+ if (found.background === undefined && found.foreground === undefined) {
101
+ done({ ok: false, theme: 'unknown', reason: 'timeout' });
102
+ return;
103
+ }
104
+ done({
105
+ ok: true,
106
+ background: found.background,
107
+ foreground: found.foreground,
108
+ theme: inferTheme(found),
109
+ });
110
+ };
111
+ const listener = (chunk) => {
112
+ buffer += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
113
+ found = parseThemeResponses(buffer);
114
+ if (isSettled())
115
+ settle();
116
+ };
117
+ const canRaw = stdin.setRawMode !== undefined;
118
+ const wasRaw = stdin.isRaw === true;
119
+ const didResume = stdin.resume !== undefined;
120
+ const timer = setTimeout(settle, timeoutMs);
121
+ stdin.on('data', listener);
122
+ if (canRaw && !wasRaw)
123
+ stdin.setRawMode?.(true);
124
+ stdin.resume?.();
125
+ if (includeForeground)
126
+ stdout.write('\x1b]10;?\x1b\\');
127
+ stdout.write('\x1b]11;?\x1b\\');
128
+ return finished;
129
+ }
130
+ /**
131
+ * Background drives the guess. With only a foreground we invert it, which
132
+ * is a weak signal — bright text usually sits on a dark terminal.
133
+ */
134
+ function inferTheme(found) {
135
+ if (found.background !== undefined)
136
+ return themeFromBackground(found.background);
137
+ if (found.foreground !== undefined) {
138
+ return relativeLuminance(found.foreground) >= 0.5 ? 'dark' : 'light';
139
+ }
140
+ return 'unknown';
141
+ }
142
+ //# sourceMappingURL=theme-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-query.js","sourceRoot":"","sources":["../src/theme-query.ts"],"names":[],"mappings":"AAgDA,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,wFAAwF;AACxF,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAChE,MAAM,QAAQ,GAAG,0DAA0D,CAAC;AAC5E,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAEhE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAE1B,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO;YACL,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAW,CAAC;YACjC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAW,CAAC;YACjC,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAW,CAAC;SAClC,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC;YACjC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC;YACjC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAW,EAAE,EAAE,CAAC;SAClC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2DAA2D;AAC3D,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAc;IAEd,MAAM,KAAK,GAA2C,EAAE,CAAC;IAEzD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5C,IAAI,KAAK,KAAK,IAAI;YAAE,SAAS;QAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;QAC5C,IAAI,IAAI,KAAK,IAAI;YAAE,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;IAC9C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,iBAAiB,CAAC,KAAU;IAC1C,MAAM,OAAO,GAAG,CAAC,GAAW,EAAU,EAAE;QACtC,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;QACpB,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,CAAC;IACjE,CAAC,CAAC;IACF,OAAO,CACL,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAClF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAe,EAAE,SAAS,GAAG,GAAG;IAClE,OAAO,iBAAiB,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAO,GAAsB,EAAE;IAE/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAK,OAAO,CAAC,MAA+B,CAAC;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAK,OAAO,CAAC,KAAoC,CAAC;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;IAC1D,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC;IAE5D,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,KAAK,GAA2C,EAAE,CAAC;IAEvD,MAAM,SAAS,GAAG,GAAY,EAAE,CAC9B,KAAK,CAAC,UAAU,KAAK,SAAS;QAC9B,CAAC,CAAC,iBAAiB,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;IAEzD,IAAI,IAAwC,CAAC;IAC7C,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,EAAE;QACzD,IAAI,GAAG,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC9B,IAAI,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;YAAE,KAAK,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC;QACjE,IAAI,SAAS;YAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAE/B,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrE,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC;SACzB,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,KAAsB,EAAQ,EAAE;QAChD,MAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACrE,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,SAAS,EAAE;YAAE,MAAM,EAAE,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC;IAE7C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAE5C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3B,IAAI,MAAM,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;IAChD,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;IAEjB,IAAI,iBAAiB;QAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAEhC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,UAAU,CAAC,KAA6C;IAC/D,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,mBAAmB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjF,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IACvE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mudah-cli/terminal",
3
- "version": "0.2.0",
4
- "description": "Terminal capability detection, OSC feature emitters, and a modern input layer (kitty keyboard, bracketed paste).",
3
+ "version": "0.4.0",
4
+ "description": "Terminal capability detection, OSC emitters, Kitty graphics, Kitty keyboard (key-up), and key/mouse parsing.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "engines": {