@code-yeongyu/senpi 2026.6.12-2 → 2026.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +4 -4
  3. package/dist/cli/startup-ui.d.ts.map +1 -1
  4. package/dist/cli/startup-ui.js +19 -14
  5. package/dist/cli/startup-ui.js.map +1 -1
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +14 -3
  8. package/dist/config.js.map +1 -1
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +3 -2
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts +3 -0
  13. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.d.ts.map +1 -0
  14. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +10 -0
  15. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -0
  16. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  17. package/dist/core/extensions/builtin/prompt-preset/presets.js +12 -0
  18. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  19. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  20. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  21. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  22. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  23. package/dist/core/model-registry.d.ts.map +1 -1
  24. package/dist/core/model-registry.js +6 -57
  25. package/dist/core/model-registry.js.map +1 -1
  26. package/dist/core/model-resolver.d.ts +1 -1
  27. package/dist/core/model-resolver.d.ts.map +1 -1
  28. package/dist/core/model-resolver.js +23 -1
  29. package/dist/core/model-resolver.js.map +1 -1
  30. package/dist/core/package-manager.d.ts +1 -1
  31. package/dist/core/package-manager.d.ts.map +1 -1
  32. package/dist/core/package-manager.js +31 -17
  33. package/dist/core/package-manager.js.map +1 -1
  34. package/dist/core/project-trust.js +2 -2
  35. package/dist/core/project-trust.js.map +1 -1
  36. package/dist/core/resolve-config-value.d.ts +0 -1
  37. package/dist/core/resolve-config-value.d.ts.map +1 -1
  38. package/dist/core/resolve-config-value.js +0 -4
  39. package/dist/core/resolve-config-value.js.map +1 -1
  40. package/dist/core/session-manager.d.ts.map +1 -1
  41. package/dist/core/session-manager.js +11 -2
  42. package/dist/core/session-manager.js.map +1 -1
  43. package/dist/core/trust-manager.d.ts +8 -3
  44. package/dist/core/trust-manager.d.ts.map +1 -1
  45. package/dist/core/trust-manager.js +26 -11
  46. package/dist/core/trust-manager.js.map +1 -1
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +1 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/main.d.ts.map +1 -1
  52. package/dist/main.js +9 -5
  53. package/dist/main.js.map +1 -1
  54. package/dist/migrations.d.ts.map +1 -1
  55. package/dist/migrations.js +1 -123
  56. package/dist/migrations.js.map +1 -1
  57. package/dist/modes/interactive/aborted-error-label.d.ts +2 -0
  58. package/dist/modes/interactive/aborted-error-label.d.ts.map +1 -0
  59. package/dist/modes/interactive/aborted-error-label.js +8 -0
  60. package/dist/modes/interactive/aborted-error-label.js.map +1 -0
  61. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/trust-selector.js +4 -4
  63. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  64. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  65. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  66. package/dist/modes/interactive/interactive-mode.js +39 -15
  67. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  68. package/dist/modes/interactive/theme/theme.d.ts +12 -8
  69. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  70. package/dist/modes/interactive/theme/theme.js +19 -41
  71. package/dist/modes/interactive/theme/theme.js.map +1 -1
  72. package/dist/modes/print-mode.d.ts.map +1 -1
  73. package/dist/modes/print-mode.js +1 -1
  74. package/dist/modes/print-mode.js.map +1 -1
  75. package/dist/modes/rpc/event-output-buffer.d.ts +10 -0
  76. package/dist/modes/rpc/event-output-buffer.d.ts.map +1 -0
  77. package/dist/modes/rpc/event-output-buffer.js +27 -0
  78. package/dist/modes/rpc/event-output-buffer.js.map +1 -0
  79. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  80. package/dist/modes/rpc/jsonl.js +9 -11
  81. package/dist/modes/rpc/jsonl.js.map +1 -1
  82. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  83. package/dist/modes/rpc/rpc-mode.js +17 -7
  84. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  85. package/dist/package-manager-cli.d.ts.map +1 -1
  86. package/dist/package-manager-cli.js +10 -3
  87. package/dist/package-manager-cli.js.map +1 -1
  88. package/dist/utils/shell.d.ts.map +1 -1
  89. package/dist/utils/shell.js +14 -0
  90. package/dist/utils/shell.js.map +1 -1
  91. package/dist/utils/version-check.d.ts.map +1 -1
  92. package/dist/utils/version-check.js +4 -27
  93. package/dist/utils/version-check.js.map +1 -1
  94. package/docs/extensions.md +7 -1
  95. package/docs/models.md +1 -1
  96. package/docs/providers.md +2 -2
  97. package/docs/security.md +9 -5
  98. package/docs/settings.md +3 -3
  99. package/docs/usage.md +4 -4
  100. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  101. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  102. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  103. package/examples/extensions/gondolin/package-lock.json +2 -2
  104. package/examples/extensions/gondolin/package.json +1 -1
  105. package/examples/extensions/sandbox/package-lock.json +2 -2
  106. package/examples/extensions/sandbox/package.json +1 -1
  107. package/examples/extensions/with-deps/package-lock.json +2 -2
  108. package/examples/extensions/with-deps/package.json +1 -1
  109. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +8 -0
  110. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  111. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +6 -1
  112. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  113. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  114. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  115. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +216 -78
  116. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  117. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +410 -304
  118. package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
  119. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  120. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +29 -16
  121. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
  122. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  123. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js +3 -1
  124. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  125. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
  126. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  127. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  128. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  129. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js +15 -21
  130. package/node_modules/@earendil-works/pi-ai/dist/utils/event-stream.js.map +1 -1
  131. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
  132. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  133. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +3 -2
  134. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  135. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  136. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts +1 -1
  137. package/node_modules/@earendil-works/pi-tui/dist/components/editor.d.ts.map +1 -1
  138. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +31 -20
  139. package/node_modules/@earendil-works/pi-tui/dist/components/editor.js.map +1 -1
  140. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts +2 -1
  141. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.d.ts.map +1 -1
  142. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js +18 -2
  143. package/node_modules/@earendil-works/pi-tui/dist/components/markdown.js.map +1 -1
  144. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.d.ts +1 -1
  145. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js +2 -2
  146. package/node_modules/@earendil-works/pi-tui/dist/fuzzy.js.map +1 -1
  147. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -0
  148. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  149. package/node_modules/@earendil-works/pi-tui/dist/index.js +2 -0
  150. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  151. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts +1 -0
  152. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  153. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js +15 -8
  154. package/node_modules/@earendil-works/pi-tui/dist/stdin-buffer.js.map +1 -1
  155. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.d.ts +8 -0
  156. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.d.ts.map +1 -0
  157. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js +51 -0
  158. package/node_modules/@earendil-works/pi-tui/dist/terminal-colors.js.map +1 -0
  159. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts +1 -0
  160. package/node_modules/@earendil-works/pi-tui/dist/terminal.d.ts.map +1 -1
  161. package/node_modules/@earendil-works/pi-tui/dist/terminal.js +9 -1
  162. package/node_modules/@earendil-works/pi-tui/dist/terminal.js.map +1 -1
  163. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +17 -2
  164. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  165. package/node_modules/@earendil-works/pi-tui/dist/tui.js +152 -18
  166. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  167. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  168. package/npm-shrinkwrap.json +25 -12
  169. package/package.json +7 -5
