@juliusbrussee/caveman-tui 0.65.2

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 (162) hide show
  1. package/README.md +767 -0
  2. package/dist/autocomplete.d.ts +52 -0
  3. package/dist/autocomplete.d.ts.map +1 -0
  4. package/dist/autocomplete.js +623 -0
  5. package/dist/autocomplete.js.map +1 -0
  6. package/dist/chord.d.ts +57 -0
  7. package/dist/chord.d.ts.map +1 -0
  8. package/dist/chord.js +97 -0
  9. package/dist/chord.js.map +1 -0
  10. package/dist/color-depth.d.ts +17 -0
  11. package/dist/color-depth.d.ts.map +1 -0
  12. package/dist/color-depth.js +147 -0
  13. package/dist/color-depth.js.map +1 -0
  14. package/dist/components/Chapters.d.ts +41 -0
  15. package/dist/components/Chapters.d.ts.map +1 -0
  16. package/dist/components/Chapters.js +103 -0
  17. package/dist/components/Chapters.js.map +1 -0
  18. package/dist/components/DiffView.d.ts +75 -0
  19. package/dist/components/DiffView.d.ts.map +1 -0
  20. package/dist/components/DiffView.js +170 -0
  21. package/dist/components/DiffView.js.map +1 -0
  22. package/dist/components/StatusLine.d.ts +135 -0
  23. package/dist/components/StatusLine.d.ts.map +1 -0
  24. package/dist/components/StatusLine.js +133 -0
  25. package/dist/components/StatusLine.js.map +1 -0
  26. package/dist/components/SubagentOverlay.d.ts +63 -0
  27. package/dist/components/SubagentOverlay.d.ts.map +1 -0
  28. package/dist/components/SubagentOverlay.js +124 -0
  29. package/dist/components/SubagentOverlay.js.map +1 -0
  30. package/dist/components/box.d.ts +22 -0
  31. package/dist/components/box.d.ts.map +1 -0
  32. package/dist/components/box.js +104 -0
  33. package/dist/components/box.js.map +1 -0
  34. package/dist/components/cancellable-loader.d.ts +22 -0
  35. package/dist/components/cancellable-loader.d.ts.map +1 -0
  36. package/dist/components/cancellable-loader.js +35 -0
  37. package/dist/components/cancellable-loader.js.map +1 -0
  38. package/dist/components/editor.d.ts +244 -0
  39. package/dist/components/editor.d.ts.map +1 -0
  40. package/dist/components/editor.js +1861 -0
  41. package/dist/components/editor.js.map +1 -0
  42. package/dist/components/grouped-select-list.d.ts +60 -0
  43. package/dist/components/grouped-select-list.d.ts.map +1 -0
  44. package/dist/components/grouped-select-list.js +312 -0
  45. package/dist/components/grouped-select-list.js.map +1 -0
  46. package/dist/components/image.d.ts +28 -0
  47. package/dist/components/image.d.ts.map +1 -0
  48. package/dist/components/image.js +69 -0
  49. package/dist/components/image.js.map +1 -0
  50. package/dist/components/input.d.ts +37 -0
  51. package/dist/components/input.d.ts.map +1 -0
  52. package/dist/components/input.js +426 -0
  53. package/dist/components/input.js.map +1 -0
  54. package/dist/components/loader.d.ts +26 -0
  55. package/dist/components/loader.d.ts.map +1 -0
  56. package/dist/components/loader.js +67 -0
  57. package/dist/components/loader.js.map +1 -0
  58. package/dist/components/markdown.d.ts +95 -0
  59. package/dist/components/markdown.d.ts.map +1 -0
  60. package/dist/components/markdown.js +663 -0
  61. package/dist/components/markdown.js.map +1 -0
  62. package/dist/components/select-list.d.ts +50 -0
  63. package/dist/components/select-list.d.ts.map +1 -0
  64. package/dist/components/select-list.js +159 -0
  65. package/dist/components/select-list.js.map +1 -0
  66. package/dist/components/settings-list.d.ts +50 -0
  67. package/dist/components/settings-list.d.ts.map +1 -0
  68. package/dist/components/settings-list.js +185 -0
  69. package/dist/components/settings-list.js.map +1 -0
  70. package/dist/components/spacer.d.ts +12 -0
  71. package/dist/components/spacer.d.ts.map +1 -0
  72. package/dist/components/spacer.js +23 -0
  73. package/dist/components/spacer.js.map +1 -0
  74. package/dist/components/spinner.d.ts +35 -0
  75. package/dist/components/spinner.d.ts.map +1 -0
  76. package/dist/components/spinner.js +77 -0
  77. package/dist/components/spinner.js.map +1 -0
  78. package/dist/components/streaming-markdown.d.ts +39 -0
  79. package/dist/components/streaming-markdown.d.ts.map +1 -0
  80. package/dist/components/streaming-markdown.js +137 -0
  81. package/dist/components/streaming-markdown.js.map +1 -0
  82. package/dist/components/text.d.ts +19 -0
  83. package/dist/components/text.d.ts.map +1 -0
  84. package/dist/components/text.js +89 -0
  85. package/dist/components/text.js.map +1 -0
  86. package/dist/components/truncated-text.d.ts +13 -0
  87. package/dist/components/truncated-text.d.ts.map +1 -0
  88. package/dist/components/truncated-text.js +51 -0
  89. package/dist/components/truncated-text.js.map +1 -0
  90. package/dist/editor-component.d.ts +39 -0
  91. package/dist/editor-component.d.ts.map +1 -0
  92. package/dist/editor-component.js +2 -0
  93. package/dist/editor-component.js.map +1 -0
  94. package/dist/fuzzy.d.ts +16 -0
  95. package/dist/fuzzy.d.ts.map +1 -0
  96. package/dist/fuzzy.js +107 -0
  97. package/dist/fuzzy.js.map +1 -0
  98. package/dist/index.d.ts +38 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +59 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/keybindings.d.ts +193 -0
  103. package/dist/keybindings.d.ts.map +1 -0
  104. package/dist/keybindings.js +174 -0
  105. package/dist/keybindings.js.map +1 -0
  106. package/dist/keys.d.ts +170 -0
  107. package/dist/keys.d.ts.map +1 -0
  108. package/dist/keys.js +1124 -0
  109. package/dist/keys.js.map +1 -0
  110. package/dist/kill-ring.d.ts +28 -0
  111. package/dist/kill-ring.d.ts.map +1 -0
  112. package/dist/kill-ring.js +44 -0
  113. package/dist/kill-ring.js.map +1 -0
  114. package/dist/notifications.d.ts +35 -0
  115. package/dist/notifications.d.ts.map +1 -0
  116. package/dist/notifications.js +62 -0
  117. package/dist/notifications.js.map +1 -0
  118. package/dist/osc52.d.ts +28 -0
  119. package/dist/osc52.d.ts.map +1 -0
  120. package/dist/osc52.js +53 -0
  121. package/dist/osc52.js.map +1 -0
  122. package/dist/scroll-buffer.d.ts +67 -0
  123. package/dist/scroll-buffer.d.ts.map +1 -0
  124. package/dist/scroll-buffer.js +222 -0
  125. package/dist/scroll-buffer.js.map +1 -0
  126. package/dist/spinners.d.ts +26 -0
  127. package/dist/spinners.d.ts.map +1 -0
  128. package/dist/spinners.js +136 -0
  129. package/dist/spinners.js.map +1 -0
  130. package/dist/stdin-buffer.d.ts +48 -0
  131. package/dist/stdin-buffer.d.ts.map +1 -0
  132. package/dist/stdin-buffer.js +317 -0
  133. package/dist/stdin-buffer.js.map +1 -0
  134. package/dist/sync-output.d.ts +58 -0
  135. package/dist/sync-output.d.ts.map +1 -0
  136. package/dist/sync-output.js +79 -0
  137. package/dist/sync-output.js.map +1 -0
  138. package/dist/terminal-detect.d.ts +66 -0
  139. package/dist/terminal-detect.d.ts.map +1 -0
  140. package/dist/terminal-detect.js +315 -0
  141. package/dist/terminal-detect.js.map +1 -0
  142. package/dist/terminal-image.d.ts +68 -0
  143. package/dist/terminal-image.d.ts.map +1 -0
  144. package/dist/terminal-image.js +288 -0
  145. package/dist/terminal-image.js.map +1 -0
  146. package/dist/terminal.d.ts +105 -0
  147. package/dist/terminal.d.ts.map +1 -0
  148. package/dist/terminal.js +427 -0
  149. package/dist/terminal.js.map +1 -0
  150. package/dist/tui.d.ts +268 -0
  151. package/dist/tui.d.ts.map +1 -0
  152. package/dist/tui.js +1161 -0
  153. package/dist/tui.js.map +1 -0
  154. package/dist/undo-stack.d.ts +17 -0
  155. package/dist/undo-stack.d.ts.map +1 -0
  156. package/dist/undo-stack.js +25 -0
  157. package/dist/undo-stack.js.map +1 -0
  158. package/dist/utils.d.ts +78 -0
  159. package/dist/utils.d.ts.map +1 -0
  160. package/dist/utils.js +960 -0
  161. package/dist/utils.js.map +1 -0
  162. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/components/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,IAAK,YAAW,SAAS;IACrC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAC,CAA2B;IAG9C,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAW;IAE/B,YAAY,IAAI,GAAE,MAAW,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAU,EAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAK/G;IAED,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAK1B;IAED,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAKzD;IAED,UAAU,IAAI,IAAI,CAIjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA4D9B;CACD","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { applyBackgroundToLine, visibleWidth, wrapTextWithAnsi } from \"../utils.js\";\n\n/**\n * Text component - displays multi-line text with word wrapping\n */\nexport class Text implements Component {\n\tprivate text: string;\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\tprivate customBgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(text: string = \"\", paddingX: number = 1, paddingY: number = 1, customBgFn?: (text: string) => string) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.customBgFn = customBgFn;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetCustomBgFn(customBgFn?: (text: string) => string): void {\n\t\tthis.customBgFn = customBgFn;\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Calculate content width (subtract left/right margins)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Wrap text (this preserves ANSI codes but does NOT pad)\n\t\tconst wrappedLines = wrapTextWithAnsi(normalizedText, contentWidth);\n\n\t\t// Add margins and background to each line\n\t\tconst leftMargin = \" \".repeat(this.paddingX);\n\t\tconst rightMargin = \" \".repeat(this.paddingX);\n\t\tconst contentLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Add margins\n\t\t\tconst lineWithMargins = leftMargin + line + rightMargin;\n\n\t\t\t// Apply background if specified (this also pads to full width)\n\t\t\tif (this.customBgFn) {\n\t\t\t\tcontentLines.push(applyBackgroundToLine(lineWithMargins, width, this.customBgFn));\n\t\t\t} else {\n\t\t\t\t// No background - just pad to width with spaces\n\t\t\t\tconst visibleLen = visibleWidth(lineWithMargins);\n\t\t\t\tconst paddingNeeded = Math.max(0, width - visibleLen);\n\t\t\t\tcontentLines.push(lineWithMargins + \" \".repeat(paddingNeeded));\n\t\t\t}\n\t\t}\n\n\t\t// Add top/bottom padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst emptyLines: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst line = this.customBgFn ? applyBackgroundToLine(emptyLine, width, this.customBgFn) : emptyLine;\n\t\t\temptyLines.push(line);\n\t\t}\n\n\t\tconst result = [...emptyLines, ...contentLines, ...emptyLines];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n}\n"]}
