@travisennis/acai 0.0.12 → 0.0.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 (242) hide show
  1. package/README.md +5 -2
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.js +91 -5
  4. package/dist/commands/history/types.d.ts +3 -2
  5. package/dist/commands/history/types.d.ts.map +1 -1
  6. package/dist/commands/init-project/utils.d.ts +0 -1
  7. package/dist/commands/init-project/utils.d.ts.map +1 -1
  8. package/dist/commands/init-project/utils.js +1 -1
  9. package/dist/commands/manager.d.ts.map +1 -1
  10. package/dist/commands/manager.js +0 -18
  11. package/dist/commands/share/html-renderer.d.ts.map +1 -1
  12. package/dist/commands/share/html-renderer.js +54 -48
  13. package/dist/commands/tools/index.js +39 -38
  14. package/dist/config/index.d.ts +0 -2
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +3 -7
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +94 -76
  20. package/dist/models/manager.d.ts +1 -10
  21. package/dist/models/manager.d.ts.map +1 -1
  22. package/dist/models/manager.js +2 -2
  23. package/dist/models/opencode-go-provider.d.ts +6 -4
  24. package/dist/models/opencode-go-provider.d.ts.map +1 -1
  25. package/dist/models/opencode-go-provider.js +55 -35
  26. package/dist/models/providers.d.ts +1 -1
  27. package/dist/models/providers.d.ts.map +1 -1
  28. package/dist/prompts/system-prompt.d.ts +0 -2
  29. package/dist/prompts/system-prompt.d.ts.map +1 -1
  30. package/dist/prompts/system-prompt.js +6 -10
  31. package/dist/repl/index.d.ts +27 -11
  32. package/dist/repl/index.d.ts.map +1 -1
  33. package/dist/repl/index.js +238 -254
  34. package/dist/sessions/manager.d.ts +41 -0
  35. package/dist/sessions/manager.d.ts.map +1 -1
  36. package/dist/sessions/manager.js +53 -0
  37. package/dist/sessions/summary.d.ts.map +1 -1
  38. package/dist/sessions/summary.js +18 -0
  39. package/dist/skills/index.d.ts +12 -2
  40. package/dist/skills/index.d.ts.map +1 -1
  41. package/dist/skills/index.js +123 -73
  42. package/dist/terminal/control.d.ts +1 -21
  43. package/dist/terminal/control.d.ts.map +1 -1
  44. package/dist/terminal/control.js +1 -32
  45. package/dist/terminal/formatting.d.ts +0 -33
  46. package/dist/terminal/formatting.d.ts.map +1 -1
  47. package/dist/terminal/formatting.js +0 -91
  48. package/dist/terminal/highlight/theme.d.ts +0 -37
  49. package/dist/terminal/highlight/theme.d.ts.map +1 -1
  50. package/dist/terminal/highlight/theme.js +1 -79
  51. package/dist/terminal/keys.d.ts +0 -97
  52. package/dist/terminal/keys.d.ts.map +1 -1
  53. package/dist/terminal/keys.js +0 -194
  54. package/dist/terminal/select-prompt.d.ts.map +1 -1
  55. package/dist/terminal/select-prompt.js +65 -51
  56. package/dist/terminal/style.d.ts +1 -1
  57. package/dist/terminal/style.d.ts.map +1 -1
  58. package/dist/terminal/supports-color.d.ts.map +1 -1
  59. package/dist/terminal/supports-color.js +38 -20
  60. package/dist/terminal/supports-hyperlinks.d.ts +3 -0
  61. package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
  62. package/dist/terminal/supports-hyperlinks.js +72 -31
  63. package/dist/terminal/table/layout-manager.d.ts +0 -20
  64. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  65. package/dist/terminal/table/layout-manager.js +68 -44
  66. package/dist/terminal/table/utils.d.ts +0 -1
  67. package/dist/terminal/table/utils.d.ts.map +1 -1
  68. package/dist/terminal/table/utils.js +2 -4
  69. package/dist/tools/apply-patch.d.ts +5 -3
  70. package/dist/tools/apply-patch.d.ts.map +1 -1
  71. package/dist/tools/apply-patch.js +154 -123
  72. package/dist/tools/bash.d.ts.map +1 -1
  73. package/dist/tools/bash.js +11 -8
  74. package/dist/tools/dynamic-tool-loader.d.ts +6 -1
  75. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  76. package/dist/tools/dynamic-tool-loader.js +154 -135
  77. package/dist/tools/index.d.ts +3 -133
  78. package/dist/tools/index.d.ts.map +1 -1
  79. package/dist/tools/index.js +0 -20
  80. package/dist/tools/read-file.d.ts.map +1 -1
  81. package/dist/tools/read-file.js +32 -13
  82. package/dist/tools/skill.d.ts.map +1 -1
  83. package/dist/tools/skill.js +20 -13
  84. package/dist/tools/web-fetch.d.ts +2 -6
  85. package/dist/tools/web-fetch.d.ts.map +1 -1
  86. package/dist/tools/web-fetch.js +59 -36
  87. package/dist/tools/web-search.d.ts +0 -4
  88. package/dist/tools/web-search.d.ts.map +1 -1
  89. package/dist/tools/web-search.js +40 -32
  90. package/dist/tui/autocomplete/utils.d.ts +0 -15
  91. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  92. package/dist/tui/autocomplete/utils.js +0 -85
  93. package/dist/tui/autocomplete.d.ts +1 -1
  94. package/dist/tui/autocomplete.d.ts.map +1 -1
  95. package/dist/tui/autocomplete.js +1 -1
  96. package/dist/tui/components/editor.d.ts +12 -0
  97. package/dist/tui/components/editor.d.ts.map +1 -1
  98. package/dist/tui/components/editor.js +181 -195
  99. package/dist/tui/components/input.d.ts +4 -0
  100. package/dist/tui/components/input.d.ts.map +1 -1
  101. package/dist/tui/components/input.js +33 -31
  102. package/dist/tui/components/markdown.d.ts +30 -0
  103. package/dist/tui/components/markdown.d.ts.map +1 -1
  104. package/dist/tui/components/markdown.js +274 -242
  105. package/dist/tui/components/modal.d.ts.map +1 -1
  106. package/dist/tui/components/modal.js +11 -11
  107. package/dist/tui/components/select-list.d.ts +5 -0
  108. package/dist/tui/components/select-list.d.ts.map +1 -1
  109. package/dist/tui/components/select-list.js +69 -98
  110. package/dist/tui/components/table.d.ts +6 -0
  111. package/dist/tui/components/table.d.ts.map +1 -1
  112. package/dist/tui/components/table.js +61 -52
  113. package/dist/tui/index.d.ts +1 -8
  114. package/dist/tui/index.d.ts.map +1 -1
  115. package/dist/tui/index.js +0 -8
  116. package/dist/tui/tui.d.ts +9 -0
  117. package/dist/tui/tui.d.ts.map +1 -1
  118. package/dist/tui/tui.js +78 -48
  119. package/dist/tui/utils.d.ts +7 -0
  120. package/dist/tui/utils.d.ts.map +1 -1
  121. package/dist/tui/utils.js +117 -53
  122. package/dist/utils/bash.d.ts.map +1 -1
  123. package/dist/utils/bash.js +156 -104
  124. package/dist/utils/command-protection.d.ts +3 -6
  125. package/dist/utils/command-protection.d.ts.map +1 -1
  126. package/dist/utils/command-protection.js +213 -100
  127. package/dist/utils/filesystem/operations.d.ts +0 -15
  128. package/dist/utils/filesystem/operations.d.ts.map +1 -1
  129. package/dist/utils/filesystem/operations.js +1 -38
  130. package/dist/utils/filesystem/security.d.ts.map +1 -1
  131. package/dist/utils/filesystem/security.js +22 -15
  132. package/dist/utils/filetype-detection.d.ts +0 -1
  133. package/dist/utils/filetype-detection.d.ts.map +1 -1
  134. package/dist/utils/filetype-detection.js +0 -12
  135. package/dist/utils/formatting.d.ts +0 -30
  136. package/dist/utils/formatting.d.ts.map +1 -1
  137. package/dist/utils/formatting.js +0 -44
  138. package/dist/utils/git.d.ts +4 -6
  139. package/dist/utils/git.d.ts.map +1 -1
  140. package/dist/utils/git.js +36 -46
  141. package/dist/utils/ignore.d.ts +1 -1
  142. package/dist/utils/ignore.d.ts.map +1 -1
  143. package/dist/utils/ignore.js +1 -1
  144. package/dist/utils/process.d.ts.map +1 -1
  145. package/dist/utils/process.js +77 -79
  146. package/dist/utils/yaml.d.ts +0 -1
  147. package/dist/utils/yaml.d.ts.map +1 -1
  148. package/dist/utils/yaml.js +80 -89
  149. package/dist/utils/zod.d.ts +0 -3
  150. package/dist/utils/zod.d.ts.map +1 -1
  151. package/dist/utils/zod.js +0 -7
  152. package/package.json +25 -24
  153. package/dist/agent/sub-agent.d.ts +0 -23
  154. package/dist/agent/sub-agent.d.ts.map +0 -1
  155. package/dist/agent/sub-agent.js +0 -109
  156. package/dist/commands/add-directory/index.d.ts +0 -3
  157. package/dist/commands/add-directory/index.d.ts.map +0 -1
  158. package/dist/commands/add-directory/index.js +0 -50
  159. package/dist/commands/add-directory/utils.d.ts +0 -3
  160. package/dist/commands/add-directory/utils.d.ts.map +0 -1
  161. package/dist/commands/add-directory/utils.js +0 -15
  162. package/dist/commands/clear/index.d.ts +0 -3
  163. package/dist/commands/clear/index.d.ts.map +0 -1
  164. package/dist/commands/clear/index.js +0 -13
  165. package/dist/commands/generate-rules/index.d.ts +0 -3
  166. package/dist/commands/generate-rules/index.d.ts.map +0 -1
  167. package/dist/commands/generate-rules/index.js +0 -206
  168. package/dist/commands/generate-rules/service.d.ts +0 -22
  169. package/dist/commands/generate-rules/service.d.ts.map +0 -1
  170. package/dist/commands/generate-rules/service.js +0 -103
  171. package/dist/commands/generate-rules/utils.d.ts +0 -5
  172. package/dist/commands/generate-rules/utils.d.ts.map +0 -1
  173. package/dist/commands/generate-rules/utils.js +0 -25
  174. package/dist/commands/handoff/index.d.ts +0 -3
  175. package/dist/commands/handoff/index.d.ts.map +0 -1
  176. package/dist/commands/handoff/index.js +0 -97
  177. package/dist/commands/handoff/utils.d.ts +0 -4
  178. package/dist/commands/handoff/utils.d.ts.map +0 -1
  179. package/dist/commands/handoff/utils.js +0 -123
  180. package/dist/commands/list-directories/index.d.ts +0 -3
  181. package/dist/commands/list-directories/index.d.ts.map +0 -1
  182. package/dist/commands/list-directories/index.js +0 -35
  183. package/dist/commands/pickup/index.d.ts +0 -3
  184. package/dist/commands/pickup/index.d.ts.map +0 -1
  185. package/dist/commands/pickup/index.js +0 -141
  186. package/dist/commands/pickup/types.d.ts +0 -6
  187. package/dist/commands/pickup/types.d.ts.map +0 -1
  188. package/dist/commands/pickup/types.js +0 -1
  189. package/dist/commands/pickup/utils.d.ts +0 -7
  190. package/dist/commands/pickup/utils.d.ts.map +0 -1
  191. package/dist/commands/pickup/utils.js +0 -56
  192. package/dist/commands/remove-directory/index.d.ts +0 -3
  193. package/dist/commands/remove-directory/index.d.ts.map +0 -1
  194. package/dist/commands/remove-directory/index.js +0 -55
  195. package/dist/commands/review/index.d.ts +0 -3
  196. package/dist/commands/review/index.d.ts.map +0 -1
  197. package/dist/commands/review/index.js +0 -12
  198. package/dist/commands/review/review-panel.d.ts +0 -3
  199. package/dist/commands/review/review-panel.d.ts.map +0 -1
  200. package/dist/commands/review/review-panel.js +0 -186
  201. package/dist/commands/review/utils.d.ts +0 -18
  202. package/dist/commands/review/utils.d.ts.map +0 -1
  203. package/dist/commands/review/utils.js +0 -146
  204. package/dist/commands/shell/index.d.ts +0 -3
  205. package/dist/commands/shell/index.d.ts.map +0 -1
  206. package/dist/commands/shell/index.js +0 -96
  207. package/dist/subagents/index.d.ts +0 -16
  208. package/dist/subagents/index.d.ts.map +0 -1
  209. package/dist/subagents/index.js +0 -231
  210. package/dist/terminal/index.d.ts +0 -9
  211. package/dist/terminal/index.d.ts.map +0 -1
  212. package/dist/terminal/index.js +0 -8
  213. package/dist/tools/agent.d.ts +0 -27
  214. package/dist/tools/agent.d.ts.map +0 -1
  215. package/dist/tools/agent.js +0 -81
  216. package/dist/tools/directory-tree.d.ts +0 -28
  217. package/dist/tools/directory-tree.d.ts.map +0 -1
  218. package/dist/tools/directory-tree.js +0 -154
  219. package/dist/tools/glob.d.ts +0 -35
  220. package/dist/tools/glob.d.ts.map +0 -1
  221. package/dist/tools/glob.js +0 -167
  222. package/dist/tools/grep.d.ts +0 -100
  223. package/dist/tools/grep.d.ts.map +0 -1
  224. package/dist/tools/grep.js +0 -608
  225. package/dist/tools/ls.d.ts +0 -26
  226. package/dist/tools/ls.d.ts.map +0 -1
  227. package/dist/tools/ls.js +0 -83
  228. package/dist/tui/components/header.d.ts +0 -21
  229. package/dist/tui/components/header.d.ts.map +0 -1
  230. package/dist/tui/components/header.js +0 -63
  231. package/dist/utils/bash/parse.d.ts +0 -19
  232. package/dist/utils/bash/parse.d.ts.map +0 -1
  233. package/dist/utils/bash/parse.js +0 -223
  234. package/dist/utils/bash/quote.d.ts +0 -6
  235. package/dist/utils/bash/quote.d.ts.map +0 -1
  236. package/dist/utils/bash/quote.js +0 -23
  237. package/dist/utils/generators.d.ts +0 -3
  238. package/dist/utils/generators.d.ts.map +0 -1
  239. package/dist/utils/generators.js +0 -25
  240. package/dist/utils/glob.d.ts +0 -52
  241. package/dist/utils/glob.d.ts.map +0 -1
  242. package/dist/utils/glob.js +0 -376