@@ -6,28 +6,42 @@ import * as os from "node:os";
6
6
  import * as path from "node:path";
7
7
  import { performance } from "node:perf_hooks";
8
8
  import { isKeyRelease, matchesKey } from "./keys.js";
9
+ import { isOsc11BackgroundColorResponse, parseOsc11BackgroundColor } from "./terminal-colors.js";
9
10
  import { deleteKittyImage, getCapabilities, isImageLine, setCellDimensions } from "./terminal-image.js";
10
11
  import { extractSegments, normalizeTerminalOutput, sliceByColumn, sliceWithWidth, visibleWidth } from "./utils.js";
11
12
  const KITTY_SEQUENCE_PREFIX = "\x1b_G";
12
- function extractKittyImageIds(line) {
13
+ function parseKittyImageHeader(line) {
13
14
  const sequenceStart = line.indexOf(KITTY_SEQUENCE_PREFIX);
14
15
  if (sequenceStart === -1)
15
- return [];
16
+ return undefined;
16
17
  const paramsStart = sequenceStart + KITTY_SEQUENCE_PREFIX.length;
17
18
  const paramsEnd = line.indexOf(";", paramsStart);
18
19
  if (paramsEnd === -1)
19
- return [];
20
+ return undefined;
21
+ const ids = [];
22
+ let rows = 1;
20
23
  const params = line.slice(paramsStart, paramsEnd);
21
24
  for (const param of params.split(",")) {
22
25
  const [key, value] = param.split("=", 2);
23
- if (key !== "i" || value === undefined)
26
+ if (value === undefined)
24
27
  continue;
25
- const id = Number(value);
26
- if (Number.isInteger(id) && id > 0 && id <= 0xffffffff) {
27
- return [id];
28
+ const numberValue = Number(value);
29
+ if (!Number.isInteger(numberValue) || numberValue <= 0 || numberValue > 0xffffffff)
30
+ continue;
31
+ if (key === "i") {
32
+ ids.push(numberValue);
33
+ }
34
+ else if (key === "r") {
35
+ rows = numberValue;
28
36
  }
29
37
  }
30
- return [];
38
+ return { ids, rows };
39
+ }
40
+ function extractKittyImageIds(line) {
41
+ return parseKittyImageHeader(line)?.ids ?? [];
42
+ }
43
+ function extractKittyImageRows(line) {
44
+ return parseKittyImageHeader(line)?.rows ?? 1;
31
45
  }
32
46
  /** Type guard to check if a component implements Focusable */
33
47
  export function isFocusable(component) {
@@ -107,6 +121,7 @@ export class TUI extends Container {
107
121
  this.inputListeners = new Set();
108
122
  this.renderRequested = false;
109
123
  this.lastRenderAt = 0;
124
+ this.inputRenderPending = false;
110
125
  this.cursorRow = 0; // Logical cursor row (end of rendered content)
111
126
  this.hardwareCursorRow = 0; // Actual terminal cursor row (may differ due to IME positioning)
112
127
  this.showHardwareCursor = process.env.PI_HARDWARE_CURSOR === "1";
@@ -115,6 +130,8 @@ export class TUI extends Container {
115
130
  this.previousViewportTop = 0; // Track previous viewport top for resize-aware cursor moves
116
131
  this.fullRedrawCount = 0;
117
132
  this.stopped = false;
133
+ this.pendingOsc11BackgroundReplies = 0;
134
+ this.pendingOsc11BackgroundQueries = [];
118
135
  // Overlay stack for modal components rendered on top of base content
119
136
  this.focusOrderCounter = 0;
120
137
  this.overlayStack = [];
@@ -462,8 +479,9 @@ export class TUI extends Container {
462
479
  this.maxLinesRendered = 0;
463
480
  this.previousViewportTop = 0;
464
481
  }
465
- requestRender(force = false) {
482
+ requestRender(force = false, source = "unknown") {
466
483
  if (force) {
484
+ this.inputRenderPending = false;
467
485
  this.previousLines = [];
468
486
  this.previousWidth = -1; // -1 triggers widthChanged, forcing a full clear
469
487
  this.previousHeight = -1; // -1 triggers heightChanged, forcing a full clear
@@ -486,6 +504,14 @@ export class TUI extends Container {
486
504
  });
487
505
  return;
488
506
  }
507
+ if (source === "input" || source === "editor.input") {
508
+ if (!this.inputRenderPending) {
509
+ this.inputRenderPending = true;
510
+ this.renderRequested = true;
511
+ process.nextTick(() => this.commitExpeditedRender());
512
+ }
513
+ return;
514
+ }
489
515
  if (this.renderRequested)
490
516
  return;
491
517
  this.renderRequested = true;
@@ -510,7 +536,25 @@ export class TUI extends Container {
510
536
  }
511
537
  }, delay);
512
538
  }
539
+ commitExpeditedRender() {
540
+ if (!this.inputRenderPending)
541
+ return;
542
+ this.inputRenderPending = false;
543
+ if (this.stopped || !this.renderRequested) {
544
+ return;
545
+ }
546
+ if (this.renderTimer) {
547
+ clearTimeout(this.renderTimer);
548
+ this.renderTimer = undefined;
549
+ }
550
+ this.renderRequested = false;
551
+ this.lastRenderAt = performance.now();
552
+ this.doRender();
553
+ }
513
554
  handleInput(data) {
555
+ if (this.consumeOsc11BackgroundResponse(data)) {
556
+ return;
557
+ }
514
558
  if (this.inputListeners.size > 0) {
515
559
  let current = data;
516
560
  for (const listener of this.inputListeners) {
@@ -573,9 +617,30 @@ export class TUI extends Container {
573
617
  return;
574
618
  }
575
619
  this.focusedComponent.handleInput(data);
576
- this.requestRender();
620
+ this.requestRender(false, "input");
577
621
  }
578
622
  }
623
+ consumeOsc11BackgroundResponse(data) {
624
+ if (this.pendingOsc11BackgroundReplies <= 0) {
625
+ return false;
626
+ }
627
+ if (!isOsc11BackgroundColorResponse(data)) {
628
+ return false;
629
+ }
630
+ const rgb = parseOsc11BackgroundColor(data);
631
+ this.pendingOsc11BackgroundReplies -= 1;
632
+ const query = this.pendingOsc11BackgroundQueries.shift();
633
+ if (query && !query.settled) {
634
+ query.settled = true;
635
+ if (query.timer) {
636
+ clearTimeout(query.timer);
637
+ query.timer = undefined;
638
+ }
639
+ query.resolve?.(rgb);
640
+ query.resolve = undefined;
641
+ }
642
+ return true;
643
+ }
579
644
  consumeCellSizeResponse(data) {
580
645
  // Response format: ESC [ 6 ; height ; width t
581
646
  const match = data.match(/^\x1b\[6;(\d+);(\d+)t$/);
@@ -795,14 +860,37 @@ export class TUI extends Container {
795
860
  }
796
861
  return buffer;
797
862
  }
798
- expandLastChangedForKittyImages(firstChanged, lastChanged) {
863
+ getKittyImageReservedRows(lines, index, maxIndex = lines.length - 1) {
864
+ const rows = extractKittyImageRows(lines[index] ?? "");
865
+ if (rows <= 1)
866
+ return 1;
867
+ const maxRows = Math.min(rows, maxIndex - index + 1, lines.length - index);
868
+ let reservedRows = 1;
869
+ while (reservedRows < maxRows) {
870
+ const line = lines[index + reservedRows] ?? "";
871
+ if (isImageLine(line) || visibleWidth(line) > 0)
872
+ break;
873
+ reservedRows++;
874
+ }
875
+ return reservedRows;
876
+ }
877
+ expandChangedRangeForKittyImages(firstChanged, lastChanged, newLines) {
878
+ let expandedFirstChanged = firstChanged;
799
879
  let expandedLastChanged = lastChanged;
800
- for (let i = firstChanged; i < this.previousLines.length; i++) {
801
- if (extractKittyImageIds(this.previousLines[i]).length > 0) {
802
- expandedLastChanged = Math.max(expandedLastChanged, i);
880
+ const expandForLines = (lines) => {
881
+ for (let i = 0; i < lines.length; i++) {
882
+ if (extractKittyImageIds(lines[i]).length === 0)
883
+ continue;
884
+ const blockEnd = i + this.getKittyImageReservedRows(lines, i) - 1;
885
+ if (i >= firstChanged || (i <= lastChanged && blockEnd >= firstChanged)) {
886
+ expandedFirstChanged = Math.min(expandedFirstChanged, i);
887
+ expandedLastChanged = Math.max(expandedLastChanged, blockEnd);
888
+ }
803
889
  }
804
- }
805
- return expandedLastChanged;
890
+ };
891
+ expandForLines(this.previousLines);
892
+ expandForLines(newLines);
893
+ return { firstChanged: expandedFirstChanged, lastChanged: expandedLastChanged };
806
894
  }
807
895
  deleteChangedKittyImages(firstChanged, lastChanged) {
808
896
  if (firstChanged < 0 || lastChanged < firstChanged)
@@ -1086,7 +1174,9 @@ export class TUI extends Container {
1086
1174
  lastChanged = newLines.length - 1;
1087
1175
  }
1088
1176
  if (firstChanged !== -1) {
1089
- lastChanged = this.expandLastChangedForKittyImages(firstChanged, lastChanged);
1177
+ const expandedRange = this.expandChangedRangeForKittyImages(firstChanged, lastChanged, newLines);
1178
+ firstChanged = expandedRange.firstChanged;
1179
+ lastChanged = expandedRange.lastChanged;
1090
1180
  }
1091
1181
  const appendStart = appendedLines && firstChanged === this.previousLines.length && firstChanged > 0;
1092
1182
  const insertScrollPlan = this.createViewportInsertScrollPlan(newLines, prevViewportTop, height, lineCountDelta);
@@ -1249,9 +1339,27 @@ export class TUI extends Container {
1249
1339
  for (let i = firstChanged; i <= renderEnd; i++) {
1250
1340
  if (i > firstChanged)
1251
1341
  buffer += "\r\n";
1252
- buffer += "\x1b[2K"; // Clear current line
1253
1342
  const line = newLines[i];
1254
1343
  const isImage = isImageLine(line);
1344
+ const imageReservedRows = isImage ? this.getKittyImageReservedRows(newLines, i, renderEnd) : 1;
1345
+ if (imageReservedRows > 1) {
1346
+ const imageStartScreenRow = i - viewportTop;
1347
+ if (imageStartScreenRow < 0 || imageStartScreenRow + imageReservedRows > height) {
1348
+ logRedraw(`kitty image pre-clear would scroll (${imageStartScreenRow} + ${imageReservedRows} > ${height})`);
1349
+ fullRender(true);
1350
+ return;
1351
+ }
1352
+ buffer += "\x1b[2K";
1353
+ for (let row = 1; row < imageReservedRows; row++) {
1354
+ buffer += "\r\n\x1b[2K";
1355
+ }
1356
+ buffer += `\x1b[${imageReservedRows - 1}A`;
1357
+ buffer += line;
1358
+ buffer += `\x1b[${imageReservedRows - 1}B`;
1359
+ i += imageReservedRows - 1;
1360
+ continue;
1361
+ }
1362
+ buffer += "\x1b[2K"; // Clear current line
1255
1363
  if (!isImage && visibleWidth(line) > width) {
1256
1364
  // Log all lines to crash file for debugging
1257
1365
  const crashLogPath = path.join(os.homedir(), ".senpi", "agent", "senpi-crash.log");
@@ -1378,5 +1486,31 @@ export class TUI extends Container {
1378
1486
  this.terminal.hideCursor();
1379
1487
  }
1380
1488
  }
1489
+ /**
1490
+ * Query the terminal's default background color with OSC 11 (`ESC ] 11 ; ? BEL`).
1491
+ * @param timeoutMs Query timeout in milliseconds.
1492
+ * @returns Promise containing the parsed RGB color, or undefined if it times out or fails to parse.
1493
+ */
1494
+ queryTerminalBackgroundColor({ timeoutMs }) {
1495
+ return new Promise((resolve) => {
1496
+ const query = {
1497
+ settled: false,
1498
+ resolve,
1499
+ timer: undefined,
1500
+ };
1501
+ query.timer = setTimeout(() => {
1502
+ if (query.settled) {
1503
+ return;
1504
+ }
1505
+ query.settled = true;
1506
+ query.timer = undefined;
1507
+ query.resolve?.(undefined);
1508
+ query.resolve = undefined;
1509
+ }, timeoutMs);
1510
+ this.pendingOsc11BackgroundQueries.push(query);
1511
+ this.pendingOsc11BackgroundReplies += 1;
1512
+ this.terminal.write("\x1b]11;?\x07");
1513
+ });
1514
+ }
1381
1515
  }
1382
1516
  //# sourceMappingURL=tui.js.map