@@ -0,0 +1,89 @@
1
+ import { applyBackgroundToLine, visibleWidth, wrapTextWithAnsi } from "../utils.js";
2
+ /**
3
+ * Text component - displays multi-line text with word wrapping
4
+ */
5
+ export class Text {
6
+ text;
7
+ paddingX; // Left/right padding
8
+ paddingY; // Top/bottom padding
9
+ customBgFn;
10
+ // Cache for rendered output
11
+ cachedText;
12
+ cachedWidth;
13
+ cachedLines;
14
+ constructor(text = "", paddingX = 1, paddingY = 1, customBgFn) {
15
+ this.text = text;
16
+ this.paddingX = paddingX;
17
+ this.paddingY = paddingY;
18
+ this.customBgFn = customBgFn;
19
+ }
20
+ setText(text) {
21
+ this.text = text;
22
+ this.cachedText = undefined;
23
+ this.cachedWidth = undefined;
24
+ this.cachedLines = undefined;
25
+ }
26
+ setCustomBgFn(customBgFn) {
27
+ this.customBgFn = customBgFn;
28
+ this.cachedText = undefined;
29
+ this.cachedWidth = undefined;
30
+ this.cachedLines = undefined;
31
+ }
32
+ invalidate() {
33
+ this.cachedText = undefined;
34
+ this.cachedWidth = undefined;
35
+ this.cachedLines = undefined;
36
+ }
37
+ render(width) {
38
+ // Check cache
39
+ if (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {
40
+ return this.cachedLines;
41
+ }
42
+ // Don't render anything if there's no actual text
43
+ if (!this.text || this.text.trim() === "") {
44
+ const result = [];
45
+ this.cachedText = this.text;
46
+ this.cachedWidth = width;
47
+ this.cachedLines = result;
48
+ return result;
49
+ }
50
+ // Replace tabs with 3 spaces
51
+ const normalizedText = this.text.replace(/\t/g, " ");
52
+ // Calculate content width (subtract left/right margins)
53
+ const contentWidth = Math.max(1, width - this.paddingX * 2);
54
+ // Wrap text (this preserves ANSI codes but does NOT pad)
55
+ const wrappedLines = wrapTextWithAnsi(normalizedText, contentWidth);
56
+ // Add margins and background to each line
57
+ const leftMargin = " ".repeat(this.paddingX);
58
+ const rightMargin = " ".repeat(this.paddingX);
59
+ const contentLines = [];
60
+ for (const line of wrappedLines) {
61
+ // Add margins
62
+ const lineWithMargins = leftMargin + line + rightMargin;
63
+ // Apply background if specified (this also pads to full width)
64
+ if (this.customBgFn) {
65
+ contentLines.push(applyBackgroundToLine(lineWithMargins, width, this.customBgFn));
66
+ }
67
+ else {
68
+ // No background - just pad to width with spaces
69
+ const visibleLen = visibleWidth(lineWithMargins);
70
+ const paddingNeeded = Math.max(0, width - visibleLen);
71
+ contentLines.push(lineWithMargins + " ".repeat(paddingNeeded));
72
+ }
73
+ }
74
+ // Add top/bottom padding (empty lines)
75
+ const emptyLine = " ".repeat(width);
76
+ const emptyLines = [];
77
+ for (let i = 0; i < this.paddingY; i++) {
78
+ const line = this.customBgFn ? applyBackgroundToLine(emptyLine, width, this.customBgFn) : emptyLine;
79
+ emptyLines.push(line);
80
+ }
81
+ const result = [...emptyLines, ...contentLines, ...emptyLines];
82
+ // Update cache
83
+ this.cachedText = this.text;
84
+ this.cachedWidth = width;
85
+ this.cachedLines = result;
86
+ return result.length > 0 ? result : [""];
87
+ }
88
+ }
89
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/components/text.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { applyBackgroundToLine, visibleWidth, wrapTextWithAnsi } from \"../utils.js\";\n\n/**\n * Text component - displays multi-line text with word wrapping\n */\nexport class Text implements Component {\n\tprivate text: string;\n\tprivate paddingX: number; // Left/right padding\n\tprivate paddingY: number; // Top/bottom padding\n\tprivate customBgFn?: (text: string) => string;\n\n\t// Cache for rendered output\n\tprivate cachedText?: string;\n\tprivate cachedWidth?: number;\n\tprivate cachedLines?: string[];\n\n\tconstructor(text: string = \"\", paddingX: number = 1, paddingY: number = 1, customBgFn?: (text: string) => string) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t\tthis.customBgFn = customBgFn;\n\t}\n\n\tsetText(text: string): void {\n\t\tthis.text = text;\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tsetCustomBgFn(customBgFn?: (text: string) => string): void {\n\t\tthis.customBgFn = customBgFn;\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\tinvalidate(): void {\n\t\tthis.cachedText = undefined;\n\t\tthis.cachedWidth = undefined;\n\t\tthis.cachedLines = undefined;\n\t}\n\n\trender(width: number): string[] {\n\t\t// Check cache\n\t\tif (this.cachedLines && this.cachedText === this.text && this.cachedWidth === width) {\n\t\t\treturn this.cachedLines;\n\t\t}\n\n\t\t// Don't render anything if there's no actual text\n\t\tif (!this.text || this.text.trim() === \"\") {\n\t\t\tconst result: string[] = [];\n\t\t\tthis.cachedText = this.text;\n\t\t\tthis.cachedWidth = width;\n\t\t\tthis.cachedLines = result;\n\t\t\treturn result;\n\t\t}\n\n\t\t// Replace tabs with 3 spaces\n\t\tconst normalizedText = this.text.replace(/\\t/g, \" \");\n\n\t\t// Calculate content width (subtract left/right margins)\n\t\tconst contentWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Wrap text (this preserves ANSI codes but does NOT pad)\n\t\tconst wrappedLines = wrapTextWithAnsi(normalizedText, contentWidth);\n\n\t\t// Add margins and background to each line\n\t\tconst leftMargin = \" \".repeat(this.paddingX);\n\t\tconst rightMargin = \" \".repeat(this.paddingX);\n\t\tconst contentLines: string[] = [];\n\n\t\tfor (const line of wrappedLines) {\n\t\t\t// Add margins\n\t\t\tconst lineWithMargins = leftMargin + line + rightMargin;\n\n\t\t\t// Apply background if specified (this also pads to full width)\n\t\t\tif (this.customBgFn) {\n\t\t\t\tcontentLines.push(applyBackgroundToLine(lineWithMargins, width, this.customBgFn));\n\t\t\t} else {\n\t\t\t\t// No background - just pad to width with spaces\n\t\t\t\tconst visibleLen = visibleWidth(lineWithMargins);\n\t\t\t\tconst paddingNeeded = Math.max(0, width - visibleLen);\n\t\t\t\tcontentLines.push(lineWithMargins + \" \".repeat(paddingNeeded));\n\t\t\t}\n\t\t}\n\n\t\t// Add top/bottom padding (empty lines)\n\t\tconst emptyLine = \" \".repeat(width);\n\t\tconst emptyLines: string[] = [];\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tconst line = this.customBgFn ? applyBackgroundToLine(emptyLine, width, this.customBgFn) : emptyLine;\n\t\t\temptyLines.push(line);\n\t\t}\n\n\t\tconst result = [...emptyLines, ...contentLines, ...emptyLines];\n\n\t\t// Update cache\n\t\tthis.cachedText = this.text;\n\t\tthis.cachedWidth = width;\n\t\tthis.cachedLines = result;\n\n\t\treturn result.length > 0 ? result : [\"\"];\n\t}\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { Component } from "../tui.js";
2
+ /**
3
+ * Text component that truncates to fit viewport width
4
+ */
5
+ export declare class TruncatedText implements Component {
6
+ private text;
7
+ private paddingX;
8
+ private paddingY;
9
+ constructor(text: string, paddingX?: number, paddingY?: number);
10
+ invalidate(): void;
11
+ render(width: number): string[];
12
+ }
13
+ //# sourceMappingURL=truncated-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncated-text.d.ts","sourceRoot":"","sources":["../../src/components/truncated-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC9C,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,YAAY,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAU,EAInE;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA0C9B;CACD","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { truncateToWidth, visibleWidth } from \"../utils.js\";\n\n/**\n * Text component that truncates to fit viewport width\n */\nexport class TruncatedText implements Component {\n\tprivate text: string;\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\n\tconstructor(text: string, paddingX: number = 0, paddingY: number = 0) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tconst result: string[] = [];\n\n\t\t// Empty line padded to width\n\t\tconst emptyLine = \" \".repeat(width);\n\n\t\t// Add vertical padding above\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(emptyLine);\n\t\t}\n\n\t\t// Calculate available width after horizontal padding\n\t\tconst availableWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Take only the first line (stop at newline)\n\t\tlet singleLineText = this.text;\n\t\tconst newlineIndex = this.text.indexOf(\"\\n\");\n\t\tif (newlineIndex !== -1) {\n\t\t\tsingleLineText = this.text.substring(0, newlineIndex);\n\t\t}\n\n\t\t// Truncate text if needed (accounting for ANSI codes)\n\t\tconst displayText = truncateToWidth(singleLineText, availableWidth);\n\n\t\t// Add horizontal padding\n\t\tconst leftPadding = \" \".repeat(this.paddingX);\n\t\tconst rightPadding = \" \".repeat(this.paddingX);\n\t\tconst lineWithPadding = leftPadding + displayText + rightPadding;\n\n\t\t// Pad line to exactly width characters\n\t\tconst lineVisibleWidth = visibleWidth(lineWithPadding);\n\t\tconst paddingNeeded = Math.max(0, width - lineVisibleWidth);\n\t\tconst finalLine = lineWithPadding + \" \".repeat(paddingNeeded);\n\n\t\tresult.push(finalLine);\n\n\t\t// Add vertical padding below\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(emptyLine);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n"]}
@@ -0,0 +1,51 @@
1
+ import { truncateToWidth, visibleWidth } from "../utils.js";
2
+ /**
3
+ * Text component that truncates to fit viewport width
4
+ */
5
+ export class TruncatedText {
6
+ text;
7
+ paddingX;
8
+ paddingY;
9
+ constructor(text, paddingX = 0, paddingY = 0) {
10
+ this.text = text;
11
+ this.paddingX = paddingX;
12
+ this.paddingY = paddingY;
13
+ }
14
+ invalidate() {
15
+ // No cached state to invalidate currently
16
+ }
17
+ render(width) {
18
+ const result = [];
19
+ // Empty line padded to width
20
+ const emptyLine = " ".repeat(width);
21
+ // Add vertical padding above
22
+ for (let i = 0; i < this.paddingY; i++) {
23
+ result.push(emptyLine);
24
+ }
25
+ // Calculate available width after horizontal padding
26
+ const availableWidth = Math.max(1, width - this.paddingX * 2);
27
+ // Take only the first line (stop at newline)
28
+ let singleLineText = this.text;
29
+ const newlineIndex = this.text.indexOf("\n");
30
+ if (newlineIndex !== -1) {
31
+ singleLineText = this.text.substring(0, newlineIndex);
32
+ }
33
+ // Truncate text if needed (accounting for ANSI codes)
34
+ const displayText = truncateToWidth(singleLineText, availableWidth);
35
+ // Add horizontal padding
36
+ const leftPadding = " ".repeat(this.paddingX);
37
+ const rightPadding = " ".repeat(this.paddingX);
38
+ const lineWithPadding = leftPadding + displayText + rightPadding;
39
+ // Pad line to exactly width characters
40
+ const lineVisibleWidth = visibleWidth(lineWithPadding);
41
+ const paddingNeeded = Math.max(0, width - lineVisibleWidth);
42
+ const finalLine = lineWithPadding + " ".repeat(paddingNeeded);
43
+ result.push(finalLine);
44
+ // Add vertical padding below
45
+ for (let i = 0; i < this.paddingY; i++) {
46
+ result.push(emptyLine);
47
+ }
48
+ return result;
49
+ }
50
+ }
51
+ //# sourceMappingURL=truncated-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncated-text.js","sourceRoot":"","sources":["../../src/components/truncated-text.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D;;GAEG;AACH,MAAM,OAAO,aAAa;IACjB,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,QAAQ,CAAS;IAEzB,YAAY,IAAY,EAAE,QAAQ,GAAW,CAAC,EAAE,QAAQ,GAAW,CAAC,EAAE;QACrE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAAA,CACzB;IAED,UAAU,GAAS;QAClB,0CAA0C;IADvB,CAEnB;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,6BAA6B;QAC7B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEpC,6BAA6B;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QAED,qDAAqD;QACrD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;QAE9D,6CAA6C;QAC7C,IAAI,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC;QAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;YACzB,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC;QAED,sDAAsD;QACtD,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;QAEpE,yBAAyB;QACzB,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,eAAe,GAAG,WAAW,GAAG,WAAW,GAAG,YAAY,CAAC;QAEjE,uCAAuC;QACvC,MAAM,gBAAgB,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAAC,CAAC;QAC5D,MAAM,SAAS,GAAG,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAE9D,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEvB,6BAA6B;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,MAAM,CAAC;IAAA,CACd;CACD","sourcesContent":["import type { Component } from \"../tui.js\";\nimport { truncateToWidth, visibleWidth } from \"../utils.js\";\n\n/**\n * Text component that truncates to fit viewport width\n */\nexport class TruncatedText implements Component {\n\tprivate text: string;\n\tprivate paddingX: number;\n\tprivate paddingY: number;\n\n\tconstructor(text: string, paddingX: number = 0, paddingY: number = 0) {\n\t\tthis.text = text;\n\t\tthis.paddingX = paddingX;\n\t\tthis.paddingY = paddingY;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tconst result: string[] = [];\n\n\t\t// Empty line padded to width\n\t\tconst emptyLine = \" \".repeat(width);\n\n\t\t// Add vertical padding above\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(emptyLine);\n\t\t}\n\n\t\t// Calculate available width after horizontal padding\n\t\tconst availableWidth = Math.max(1, width - this.paddingX * 2);\n\n\t\t// Take only the first line (stop at newline)\n\t\tlet singleLineText = this.text;\n\t\tconst newlineIndex = this.text.indexOf(\"\\n\");\n\t\tif (newlineIndex !== -1) {\n\t\t\tsingleLineText = this.text.substring(0, newlineIndex);\n\t\t}\n\n\t\t// Truncate text if needed (accounting for ANSI codes)\n\t\tconst displayText = truncateToWidth(singleLineText, availableWidth);\n\n\t\t// Add horizontal padding\n\t\tconst leftPadding = \" \".repeat(this.paddingX);\n\t\tconst rightPadding = \" \".repeat(this.paddingX);\n\t\tconst lineWithPadding = leftPadding + displayText + rightPadding;\n\n\t\t// Pad line to exactly width characters\n\t\tconst lineVisibleWidth = visibleWidth(lineWithPadding);\n\t\tconst paddingNeeded = Math.max(0, width - lineVisibleWidth);\n\t\tconst finalLine = lineWithPadding + \" \".repeat(paddingNeeded);\n\n\t\tresult.push(finalLine);\n\n\t\t// Add vertical padding below\n\t\tfor (let i = 0; i < this.paddingY; i++) {\n\t\t\tresult.push(emptyLine);\n\t\t}\n\n\t\treturn result;\n\t}\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import type { AutocompleteProvider } from "./autocomplete.js";
2
+ import type { Component } from "./tui.js";
3
+ /**
4
+ * Interface for custom editor components.
5
+ *
6
+ * This allows extensions to provide their own editor implementation
7
+ * (e.g., vim mode, emacs mode, custom keybindings) while maintaining
8
+ * compatibility with the core application.
9
+ */
10
+ export interface EditorComponent extends Component {
11
+ /** Get the current text content */
12
+ getText(): string;
13
+ /** Set the text content */
14
+ setText(text: string): void;
15
+ /** Handle raw terminal input (key presses, paste sequences, etc.) */
16
+ handleInput(data: string): void;
17
+ /** Called when user submits (e.g., Enter key) */
18
+ onSubmit?: (text: string) => void;
19
+ /** Called when text changes */
20
+ onChange?: (text: string) => void;
21
+ /** Add text to history for up/down navigation */
22
+ addToHistory?(text: string): void;
23
+ /** Insert text at current cursor position */
24
+ insertTextAtCursor?(text: string): void;
25
+ /**
26
+ * Get text with any markers expanded (e.g., paste markers).
27
+ * Falls back to getText() if not implemented.
28
+ */
29
+ getExpandedText?(): string;
30
+ /** Set the autocomplete provider */
31
+ setAutocompleteProvider?(provider: AutocompleteProvider): void;
32
+ /** Border color function */
33
+ borderColor?: (str: string) => string;
34
+ /** Set horizontal padding */
35
+ setPaddingX?(padding: number): void;
36
+ /** Set max visible items in autocomplete dropdown */
37
+ setAutocompleteMaxVisible?(maxVisible: number): void;
38
+ }
39
+ //# sourceMappingURL=editor-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-component.d.ts","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAKjD,mCAAmC;IACnC,OAAO,IAAI,MAAM,CAAC;IAElB,2BAA2B;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,qEAAqE;IACrE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMhC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAMlC,iDAAiD;IACjD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAMlC,6CAA6C;IAC7C,kBAAkB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,eAAe,CAAC,IAAI,MAAM,CAAC;IAM3B,oCAAoC;IACpC,uBAAuB,CAAC,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAM/D,4BAA4B;IAC5B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC,6BAA6B;IAC7B,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC,qDAAqD;IACrD,yBAAyB,CAAC,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACrD","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.js\";\nimport type { Component } from \"./tui.js\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=editor-component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-component.js","sourceRoot":"","sources":["../src/editor-component.ts"],"names":[],"mappings":"","sourcesContent":["import type { AutocompleteProvider } from \"./autocomplete.js\";\nimport type { Component } from \"./tui.js\";\n\n/**\n * Interface for custom editor components.\n *\n * This allows extensions to provide their own editor implementation\n * (e.g., vim mode, emacs mode, custom keybindings) while maintaining\n * compatibility with the core application.\n */\nexport interface EditorComponent extends Component {\n\t// =========================================================================\n\t// Core text access (required)\n\t// =========================================================================\n\n\t/** Get the current text content */\n\tgetText(): string;\n\n\t/** Set the text content */\n\tsetText(text: string): void;\n\n\t/** Handle raw terminal input (key presses, paste sequences, etc.) */\n\thandleInput(data: string): void;\n\n\t// =========================================================================\n\t// Callbacks (required)\n\t// =========================================================================\n\n\t/** Called when user submits (e.g., Enter key) */\n\tonSubmit?: (text: string) => void;\n\n\t/** Called when text changes */\n\tonChange?: (text: string) => void;\n\n\t// =========================================================================\n\t// History support (optional)\n\t// =========================================================================\n\n\t/** Add text to history for up/down navigation */\n\taddToHistory?(text: string): void;\n\n\t// =========================================================================\n\t// Advanced text manipulation (optional)\n\t// =========================================================================\n\n\t/** Insert text at current cursor position */\n\tinsertTextAtCursor?(text: string): void;\n\n\t/**\n\t * Get text with any markers expanded (e.g., paste markers).\n\t * Falls back to getText() if not implemented.\n\t */\n\tgetExpandedText?(): string;\n\n\t// =========================================================================\n\t// Autocomplete support (optional)\n\t// =========================================================================\n\n\t/** Set the autocomplete provider */\n\tsetAutocompleteProvider?(provider: AutocompleteProvider): void;\n\n\t// =========================================================================\n\t// Appearance (optional)\n\t// =========================================================================\n\n\t/** Border color function */\n\tborderColor?: (str: string) => string;\n\n\t/** Set horizontal padding */\n\tsetPaddingX?(padding: number): void;\n\n\t/** Set max visible items in autocomplete dropdown */\n\tsetAutocompleteMaxVisible?(maxVisible: number): void;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Fuzzy matching utilities.
3
+ * Matches if all query characters appear in order (not necessarily consecutive).
4
+ * Lower score = better match.
5
+ */
6
+ export interface FuzzyMatch {
7
+ matches: boolean;
8
+ score: number;
9
+ }
10
+ export declare function fuzzyMatch(query: string, text: string): FuzzyMatch;
11
+ /**
12
+ * Filter and sort items by fuzzy match quality (best matches first).
13
+ * Supports space-separated tokens: all tokens must match.
14
+ */
15
+ export declare function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[];
16
+ //# sourceMappingURL=fuzzy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy.d.ts","sourceRoot":"","sources":["../src/fuzzy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,CA6ElE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,CAAC,EAAE,CAsC3F","sourcesContent":["/**\n * Fuzzy matching utilities.\n * Matches if all query characters appear in order (not necessarily consecutive).\n * Lower score = better match.\n */\n\nexport interface FuzzyMatch {\n\tmatches: boolean;\n\tscore: number;\n}\n\nexport function fuzzyMatch(query: string, text: string): FuzzyMatch {\n\tconst queryLower = query.toLowerCase();\n\tconst textLower = text.toLowerCase();\n\n\tconst matchQuery = (normalizedQuery: string): FuzzyMatch => {\n\t\tif (normalizedQuery.length === 0) {\n\t\t\treturn { matches: true, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery.length > textLower.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tlet queryIndex = 0;\n\t\tlet score = 0;\n\t\tlet lastMatchIndex = -1;\n\t\tlet consecutiveMatches = 0;\n\n\t\tfor (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {\n\t\t\tif (textLower[i] === normalizedQuery[queryIndex]) {\n\t\t\t\tconst isWordBoundary = i === 0 || /[\\s\\-_./:]/.test(textLower[i - 1]!);\n\n\t\t\t\t// Reward consecutive matches\n\t\t\t\tif (lastMatchIndex === i - 1) {\n\t\t\t\t\tconsecutiveMatches++;\n\t\t\t\t\tscore -= consecutiveMatches * 5;\n\t\t\t\t} else {\n\t\t\t\t\tconsecutiveMatches = 0;\n\t\t\t\t\t// Penalize gaps\n\t\t\t\t\tif (lastMatchIndex >= 0) {\n\t\t\t\t\t\tscore += (i - lastMatchIndex - 1) * 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reward word boundary matches\n\t\t\t\tif (isWordBoundary) {\n\t\t\t\t\tscore -= 10;\n\t\t\t\t}\n\n\t\t\t\t// Slight penalty for later matches\n\t\t\t\tscore += i * 0.1;\n\n\t\t\t\tlastMatchIndex = i;\n\t\t\t\tqueryIndex++;\n\t\t\t}\n\t\t}\n\n\t\tif (queryIndex < normalizedQuery.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\treturn { matches: true, score };\n\t};\n\n\tconst primaryMatch = matchQuery(queryLower);\n\tif (primaryMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);\n\tconst numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);\n\tconst swappedQuery = alphaNumericMatch\n\t\t? `${alphaNumericMatch.groups?.digits ?? \"\"}${alphaNumericMatch.groups?.letters ?? \"\"}`\n\t\t: numericAlphaMatch\n\t\t\t? `${numericAlphaMatch.groups?.letters ?? \"\"}${numericAlphaMatch.groups?.digits ?? \"\"}`\n\t\t\t: \"\";\n\n\tif (!swappedQuery) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst swappedMatch = matchQuery(swappedQuery);\n\tif (!swappedMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\treturn { matches: true, score: swappedMatch.score + 5 };\n}\n\n/**\n * Filter and sort items by fuzzy match quality (best matches first).\n * Supports space-separated tokens: all tokens must match.\n */\nexport function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {\n\tif (!query.trim()) {\n\t\treturn items;\n\t}\n\n\tconst tokens = query\n\t\t.trim()\n\t\t.split(/\\s+/)\n\t\t.filter((t) => t.length > 0);\n\n\tif (tokens.length === 0) {\n\t\treturn items;\n\t}\n\n\tconst results: { item: T; totalScore: number }[] = [];\n\n\tfor (const item of items) {\n\t\tconst text = getText(item);\n\t\tlet totalScore = 0;\n\t\tlet allMatch = true;\n\n\t\tfor (const token of tokens) {\n\t\t\tconst match = fuzzyMatch(token, text);\n\t\t\tif (match.matches) {\n\t\t\t\ttotalScore += match.score;\n\t\t\t} else {\n\t\t\t\tallMatch = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (allMatch) {\n\t\t\tresults.push({ item, totalScore });\n\t\t}\n\t}\n\n\tresults.sort((a, b) => a.totalScore - b.totalScore);\n\treturn results.map((r) => r.item);\n}\n"]}
package/dist/fuzzy.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Fuzzy matching utilities.
3
+ * Matches if all query characters appear in order (not necessarily consecutive).
4
+ * Lower score = better match.
5
+ */
6
+ export function fuzzyMatch(query, text) {
7
+ const queryLower = query.toLowerCase();
8
+ const textLower = text.toLowerCase();
9
+ const matchQuery = (normalizedQuery) => {
10
+ if (normalizedQuery.length === 0) {
11
+ return { matches: true, score: 0 };
12
+ }
13
+ if (normalizedQuery.length > textLower.length) {
14
+ return { matches: false, score: 0 };
15
+ }
16
+ let queryIndex = 0;
17
+ let score = 0;
18
+ let lastMatchIndex = -1;
19
+ let consecutiveMatches = 0;
20
+ for (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {
21
+ if (textLower[i] === normalizedQuery[queryIndex]) {
22
+ const isWordBoundary = i === 0 || /[\s\-_./:]/.test(textLower[i - 1]);
23
+ // Reward consecutive matches
24
+ if (lastMatchIndex === i - 1) {
25
+ consecutiveMatches++;
26
+ score -= consecutiveMatches * 5;
27
+ }
28
+ else {
29
+ consecutiveMatches = 0;
30
+ // Penalize gaps
31
+ if (lastMatchIndex >= 0) {
32
+ score += (i - lastMatchIndex - 1) * 2;
33
+ }
34
+ }
35
+ // Reward word boundary matches
36
+ if (isWordBoundary) {
37
+ score -= 10;
38
+ }
39
+ // Slight penalty for later matches
40
+ score += i * 0.1;
41
+ lastMatchIndex = i;
42
+ queryIndex++;
43
+ }
44
+ }
45
+ if (queryIndex < normalizedQuery.length) {
46
+ return { matches: false, score: 0 };
47
+ }
48
+ return { matches: true, score };
49
+ };
50
+ const primaryMatch = matchQuery(queryLower);
51
+ if (primaryMatch.matches) {
52
+ return primaryMatch;
53
+ }
54
+ const alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);
55
+ const numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);
56
+ const swappedQuery = alphaNumericMatch
57
+ ? `${alphaNumericMatch.groups?.digits ?? ""}${alphaNumericMatch.groups?.letters ?? ""}`
58
+ : numericAlphaMatch
59
+ ? `${numericAlphaMatch.groups?.letters ?? ""}${numericAlphaMatch.groups?.digits ?? ""}`
60
+ : "";
61
+ if (!swappedQuery) {
62
+ return primaryMatch;
63
+ }
64
+ const swappedMatch = matchQuery(swappedQuery);
65
+ if (!swappedMatch.matches) {
66
+ return primaryMatch;
67
+ }
68
+ return { matches: true, score: swappedMatch.score + 5 };
69
+ }
70
+ /**
71
+ * Filter and sort items by fuzzy match quality (best matches first).
72
+ * Supports space-separated tokens: all tokens must match.
73
+ */
74
+ export function fuzzyFilter(items, query, getText) {
75
+ if (!query.trim()) {
76
+ return items;
77
+ }
78
+ const tokens = query
79
+ .trim()
80
+ .split(/\s+/)
81
+ .filter((t) => t.length > 0);
82
+ if (tokens.length === 0) {
83
+ return items;
84
+ }
85
+ const results = [];
86
+ for (const item of items) {
87
+ const text = getText(item);
88
+ let totalScore = 0;
89
+ let allMatch = true;
90
+ for (const token of tokens) {
91
+ const match = fuzzyMatch(token, text);
92
+ if (match.matches) {
93
+ totalScore += match.score;
94
+ }
95
+ else {
96
+ allMatch = false;
97
+ break;
98
+ }
99
+ }
100
+ if (allMatch) {
101
+ results.push({ item, totalScore });
102
+ }
103
+ }
104
+ results.sort((a, b) => a.totalScore - b.totalScore);
105
+ return results.map((r) => r.item);
106
+ }
107
+ //# sourceMappingURL=fuzzy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fuzzy.js","sourceRoot":"","sources":["../src/fuzzy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAY,EAAc;IACnE,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,UAAU,GAAG,CAAC,eAAuB,EAAc,EAAE,CAAC;QAC3D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACpC,CAAC;QAED,IAAI,eAAe,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YAC/C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACrC,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,cAAc,GAAG,CAAC,CAAC,CAAC;QACxB,IAAI,kBAAkB,GAAG,CAAC,CAAC;QAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,IAAI,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClF,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClD,MAAM,cAAc,GAAG,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC;gBAEvE,6BAA6B;gBAC7B,IAAI,cAAc,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,kBAAkB,EAAE,CAAC;oBACrB,KAAK,IAAI,kBAAkB,GAAG,CAAC,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACP,kBAAkB,GAAG,CAAC,CAAC;oBACvB,gBAAgB;oBAChB,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;wBACzB,KAAK,IAAI,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;oBACvC,CAAC;gBACF,CAAC;gBAED,+BAA+B;gBAC/B,IAAI,cAAc,EAAE,CAAC;oBACpB,KAAK,IAAI,EAAE,CAAC;gBACb,CAAC;gBAED,mCAAmC;gBACnC,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC;gBAEjB,cAAc,GAAG,CAAC,CAAC;gBACnB,UAAU,EAAE,CAAC;YACd,CAAC;QACF,CAAC;QAED,IAAI,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;YACzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACrC,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAAA,CAChC,CAAC;IAEF,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACpF,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACpF,MAAM,YAAY,GAAG,iBAAiB;QACrC,CAAC,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE;QACvF,CAAC,CAAC,iBAAiB;YAClB,CAAC,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE;YACvF,CAAC,CAAC,EAAE,CAAC;IAEP,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;AAAA,CACxD;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAI,KAAU,EAAE,KAAa,EAAE,OAA4B,EAAO;IAC5F,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,KAAK;SAClB,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE9B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAsC,EAAE,CAAC;IAEtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,QAAQ,GAAG,IAAI,CAAC;QAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACtC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBACnB,UAAU,IAAI,KAAK,CAAC,KAAK,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACP,QAAQ,GAAG,KAAK,CAAC;gBACjB,MAAM;YACP,CAAC;QACF,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAAA,CAClC","sourcesContent":["/**\n * Fuzzy matching utilities.\n * Matches if all query characters appear in order (not necessarily consecutive).\n * Lower score = better match.\n */\n\nexport interface FuzzyMatch {\n\tmatches: boolean;\n\tscore: number;\n}\n\nexport function fuzzyMatch(query: string, text: string): FuzzyMatch {\n\tconst queryLower = query.toLowerCase();\n\tconst textLower = text.toLowerCase();\n\n\tconst matchQuery = (normalizedQuery: string): FuzzyMatch => {\n\t\tif (normalizedQuery.length === 0) {\n\t\t\treturn { matches: true, score: 0 };\n\t\t}\n\n\t\tif (normalizedQuery.length > textLower.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\tlet queryIndex = 0;\n\t\tlet score = 0;\n\t\tlet lastMatchIndex = -1;\n\t\tlet consecutiveMatches = 0;\n\n\t\tfor (let i = 0; i < textLower.length && queryIndex < normalizedQuery.length; i++) {\n\t\t\tif (textLower[i] === normalizedQuery[queryIndex]) {\n\t\t\t\tconst isWordBoundary = i === 0 || /[\\s\\-_./:]/.test(textLower[i - 1]!);\n\n\t\t\t\t// Reward consecutive matches\n\t\t\t\tif (lastMatchIndex === i - 1) {\n\t\t\t\t\tconsecutiveMatches++;\n\t\t\t\t\tscore -= consecutiveMatches * 5;\n\t\t\t\t} else {\n\t\t\t\t\tconsecutiveMatches = 0;\n\t\t\t\t\t// Penalize gaps\n\t\t\t\t\tif (lastMatchIndex >= 0) {\n\t\t\t\t\t\tscore += (i - lastMatchIndex - 1) * 2;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Reward word boundary matches\n\t\t\t\tif (isWordBoundary) {\n\t\t\t\t\tscore -= 10;\n\t\t\t\t}\n\n\t\t\t\t// Slight penalty for later matches\n\t\t\t\tscore += i * 0.1;\n\n\t\t\t\tlastMatchIndex = i;\n\t\t\t\tqueryIndex++;\n\t\t\t}\n\t\t}\n\n\t\tif (queryIndex < normalizedQuery.length) {\n\t\t\treturn { matches: false, score: 0 };\n\t\t}\n\n\t\treturn { matches: true, score };\n\t};\n\n\tconst primaryMatch = matchQuery(queryLower);\n\tif (primaryMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst alphaNumericMatch = queryLower.match(/^(?<letters>[a-z]+)(?<digits>[0-9]+)$/);\n\tconst numericAlphaMatch = queryLower.match(/^(?<digits>[0-9]+)(?<letters>[a-z]+)$/);\n\tconst swappedQuery = alphaNumericMatch\n\t\t? `${alphaNumericMatch.groups?.digits ?? \"\"}${alphaNumericMatch.groups?.letters ?? \"\"}`\n\t\t: numericAlphaMatch\n\t\t\t? `${numericAlphaMatch.groups?.letters ?? \"\"}${numericAlphaMatch.groups?.digits ?? \"\"}`\n\t\t\t: \"\";\n\n\tif (!swappedQuery) {\n\t\treturn primaryMatch;\n\t}\n\n\tconst swappedMatch = matchQuery(swappedQuery);\n\tif (!swappedMatch.matches) {\n\t\treturn primaryMatch;\n\t}\n\n\treturn { matches: true, score: swappedMatch.score + 5 };\n}\n\n/**\n * Filter and sort items by fuzzy match quality (best matches first).\n * Supports space-separated tokens: all tokens must match.\n */\nexport function fuzzyFilter<T>(items: T[], query: string, getText: (item: T) => string): T[] {\n\tif (!query.trim()) {\n\t\treturn items;\n\t}\n\n\tconst tokens = query\n\t\t.trim()\n\t\t.split(/\\s+/)\n\t\t.filter((t) => t.length > 0);\n\n\tif (tokens.length === 0) {\n\t\treturn items;\n\t}\n\n\tconst results: { item: T; totalScore: number }[] = [];\n\n\tfor (const item of items) {\n\t\tconst text = getText(item);\n\t\tlet totalScore = 0;\n\t\tlet allMatch = true;\n\n\t\tfor (const token of tokens) {\n\t\t\tconst match = fuzzyMatch(token, text);\n\t\t\tif (match.matches) {\n\t\t\t\ttotalScore += match.score;\n\t\t\t} else {\n\t\t\t\tallMatch = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (allMatch) {\n\t\t\tresults.push({ item, totalScore });\n\t\t}\n\t}\n\n\tresults.sort((a, b) => a.totalScore - b.totalScore);\n\treturn results.map((r) => r.item);\n}\n"]}
@@ -0,0 +1,38 @@
1
+ export { type AutocompleteItem, type AutocompleteProvider, type AutocompleteSuggestions, CombinedAutocompleteProvider, type SlashCommand, } from "./autocomplete.js";
2
+ export { type ChordResult, type ChordSegment, ChordSession, parseChord } from "./chord.js";
3
+ export { type ColorDepth, detectColorDepth, hexToSgr, resetColorDepthCache, sgrReset } from "./color-depth.js";
4
+ export { Box } from "./components/box.js";
5
+ export { type Chapter, detectIntent, groupTurnsIntoChapters, type Intent, intentLabel, type Turn, toggleChapter, } from "./components/Chapters.js";
6
+ export { CancellableLoader } from "./components/cancellable-loader.js";
7
+ export { type DiffLayout, type DiffLine, type DiffLineKind, DiffView, type DiffViewOptions, type DiffViewTheme, pairUpHunks, pickLayout, SIDE_BY_SIDE_MIN_WIDTH, } from "./components/DiffView.js";
8
+ export { Editor, type EditorOptions, type EditorTheme } from "./components/editor.js";
9
+ export { type GroupedSelectGroup, type GroupedSelection, GroupedSelectList, type GroupedSelectListOptions, } from "./components/grouped-select-list.js";
10
+ export { Image, type ImageOptions, type ImageTheme } from "./components/image.js";
11
+ export { Input } from "./components/input.js";
12
+ export { Loader } from "./components/loader.js";
13
+ export { type DefaultTextStyle, Markdown, type MarkdownTheme } from "./components/markdown.js";
14
+ export { parseStatusLineSettings, renderDefault as renderStatusLineDefault, renderDetailed as renderStatusLineDetailed, renderStatusLineSync, StatusLine, type StatusLineComponentTheme, type StatusLineContext, type StatusLineRenderer, type StatusLineResult, type StatusLineSettings, sanitizeOneLine, tailPath, } from "./components/StatusLine.js";
15
+ export { formatElapsed, NULL_SUBAGENT_REGISTRY, SubagentOverlay, type SubagentOverlayOptions, type SubagentOverlayTheme, type SubagentRegistry, type SubagentSnapshot, } from "./components/SubagentOverlay.js";
16
+ export { type SelectItem, SelectList, type SelectListLayoutOptions, type SelectListTheme, type SelectListTruncatePrimaryContext, } from "./components/select-list.js";
17
+ export { type SettingItem, SettingsList, type SettingsListTheme } from "./components/settings-list.js";
18
+ export { Spacer } from "./components/spacer.js";
19
+ export { Spinner, type SpinnerOptions } from "./components/spinner.js";
20
+ export { balancePartial, StreamingMarkdown } from "./components/streaming-markdown.js";
21
+ export { Text } from "./components/text.js";
22
+ export { TruncatedText } from "./components/truncated-text.js";
23
+ export type { EditorComponent } from "./editor-component.js";
24
+ export { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from "./fuzzy.js";
25
+ export { getKeybindings, type Keybinding, type KeybindingConflict, type KeybindingDefinition, type KeybindingDefinitions, type Keybindings, type KeybindingsConfig, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.js";
26
+ export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, type KeyEventType, type KeyId, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.js";
27
+ export { bell, type NotifyOptions, notify } from "./notifications.js";
28
+ export { encodeOsc52, OSC52_MAX_BYTES, writeOsc52 } from "./osc52.js";
29
+ export { ScrollBuffer, type ScrollBufferOptions, type ScrollMode } from "./scroll-buffer.js";
30
+ export { getSpinner, SPINNERS, type SpinnerName, type SpinnerVariant, THINKING_SPINNERS, TOOL_SPINNERS, } from "./spinners.js";
31
+ export { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from "./stdin-buffer.js";
32
+ export { classifySyncOutputSupport, emitSyncOutputBegin, emitSyncOutputEnd, SYNC_OUTPUT_BEGIN, SYNC_OUTPUT_END, type SyncOutputCapabilityInput, type SyncOutputSupport, wrapSyncOutput, } from "./sync-output.js";
33
+ export { ProcessTerminal, type Terminal } from "./terminal.js";
34
+ export { type BackgroundClassification, detectTerminalIdentity, type Multiplexer, type ProbeResult, probeTerminal, queryOsc11Standalone, queryTerminalBackground, relativeLuminance, type TerminalBackground, type TerminalIdentity, type TerminalProgram, } from "./terminal-detect.js";
35
+ export { allocateImageId, type CellDimensions, calculateImageRows, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, type ImageDimensions, type ImageProtocol, type ImageRenderOptions, imageFallback, renderImage, resetCapabilitiesCache, setCellDimensions, type TerminalCapabilities, } from "./terminal-image.js";
36
+ export { type Component, Container, CURSOR_MARKER, type Focusable, isFocusable, type OverlayAnchor, type OverlayHandle, type OverlayMargin, type OverlayOptions, type SidePanelHandle, type SidePanelOptions, type SizeValue, TUI, } from "./tui.js";
37
+ export { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "./utils.js";
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Chord (multi-key sequence) matcher — sits on top of KeybindingsManager\nexport { type ChordResult, type ChordSegment, ChordSession, parseChord } from \"./chord.js\";\n// Color depth emission\nexport { type ColorDepth, detectColorDepth, hexToSgr, resetColorDepthCache, sgrReset } from \"./color-depth.js\";\n// Components\nexport { Box } from \"./components/box.js\";\n// Chapters (auto-folded transcript intent groups)\nexport {\n\ttype Chapter,\n\tdetectIntent,\n\tgroupTurnsIntoChapters,\n\ttype Intent,\n\tintentLabel,\n\ttype Turn,\n\ttoggleChapter,\n} from \"./components/Chapters.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\n// Diff view (side-by-side ≥ 100 cols)\nexport {\n\ttype DiffLayout,\n\ttype DiffLine,\n\ttype DiffLineKind,\n\tDiffView,\n\ttype DiffViewOptions,\n\ttype DiffViewTheme,\n\tpairUpHunks,\n\tpickLayout,\n\tSIDE_BY_SIDE_MIN_WIDTH,\n} from \"./components/DiffView.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport {\n\ttype GroupedSelectGroup,\n\ttype GroupedSelection,\n\tGroupedSelectList,\n\ttype GroupedSelectListOptions,\n} from \"./components/grouped-select-list.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\n// Status line (Claude Code v2.1.119 schema)\nexport {\n\tparseStatusLineSettings,\n\trenderDefault as renderStatusLineDefault,\n\trenderDetailed as renderStatusLineDetailed,\n\trenderStatusLineSync,\n\tStatusLine,\n\ttype StatusLineComponentTheme,\n\ttype StatusLineContext,\n\ttype StatusLineRenderer,\n\ttype StatusLineResult,\n\ttype StatusLineSettings,\n\tsanitizeOneLine,\n\ttailPath,\n} from \"./components/StatusLine.js\";\n// Subagent observability overlay (F2)\nexport {\n\tformatElapsed,\n\tNULL_SUBAGENT_REGISTRY,\n\tSubagentOverlay,\n\ttype SubagentOverlayOptions,\n\ttype SubagentOverlayTheme,\n\ttype SubagentRegistry,\n\ttype SubagentSnapshot,\n} from \"./components/SubagentOverlay.js\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Spinner, type SpinnerOptions } from \"./components/spinner.js\";\nexport { balancePartial, StreamingMarkdown } from \"./components/streaming-markdown.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Terminal notifications (OSC 9 + bell)\nexport { bell, type NotifyOptions, notify } from \"./notifications.js\";\n// OSC-52 clipboard write\nexport { encodeOsc52, OSC52_MAX_BYTES, writeOsc52 } from \"./osc52.js\";\n// Scroll buffer (in-app scrollback)\nexport { ScrollBuffer, type ScrollBufferOptions, type ScrollMode } from \"./scroll-buffer.js\";\n// Spinner frame data\nexport {\n\tgetSpinner,\n\tSPINNERS,\n\ttype SpinnerName,\n\ttype SpinnerVariant,\n\tTHINKING_SPINNERS,\n\tTOOL_SPINNERS,\n} from \"./spinners.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Synchronized output (DEC private mode 2026)\nexport {\n\tclassifySyncOutputSupport,\n\temitSyncOutputBegin,\n\temitSyncOutputEnd,\n\tSYNC_OUTPUT_BEGIN,\n\tSYNC_OUTPUT_END,\n\ttype SyncOutputCapabilityInput,\n\ttype SyncOutputSupport,\n\twrapSyncOutput,\n} from \"./sync-output.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal identity + background detection\nexport {\n\ttype BackgroundClassification,\n\tdetectTerminalIdentity,\n\ttype Multiplexer,\n\ttype ProbeResult,\n\tprobeTerminal,\n\tqueryOsc11Standalone,\n\tqueryTerminalBackground,\n\trelativeLuminance,\n\ttype TerminalBackground,\n\ttype TerminalIdentity,\n\ttype TerminalProgram,\n} from \"./terminal-detect.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SidePanelHandle,\n\ttype SidePanelOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ // Core TUI interfaces and classes
2
+ // Autocomplete support
3
+ export { CombinedAutocompleteProvider, } from "./autocomplete.js";
4
+ // Chord (multi-key sequence) matcher — sits on top of KeybindingsManager
5
+ export { ChordSession, parseChord } from "./chord.js";
6
+ // Color depth emission
7
+ export { detectColorDepth, hexToSgr, resetColorDepthCache, sgrReset } from "./color-depth.js";
8
+ // Components
9
+ export { Box } from "./components/box.js";
10
+ // Chapters (auto-folded transcript intent groups)
11
+ export { detectIntent, groupTurnsIntoChapters, intentLabel, toggleChapter, } from "./components/Chapters.js";
12
+ export { CancellableLoader } from "./components/cancellable-loader.js";
13
+ // Diff view (side-by-side ≥ 100 cols)
14
+ export { DiffView, pairUpHunks, pickLayout, SIDE_BY_SIDE_MIN_WIDTH, } from "./components/DiffView.js";
15
+ export { Editor } from "./components/editor.js";
16
+ export { GroupedSelectList, } from "./components/grouped-select-list.js";
17
+ export { Image } from "./components/image.js";
18
+ export { Input } from "./components/input.js";
19
+ export { Loader } from "./components/loader.js";
20
+ export { Markdown } from "./components/markdown.js";
21
+ // Status line (Claude Code v2.1.119 schema)
22
+ export { parseStatusLineSettings, renderDefault as renderStatusLineDefault, renderDetailed as renderStatusLineDetailed, renderStatusLineSync, StatusLine, sanitizeOneLine, tailPath, } from "./components/StatusLine.js";
23
+ // Subagent observability overlay (F2)
24
+ export { formatElapsed, NULL_SUBAGENT_REGISTRY, SubagentOverlay, } from "./components/SubagentOverlay.js";
25
+ export { SelectList, } from "./components/select-list.js";
26
+ export { SettingsList } from "./components/settings-list.js";
27
+ export { Spacer } from "./components/spacer.js";
28
+ export { Spinner } from "./components/spinner.js";
29
+ export { balancePartial, StreamingMarkdown } from "./components/streaming-markdown.js";
30
+ export { Text } from "./components/text.js";
31
+ export { TruncatedText } from "./components/truncated-text.js";
32
+ // Fuzzy matching
33
+ export { fuzzyFilter, fuzzyMatch } from "./fuzzy.js";
34
+ // Keybindings
35
+ export { getKeybindings, KeybindingsManager, setKeybindings, TUI_KEYBINDINGS, } from "./keybindings.js";
36
+ // Keyboard input handling
37
+ export { decodeKittyPrintable, isKeyRelease, isKeyRepeat, isKittyProtocolActive, Key, matchesKey, parseKey, setKittyProtocolActive, } from "./keys.js";
38
+ // Terminal notifications (OSC 9 + bell)
39
+ export { bell, notify } from "./notifications.js";
40
+ // OSC-52 clipboard write
41
+ export { encodeOsc52, OSC52_MAX_BYTES, writeOsc52 } from "./osc52.js";
42
+ // Scroll buffer (in-app scrollback)
43
+ export { ScrollBuffer } from "./scroll-buffer.js";
44
+ // Spinner frame data
45
+ export { getSpinner, SPINNERS, THINKING_SPINNERS, TOOL_SPINNERS, } from "./spinners.js";
46
+ // Input buffering for batch splitting
47
+ export { StdinBuffer } from "./stdin-buffer.js";
48
+ // Synchronized output (DEC private mode 2026)
49
+ export { classifySyncOutputSupport, emitSyncOutputBegin, emitSyncOutputEnd, SYNC_OUTPUT_BEGIN, SYNC_OUTPUT_END, wrapSyncOutput, } from "./sync-output.js";
50
+ // Terminal interface and implementations
51
+ export { ProcessTerminal } from "./terminal.js";
52
+ // Terminal identity + background detection
53
+ export { detectTerminalIdentity, probeTerminal, queryOsc11Standalone, queryTerminalBackground, relativeLuminance, } from "./terminal-detect.js";
54
+ // Terminal image support
55
+ export { allocateImageId, calculateImageRows, deleteAllKittyImages, deleteKittyImage, detectCapabilities, encodeITerm2, encodeKitty, getCapabilities, getCellDimensions, getGifDimensions, getImageDimensions, getJpegDimensions, getPngDimensions, getWebpDimensions, imageFallback, renderImage, resetCapabilitiesCache, setCellDimensions, } from "./terminal-image.js";
56
+ export { Container, CURSOR_MARKER, isFocusable, TUI, } from "./tui.js";
57
+ // Utilities
58
+ export { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "./utils.js";
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,uBAAuB;AACvB,OAAO,EAIN,4BAA4B,GAE5B,MAAM,mBAAmB,CAAC;AAC3B,2EAAyE;AACzE,OAAO,EAAuC,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,uBAAuB;AACvB,OAAO,EAAmB,gBAAgB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC/G,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,kDAAkD;AAClD,OAAO,EAEN,YAAY,EACZ,sBAAsB,EAEtB,WAAW,EAEX,aAAa,GACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,wCAAsC;AACtC,OAAO,EAIN,QAAQ,EAGR,WAAW,EACX,UAAU,EACV,sBAAsB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAwC,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAGN,iBAAiB,GAEjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAsC,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAyB,QAAQ,EAAsB,MAAM,0BAA0B,CAAC;AAC/F,4CAA4C;AAC5C,OAAO,EACN,uBAAuB,EACvB,aAAa,IAAI,uBAAuB,EACxC,cAAc,IAAI,wBAAwB,EAC1C,oBAAoB,EACpB,UAAU,EAMV,eAAe,EACf,QAAQ,GACR,MAAM,4BAA4B,CAAC;AACpC,sCAAsC;AACtC,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,eAAe,GAKf,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEN,UAAU,GAIV,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAoB,YAAY,EAA0B,MAAM,+BAA+B,CAAC;AACvG,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAuB,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvF,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,iBAAiB;AACjB,OAAO,EAAmB,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,cAAc;AACd,OAAO,EACN,cAAc,EAOd,kBAAkB,EAClB,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,0BAA0B;AAC1B,OAAO,EACN,oBAAoB,EACpB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,GAAG,EAGH,UAAU,EACV,QAAQ,EACR,sBAAsB,GACtB,MAAM,WAAW,CAAC;AACnB,wCAAwC;AACxC,OAAO,EAAE,IAAI,EAAsB,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACtE,yBAAyB;AACzB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAA6C,MAAM,oBAAoB,CAAC;AAC7F,qBAAqB;AACrB,OAAO,EACN,UAAU,EACV,QAAQ,EAGR,iBAAiB,EACjB,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,sCAAsC;AACtC,OAAO,EAAE,WAAW,EAAqD,MAAM,mBAAmB,CAAC;AACnG,8CAA8C;AAC9C,OAAO,EACN,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAGf,cAAc,GACd,MAAM,kBAAkB,CAAC;AAC1B,yCAAyC;AACzC,OAAO,EAAE,eAAe,EAAiB,MAAM,eAAe,CAAC;AAC/D,2CAA2C;AAC3C,OAAO,EAEN,sBAAsB,EAGtB,aAAa,EACb,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,GAIjB,MAAM,sBAAsB,CAAC;AAC9B,yBAAyB;AACzB,OAAO,EACN,eAAe,EAEf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EAIjB,aAAa,EACb,WAAW,EACX,sBAAsB,EACtB,iBAAiB,GAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEN,SAAS,EACT,aAAa,EAEb,WAAW,EAQX,GAAG,GACH,MAAM,UAAU,CAAC;AAClB,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["// Core TUI interfaces and classes\n\n// Autocomplete support\nexport {\n\ttype AutocompleteItem,\n\ttype AutocompleteProvider,\n\ttype AutocompleteSuggestions,\n\tCombinedAutocompleteProvider,\n\ttype SlashCommand,\n} from \"./autocomplete.js\";\n// Chord (multi-key sequence) matcher — sits on top of KeybindingsManager\nexport { type ChordResult, type ChordSegment, ChordSession, parseChord } from \"./chord.js\";\n// Color depth emission\nexport { type ColorDepth, detectColorDepth, hexToSgr, resetColorDepthCache, sgrReset } from \"./color-depth.js\";\n// Components\nexport { Box } from \"./components/box.js\";\n// Chapters (auto-folded transcript intent groups)\nexport {\n\ttype Chapter,\n\tdetectIntent,\n\tgroupTurnsIntoChapters,\n\ttype Intent,\n\tintentLabel,\n\ttype Turn,\n\ttoggleChapter,\n} from \"./components/Chapters.js\";\nexport { CancellableLoader } from \"./components/cancellable-loader.js\";\n// Diff view (side-by-side ≥ 100 cols)\nexport {\n\ttype DiffLayout,\n\ttype DiffLine,\n\ttype DiffLineKind,\n\tDiffView,\n\ttype DiffViewOptions,\n\ttype DiffViewTheme,\n\tpairUpHunks,\n\tpickLayout,\n\tSIDE_BY_SIDE_MIN_WIDTH,\n} from \"./components/DiffView.js\";\nexport { Editor, type EditorOptions, type EditorTheme } from \"./components/editor.js\";\nexport {\n\ttype GroupedSelectGroup,\n\ttype GroupedSelection,\n\tGroupedSelectList,\n\ttype GroupedSelectListOptions,\n} from \"./components/grouped-select-list.js\";\nexport { Image, type ImageOptions, type ImageTheme } from \"./components/image.js\";\nexport { Input } from \"./components/input.js\";\nexport { Loader } from \"./components/loader.js\";\nexport { type DefaultTextStyle, Markdown, type MarkdownTheme } from \"./components/markdown.js\";\n// Status line (Claude Code v2.1.119 schema)\nexport {\n\tparseStatusLineSettings,\n\trenderDefault as renderStatusLineDefault,\n\trenderDetailed as renderStatusLineDetailed,\n\trenderStatusLineSync,\n\tStatusLine,\n\ttype StatusLineComponentTheme,\n\ttype StatusLineContext,\n\ttype StatusLineRenderer,\n\ttype StatusLineResult,\n\ttype StatusLineSettings,\n\tsanitizeOneLine,\n\ttailPath,\n} from \"./components/StatusLine.js\";\n// Subagent observability overlay (F2)\nexport {\n\tformatElapsed,\n\tNULL_SUBAGENT_REGISTRY,\n\tSubagentOverlay,\n\ttype SubagentOverlayOptions,\n\ttype SubagentOverlayTheme,\n\ttype SubagentRegistry,\n\ttype SubagentSnapshot,\n} from \"./components/SubagentOverlay.js\";\nexport {\n\ttype SelectItem,\n\tSelectList,\n\ttype SelectListLayoutOptions,\n\ttype SelectListTheme,\n\ttype SelectListTruncatePrimaryContext,\n} from \"./components/select-list.js\";\nexport { type SettingItem, SettingsList, type SettingsListTheme } from \"./components/settings-list.js\";\nexport { Spacer } from \"./components/spacer.js\";\nexport { Spinner, type SpinnerOptions } from \"./components/spinner.js\";\nexport { balancePartial, StreamingMarkdown } from \"./components/streaming-markdown.js\";\nexport { Text } from \"./components/text.js\";\nexport { TruncatedText } from \"./components/truncated-text.js\";\n// Editor component interface (for custom editors)\nexport type { EditorComponent } from \"./editor-component.js\";\n// Fuzzy matching\nexport { type FuzzyMatch, fuzzyFilter, fuzzyMatch } from \"./fuzzy.js\";\n// Keybindings\nexport {\n\tgetKeybindings,\n\ttype Keybinding,\n\ttype KeybindingConflict,\n\ttype KeybindingDefinition,\n\ttype KeybindingDefinitions,\n\ttype Keybindings,\n\ttype KeybindingsConfig,\n\tKeybindingsManager,\n\tsetKeybindings,\n\tTUI_KEYBINDINGS,\n} from \"./keybindings.js\";\n// Keyboard input handling\nexport {\n\tdecodeKittyPrintable,\n\tisKeyRelease,\n\tisKeyRepeat,\n\tisKittyProtocolActive,\n\tKey,\n\ttype KeyEventType,\n\ttype KeyId,\n\tmatchesKey,\n\tparseKey,\n\tsetKittyProtocolActive,\n} from \"./keys.js\";\n// Terminal notifications (OSC 9 + bell)\nexport { bell, type NotifyOptions, notify } from \"./notifications.js\";\n// OSC-52 clipboard write\nexport { encodeOsc52, OSC52_MAX_BYTES, writeOsc52 } from \"./osc52.js\";\n// Scroll buffer (in-app scrollback)\nexport { ScrollBuffer, type ScrollBufferOptions, type ScrollMode } from \"./scroll-buffer.js\";\n// Spinner frame data\nexport {\n\tgetSpinner,\n\tSPINNERS,\n\ttype SpinnerName,\n\ttype SpinnerVariant,\n\tTHINKING_SPINNERS,\n\tTOOL_SPINNERS,\n} from \"./spinners.js\";\n// Input buffering for batch splitting\nexport { StdinBuffer, type StdinBufferEventMap, type StdinBufferOptions } from \"./stdin-buffer.js\";\n// Synchronized output (DEC private mode 2026)\nexport {\n\tclassifySyncOutputSupport,\n\temitSyncOutputBegin,\n\temitSyncOutputEnd,\n\tSYNC_OUTPUT_BEGIN,\n\tSYNC_OUTPUT_END,\n\ttype SyncOutputCapabilityInput,\n\ttype SyncOutputSupport,\n\twrapSyncOutput,\n} from \"./sync-output.js\";\n// Terminal interface and implementations\nexport { ProcessTerminal, type Terminal } from \"./terminal.js\";\n// Terminal identity + background detection\nexport {\n\ttype BackgroundClassification,\n\tdetectTerminalIdentity,\n\ttype Multiplexer,\n\ttype ProbeResult,\n\tprobeTerminal,\n\tqueryOsc11Standalone,\n\tqueryTerminalBackground,\n\trelativeLuminance,\n\ttype TerminalBackground,\n\ttype TerminalIdentity,\n\ttype TerminalProgram,\n} from \"./terminal-detect.js\";\n// Terminal image support\nexport {\n\tallocateImageId,\n\ttype CellDimensions,\n\tcalculateImageRows,\n\tdeleteAllKittyImages,\n\tdeleteKittyImage,\n\tdetectCapabilities,\n\tencodeITerm2,\n\tencodeKitty,\n\tgetCapabilities,\n\tgetCellDimensions,\n\tgetGifDimensions,\n\tgetImageDimensions,\n\tgetJpegDimensions,\n\tgetPngDimensions,\n\tgetWebpDimensions,\n\ttype ImageDimensions,\n\ttype ImageProtocol,\n\ttype ImageRenderOptions,\n\timageFallback,\n\trenderImage,\n\tresetCapabilitiesCache,\n\tsetCellDimensions,\n\ttype TerminalCapabilities,\n} from \"./terminal-image.js\";\nexport {\n\ttype Component,\n\tContainer,\n\tCURSOR_MARKER,\n\ttype Focusable,\n\tisFocusable,\n\ttype OverlayAnchor,\n\ttype OverlayHandle,\n\ttype OverlayMargin,\n\ttype OverlayOptions,\n\ttype SidePanelHandle,\n\ttype SidePanelOptions,\n\ttype SizeValue,\n\tTUI,\n} from \"./tui.js\";\n// Utilities\nexport { truncateToWidth, visibleWidth, wrapTextWithAnsi } from \"./utils.js\";\n"]}