@@ -56,122 +56,93 @@ export class SelectList {
56
56
  if (!item)
57
57
  continue;
58
58
  const isSelected = i === this.selectedIndex;
59
- let line = "";
60
- if (isSelected) {
61
- // Use arrow indicator for selection - entire line uses selectedText color
62
- const prefixWidth = 2; // "→ " is 2 characters visually
63
- const displayValue = item.label || item.value;
64
- if (item.description && width > 40) {
65
- // Calculate how much space we have for value + description
66
- const maxValueWidth = width - prefixWidth - 4;
67
- const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "...");
68
- const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
69
- // Calculate remaining space for description using visible widths
70
- const descriptionStart = prefixWidth + truncatedValue.length + spacing.length;
71
- const remainingWidth = width - descriptionStart - 2; // -2 for safety
72
- if (remainingWidth > 10) {
73
- const truncatedDesc = truncateToWidth(item.description, remainingWidth, "...");
74
- // Apply selectedText to entire line content
75
- line = this.theme.selectedText(`→ ${truncatedValue}${spacing}${truncatedDesc}`);
76
- }
77
- else {
78
- // Not enough space for description
79
- const maxWidth = width - prefixWidth - 2;
80
- line = this.theme.selectedText(`→ ${truncateToWidth(displayValue, maxWidth, "...")}`);
81
- }
82
- }
83
- else {
84
- // No description or not enough width
85
- const maxWidth = width - prefixWidth - 2;
86
- line = this.theme.selectedText(`→ ${truncateToWidth(displayValue, maxWidth, "...")}`);
87
- }
88
- }
89
- else {
90
- const displayValue = item.label || item.value;
91
- const prefix = " ";
92
- if (item.description && width > 40) {
93
- // Calculate how much space we have for value + description
94
- const maxValueWidth = width - prefix.length - 4;
95
- const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "...");
96
- const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
97
- // Calculate remaining space for description
98
- const descriptionStart = prefix.length + truncatedValue.length + spacing.length;
99
- const remainingWidth = width - descriptionStart - 2; // -2 for safety
100
- if (remainingWidth > 10) {
101
- const truncatedDesc = truncateToWidth(item.description, remainingWidth, "...");
102
- const descText = this.theme.description(spacing + truncatedDesc);
103
- line = prefix + truncatedValue + descText;
104
- }
105
- else {
106
- // Not enough space for description
107
- const maxWidth = width - prefix.length - 2;
108
- line = prefix + truncateToWidth(displayValue, maxWidth, "...");
109
- }
110
- }
111
- else {
112
- // No description or not enough width
113
- const maxWidth = width - prefix.length - 2;
114
- line = prefix + truncateToWidth(displayValue, maxWidth, "...");
115
- }
116
- }
117
- lines.push(line);
59
+ lines.push(this.formatItemLine(item, isSelected, width));
118
60
  }
