@fairyhunter13/opentui-core 0.1.132 → 0.1.134

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.
@@ -1969,23 +1969,126 @@ class InternalKeyHandler extends KeyHandler {
1969
1969
  }
1970
1970
 
1971
1971
  // src/lib/RGBA.ts
1972
+ var COLOR_TAG_RGB = 256;
1973
+ var COLOR_TAG_DEFAULT = 257;
1974
+ var DEFAULT_FOREGROUND_RGB = [255, 255, 255];
1975
+ var DEFAULT_BACKGROUND_RGB = [0, 0, 0];
1976
+ var RGBA_BUFFER_STRIDE = 5;
1977
+ var ANSI16_RGB = [
1978
+ [0, 0, 0],
1979
+ [128, 0, 0],
1980
+ [0, 128, 0],
1981
+ [128, 128, 0],
1982
+ [0, 0, 128],
1983
+ [128, 0, 128],
1984
+ [0, 128, 128],
1985
+ [192, 192, 192],
1986
+ [128, 128, 128],
1987
+ [255, 0, 0],
1988
+ [0, 255, 0],
1989
+ [255, 255, 0],
1990
+ [0, 0, 255],
1991
+ [255, 0, 255],
1992
+ [0, 255, 255],
1993
+ [255, 255, 255]
1994
+ ];
1995
+ var ANSI_256_CUBE_LEVELS = [0, 95, 135, 175, 215, 255];
1996
+ function normalizeColorTag(tag) {
1997
+ const normalizedTag = tag != null && Number.isFinite(tag) ? Math.round(tag) : COLOR_TAG_RGB;
1998
+ if (normalizedTag === COLOR_TAG_RGB || normalizedTag === COLOR_TAG_DEFAULT) {
1999
+ return normalizedTag;
2000
+ }
2001
+ if (Number.isInteger(normalizedTag) && normalizedTag >= 0 && normalizedTag <= 255) {
2002
+ return normalizedTag;
2003
+ }
2004
+ return COLOR_TAG_RGB;
2005
+ }
2006
+ function normalizeRGBABuffer(buffer) {
2007
+ if (buffer.length === RGBA_BUFFER_STRIDE) {
2008
+ buffer[4] = normalizeColorTag(buffer[4]);
2009
+ return buffer;
2010
+ }
2011
+ const normalized = new Float32Array(RGBA_BUFFER_STRIDE);
2012
+ normalized[0] = buffer[0] ?? 0;
2013
+ normalized[1] = buffer[1] ?? 0;
2014
+ normalized[2] = buffer[2] ?? 0;
2015
+ normalized[3] = buffer[3] ?? 0;
2016
+ normalized[4] = COLOR_TAG_RGB;
2017
+ return normalized;
2018
+ }
2019
+ function withTag(rgba, tag) {
2020
+ const tagged = RGBA.clone(rgba);
2021
+ tagged.tag = tag;
2022
+ return tagged;
2023
+ }
2024
+ function rgbaForAnsi256Index(index) {
2025
+ const [r, g, b] = ansi256IndexToRgb(index);
2026
+ return RGBA.fromInts(r, g, b);
2027
+ }
2028
+ function normalizeIndexedColorIndex(index) {
2029
+ if (!Number.isInteger(index) || index < 0 || index > 255) {
2030
+ throw new RangeError(`Indexed color must be an integer in the range 0..255, got ${index}`);
2031
+ }
2032
+ return index;
2033
+ }
2034
+ function ansi256IndexToRgb(index) {
2035
+ const normalizedIndex = normalizeIndexedColorIndex(index);
2036
+ if (normalizedIndex < ANSI16_RGB.length) {
2037
+ return ANSI16_RGB[normalizedIndex];
2038
+ }
2039
+ if (normalizedIndex < 232) {
2040
+ const cubeIndex = normalizedIndex - 16;
2041
+ const r = Math.floor(cubeIndex / 36);
2042
+ const g = Math.floor(cubeIndex / 6) % 6;
2043
+ const b = cubeIndex % 6;
2044
+ return [ANSI_256_CUBE_LEVELS[r], ANSI_256_CUBE_LEVELS[g], ANSI_256_CUBE_LEVELS[b]];
2045
+ }
2046
+ const value = 8 + (normalizedIndex - 232) * 10;
2047
+ return [value, value, value];
2048
+ }
2049
+ function decodeColorTag(tag) {
2050
+ if (tag === COLOR_TAG_DEFAULT) {
2051
+ return { kind: "default" };
2052
+ }
2053
+ if (tag === COLOR_TAG_RGB) {
2054
+ return { kind: "rgb" };
2055
+ }
2056
+ return { kind: "indexed", index: normalizeIndexedColorIndex(tag) };
2057
+ }
2058
+
1972
2059
  class RGBA {
1973
2060
  buffer;
1974
2061
  constructor(buffer) {
1975
- this.buffer = buffer;
2062
+ this.buffer = normalizeRGBABuffer(buffer);
1976
2063
  }
1977
2064
  static fromArray(array) {
1978
2065
  return new RGBA(array);
1979
2066
  }
1980
- static fromValues(r, g, b, a = 1) {
1981
- return new RGBA(new Float32Array([r, g, b, a]));
2067
+ static fromValues(r, g, b, a = 1, tag = COLOR_TAG_RGB) {
2068
+ return new RGBA(new Float32Array([r, g, b, a, normalizeColorTag(tag)]));
1982
2069
  }
1983
- static fromInts(r, g, b, a = 255) {
1984
- return new RGBA(new Float32Array([r / 255, g / 255, b / 255, a / 255]));
2070
+ static clone(rgba) {
2071
+ return RGBA.fromValues(rgba.r, rgba.g, rgba.b, rgba.a, rgba.tag);
2072
+ }
2073
+ static fromInts(r, g, b, a = 255, tag = COLOR_TAG_RGB) {
2074
+ return new RGBA(new Float32Array([r / 255, g / 255, b / 255, a / 255, normalizeColorTag(tag)]));
1985
2075
  }
1986
2076
  static fromHex(hex) {
1987
2077
  return hexToRgb(hex);
1988
2078
  }
2079
+ static fromIndex(index, snapshot) {
2080
+ const normalizedIndex = normalizeIndexedColorIndex(index);
2081
+ return withTag(snapshot ? parseColor(snapshot) : rgbaForAnsi256Index(normalizedIndex), normalizedIndex);
2082
+ }
2083
+ static defaultForeground(snapshot) {
2084
+ return withTag(snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_FOREGROUND_RGB), COLOR_TAG_DEFAULT);
2085
+ }
2086
+ static defaultBackground(snapshot) {
2087
+ return withTag(snapshot ? parseColor(snapshot) : RGBA.fromInts(...DEFAULT_BACKGROUND_RGB), COLOR_TAG_DEFAULT);
2088
+ }
2089
+ static getIntentTag(rgba) {
2090
+ return rgba.tag;
2091
+ }
1989
2092
  toInts() {
1990
2093
  return [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255), Math.round(this.a * 255)];
1991
2094
  }
@@ -2013,6 +2116,12 @@ class RGBA {
2013
2116
  set a(value) {
2014
2117
  this.buffer[3] = value;
2015
2118
  }
2119
+ get tag() {
2120
+ return normalizeColorTag(this.buffer[4]);
2121
+ }
2122
+ set tag(value) {
2123
+ this.buffer[4] = normalizeColorTag(value);
2124
+ }
2016
2125
  map(fn) {
2017
2126
  return [fn(this.r), fn(this.g), fn(this.b), fn(this.a)];
2018
2127
  }
@@ -2022,9 +2131,15 @@ class RGBA {
2022
2131
  equals(other) {
2023
2132
  if (!other)
2024
2133
  return false;
2025
- return this.r === other.r && this.g === other.g && this.b === other.b && this.a === other.a;
2134
+ return this.r === other.r && this.g === other.g && this.b === other.b && this.a === other.a && this.tag === other.tag;
2026
2135
  }
2027
2136
  }
2137
+ function normalizeColorValue(value) {
2138
+ if (value == null)
2139
+ return null;
2140
+ const rgba = parseColor(value);
2141
+ return { rgba, tag: rgba.tag };
2142
+ }
2028
2143
  function hexToRgb(hex) {
2029
2144
  hex = hex.replace(/^#/, "");
2030
2145
  if (hex.length === 3) {
@@ -5460,6 +5575,7 @@ var kittyKeyMap = {
5460
5575
  57453: "iso_level3_shift",
5461
5576
  57454: "iso_level5_shift"
5462
5577
  };
5578
+ var kittyNamedSingleStrokeKeys = [...new Set(Object.values(kittyKeyMap))];
5463
5579
  function fromKittyMods(mod) {
5464
5580
  return {
5465
5581
  shift: !!(mod & 1),
@@ -5782,6 +5898,9 @@ var keyName = {
5782
5898
  "[Z": "tab"
5783
5899
  };
5784
5900
  var nonAlphanumericKeys = [...Object.values(keyName), "backspace"];
5901
+ var terminalNamedSingleStrokeKeys = [
5902
+ ...new Set(["return", "linefeed", "tab", "escape", "space", ...nonAlphanumericKeys, ...kittyNamedSingleStrokeKeys])
5903
+ ];
5785
5904
  var isShiftKey = (code) => {
5786
5905
  return ["[a", "[b", "[c", "[d", "[e", "[2$", "[3$", "[5$", "[6$", "[7$", "[8$", "[Z"].includes(code);
5787
5906
  };
@@ -10663,6 +10782,38 @@ class TerminalPalette {
10663
10782
  function createTerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource, clock) {
10664
10783
  return new TerminalPalette(stdin, stdout, writeFn, isLegacyTmux, oscSource, clock);
10665
10784
  }
10785
+ var DEFAULT_FOREGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_FOREGROUND_RGB);
10786
+ var DEFAULT_BACKGROUND_FALLBACK = RGBA.fromInts(...DEFAULT_BACKGROUND_RGB);
10787
+ var fallbackAnsi256Palette = null;
10788
+ function getFallbackAnsi256Palette() {
10789
+ if (!fallbackAnsi256Palette) {
10790
+ fallbackAnsi256Palette = Array.from({ length: 256 }, (_, index) => {
10791
+ const [r, g, b] = ansi256IndexToRgb(index);
10792
+ return RGBA.fromInts(r, g, b);
10793
+ });
10794
+ }
10795
+ return fallbackAnsi256Palette;
10796
+ }
10797
+ function normalizeTerminalPalette(colors) {
10798
+ const fallbackPalette = getFallbackAnsi256Palette();
10799
+ return {
10800
+ palette: Array.from({ length: 256 }, (_, index) => {
10801
+ const detected = colors?.palette[index];
10802
+ return detected ? RGBA.fromHex(detected) : RGBA.clone(fallbackPalette[index]);
10803
+ }),
10804
+ defaultForeground: colors?.defaultForeground ? RGBA.fromHex(colors.defaultForeground) : RGBA.clone(DEFAULT_FOREGROUND_FALLBACK),
10805
+ defaultBackground: colors?.defaultBackground ? RGBA.fromHex(colors.defaultBackground) : RGBA.clone(DEFAULT_BACKGROUND_FALLBACK)
10806
+ };
10807
+ }
10808
+ function buildTerminalPaletteSignature(colors) {
10809
+ const normalized = normalizeTerminalPalette(colors);
10810
+ const paletteSignature = normalized.palette.map((color) => color.toInts().join(",")).join(";");
10811
+ return [
10812
+ paletteSignature,
10813
+ normalized.defaultForeground.toInts().join(","),
10814
+ normalized.defaultBackground.toInts().join(",")
10815
+ ].join("|");
10816
+ }
10666
10817
 
10667
10818
  // src/lib/paste.ts
10668
10819
  var PASTE_TEXT_DECODER = new TextDecoder;
@@ -10760,6 +10911,7 @@ class OptimizedBuffer {
10760
10911
  _widthMethod;
10761
10912
  respectAlpha = false;
10762
10913
  _rawBuffers = null;
10914
+ _rawColorTags = null;
10763
10915
  _destroyed = false;
10764
10916
  get ptr() {
10765
10917
  return this.bufferPtr;
@@ -10768,23 +10920,38 @@ class OptimizedBuffer {
10768
10920
  if (this._destroyed)
10769
10921
  throw new Error(`Buffer ${this.id} is destroyed`);
10770
10922
  }
10923
+ ensureRawBufferViews() {
10924
+ if (this._rawBuffers !== null && this._rawColorTags !== null) {
10925
+ return;
10926
+ }
10927
+ const size = this._width * this._height;
10928
+ const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr);
10929
+ const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr);
10930
+ const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr);
10931
+ const fgTagPtr = this.lib.bufferGetFgTagPtr(this.bufferPtr);
10932
+ const bgTagPtr = this.lib.bufferGetBgTagPtr(this.bufferPtr);
10933
+ const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr);
10934
+ this._rawBuffers = {
10935
+ char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
10936
+ fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
10937
+ bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
10938
+ attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4))
10939
+ };
10940
+ this._rawColorTags = {
10941
+ fg: new Uint16Array(toArrayBuffer(fgTagPtr, 0, size * 2)),
10942
+ bg: new Uint16Array(toArrayBuffer(bgTagPtr, 0, size * 2))
10943
+ };
10944
+ }
10771
10945
  get buffers() {
10772
10946
  this.guard();
10773
- if (this._rawBuffers === null) {
10774
- const size = this._width * this._height;
10775
- const charPtr = this.lib.bufferGetCharPtr(this.bufferPtr);
10776
- const fgPtr = this.lib.bufferGetFgPtr(this.bufferPtr);
10777
- const bgPtr = this.lib.bufferGetBgPtr(this.bufferPtr);
10778
- const attributesPtr = this.lib.bufferGetAttributesPtr(this.bufferPtr);
10779
- this._rawBuffers = {
10780
- char: new Uint32Array(toArrayBuffer(charPtr, 0, size * 4)),
10781
- fg: new Float32Array(toArrayBuffer(fgPtr, 0, size * 4 * 4)),
10782
- bg: new Float32Array(toArrayBuffer(bgPtr, 0, size * 4 * 4)),
10783
- attributes: new Uint32Array(toArrayBuffer(attributesPtr, 0, size * 4))
10784
- };
10785
- }
10947
+ this.ensureRawBufferViews();
10786
10948
  return this._rawBuffers;
10787
10949
  }
10950
+ get rawColorTags() {
10951
+ this.guard();
10952
+ this.ensureRawBufferViews();
10953
+ return this._rawColorTags;
10954
+ }
10788
10955
  constructor(lib, ptr2, width, height, options) {
10789
10956
  this.id = options.id || `fb_${OptimizedBuffer.fbIdCounter++}`;
10790
10957
  this.lib = lib;
@@ -10829,6 +10996,7 @@ class OptimizedBuffer {
10829
10996
  getSpanLines() {
10830
10997
  this.guard();
10831
10998
  const { char, fg: fg2, bg: bg2, attributes } = this.buffers;
10999
+ const { fg: fgTag, bg: bgTag } = this.rawColorTags;
10832
11000
  const lines = [];
10833
11001
  const CHAR_FLAG_CONTINUATION = 3221225472 | 0;
10834
11002
  const CHAR_FLAG_MASK = 3221225472 | 0;
@@ -10843,8 +11011,8 @@ class OptimizedBuffer {
10843
11011
  for (let x = 0;x < this._width; x++) {
10844
11012
  const i = y * this._width + x;
10845
11013
  const cp = char[i];
10846
- const cellFg = RGBA.fromValues(fg2[i * 4], fg2[i * 4 + 1], fg2[i * 4 + 2], fg2[i * 4 + 3]);
10847
- const cellBg = RGBA.fromValues(bg2[i * 4], bg2[i * 4 + 1], bg2[i * 4 + 2], bg2[i * 4 + 3]);
11014
+ const cellFg = RGBA.fromValues(fg2[i * 4], fg2[i * 4 + 1], fg2[i * 4 + 2], fg2[i * 4 + 3], fgTag[i]);
11015
+ const cellBg = RGBA.fromValues(bg2[i * 4], bg2[i * 4 + 1], bg2[i * 4 + 2], bg2[i * 4 + 3], bgTag[i]);
10848
11016
  const cellAttrs = attributes[i] & 255;
10849
11017
  const isContinuation = (cp & CHAR_FLAG_MASK) === CHAR_FLAG_CONTINUATION;
10850
11018
  const cellChar = isContinuation ? "" : lineChars[charIdx++] ?? " ";
@@ -10972,6 +11140,7 @@ class OptimizedBuffer {
10972
11140
  this._width = width;
10973
11141
  this._height = height;
10974
11142
  this._rawBuffers = null;
11143
+ this._rawColorTags = null;
10975
11144
  this.lib.bufferResize(this.bufferPtr, width, height);
10976
11145
  }
10977
11146
  drawBox(options) {
@@ -11665,16 +11834,30 @@ var StyledChunkStruct = defineStruct([
11665
11834
  unpackTransform: rgbaUnpackTransform
11666
11835
  }
11667
11836
  ],
11837
+ ["fg_tag", "u16", { default: COLOR_TAG_RGB }],
11838
+ ["bg_tag", "u16", { default: COLOR_TAG_RGB }],
11668
11839
  ["attributes", "u32", { default: 0 }],
11669
11840
  ["link", "char*", { default: "" }],
11670
11841
  ["link_len", "u64", { lengthOf: "link" }]
11671
11842
  ], {
11672
11843
  mapValue: (chunk) => {
11844
+ const normalizedFg = normalizeColorValue(chunk.fg ?? null);
11845
+ const normalizedBg = normalizeColorValue(chunk.bg ?? null);
11673
11846
  if (!chunk.link || typeof chunk.link === "string") {
11674
- return chunk;
11847
+ return {
11848
+ ...chunk,
11849
+ fg: normalizedFg?.rgba ?? null,
11850
+ bg: normalizedBg?.rgba ?? null,
11851
+ fg_tag: normalizedFg?.tag ?? COLOR_TAG_RGB,
11852
+ bg_tag: normalizedBg?.tag ?? COLOR_TAG_RGB
11853
+ };
11675
11854
  }
11676
11855
  return {
11677
11856
  ...chunk,
11857
+ fg: normalizedFg?.rgba ?? null,
11858
+ bg: normalizedBg?.rgba ?? null,
11859
+ fg_tag: normalizedFg?.tag ?? COLOR_TAG_RGB,
11860
+ bg_tag: normalizedBg?.tag ?? COLOR_TAG_RGB,
11678
11861
  link: chunk.link.url
11679
11862
  };
11680
11863
  }
@@ -11703,6 +11886,7 @@ var TerminalCapabilitiesStruct = defineStruct([
11703
11886
  ["kitty_keyboard", "bool_u8"],
11704
11887
  ["kitty_graphics", "bool_u8"],
11705
11888
  ["rgb", "bool_u8"],
11889
+ ["ansi256", "bool_u8"],
11706
11890
  ["unicode", UnicodeMethodEnum],
11707
11891
  ["sgr_pixels", "bool_u8"],
11708
11892
  ["color_scheme_updates", "bool_u8"],
@@ -11966,10 +12150,18 @@ function getOpenTUILib(libPath) {
11966
12150
  args: ["ptr"],
11967
12151
  returns: "ptr"
11968
12152
  },
12153
+ rendererSetPaletteState: {
12154
+ args: ["ptr", "ptr", "usize", "ptr", "ptr", "u32"],
12155
+ returns: "void"
12156
+ },
11969
12157
  queryPixelResolution: {
11970
12158
  args: ["ptr"],
11971
12159
  returns: "void"
11972
12160
  },
12161
+ queryThemeColors: {
12162
+ args: ["ptr"],
12163
+ returns: "void"
12164
+ },
11973
12165
  createOptimizedBuffer: {
11974
12166
  args: ["u32", "u32", "bool", "u8", "ptr", "usize"],
11975
12167
  returns: "ptr"
@@ -12006,6 +12198,14 @@ function getOpenTUILib(libPath) {
12006
12198
  args: ["ptr"],
12007
12199
  returns: "ptr"
12008
12200
  },
12201
+ bufferGetFgTagPtr: {
12202
+ args: ["ptr"],
12203
+ returns: "ptr"
12204
+ },
12205
+ bufferGetBgTagPtr: {
12206
+ args: ["ptr"],
12207
+ returns: "ptr"
12208
+ },
12009
12209
  bufferGetAttributesPtr: {
12010
12210
  args: ["ptr"],
12011
12211
  returns: "ptr"
@@ -12807,7 +13007,7 @@ function getOpenTUILib(libPath) {
12807
13007
  returns: "void"
12808
13008
  },
12809
13009
  syntaxStyleRegister: {
12810
- args: ["ptr", "ptr", "usize", "ptr", "ptr", "u8"],
13010
+ args: ["ptr", "ptr", "usize", "ptr", "ptr", "u32"],
12811
13011
  returns: "u32"
12812
13012
  },
12813
13013
  syntaxStyleResolveByName: {
@@ -13216,6 +13416,18 @@ class FFIRenderLib {
13216
13416
  const height = this.opentui.symbols.getBufferHeight(bufferPtr);
13217
13417
  return new OptimizedBuffer(this, bufferPtr, width, height, { id: "current buffer", widthMethod: "unicode" });
13218
13418
  }
13419
+ rendererSetPaletteState(renderer, palette, defaultForeground, defaultBackground, paletteEpoch) {
13420
+ const paletteBuffer = new Float32Array(palette.length * 4);
13421
+ for (let index = 0;index < palette.length; index++) {
13422
+ const color = palette[index];
13423
+ const base = index * 4;
13424
+ paletteBuffer[base] = color.r;
13425
+ paletteBuffer[base + 1] = color.g;
13426
+ paletteBuffer[base + 2] = color.b;
13427
+ paletteBuffer[base + 3] = color.a;
13428
+ }
13429
+ this.opentui.symbols.rendererSetPaletteState(renderer, paletteBuffer, palette.length, defaultForeground.buffer, defaultBackground.buffer, paletteEpoch >>> 0);
13430
+ }
13219
13431
  bufferGetCharPtr(buffer) {
13220
13432
  const ptr5 = this.opentui.symbols.bufferGetCharPtr(buffer);
13221
13433
  if (!ptr5) {
@@ -13237,6 +13449,20 @@ class FFIRenderLib {
13237
13449
  }
13238
13450
  return ptr5;
13239
13451
  }
13452
+ bufferGetFgTagPtr(buffer) {
13453
+ const ptr5 = this.opentui.symbols.bufferGetFgTagPtr(buffer);
13454
+ if (!ptr5) {
13455
+ throw new Error("Failed to get fg tag pointer");
13456
+ }
13457
+ return ptr5;
13458
+ }
13459
+ bufferGetBgTagPtr(buffer) {
13460
+ const ptr5 = this.opentui.symbols.bufferGetBgTagPtr(buffer);
13461
+ if (!ptr5) {
13462
+ throw new Error("Failed to get bg tag pointer");
13463
+ }
13464
+ return ptr5;
13465
+ }
13240
13466
  bufferGetAttributesPtr(buffer) {
13241
13467
  const ptr5 = this.opentui.symbols.bufferGetAttributesPtr(buffer);
13242
13468
  if (!ptr5) {
@@ -13494,6 +13720,9 @@ class FFIRenderLib {
13494
13720
  queryPixelResolution(renderer) {
13495
13721
  this.opentui.symbols.queryPixelResolution(renderer);
13496
13722
  }
13723
+ queryThemeColors(renderer) {
13724
+ this.opentui.symbols.queryThemeColors(renderer);
13725
+ }
13497
13726
  writeOut(renderer, data) {
13498
13727
  const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
13499
13728
  if (bytes.length === 0)
@@ -14198,6 +14427,7 @@ class FFIRenderLib {
14198
14427
  kitty_keyboard: caps.kitty_keyboard,
14199
14428
  kitty_graphics: caps.kitty_graphics,
14200
14429
  rgb: caps.rgb,
14430
+ ansi256: caps.ansi256,
14201
14431
  unicode: caps.unicode,
14202
14432
  sgr_pixels: caps.sgr_pixels,
14203
14433
  color_scheme_updates: caps.color_scheme_updates,
@@ -14668,6 +14898,7 @@ var RenderableEvents;
14668
14898
  ((RenderableEvents2) => {
14669
14899
  RenderableEvents2["FOCUSED"] = "focused";
14670
14900
  RenderableEvents2["BLURRED"] = "blurred";
14901
+ RenderableEvents2["DESTROYED"] = "destroyed";
14671
14902
  })(RenderableEvents ||= {});
14672
14903
  function isRenderable(obj) {
14673
14904
  return !!obj?.[BrandedRenderable];
@@ -14860,8 +15091,8 @@ class Renderable extends BaseRenderable {
14860
15091
  focus() {
14861
15092
  if (this._isDestroyed || this._focused || !this._focusable)
14862
15093
  return;
14863
- this._ctx.focusRenderable(this);
14864
15094
  this._focused = true;
15095
+ this._ctx.focusRenderable(this);
14865
15096
  this.requestRender();
14866
15097
  this.keypressHandler = (key) => {
14867
15098
  if (this._isDestroyed)
@@ -15535,8 +15766,13 @@ class Renderable extends BaseRenderable {
15535
15766
  const childLayoutNode = renderable.getLayoutNode();
15536
15767
  const insertedIndex = this._childrenInLayoutOrder.length;
15537
15768
  this._childrenInLayoutOrder.push(renderable);
15538
- if (!this._isDestroyed && !renderable.isDestroyed)
15769
+ if (!this._isDestroyed && !renderable.isDestroyed) {
15770
+ const existingParent = childLayoutNode.getParent();
15771
+ if (existingParent && existingParent !== this.yogaNode) {
15772
+ existingParent.removeChild(childLayoutNode);
15773
+ }
15539
15774
  this.yogaNode.insertChild(childLayoutNode, insertedIndex);
15775
+ }
15540
15776
  this.childrenPrimarySortDirty = true;
15541
15777
  this._shouldUpdateBefore.add(renderable);
15542
15778
  this.requestRender();
@@ -15602,8 +15838,13 @@ class Renderable extends BaseRenderable {
15602
15838
  const anchorIndex = this._childrenInLayoutOrder.indexOf(anchor);
15603
15839
  const insertedIndex = Math.max(0, Math.min(anchorIndex, this._childrenInLayoutOrder.length));
15604
15840
  this._childrenInLayoutOrder.splice(insertedIndex, 0, renderable);
15605
- if (!this._isDestroyed && !renderable.isDestroyed)
15841
+ if (!this._isDestroyed && !renderable.isDestroyed) {
15842
+ const existingParent = renderable.getLayoutNode().getParent();
15843
+ if (existingParent && existingParent !== this.yogaNode) {
15844
+ existingParent.removeChild(renderable.getLayoutNode());
15845
+ }
15606
15846
  this.yogaNode.insertChild(renderable.getLayoutNode(), insertedIndex);
15847
+ }
15607
15848
  this._shouldUpdateBefore.add(renderable);
15608
15849
  this.requestRender();
15609
15850
  return insertedIndex;
@@ -15755,6 +15996,7 @@ class Renderable extends BaseRenderable {
15755
15996
  return;
15756
15997
  }
15757
15998
  this._isDestroyed = true;
15999
+ this.emit("destroyed" /* DESTROYED */);
15758
16000
  if (this.parent) {
15759
16001
  this.parent.remove(this.id);
15760
16002
  }
@@ -17634,6 +17876,7 @@ class CodeRenderable extends TextBufferRenderable {
17634
17876
  this._highlightsDirty = true;
17635
17877
  this._highlightSnapshotId++;
17636
17878
  if (this._streaming && !this._drawUnstyledText && this._filetype) {
17879
+ this.requestRender();
17637
17880
  return;
17638
17881
  }
17639
17882
  this.textBuffer.setText(value);
@@ -18253,7 +18496,7 @@ class CapturedWritableStream extends Writable {
18253
18496
  }
18254
18497
  }
18255
18498
 
18256
- // src/lib/keymapping.ts
18499
+ // src/lib/keybinding.internal.ts
18257
18500
  var defaultKeyAliases = {
18258
18501
  enter: "return",
18259
18502
  esc: "escape",
@@ -20435,7 +20678,7 @@ function parsePixelResolution(sequence) {
20435
20678
  return null;
20436
20679
  }
20437
20680
 
20438
- // src/renderer.ts
20681
+ // src/renderer-theme-mode.ts
20439
20682
  var OSC_THEME_RESPONSE = /\x1b](10|11);(?:(?:rgb:)([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)|#([0-9a-fA-F]{6}))(?:\x07|\x1b\\)/g;
20440
20683
  function scaleOscThemeComponent(component) {
20441
20684
  const value = parseInt(component, 16);
@@ -20456,6 +20699,134 @@ function inferThemeModeFromBackgroundColor(color) {
20456
20699
  const brightness = (r * 299 + g * 587 + b * 114) / 1000;
20457
20700
  return brightness > 128 ? "light" : "dark";
20458
20701
  }
20702
+
20703
+ class RendererThemeMode {
20704
+ host;
20705
+ clock;
20706
+ static QUERY_TIMEOUT_MS = 250;
20707
+ _themeMode = null;
20708
+ themeQueryPending = true;
20709
+ themeOscForeground = null;
20710
+ themeOscBackground = null;
20711
+ themeRefreshTimeoutId = null;
20712
+ waiters = new Set;
20713
+ constructor(host, clock2) {
20714
+ this.host = host;
20715
+ this.clock = clock2;
20716
+ }
20717
+ get themeMode() {
20718
+ return this._themeMode;
20719
+ }
20720
+ waitForThemeMode(timeoutMs, isDestroyed) {
20721
+ if (this._themeMode !== null || isDestroyed || timeoutMs === 0) {
20722
+ return Promise.resolve(this._themeMode);
20723
+ }
20724
+ return new Promise((resolve4) => {
20725
+ const waiter = {
20726
+ resolve: resolve4,
20727
+ timeoutHandle: null
20728
+ };
20729
+ if (timeoutMs > 0) {
20730
+ waiter.timeoutHandle = this.clock.setTimeout(() => {
20731
+ this.waiters.delete(waiter);
20732
+ waiter.timeoutHandle = null;
20733
+ resolve4(this._themeMode);
20734
+ }, timeoutMs);
20735
+ }
20736
+ this.waiters.add(waiter);
20737
+ });
20738
+ }
20739
+ cancelRefresh() {
20740
+ if (this.themeRefreshTimeoutId === null) {
20741
+ return;
20742
+ }
20743
+ this.clock.clearTimeout(this.themeRefreshTimeoutId);
20744
+ this.themeRefreshTimeoutId = null;
20745
+ this.themeQueryPending = false;
20746
+ }
20747
+ dispose() {
20748
+ this.cancelRefresh();
20749
+ for (const waiter of this.waiters) {
20750
+ if (waiter.timeoutHandle !== null) {
20751
+ this.clock.clearTimeout(waiter.timeoutHandle);
20752
+ }
20753
+ waiter.resolve(this._themeMode);
20754
+ }
20755
+ this.waiters.clear();
20756
+ }
20757
+ handleSequence(sequence) {
20758
+ if (sequence === "\x1B[?997;1n" || sequence === "\x1B[?997;2n") {
20759
+ this.requestThemeOscColors();
20760
+ return { handled: true, changedMode: null };
20761
+ }
20762
+ let handledOscThemeResponse = false;
20763
+ let match;
20764
+ OSC_THEME_RESPONSE.lastIndex = 0;
20765
+ while (match = OSC_THEME_RESPONSE.exec(sequence)) {
20766
+ handledOscThemeResponse = true;
20767
+ const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]);
20768
+ if (match[1] === "10") {
20769
+ this.themeOscForeground = color;
20770
+ } else {
20771
+ this.themeOscBackground = color;
20772
+ }
20773
+ }
20774
+ if (!handledOscThemeResponse) {
20775
+ return { handled: false, changedMode: null };
20776
+ }
20777
+ if (!this.themeQueryPending) {
20778
+ return { handled: true, changedMode: null };
20779
+ }
20780
+ if (!this.themeOscForeground || !this.themeOscBackground) {
20781
+ return { handled: true, changedMode: null };
20782
+ }
20783
+ const nextMode = inferThemeModeFromBackgroundColor(this.themeOscBackground);
20784
+ const changedMode = this.applyThemeMode(nextMode);
20785
+ this.completeThemeQuery();
20786
+ return { handled: true, changedMode };
20787
+ }
20788
+ clearThemeRefreshTimeout() {
20789
+ if (this.themeRefreshTimeoutId === null) {
20790
+ return;
20791
+ }
20792
+ this.clock.clearTimeout(this.themeRefreshTimeoutId);
20793
+ this.themeRefreshTimeoutId = null;
20794
+ }
20795
+ completeThemeQuery() {
20796
+ this.clearThemeRefreshTimeout();
20797
+ this.themeQueryPending = false;
20798
+ }
20799
+ requestThemeOscColors() {
20800
+ if (this.themeRefreshTimeoutId !== null) {
20801
+ return;
20802
+ }
20803
+ this.themeQueryPending = true;
20804
+ this.themeOscForeground = null;
20805
+ this.themeOscBackground = null;
20806
+ this.host.queryThemeColors();
20807
+ this.clearThemeRefreshTimeout();
20808
+ this.themeRefreshTimeoutId = this.clock.setTimeout(() => {
20809
+ this.completeThemeQuery();
20810
+ }, RendererThemeMode.QUERY_TIMEOUT_MS);
20811
+ }
20812
+ applyThemeMode(mode) {
20813
+ const changed = this._themeMode !== mode;
20814
+ this._themeMode = mode;
20815
+ if (!changed) {
20816
+ return null;
20817
+ }
20818
+ for (const waiter of this.waiters) {
20819
+ if (waiter.timeoutHandle !== null) {
20820
+ this.clock.clearTimeout(waiter.timeoutHandle);
20821
+ }
20822
+ waiter.resolve(mode);
20823
+ }
20824
+ this.waiters.clear();
20825
+ return mode;
20826
+ }
20827
+ }
20828
+
20829
+ // src/renderer.ts
20459
20830
  registerEnvVar({
20460
20831
  name: "OTUI_DUMP_CAPTURES",
20461
20832
  description: "Dump captured stdout and console caches when the renderer exit handler runs.",
@@ -20649,6 +21020,7 @@ var KITTY_FLAG_ALTERNATE_KEYS = 4;
20649
21020
  var KITTY_FLAG_ALL_KEYS_AS_ESCAPES = 8;
20650
21021
  var KITTY_FLAG_REPORT_TEXT = 16;
20651
21022
  var DEFAULT_STDIN_PARSER_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
21023
+ var NATIVE_PALETTE_QUERY_SIZE = 16;
20652
21024
  function buildKittyKeyboardFlags(config) {
20653
21025
  if (!config) {
20654
21026
  return 0;
@@ -20773,6 +21145,7 @@ var CliRenderEvents;
20773
21145
  CliRenderEvents2["RESIZE"] = "resize";
20774
21146
  CliRenderEvents2["FOCUS"] = "focus";
20775
21147
  CliRenderEvents2["BLUR"] = "blur";
21148
+ CliRenderEvents2["FOCUSED_RENDERABLE"] = "focused_renderable";
20776
21149
  CliRenderEvents2["FOCUSED_EDITOR"] = "focused_editor";
20777
21150
  CliRenderEvents2["THEME_MODE"] = "theme_mode";
20778
21151
  CliRenderEvents2["CAPABILITIES"] = "capabilities";
@@ -20910,18 +21283,20 @@ class CliRenderer extends EventEmitter9 {
20910
21283
  lifecyclePasses = new Set;
20911
21284
  _openConsoleOnError = false;
20912
21285
  _paletteDetector = null;
21286
+ _paletteCache = new Map;
20913
21287
  _cachedPalette = null;
20914
21288
  _paletteDetectionPromise = null;
21289
+ _paletteDetectionSize = 0;
21290
+ _paletteEpoch = 0;
21291
+ _publishedPaletteSignature = null;
21292
+ _palettePublishGeneration = 0;
20915
21293
  _onDestroy;
20916
- _themeMode = null;
20917
- _themeModeSource = "none";
20918
- _themeFallbackPending = true;
20919
- _themeOscForeground = null;
20920
- _themeOscBackground = null;
21294
+ themeModeState;
20921
21295
  _terminalFocusState = null;
20922
21296
  sequenceHandlers = [];
20923
21297
  prependedInputHandlers = [];
20924
21298
  shouldRestoreModesOnNextFocus = false;
21299
+ themeModeHandler;
20925
21300
  idleResolvers = [];
20926
21301
  _debugInputs = [];
20927
21302
  _debugModeEnabled = env.OTUI_DEBUG;
@@ -21001,7 +21376,7 @@ Captured external output:
21001
21376
  this.rendererPtr = rendererPtr;
21002
21377
  this.clearOnShutdown = config.clearOnShutdown ?? true;
21003
21378
  this.lib.setClearOnShutdown(this.rendererPtr, this.clearOnShutdown);
21004
- const forwardEnvKeys = config.forwardEnvKeys ?? [...DEFAULT_FORWARDED_ENV_KEYS];
21379
+ const forwardEnvKeys = config.forwardEnvKeys ?? (config.remote ? [] : [...DEFAULT_FORWARDED_ENV_KEYS]);
21005
21380
  for (const key of forwardEnvKeys) {
21006
21381
  const value = process.env[key];
21007
21382
  if (value === undefined)
@@ -21024,6 +21399,18 @@ Captured external output:
21024
21399
  this.targetFps = config.targetFps || 30;
21025
21400
  this.maxFps = config.maxFps || 60;
21026
21401
  this.clock = config.clock ?? new SystemClock;
21402
+ this.themeModeState = new RendererThemeMode({
21403
+ queryThemeColors: () => {
21404
+ this.lib.queryThemeColors(this.rendererPtr);
21405
+ }
21406
+ }, this.clock);
21407
+ this.themeModeHandler = (sequence) => {
21408
+ const result = this.themeModeState.handleSequence(sequence);
21409
+ if (result.changedMode) {
21410
+ this.emit("theme_mode" /* THEME_MODE */, result.changedMode);
21411
+ }
21412
+ return result.handled;
21413
+ };
21027
21414
  this.memorySnapshotInterval = config.memorySnapshotInterval ?? 0;
21028
21415
  this.gatherStats = config.gatherStats || false;
21029
21416
  this.maxStatSamples = config.maxStatSamples || 300;
@@ -21156,20 +21543,29 @@ Captured external output:
21156
21543
  return Math.max(now - then, 0);
21157
21544
  }
21158
21545
  focusRenderable(renderable) {
21159
- if (this._currentFocusedRenderable === renderable)
21546
+ if (this._currentFocusedRenderable === renderable) {
21160
21547
  return;
21161
- const prev = this.currentFocusedEditor;
21162
- this._currentFocusedRenderable?.blur();
21548
+ }
21549
+ const previousRenderable = this._currentFocusedRenderable;
21550
+ const previousEditor = this.currentFocusedEditor;
21163
21551
  this._currentFocusedRenderable = renderable;
21164
- const next = this.currentFocusedEditor;
21165
- if (prev !== next) {
21166
- this.emit("focused_editor" /* FOCUSED_EDITOR */, next, prev);
21552
+ previousRenderable?.blur();
21553
+ const currentEditor = this.currentFocusedEditor;
21554
+ if (previousEditor !== currentEditor) {
21555
+ this.emit("focused_editor" /* FOCUSED_EDITOR */, currentEditor, previousEditor);
21167
21556
  }
21557
+ this.emit("focused_renderable" /* FOCUSED_RENDERABLE */, renderable, previousRenderable);
21168
21558
  }
21169
21559
  blurRenderable(renderable) {
21170
- if (this._currentFocusedRenderable === renderable) {
21171
- this._currentFocusedRenderable = null;
21560
+ if (this._currentFocusedRenderable !== renderable) {
21561
+ return;
21172
21562
  }
21563
+ const previousEditor = this.currentFocusedEditor;
21564
+ this._currentFocusedRenderable = null;
21565
+ if (previousEditor !== null) {
21566
+ this.emit("focused_editor" /* FOCUSED_EDITOR */, null, previousEditor);
21567
+ }
21568
+ this.emit("focused_renderable" /* FOCUSED_RENDERABLE */, null, renderable);
21173
21569
  }
21174
21570
  setCapturedRenderable(renderable) {
21175
21571
  if (this.capturedRenderable === renderable) {
@@ -21385,39 +21781,13 @@ Captured external output:
21385
21781
  return this._capabilities;
21386
21782
  }
21387
21783
  get themeMode() {
21388
- return this._themeMode;
21784
+ return this.themeModeState.themeMode;
21389
21785
  }
21390
21786
  waitForThemeMode(timeoutMs = 1000) {
21391
21787
  if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
21392
21788
  throw new Error("timeoutMs must be a non-negative finite number");
21393
21789
  }
21394
- if (this._themeMode !== null || this._isDestroyed || timeoutMs === 0) {
21395
- return Promise.resolve(this._themeMode);
21396
- }
21397
- return new Promise((resolve4) => {
21398
- let timeoutHandle = null;
21399
- const cleanup = () => {
21400
- if (timeoutHandle !== null) {
21401
- this.clock.clearTimeout(timeoutHandle);
21402
- timeoutHandle = null;
21403
- }
21404
- this.off("theme_mode" /* THEME_MODE */, handleThemeMode);
21405
- this.off("destroy" /* DESTROY */, handleDestroy);
21406
- };
21407
- const finish = () => {
21408
- cleanup();
21409
- resolve4(this._themeMode);
21410
- };
21411
- const handleThemeMode = () => {
21412
- finish();
21413
- };
21414
- const handleDestroy = () => {
21415
- finish();
21416
- };
21417
- this.on("theme_mode" /* THEME_MODE */, handleThemeMode);
21418
- this.on("destroy" /* DESTROY */, handleDestroy);
21419
- timeoutHandle = this.clock.setTimeout(finish, timeoutMs);
21420
- });
21790
+ return this.themeModeState.waitForThemeMode(timeoutMs, this._isDestroyed);
21421
21791
  }
21422
21792
  getDebugInputs() {
21423
21793
  return [...this._debugInputs];
@@ -22224,6 +22594,7 @@ Captured external output:
22224
22594
  }, 120);
22225
22595
  }
22226
22596
  this.queryPixelResolution();
22597
+ this.ensureNativePaletteState();
22227
22598
  }
22228
22599
  stdinListener = ((chunk) => {
22229
22600
  const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
@@ -22266,6 +22637,10 @@ Captured external output:
22266
22637
  }
22267
22638
  this.lib.processCapabilityResponse(this.rendererPtr, sequence);
22268
22639
  this._capabilities = this.lib.getTerminalCapabilities(this.rendererPtr);
22640
+ if (hasStandardCapabilitySignature) {
22641
+ this.forceFullRepaintRequested = true;
22642
+ this.requestRender();
22643
+ }
22269
22644
  this.emit("capabilities" /* CAPABILITIES */, this._capabilities);
22270
22645
  const hadPendingSplitStartupCursorSeed = this.pendingSplitStartupCursorSeed;
22271
22646
  if (hadPendingSplitStartupCursorSeed && hasCursorReport && this._screenMode === "split-footer" && this._externalOutputMode === "capture-stdout") {
@@ -22307,52 +22682,6 @@ Captured external output:
22307
22682
  }
22308
22683
  return false;
22309
22684
  }).bind(this);
22310
- themeModeHandler = ((sequence) => {
22311
- if (sequence === "\x1B[?997;1n") {
22312
- this.applyThemeMode("dark", "csi");
22313
- this._themeFallbackPending = false;
22314
- return true;
22315
- }
22316
- if (sequence === "\x1B[?997;2n") {
22317
- this.applyThemeMode("light", "csi");
22318
- this._themeFallbackPending = false;
22319
- return true;
22320
- }
22321
- let handledOscThemeResponse = false;
22322
- let match;
22323
- OSC_THEME_RESPONSE.lastIndex = 0;
22324
- while (match = OSC_THEME_RESPONSE.exec(sequence)) {
22325
- handledOscThemeResponse = true;
22326
- const color = oscThemeColorToHex(match[2], match[3], match[4], match[5]);
22327
- if (match[1] === "10") {
22328
- this._themeOscForeground = color;
22329
- } else {
22330
- this._themeOscBackground = color;
22331
- }
22332
- }
22333
- if (!handledOscThemeResponse) {
22334
- return false;
22335
- }
22336
- if (!this._themeFallbackPending) {
22337
- return true;
22338
- }
22339
- if (this._themeOscForeground && this._themeOscBackground) {
22340
- this.applyThemeMode(inferThemeModeFromBackgroundColor(this._themeOscBackground), "osc");
22341
- this._themeFallbackPending = false;
22342
- }
22343
- return true;
22344
- }).bind(this);
22345
- applyThemeMode(mode, source) {
22346
- if (source === "osc" && this._themeModeSource === "csi") {
22347
- return;
22348
- }
22349
- const changed = this._themeMode !== mode;
22350
- this._themeMode = mode;
22351
- this._themeModeSource = source;
22352
- if (changed) {
22353
- this.emit("theme_mode" /* THEME_MODE */, mode);
22354
- }
22355
- }
22356
22685
  dispatchSequenceHandlers(sequence) {
22357
22686
  if (this._debugModeEnabled) {
22358
22687
  this._debugInputs.push({
@@ -22887,6 +23216,7 @@ Captured external output:
22887
23216
  });
22888
23217
  this.stdinParser?.reset();
22889
23218
  this.stdin.removeListener("data", this.stdinListener);
23219
+ this.themeModeState.cancelRefresh();
22890
23220
  this.lib.suspendRenderer(this.rendererPtr);
22891
23221
  if (this.stdin.setRawMode) {
22892
23222
  this.stdin.setRawMode(false);
@@ -22987,6 +23317,7 @@ Captured external output:
22987
23317
  this.clock.clearTimeout(this.renderTimeout);
22988
23318
  this.renderTimeout = null;
22989
23319
  }
23320
+ this.themeModeState.cancelRefresh();
22990
23321
  this._isRunning = false;
22991
23322
  this.waitingForPixelResolution = false;
22992
23323
  this.updateStdinParserProtocolContext({
@@ -23023,8 +23354,14 @@ Captured external output:
23023
23354
  this._paletteDetector.cleanup();
23024
23355
  this._paletteDetector = null;
23025
23356
  }
23357
+ this._paletteCache.clear();
23026
23358
  this._paletteDetectionPromise = null;
23359
+ this._paletteDetectionSize = 0;
23027
23360
  this._cachedPalette = null;
23361
+ this._publishedPaletteSignature = null;
23362
+ this._paletteEpoch = 0;
23363
+ this._palettePublishGeneration = 0;
23364
+ this.themeModeState.dispose();
23028
23365
  this.emit("destroy" /* DESTROY */);
23029
23366
  try {
23030
23367
  this.root.destroyRecursively();
@@ -23164,9 +23501,10 @@ Captured external output:
23164
23501
  this.flushPendingSplitCommits(forceSplitRepaint);
23165
23502
  this.pendingSplitFooterTransition = null;
23166
23503
  } else {
23504
+ const force = this.forceFullRepaintRequested;
23167
23505
  this.forceFullRepaintRequested = false;
23168
23506
  this.pendingSplitFooterTransition = null;
23169
- this.lib.render(this.rendererPtr, false);
23507
+ this.lib.render(this.rendererPtr, force);
23170
23508
  }
23171
23509
  this.renderingNative = false;
23172
23510
  }
@@ -23311,13 +23649,63 @@ Captured external output:
23311
23649
  }
23312
23650
  }
23313
23651
  get paletteDetectionStatus() {
23314
- if (this._cachedPalette)
23315
- return "cached";
23316
23652
  if (this._paletteDetectionPromise)
23317
23653
  return "detecting";
23654
+ if (this._paletteCache.size > 0)
23655
+ return "cached";
23318
23656
  return "idle";
23319
23657
  }
23658
+ getCachedPaletteBySize(size) {
23659
+ const exactMatch = this._paletteCache.get(size);
23660
+ if (exactMatch) {
23661
+ return exactMatch;
23662
+ }
23663
+ const largerSize = [...this._paletteCache.keys()].sort((a, b) => a - b).find((candidate) => candidate >= size);
23664
+ if (largerSize === undefined) {
23665
+ return null;
23666
+ }
23667
+ const source = this._paletteCache.get(largerSize);
23668
+ if (!source) {
23669
+ return null;
23670
+ }
23671
+ const projected = {
23672
+ ...source,
23673
+ palette: source.palette.slice(0, size)
23674
+ };
23675
+ this._paletteCache.set(size, projected);
23676
+ return projected;
23677
+ }
23678
+ ensurePaletteDetector() {
23679
+ if (!this._paletteDetector) {
23680
+ const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0;
23681
+ this._paletteDetector = createTerminalPalette(this.stdin, this.stdout, this.writeOut.bind(this), isLegacyTmux, {
23682
+ subscribeOsc: this.subscribeOsc.bind(this)
23683
+ }, this.clock);
23684
+ }
23685
+ return this._paletteDetector;
23686
+ }
23687
+ syncNativePaletteState(colors) {
23688
+ const signature = buildTerminalPaletteSignature(colors);
23689
+ if (this._publishedPaletteSignature !== null && this._publishedPaletteSignature !== signature) {
23690
+ this._paletteEpoch = this._paletteEpoch + 1 >>> 0;
23691
+ }
23692
+ this._publishedPaletteSignature = signature;
23693
+ const normalized = normalizeTerminalPalette(colors);
23694
+ this.lib.rendererSetPaletteState(this.rendererPtr, normalized.palette, normalized.defaultForeground, normalized.defaultBackground, this._paletteEpoch);
23695
+ }
23696
+ ensureNativePaletteState() {
23697
+ if (!this._terminalIsSetup || this._isDestroyed)
23698
+ return;
23699
+ const publishGeneration = this._palettePublishGeneration;
23700
+ this.getPalette({ size: NATIVE_PALETTE_QUERY_SIZE }).then((colors) => {
23701
+ if (this._palettePublishGeneration === publishGeneration) {
23702
+ this.syncNativePaletteState(colors);
23703
+ }
23704
+ this.requestRender();
23705
+ }).catch(() => {});
23706
+ }
23320
23707
  clearPaletteCache() {
23708
+ this._paletteCache.clear();
23321
23709
  this._cachedPalette = null;
23322
23710
  }
23323
23711
  async getPalette(options) {
@@ -23325,31 +23713,65 @@ Captured external output:
23325
23713
  throw new Error("Cannot detect palette while renderer is suspended");
23326
23714
  }
23327
23715
  const requestedSize = options?.size ?? 16;
23328
- if (this._cachedPalette && this._cachedPalette.palette.length !== requestedSize) {
23329
- this._cachedPalette = null;
23330
- }
23331
- if (this._cachedPalette) {
23332
- return this._cachedPalette;
23716
+ const detectionTimeout = options?.timeout;
23717
+ const cachedPalette = this.getCachedPaletteBySize(requestedSize);
23718
+ if (cachedPalette) {
23719
+ this._cachedPalette = cachedPalette;
23720
+ return cachedPalette;
23333
23721
  }
23334
23722
  if (this._paletteDetectionPromise) {
23335
- return this._paletteDetectionPromise;
23336
- }
23337
- if (!this._paletteDetector) {
23338
- const isLegacyTmux = this.capabilities?.terminal?.name?.toLowerCase()?.includes("tmux") && this.capabilities?.terminal?.version?.localeCompare("3.6") < 0;
23339
- this._paletteDetector = createTerminalPalette(this.stdin, this.stdout, this.writeOut.bind(this), isLegacyTmux, {
23340
- subscribeOsc: this.subscribeOsc.bind(this)
23341
- }, this.clock);
23723
+ if (this._paletteDetectionSize >= requestedSize) {
23724
+ return this._paletteDetectionPromise.then((palette) => {
23725
+ const cached = this.getCachedPaletteBySize(requestedSize);
23726
+ if (cached) {
23727
+ this._cachedPalette = cached;
23728
+ return cached;
23729
+ }
23730
+ const projected = {
23731
+ ...palette,
23732
+ palette: palette.palette.slice(0, requestedSize)
23733
+ };
23734
+ this._paletteCache.set(requestedSize, projected);
23735
+ this._cachedPalette = projected;
23736
+ return projected;
23737
+ });
23738
+ }
23739
+ await this._paletteDetectionPromise;
23740
+ const afterWait = this.getCachedPaletteBySize(requestedSize);
23741
+ if (afterWait) {
23742
+ this._cachedPalette = afterWait;
23743
+ return afterWait;
23744
+ }
23342
23745
  }
23343
- this._paletteDetectionPromise = this._paletteDetector.detect(options).then((result) => {
23746
+ const detector = this.ensurePaletteDetector();
23747
+ const publishGeneration = this._palettePublishGeneration;
23748
+ this._paletteDetectionSize = requestedSize;
23749
+ this._paletteDetectionPromise = detector.detect({ ...options, timeout: detectionTimeout }).then((result) => {
23750
+ this._paletteCache.set(result.palette.length, result);
23344
23751
  this._cachedPalette = result;
23345
23752
  this._paletteDetectionPromise = null;
23753
+ this._paletteDetectionSize = 0;
23754
+ if (this._palettePublishGeneration === publishGeneration) {
23755
+ if (result.palette.length >= NATIVE_PALETTE_QUERY_SIZE) {
23756
+ this.syncNativePaletteState(result);
23757
+ } else if (this._terminalIsSetup && !this._paletteCache.has(NATIVE_PALETTE_QUERY_SIZE)) {
23758
+ this.ensureNativePaletteState();
23759
+ }
23760
+ }
23346
23761
  return result;
23762
+ }).catch((error) => {
23763
+ this._paletteDetectionPromise = null;
23764
+ this._paletteDetectionSize = 0;
23765
+ throw error;
23347
23766
  });
23348
- return this._paletteDetectionPromise;
23767
+ const detected = await this._paletteDetectionPromise;
23768
+ const finalPalette = this.getCachedPaletteBySize(requestedSize) ?? detected;
23769
+ this._cachedPalette = finalPalette;
23770
+ return finalPalette;
23349
23771
  }
23350
23772
  }
23351
23773
 
23352
- export { __toESM, __commonJS, __export, __require, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, RGBA, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, decodePasteBytes, stripAnsiSequences, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, TextBufferView, EditBuffer, EditorView, convertThemeToStyles, SyntaxStyle, ANSI, BoxRenderable, TextBufferRenderable, CodeRenderable, isTextNodeRenderable, TextNodeRenderable, RootTextNodeRenderable, TextRenderable, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingAction, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, EditBufferRenderableEvents, isEditBufferRenderable, EditBufferRenderable, calculateRenderGeometry, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
23774
+ export { __toESM, __commonJS, __export, __require, MeasureMode, exports_src, isValidBorderStyle, parseBorderStyle, BorderChars, getBorderFromSides, getBorderSides, borderCharsToArray, BorderCharArrays, KeyEvent, PasteEvent, KeyHandler, InternalKeyHandler, COLOR_TAG_RGB, COLOR_TAG_DEFAULT, DEFAULT_FOREGROUND_RGB, DEFAULT_BACKGROUND_RGB, normalizeIndexedColorIndex, ansi256IndexToRgb, decodeColorTag, RGBA, normalizeColorValue, hexToRgb, rgbToHex, hsvToRgb, parseColor, fonts, measureText, getCharacterPositions, coordinateToCharacterIndex, renderFontToFrameBuffer, TextAttributes, ATTRIBUTE_BASE_BITS, ATTRIBUTE_BASE_MASK, getBaseAttributes, DebugOverlayCorner, TargetChannel, createTextAttributes, attributesWithLink, getLinkId, visualizeRenderableTree, isStyledText, StyledText, stringToStyledText, black, red, green, yellow, blue, magenta, cyan, white, brightBlack, brightRed, brightGreen, brightYellow, brightBlue, brightMagenta, brightCyan, brightWhite, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bold, italic, underline, strikethrough, dim, reverse, blink, fg, bg, link, t, hastToStyledText, SystemClock, nonAlphanumericKeys, terminalNamedSingleStrokeKeys, parseKeypress, LinearScrollAccel, MacOSScrollAccel, parseAlign, parseAlignItems, parseBoxSizing, parseDimension, parseDirection, parseDisplay, parseEdge, parseFlexDirection, parseGutter, parseJustify, parseLogLevel, parseMeasureMode, parseOverflow, parsePositionType, parseUnit, parseWrap, MouseParser, Selection, convertGlobalToLocalSelection, ASCIIFontSelectionHelper, envRegistry, registerEnvVar, clearEnvCache, generateEnvMarkdown, generateEnvColored, env, StdinParser, treeSitterToTextChunks, treeSitterToStyledText, addDefaultParsers, TreeSitterClient, DataPathsManager, getDataPaths, extensionToFiletype, basenameToFiletype, extToFiletype, pathToFiletype, infoStringToFiletype, main, getTreeSitterClient, ExtmarksController, createExtmarksController, TerminalPalette, createTerminalPalette, normalizeTerminalPalette, buildTerminalPaletteSignature, decodePasteBytes, stripAnsiSequences, detectLinks, TextBuffer, SpanInfoStruct, LogLevel2 as LogLevel, setRenderLibPath, resolveRenderLib, OptimizedBuffer, h, isVNode, maybeMakeRenderable, wrapWithDelegates, instantiate, delegate, LayoutEvents, RenderableEvents, isRenderable, BaseRenderable, Renderable, RootRenderable, TextBufferView, EditBuffer, EditorView, convertThemeToStyles, SyntaxStyle, ANSI, BoxRenderable, TextBufferRenderable, CodeRenderable, isTextNodeRenderable, TextNodeRenderable, RootTextNodeRenderable, TextRenderable, defaultKeyAliases, mergeKeyAliases, mergeKeyBindings, getKeyBindingAction, buildKeyBindingsMap, capture, ConsolePosition, TerminalConsole, getObjectsInViewport, EditBufferRenderableEvents, isEditBufferRenderable, EditBufferRenderable, calculateRenderGeometry, buildKittyKeyboardFlags, MouseEvent, MouseButton, createCliRenderer, CliRenderEvents, RendererControlState, CliRenderer };
23353
23775
 
23354
- //# debugId=8C02D415BAC7A02B64756E2164756E21
23355
- //# sourceMappingURL=index-t3rrpex7.js.map
23776
+ //# debugId=A3534BF85C8469EA64756E2164756E21
23777
+ //# sourceMappingURL=index-n2b7w731.js.map