119
61
  // Add scroll indicators if needed
120
62
  if (startIndex > 0 || endIndex < this.filteredItems.length) {
121
63
  const scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;
122
- // Truncate if too long for terminal
123
64
  lines.push(this.theme.scrollInfo(truncateToWidth(scrollText, width - 2, "...")));
124
65
  }
125
66
  return lines;
126
67
  }
68
+ formatItemLine(item, isSelected, width) {
69
+ const displayValue = item.label || item.value;
70
+ const prefixWidth = 2;
71
+ const prefix = isSelected ? "→ " : " ";
72
+ // Try to show description if available and enough width
73
+ if (item.description && width > 40) {
74
+ const maxValueWidth = width - prefixWidth - 4;
75
+ const truncatedValue = truncateToWidth(displayValue, maxValueWidth, "...");
76
+ const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
77
+ const descriptionStart = prefixWidth + truncatedValue.length + spacing.length;
78
+ const remainingWidth = width - descriptionStart - 2;
79
+ if (remainingWidth > 10) {
80
+ const truncatedDesc = truncateToWidth(item.description, remainingWidth, "...");
81
+ const content = `${prefix}${truncatedValue}${spacing}${truncatedDesc}`;
82
+ return isSelected
83
+ ? this.theme.selectedText(content)
84
+ : `${prefix}${truncatedValue}${this.theme.description(spacing + truncatedDesc)}`;
85
+ }
86
+ }
87
+ // Fallback: no description or not enough room
88
+ const maxWidth = width - prefixWidth - 2;
89
+ const truncated = truncateToWidth(displayValue, maxWidth, "...");
90
+ if (isSelected) {
91
+ return this.theme.selectedText(`${prefix}${truncated}`);
92
+ }
93
+ return `${prefix}${truncated}`;
94
+ }
127
95
  wantsNavigationKeys() {
128
96
  return true;
129
97
  }
130
98
  handleInput(keyData) {
131
- // Up arrow - wrap to bottom when at top
132
99
  if (isArrowUp(keyData)) {
133
- this.selectedIndex =
134
- this.selectedIndex === 0
135
- ? this.filteredItems.length - 1
136
- : this.selectedIndex - 1;
137
- this.notifySelectionChange();
100
+ this.moveSelectionUp();
101
+ return;
138
102
  }
139
- // Down arrow - wrap to top when at bottom
140
- else if (isArrowDown(keyData)) {
141
- this.selectedIndex =
142
- this.selectedIndex === this.filteredItems.length - 1
143
- ? 0
144
- : this.selectedIndex + 1;
145
- this.notifySelectionChange();
103
+ if (isArrowDown(keyData)) {
104
+ this.moveSelectionDown();
105
+ return;
146
106
  }
147
- // Tab - move down with wrapping (like down arrow)
148
- else if (isTab(keyData)) {
149
- this.selectedIndex =
150
- this.selectedIndex === this.filteredItems.length - 1
151
- ? 0
152
- : this.selectedIndex + 1;
153
- this.notifySelectionChange();
107
+ if (isTab(keyData)) {
108
+ this.moveSelectionDown();
109
+ return;
154
110
  }
155
- // Shift+Tab - move up with wrapping (like up arrow)
156
- else if (isShiftTab(keyData)) {
157
- this.selectedIndex =
158
- this.selectedIndex === 0
159
- ? this.filteredItems.length - 1
160
- : this.selectedIndex - 1;
161
- this.notifySelectionChange();
111
+ if (isShiftTab(keyData)) {
112
+ this.moveSelectionUp();
113
+ return;
162
114
  }
163
- // Enter
164
- else if (isEnter(keyData)) {
165
- const selectedItem = this.filteredItems[this.selectedIndex];
166
- if (selectedItem && this.onSelect) {
167
- this.onSelect(selectedItem);
168
- }
115
+ if (isEnter(keyData)) {
116
+ this.selectCurrentItem();
117
+ return;
169
118
  }
170
- // Escape or Ctrl+C
171
- else if (isEscape(keyData) || isCtrlC(keyData)) {
172
- if (this.onCancel) {
173
- this.onCancel();
174
- }
119
+ if (isEscape(keyData) || isCtrlC(keyData)) {
120
+ this.cancelSelection();
121
+ }
122
+ }
123
+ moveSelectionUp() {
124
+ this.selectedIndex =
125
+ this.selectedIndex === 0
126
+ ? this.filteredItems.length - 1
127
+ : this.selectedIndex - 1;
128
+ this.notifySelectionChange();
129
+ }
130
+ moveSelectionDown() {
131
+ this.selectedIndex =
132
+ this.selectedIndex === this.filteredItems.length - 1
133
+ ? 0
134
+ : this.selectedIndex + 1;
135
+ this.notifySelectionChange();
136
+ }
137
+ selectCurrentItem() {
138
+ const selectedItem = this.filteredItems[this.selectedIndex];
139
+ if (selectedItem && this.onSelect) {
140
+ this.onSelect(selectedItem);
141
+ }
142
+ }
143
+ cancelSelection() {
144
+ if (this.onCancel) {
145
+ this.onCancel();
175
146
  }
176
147
  }
177
148
  notifySelectionChange() {
@@ -23,5 +23,11 @@ export declare class TableComponent implements Component {
23
23
  setWidth(width: number): void;
24
24
  private invalidateCache;
25
25
  render(width: number): string[];
26
+ private getCachedOutput;
27
+ private getColumnCount;
28
+ private getColumnWidths;
29
+ private distributeColumnWidths;
30
+ private normalizeData;
31
+ private updateCache;
26
32
  }
27
33
  //# sourceMappingURL=table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../source/tui/components/table.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,OAAO,CAAC,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAW;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAS;IAGvB,OAAO,CAAC,YAAY,CAAC,CAAW;IAChC,OAAO,CAAC,UAAU,CAAC,CAAwB;IAC3C,OAAO,CAAC,aAAa,CAAC,CAAW;IACjC,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,WAAW,CAAC,CAAS;gBAG3B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,EAC3B,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAQvE,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,IAAI;IAK1C,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAKpC,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAKxC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,eAAe;IAQvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAiGhC"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../source/tui/components/table.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,OAAO,CAAC,CAAW;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAW;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAS;IAGvB,OAAO,CAAC,YAAY,CAAC,CAAW;IAChC,OAAO,CAAC,UAAU,CAAC,CAAwB;IAC3C,OAAO,CAAC,aAAa,CAAC,CAAW;IACjC,OAAO,CAAC,eAAe,CAAC,CAAW;IACnC,OAAO,CAAC,WAAW,CAAC,CAAS;gBAG3B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,EAC3B,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAQvE,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,GAAG,IAAI;IAK1C,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAKpC,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAKxC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,eAAe;IAQvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAoC/B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,WAAW;CAOpB"}
@@ -43,83 +43,92 @@ export class TableComponent {
43
43
  this.cachedWidth = undefined;
44
44
  }
45
45
  render(width) {
46
- // Use provided width if specified, otherwise use component width
47
46
  const renderWidth = this.width || width;
48
- // Check cache
49
- if (this.cachedOutput &&
50
- this.cachedData === this.data &&
51
- this.cachedHeaders === this.headers &&
52
- this.cachedColWidths === this.colWidths &&
53
- this.cachedWidth === renderWidth) {
54
- return this.cachedOutput;
47
+ const cached = this.getCachedOutput(renderWidth);
48
+ if (cached) {
49
+ return cached;
55
50
  }
56
51
  if (this.data.length === 0) {
57
52
  this.cachedOutput = [];
58
53
  return [];
59
54
  }
60
- // Determine number of columns from data or header
61
- let colCount = this.headers?.length;
62
- if (colCount === undefined) {
63
- colCount = this.data.length > 0 && this.data[0] ? this.data[0].length : 1;
64
- }
65
- // Calculate column widths based on terminal width
66
- const padding = 5; // Account for table borders and padding
55
+ const colCount = this.getColumnCount();
56
+ const padding = 5;
67
57
  const availableWidth = Math.max(20, renderWidth - padding);
68
- let computedColWidths;
69
- if (this.colWidths && this.colWidths.length === colCount) {
70
- // Use provided percentages
71
- computedColWidths = this.colWidths.map((percent) => Math.max(10, Math.floor((percent / 100) * availableWidth)));
72
- }
73
- else {
74
- // Distribute width evenly with minimum width per column
75
- const minColWidth = 15;
76
- const maxColsThatFit = Math.floor(availableWidth / minColWidth);
77
- const actualColCount = Math.min(colCount, maxColsThatFit);
78
- if (actualColCount === 1) {
79
- computedColWidths = [availableWidth];
80
- }
81
- else {
82
- // Calculate base width and distribute remaining pixels
83
- const baseWidth = Math.floor(availableWidth / actualColCount);
84
- const remainder = availableWidth % actualColCount;
85
- computedColWidths = Array(actualColCount).fill(baseWidth);
86
- // Distribute remainder pixels to first few columns
87
- for (let i = 0; i < remainder && i < actualColCount; i++) {
88
- computedColWidths[i] = (computedColWidths[i] || 0) + 1;
89
- }
90
- }
91
- // If we have fewer computed widths than columns, extend the array
92
- while (computedColWidths.length < colCount) {
93
- computedColWidths.push(minColWidth);
94
- }
95
- }
58
+ const computedColWidths = this.getColumnWidths(colCount, availableWidth);
96
59
  const table = new Table({
97
60
  head: this.headers,
98
61
  colWidths: computedColWidths,
99
62
  wordWrap: true,
100
63
  wrapOnWordBoundary: true,
101
64
  });
102
- // Ensure all data rows have the same number of columns
103
- const normalizedData = this.data.map((row) => {
65
+ const normalizedData = this.normalizeData(colCount);
66
+ table.push(...normalizedData);
67
+ const tableString = table.toString();
68
+ const result = tableString.split("\n");
69
+ this.updateCache(result, renderWidth);
70
+ return result;
71
+ }
72
+ getCachedOutput(renderWidth) {
73
+ if (this.cachedOutput &&
74
+ this.cachedData === this.data &&
75
+ this.cachedHeaders === this.headers &&
76
+ this.cachedColWidths === this.colWidths &&
77
+ this.cachedWidth === renderWidth) {
78
+ return this.cachedOutput;
79
+ }
80
+ return undefined;
81
+ }
82
+ getColumnCount() {
83
+ if (this.headers?.length !== undefined) {
84
+ return this.headers.length;
85
+ }
86
+ if (this.data.length > 0 && this.data[0]) {
87
+ return this.data[0].length;
88
+ }
89
+ return 1;
90
+ }
91
+ getColumnWidths(colCount, availableWidth) {
92
+ if (this.colWidths && this.colWidths.length === colCount) {
93
+ return this.colWidths.map((percent) => Math.max(10, Math.floor((percent / 100) * availableWidth)));
94
+ }
95
+ const minColWidth = 15;
96
+ const maxColsThatFit = Math.floor(availableWidth / minColWidth);
97
+ const actualColCount = Math.min(colCount, maxColsThatFit);
98
+ const computedColWidths = this.distributeColumnWidths(actualColCount, availableWidth);
99
+ while (computedColWidths.length < colCount) {
100
+ computedColWidths.push(minColWidth);
101
+ }
102
+ return computedColWidths;
103
+ }
104
+ distributeColumnWidths(actualColCount, availableWidth) {
105
+ if (actualColCount === 1) {
106
+ return [availableWidth];
107
+ }
108
+ const baseWidth = Math.floor(availableWidth / actualColCount);
109
+ const remainder = availableWidth % actualColCount;
110
+ const widths = Array(actualColCount).fill(baseWidth);
111
+ for (let i = 0; i < remainder && i < actualColCount; i++) {
112
+ widths[i] = (widths[i] || 0) + 1;
113
+ }
114
+ return widths;
115
+ }
116
+ normalizeData(colCount) {
117
+ return this.data.map((row) => {
104
118
  if (row.length < colCount) {
105
- // Pad with empty strings if row has fewer columns
106
119
  return [...row, ...Array(colCount - row.length).fill("")];
107
120
  }
108
121
  if (row.length > colCount) {
109
- // Truncate if row has more columns
110
122
  return row.slice(0, colCount);
111
123
  }
112
124
  return row;
113
125
  });
114
- table.push(...normalizedData);
115
- const tableString = table.toString();
116
- const result = tableString.split("\n");
117
- // Update cache
126
+ }
127
+ updateCache(result, renderWidth) {
118
128
  this.cachedOutput = result;
119
129
  this.cachedData = this.data;
120
130
  this.cachedHeaders = this.headers;
121
131
  this.cachedColWidths = this.colWidths;
122
132
  this.cachedWidth = renderWidth;
123
- return result;
124
133
  }
125
134
  }
@@ -1,21 +1,14 @@
1
- export { CombinedProvider as CombinedAutocompleteProvider } from "./autocomplete/combined-provider.ts";
2
1
  export type { AutocompleteItem, SlashCommand, } from "./autocomplete.ts";
3
- export { BoxComponent } from "./components/box.ts";
4
2
  export { Editor } from "./components/editor.ts";
5
- export { HeaderComponent } from "./components/header.ts";
6
3
  export { Input } from "./components/input.ts";
7
4
  export { Loader } from "./components/loader.ts";
8
5
  export { Markdown } from "./components/markdown.ts";
9
6
  export { Modal, ModalText } from "./components/modal.ts";
10
7
  export { NotificationComponent } from "./components/notification.ts";
11
- export { ProgressBarComponent } from "./components/progress-bar.ts";
12
- export { SelectList } from "./components/select-list.ts";
13
8
  export { Spacer } from "./components/spacer.ts";
14
9
  export { TableComponent } from "./components/table.ts";
15
10
  export { Text } from "./components/text.ts";
16
11
  export { UserMessageComponent } from "./components/user-message.ts";
17
- export { launchEditor } from "./editor-launcher.ts";
18
- export { ProcessTerminal, type ProcessTerminalOptions } from "./terminal.ts";
12
+ export { ProcessTerminal } from "./terminal.ts";
19
13
  export { Container, TUI } from "./tui.ts";
20
- export { visibleWidth } from "./utils.ts";
21
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/tui/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,IAAI,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AAEvG,YAAY,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/tui/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
package/dist/tui/index.js CHANGED
@@ -1,23 +1,15 @@
1
1
  // Core TUI interfaces and classes
2
- export { CombinedProvider as CombinedAutocompleteProvider } from "./autocomplete/combined-provider.js";
3
2
  // Components
4
- export { BoxComponent } from "./components/box.js";
5
3
  export { Editor } from "./components/editor.js";
6
- export { HeaderComponent } from "./components/header.js";
7
4
  export { Input } from "./components/input.js";
8
5
  export { Loader } from "./components/loader.js";
9
6
  export { Markdown } from "./components/markdown.js";
10
7
  export { Modal, ModalText } from "./components/modal.js";
11
8
  export { NotificationComponent } from "./components/notification.js";
12
- export { ProgressBarComponent } from "./components/progress-bar.js";
13
- export { SelectList } from "./components/select-list.js";
14
9
  export { Spacer } from "./components/spacer.js";
15
10
  export { TableComponent } from "./components/table.js";
16
11
  export { Text } from "./components/text.js";
17
12
  export { UserMessageComponent } from "./components/user-message.js";
18
- export { launchEditor } from "./editor-launcher.js";
19
13
  // Terminal interface and implementations
20
14
  export { ProcessTerminal } from "./terminal.js";
21
15
  export { Container, TUI } from "./tui.js";
22
- // Utilities
23
- export { visibleWidth } from "./utils.js";
package/dist/tui/tui.d.ts CHANGED
@@ -92,11 +92,20 @@ export declare class TUI extends Container {
92
92
  private inBracketedPaste;
93
93
  private focusedComponentWantsNavigation;
94
94
  private handleInput;
95
+ private handleBracketedPaste;
96
+ private handleCtrlZ;
97
+ private handleCtrlC;
98
+ private handleCtrlD;
99
+ private handleKeyBindings;
100
+ private handleShiftTab;
101
+ private handleEscapeModal;
102
+ private dispatchInput;
95
103
  private handleMouseEvent;
96
104
  scrollToBottom(): void;
97
105
  private getFixedFooterHeight;
98
106
  private renderScrollableContent;
99
107
  private renderFixedFooter;
108
+ private renderModal;
100
109
  private doRender;
101
110
  /**
102
111
  * Show a modal dialog
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../source/tui/tui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEhC;;OAEG;IACH,WAAW,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAE9C;;;OAGG;IACH,mBAAmB,CAAC,IAAI,OAAO,CAAC;CACjC;AAED,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB;;GAEG;AACH,qBAAa,SAAU,YAAW,SAAS;IACzC,QAAQ,EAAE,SAAS,EAAE,CAAM;IAE3B,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAIpC,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAOvC,iBAAiB,CAAC,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,GAAG,IAAI;IAS5E,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAGhC;AAED;;;;;;;;;;GAUG;AAGH,qBAAa,GAAI,SAAQ,SAAS;IAChC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,gBAAgB,CAAM;IAC9B,OAAO,CAAC,gBAAgB,CAAS;IAE1B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,sEAAsE;IAC/D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;gBAEnB,QAAQ,EAAE,QAAQ;IAK9B;;;;OAIG;IACH,mBAAmB,IAAI,IAAI;IAI3B,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAI3C;;;OAGG;IACH,WAAW,IAAI,QAAQ;IAIvB,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;IAKZ,aAAa,IAAI,IAAI;IAarB,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,+BAA+B;IAIvC,OAAO,CAAC,WAAW;IAyFnB,OAAO,CAAC,gBAAgB;IAiCxB,cAAc,IAAI,IAAI;IAWtB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,QAAQ;IAoFhB;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAK7B;;OAEG;IACH,SAAS,IAAI,IAAI;IAKjB;;OAEG;IACH,aAAa,IAAI,OAAO;CAGzB"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../../source/tui/tui.ts"],"names":[],"mappings":"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"}
package/dist/tui/tui.js CHANGED
@@ -123,37 +123,60 @@ export class TUI extends Container {
123
123
  this.handleMouseEvent(data);
124
124
  return;
125
125
  }
126
+ this.handleBracketedPaste(data);
127
+ if (this.handleCtrlZ(data))
128
+ return;
129
+ if (this.handleCtrlC(data))
130
+ return;
131
+ if (this.handleCtrlD(data))
132
+ return;
133
+ if (this.handleKeyBindings(data))
134
+ return;
135
+ if (this.handleShiftTab(data))
136
+ return;
137
+ if (this.handleEscapeModal(data))
138
+ return;
139
+ this.dispatchInput(data);
140
+ }
141
+ handleBracketedPaste(data) {
126
142
  if (data.includes("\x1b[200~")) {
127
143
  this.inBracketedPaste = true;
128
144
  }
129
145
  if (data.includes("\x1b[201~")) {
130
146
  this.inBracketedPaste = false;
131
147
  }
132
- // Handle Ctrl+Z - background the process (POSIX only)
148
+ }
149
+ handleCtrlZ(data) {
133
150
  if (isCtrlZ(data) &&
134
151
  !this.inBracketedPaste &&
135
152
  process.platform !== "win32") {
136
153
  this.terminal.background();
137
- return;
154
+ return true;
138
155
  }
139
- // Handle Ctrl+C globally - exit the application
140
- if (isCtrlC(data)) {
141
- console.info("\nCtrl+C pressed - exiting...");
142
- if (this.onCtrlC) {
143
- this.onCtrlC();
144
- }
145
- else {
146
- this.stop();
147
- process.exit(0);
148
- }
156
+ return false;
157
+ }
158
+ handleCtrlC(data) {
159
+ if (!isCtrlC(data))
160
+ return false;
161
+ console.info("\nCtrl+C pressed - exiting...");
162
+ if (this.onCtrlC) {
163
+ this.onCtrlC();
149
164
  }
150
- // Handle Ctrl+D - exit only if editor is empty (handled by Repl)
151
- if (isCtrlD(data)) {
152
- if (this.onCtrlD) {
153
- this.onCtrlD();
154
- }
155
- return;
165
+ else {
166
+ this.stop();
167
+ process.exit(0);
156
168
  }
169
+ return true;
170
+ }
171
+ handleCtrlD(data) {
172
+ if (!isCtrlD(data))
173
+ return false;
174
+ if (this.onCtrlD) {
175
+ this.onCtrlD();
176
+ }
177
+ return true;
178
+ }
179
+ handleKeyBindings(data) {
157
180
  const keyBindings = [
158
181
  { check: isCtrlO, handler: this.onCtrlO },
159
182
  { check: isCtrlR, handler: this.onCtrlR },
@@ -163,26 +186,30 @@ export class TUI extends Container {
163
186
  for (const binding of keyBindings) {
164
187
  if (binding.check(data)) {
165
188
  binding.handler?.();
166
- return;
189
+ return true;
167
190
  }
168
191
  }
169
- // Handle Shift+Tab - cycle mode only when no modal is active,
170
- // the focused component won't handle navigation (e.g., model selector),
171
- // and the editor isn't showing autocomplete
172
- if (isShiftTab(data) && !this.inBracketedPaste) {
173
- if (!this.activeModal && !this.focusedComponentWantsNavigation()) {
174
- if (this.onShiftTab) {
175
- this.onShiftTab();
176
- }
177
- return;
192
+ return false;
193
+ }
194
+ handleShiftTab(data) {
195
+ if (!isShiftTab(data) || this.inBracketedPaste)
196
+ return false;
197
+ if (!this.activeModal && !this.focusedComponentWantsNavigation()) {
198
+ if (this.onShiftTab) {
199
+ this.onShiftTab();
178
200
  }
201
+ return true;
179
202
  }
180
- // Handle Escape key to close modal if one is active
203
+ return false;
204
+ }
205
+ handleEscapeModal(data) {
181
206
  if (isEscape(data) && this.activeModal) {
182
207
  this.hideModal();
183
- return;
208
+ return true;
184
209
  }
185
- // Pass input to active modal first, then focused component
210
+ return false;
211
+ }
212
+ dispatchInput(data) {
186
213
  if (this.activeModal?.handleInput) {
187
214
  this.activeModal.handleInput(data);
188
215
  this.requestRender();
@@ -252,6 +279,25 @@ export class TUI extends Container {
252
279
  }
253
280
  return lines;
254
281
  }
282
+ renderModal(width, bufferParts) {
283
+ if (!this.activeModal)
284
+ return;
285
+ const modalLines = this.activeModal.render(width);
286
+ // Render backdrop first if modal has backdrop
287
+ if (this.activeModal.backdrop) {
288
+ const backdropLine = style.bgRgb(0, 0, 0)(" ".repeat(width));
289
+ const { rows } = getTerminalSize();
290
+ for (let i = 0; i < rows; i++) {
291
+ bufferParts.push(`\x1b[${i + 1};1H`, backdropLine);
292
+ }
293
+ }
294
+ // Render modal content
295
+ for (let i = 0; i < modalLines.length; i++) {
296
+ if (modalLines[i]) {
297
+ bufferParts.push(`\x1b[${i + 1};1H`, modalLines[i]);
298
+ }
299
+ }
300
+ }
255
301
  doRender() {
256
302
  if (this.isRendering) {
257
303
  this.renderAgain = true;
@@ -288,23 +334,7 @@ export class TUI extends Container {
288
334
  visibleLines.join("\r\n"),
289
335
  ];
290
336
  // Render modal on top if active
291
- if (this.activeModal) {
292
- const modalLines = this.activeModal.render(width);
293
- // Render backdrop first if modal has backdrop
294
- if (this.activeModal.backdrop) {
295
- const backdropLine = style.bgRgb(0, 0, 0)(" ".repeat(width));
296
- const { rows } = getTerminalSize();
297
- for (let i = 0; i < rows; i++) {
298
- bufferParts.push(`\x1b[${i + 1};1H`, backdropLine);
299
- }
300
- }
301
- // Render modal content
302
- for (let i = 0; i < modalLines.length; i++) {
303
- if (modalLines[i]) {
304
- bufferParts.push(`\x1b[${i + 1};1H`, modalLines[i]);
305
- }
306
- }
307
- }
337
+ this.renderModal(width, bufferParts);
308
338
  bufferParts.push("\x1b[?2026l"); // End synchronized output
309
339
  this.terminal.write(bufferParts.join(""));
310
340
  }
@@ -8,6 +8,13 @@
8
8
  */
9
9
  export declare function visibleWidth(str: string): number;
10
10
  export declare function truncateToWidth(text: string, maxWidth: number, ellipsis?: string, pad?: boolean): string;
11
+ /**
12
+ * Truncate a single fragment to a maximum width.
13
+ */
14
+ export declare function truncateFragmentToWidth(text: string, maxWidth: number): {
15
+ text: string;
16
+ width: number;
17
+ };
11
18
  /**
12
19
  * Apply background color to a line, padding to full width.
13
20
  *
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../source/tui/utils.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAwOD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAQ,EAChB,GAAG,UAAQ,GACV,MAAM,CAuER;AAwHD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC7B,MAAM,CASR"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../source/tui/utils.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAgPD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAQ,EAChB,GAAG,UAAQ,GACV,MAAM,CAyBR;AAiND;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAiBjC;AAkCD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC7B,MAAM,CASR"}