@travisennis/acai 0.0.11 → 0.0.13

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 (292) hide show
  1. package/README.md +5 -5
  2. package/dist/agent/index.d.ts.map +1 -1
  3. package/dist/agent/index.js +2 -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 -12
  9. package/dist/commands/manager.d.ts.map +1 -1
  10. package/dist/commands/manager.js +6 -19
  11. package/dist/commands/resources/index.d.ts.map +1 -1
  12. package/dist/commands/resources/index.js +4 -1
  13. package/dist/commands/session/index.d.ts.map +1 -1
  14. package/dist/commands/session/index.js +6 -0
  15. package/dist/commands/session/types.d.ts +1 -0
  16. package/dist/commands/session/types.d.ts.map +1 -1
  17. package/dist/commands/share/html-renderer.d.ts.map +1 -1
  18. package/dist/commands/share/html-renderer.js +54 -48
  19. package/dist/commands/tools/index.d.ts +3 -0
  20. package/dist/commands/tools/index.d.ts.map +1 -0
  21. package/dist/commands/tools/index.js +191 -0
  22. package/dist/commands/tools/templates.d.ts +6 -0
  23. package/dist/commands/tools/templates.d.ts.map +1 -0
  24. package/dist/commands/tools/templates.js +97 -0
  25. package/dist/config/index.d.ts +5 -2
  26. package/dist/config/index.d.ts.map +1 -1
  27. package/dist/config/index.js +42 -6
  28. package/dist/index.d.ts +14 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +98 -68
  31. package/dist/models/anthropic-provider.d.ts +1 -1
  32. package/dist/models/deepseek-provider.d.ts +3 -3
  33. package/dist/models/deepseek-provider.js +17 -17
  34. package/dist/models/google-provider.d.ts +2 -4
  35. package/dist/models/google-provider.d.ts.map +1 -1
  36. package/dist/models/google-provider.js +2 -17
  37. package/dist/models/groq-provider.d.ts +2 -4
  38. package/dist/models/groq-provider.d.ts.map +1 -1
  39. package/dist/models/groq-provider.js +3 -21
  40. package/dist/models/manager.d.ts +1 -10
  41. package/dist/models/manager.d.ts.map +1 -1
  42. package/dist/models/manager.js +2 -2
  43. package/dist/models/opencode-go-provider.d.ts +11 -1
  44. package/dist/models/opencode-go-provider.d.ts.map +1 -1
  45. package/dist/models/opencode-go-provider.js +130 -0
  46. package/dist/models/opencode-zen-provider.d.ts +3 -3
  47. package/dist/models/opencode-zen-provider.d.ts.map +1 -1
  48. package/dist/models/opencode-zen-provider.js +26 -32
  49. package/dist/models/openrouter-provider.d.ts +4 -15
  50. package/dist/models/openrouter-provider.d.ts.map +1 -1
  51. package/dist/models/openrouter-provider.js +26 -169
  52. package/dist/models/providers.d.ts +1 -1
  53. package/dist/models/providers.d.ts.map +1 -1
  54. package/dist/models/xai-provider.d.ts +1 -2
  55. package/dist/models/xai-provider.d.ts.map +1 -1
  56. package/dist/models/xai-provider.js +0 -13
  57. package/dist/prompts/manager.d.ts.map +1 -1
  58. package/dist/prompts/manager.js +5 -1
  59. package/dist/prompts/system-prompt.d.ts +1 -2
  60. package/dist/prompts/system-prompt.d.ts.map +1 -1
  61. package/dist/prompts/system-prompt.js +26 -15
  62. package/dist/repl/index.d.ts +28 -13
  63. package/dist/repl/index.d.ts.map +1 -1
  64. package/dist/repl/index.js +242 -305
  65. package/dist/skills/activated-tracker.d.ts +11 -0
  66. package/dist/skills/activated-tracker.d.ts.map +1 -0
  67. package/dist/skills/activated-tracker.js +16 -0
  68. package/dist/skills/index.d.ts +12 -2
  69. package/dist/skills/index.d.ts.map +1 -1
  70. package/dist/skills/index.js +127 -71
  71. package/dist/terminal/control.d.ts +1 -21
  72. package/dist/terminal/control.d.ts.map +1 -1
  73. package/dist/terminal/control.js +1 -32
  74. package/dist/terminal/formatting.d.ts +0 -33
  75. package/dist/terminal/formatting.d.ts.map +1 -1
  76. package/dist/terminal/formatting.js +0 -91
  77. package/dist/terminal/highlight/theme.d.ts +0 -37
  78. package/dist/terminal/highlight/theme.d.ts.map +1 -1
  79. package/dist/terminal/highlight/theme.js +1 -79
  80. package/dist/terminal/keys.d.ts +0 -97
  81. package/dist/terminal/keys.d.ts.map +1 -1
  82. package/dist/terminal/keys.js +0 -194
  83. package/dist/terminal/select-prompt.d.ts.map +1 -1
  84. package/dist/terminal/select-prompt.js +65 -51
  85. package/dist/terminal/style.d.ts +1 -1
  86. package/dist/terminal/style.d.ts.map +1 -1
  87. package/dist/terminal/supports-color.d.ts.map +1 -1
  88. package/dist/terminal/supports-color.js +38 -20
  89. package/dist/terminal/supports-hyperlinks.d.ts +3 -0
  90. package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
  91. package/dist/terminal/supports-hyperlinks.js +72 -31
  92. package/dist/terminal/table/layout-manager.d.ts +0 -20
  93. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  94. package/dist/terminal/table/layout-manager.js +68 -44
  95. package/dist/terminal/table/utils.d.ts +0 -1
  96. package/dist/terminal/table/utils.d.ts.map +1 -1
  97. package/dist/terminal/table/utils.js +2 -4
  98. package/dist/tools/apply-patch.d.ts +5 -3
  99. package/dist/tools/apply-patch.d.ts.map +1 -1
  100. package/dist/tools/apply-patch.js +154 -123
  101. package/dist/tools/bash.d.ts +4 -4
  102. package/dist/tools/bash.d.ts.map +1 -1
  103. package/dist/tools/bash.js +27 -13
  104. package/dist/tools/dynamic-tool-loader.d.ts +17 -3
  105. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  106. package/dist/tools/dynamic-tool-loader.js +360 -81
  107. package/dist/tools/edit-file.d.ts +2 -2
  108. package/dist/tools/index.d.ts +27 -151
  109. package/dist/tools/index.d.ts.map +1 -1
  110. package/dist/tools/index.js +16 -21
  111. package/dist/tools/read-file.d.ts +8 -8
  112. package/dist/tools/read-file.d.ts.map +1 -1
  113. package/dist/tools/read-file.js +32 -13
  114. package/dist/tools/save-file.d.ts +4 -4
  115. package/dist/tools/skill.d.ts +2 -1
  116. package/dist/tools/skill.d.ts.map +1 -1
  117. package/dist/tools/skill.js +64 -14
  118. package/dist/tools/types.d.ts +8 -2
  119. package/dist/tools/types.d.ts.map +1 -1
  120. package/dist/tools/web-fetch.d.ts +8 -12
  121. package/dist/tools/web-fetch.d.ts.map +1 -1
  122. package/dist/tools/web-fetch.js +86 -44
  123. package/dist/tools/web-search.d.ts +4 -8
  124. package/dist/tools/web-search.d.ts.map +1 -1
  125. package/dist/tools/web-search.js +41 -33
  126. package/dist/tui/autocomplete/utils.d.ts +0 -15
  127. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  128. package/dist/tui/autocomplete/utils.js +0 -85
  129. package/dist/tui/autocomplete.d.ts +1 -1
  130. package/dist/tui/autocomplete.d.ts.map +1 -1
  131. package/dist/tui/autocomplete.js +1 -1
  132. package/dist/tui/components/editor.d.ts +12 -0
  133. package/dist/tui/components/editor.d.ts.map +1 -1
  134. package/dist/tui/components/editor.js +181 -195
  135. package/dist/tui/components/footer.d.ts +0 -2
  136. package/dist/tui/components/footer.d.ts.map +1 -1
  137. package/dist/tui/components/footer.js +1 -17
  138. package/dist/tui/components/input.d.ts +4 -0
  139. package/dist/tui/components/input.d.ts.map +1 -1
  140. package/dist/tui/components/input.js +33 -31
  141. package/dist/tui/components/markdown.d.ts +30 -0
  142. package/dist/tui/components/markdown.d.ts.map +1 -1
  143. package/dist/tui/components/markdown.js +274 -242
  144. package/dist/tui/components/modal.d.ts.map +1 -1
  145. package/dist/tui/components/modal.js +11 -11
  146. package/dist/tui/components/select-list.d.ts +5 -0
  147. package/dist/tui/components/select-list.d.ts.map +1 -1
  148. package/dist/tui/components/select-list.js +69 -98
  149. package/dist/tui/components/table.d.ts +6 -0
  150. package/dist/tui/components/table.d.ts.map +1 -1
  151. package/dist/tui/components/table.js +61 -52
  152. package/dist/tui/index.d.ts +1 -8
  153. package/dist/tui/index.d.ts.map +1 -1
  154. package/dist/tui/index.js +0 -8
  155. package/dist/tui/tui.d.ts +9 -0
  156. package/dist/tui/tui.d.ts.map +1 -1
  157. package/dist/tui/tui.js +78 -48
  158. package/dist/tui/utils.d.ts +7 -0
  159. package/dist/tui/utils.d.ts.map +1 -1
  160. package/dist/tui/utils.js +117 -53
  161. package/dist/utils/bash.d.ts.map +1 -1
  162. package/dist/utils/bash.js +121 -104
  163. package/dist/utils/binary-output.d.ts +32 -0
  164. package/dist/utils/binary-output.d.ts.map +1 -0
  165. package/dist/utils/binary-output.js +127 -0
  166. package/dist/utils/command-protection.d.ts +3 -2
  167. package/dist/utils/command-protection.d.ts.map +1 -1
  168. package/dist/utils/command-protection.js +121 -29
  169. package/dist/utils/filesystem/operations.d.ts +0 -15
  170. package/dist/utils/filesystem/operations.d.ts.map +1 -1
  171. package/dist/utils/filesystem/operations.js +1 -38
  172. package/dist/utils/filesystem/security.d.ts.map +1 -1
  173. package/dist/utils/filesystem/security.js +22 -15
  174. package/dist/utils/filetype-detection.d.ts +0 -1
  175. package/dist/utils/filetype-detection.d.ts.map +1 -1
  176. package/dist/utils/filetype-detection.js +0 -12
  177. package/dist/utils/formatting.d.ts +0 -30
  178. package/dist/utils/formatting.d.ts.map +1 -1
  179. package/dist/utils/formatting.js +0 -44
  180. package/dist/utils/git.d.ts +4 -6
  181. package/dist/utils/git.d.ts.map +1 -1
  182. package/dist/utils/git.js +36 -46
  183. package/dist/utils/ignore.d.ts +1 -1
  184. package/dist/utils/ignore.d.ts.map +1 -1
  185. package/dist/utils/ignore.js +1 -1
  186. package/dist/utils/parsing.d.ts +1 -1
  187. package/dist/utils/parsing.d.ts.map +1 -1
  188. package/dist/utils/process.d.ts.map +1 -1
  189. package/dist/utils/process.js +77 -79
  190. package/dist/utils/yaml.d.ts +0 -1
  191. package/dist/utils/yaml.d.ts.map +1 -1
  192. package/dist/utils/yaml.js +80 -89
  193. package/dist/utils/zod.d.ts +0 -3
  194. package/dist/utils/zod.d.ts.map +1 -1
  195. package/dist/utils/zod.js +0 -7
  196. package/package.json +32 -29
  197. package/dist/agent/sub-agent.d.ts +0 -23
  198. package/dist/agent/sub-agent.d.ts.map +0 -1
  199. package/dist/agent/sub-agent.js +0 -109
  200. package/dist/commands/add-directory/index.d.ts +0 -3
  201. package/dist/commands/add-directory/index.d.ts.map +0 -1
  202. package/dist/commands/add-directory/index.js +0 -50
  203. package/dist/commands/add-directory/utils.d.ts +0 -3
  204. package/dist/commands/add-directory/utils.d.ts.map +0 -1
  205. package/dist/commands/add-directory/utils.js +0 -15
  206. package/dist/commands/clear/index.d.ts +0 -3
  207. package/dist/commands/clear/index.d.ts.map +0 -1
  208. package/dist/commands/clear/index.js +0 -13
  209. package/dist/commands/generate-rules/index.d.ts +0 -3
  210. package/dist/commands/generate-rules/index.d.ts.map +0 -1
  211. package/dist/commands/generate-rules/index.js +0 -206
  212. package/dist/commands/generate-rules/service.d.ts +0 -22
  213. package/dist/commands/generate-rules/service.d.ts.map +0 -1
  214. package/dist/commands/generate-rules/service.js +0 -103
  215. package/dist/commands/generate-rules/utils.d.ts +0 -5
  216. package/dist/commands/generate-rules/utils.d.ts.map +0 -1
  217. package/dist/commands/generate-rules/utils.js +0 -25
  218. package/dist/commands/handoff/index.d.ts +0 -3
  219. package/dist/commands/handoff/index.d.ts.map +0 -1
  220. package/dist/commands/handoff/index.js +0 -97
  221. package/dist/commands/handoff/utils.d.ts +0 -4
  222. package/dist/commands/handoff/utils.d.ts.map +0 -1
  223. package/dist/commands/handoff/utils.js +0 -123
  224. package/dist/commands/list-directories/index.d.ts +0 -3
  225. package/dist/commands/list-directories/index.d.ts.map +0 -1
  226. package/dist/commands/list-directories/index.js +0 -35
  227. package/dist/commands/pickup/index.d.ts +0 -3
  228. package/dist/commands/pickup/index.d.ts.map +0 -1
  229. package/dist/commands/pickup/index.js +0 -141
  230. package/dist/commands/pickup/types.d.ts +0 -6
  231. package/dist/commands/pickup/types.d.ts.map +0 -1
  232. package/dist/commands/pickup/types.js +0 -1
  233. package/dist/commands/pickup/utils.d.ts +0 -7
  234. package/dist/commands/pickup/utils.d.ts.map +0 -1
  235. package/dist/commands/pickup/utils.js +0 -56
  236. package/dist/commands/remove-directory/index.d.ts +0 -3
  237. package/dist/commands/remove-directory/index.d.ts.map +0 -1
  238. package/dist/commands/remove-directory/index.js +0 -55
  239. package/dist/commands/review/index.d.ts +0 -3
  240. package/dist/commands/review/index.d.ts.map +0 -1
  241. package/dist/commands/review/index.js +0 -12
  242. package/dist/commands/review/review-panel.d.ts +0 -3
  243. package/dist/commands/review/review-panel.d.ts.map +0 -1
  244. package/dist/commands/review/review-panel.js +0 -186
  245. package/dist/commands/review/utils.d.ts +0 -18
  246. package/dist/commands/review/utils.d.ts.map +0 -1
  247. package/dist/commands/review/utils.js +0 -146
  248. package/dist/commands/shell/index.d.ts +0 -3
  249. package/dist/commands/shell/index.d.ts.map +0 -1
  250. package/dist/commands/shell/index.js +0 -96
  251. package/dist/modes/manager.d.ts +0 -24
  252. package/dist/modes/manager.d.ts.map +0 -1
  253. package/dist/modes/manager.js +0 -77
  254. package/dist/modes/prompts.d.ts +0 -2
  255. package/dist/modes/prompts.d.ts.map +0 -1
  256. package/dist/modes/prompts.js +0 -142
  257. package/dist/subagents/index.d.ts +0 -16
  258. package/dist/subagents/index.d.ts.map +0 -1
  259. package/dist/subagents/index.js +0 -231
  260. package/dist/terminal/index.d.ts +0 -9
  261. package/dist/terminal/index.d.ts.map +0 -1
  262. package/dist/terminal/index.js +0 -8
  263. package/dist/tools/agent.d.ts +0 -27
  264. package/dist/tools/agent.d.ts.map +0 -1
  265. package/dist/tools/agent.js +0 -81
  266. package/dist/tools/directory-tree.d.ts +0 -28
  267. package/dist/tools/directory-tree.d.ts.map +0 -1
  268. package/dist/tools/directory-tree.js +0 -152
  269. package/dist/tools/glob.d.ts +0 -35
  270. package/dist/tools/glob.d.ts.map +0 -1
  271. package/dist/tools/glob.js +0 -159
  272. package/dist/tools/grep.d.ts +0 -100
  273. package/dist/tools/grep.d.ts.map +0 -1
  274. package/dist/tools/grep.js +0 -601
  275. package/dist/tools/ls.d.ts +0 -26
  276. package/dist/tools/ls.d.ts.map +0 -1
  277. package/dist/tools/ls.js +0 -82
  278. package/dist/tui/components/header.d.ts +0 -21
  279. package/dist/tui/components/header.d.ts.map +0 -1
  280. package/dist/tui/components/header.js +0 -63
  281. package/dist/utils/bash/parse.d.ts +0 -19
  282. package/dist/utils/bash/parse.d.ts.map +0 -1
  283. package/dist/utils/bash/parse.js +0 -223
  284. package/dist/utils/bash/quote.d.ts +0 -6
  285. package/dist/utils/bash/quote.d.ts.map +0 -1
  286. package/dist/utils/bash/quote.js +0 -23
  287. package/dist/utils/generators.d.ts +0 -3
  288. package/dist/utils/generators.d.ts.map +0 -1
  289. package/dist/utils/generators.js +0 -25
  290. package/dist/utils/glob.d.ts +0 -52
  291. package/dist/utils/glob.d.ts.map +0 -1
  292. package/dist/utils/glob.js +0 -376
@@ -8,7 +8,7 @@ export { CombinedProvider } from "./autocomplete/combined-provider.js";
8
8
  export { CommandProvider } from "./autocomplete/command-provider.js";
9
9
  export { FileSearchProvider } from "./autocomplete/file-search-provider.js";
10
10
  export { SkillProvider } from "./autocomplete/skill-provider.js";
11
- export { DirectoryCache, directoryCache, extractPathPrefix, getDirectoryEntries, isPathWithinAllowedDirs, } from "./autocomplete/utils.js";
11
+ export { extractPathPrefix } from "./autocomplete/utils.js";
12
12
  // Convenience function for backward compatibility
13
13
  export function createDefaultProvider(commands = [], _allowedDirs = [process.cwd()]) {
14
14
  return new CombinedProvider([
@@ -68,6 +68,7 @@ export declare class Editor implements Component {
68
68
  /** Internal setText that doesn't reset history state - used by navigateHistory */
69
69
  private setTextInternal;
70
70
  invalidate(): void;
71
+ private renderCursorOnLine;
71
72
  render(width: number): string[];
72
73
  handleInput(data: string): void;
73
74
  private processInputData;
@@ -83,10 +84,15 @@ export declare class Editor implements Component {
83
84
  private handleWordNavigation;
84
85
  private handleArrowKeys;
85
86
  private layoutText;
87
+ private pushSingleLayoutLine;
88
+ private pushWrappedLayoutLines;
86
89
  getText(): string;
87
90
  setText(text: string): void;
88
91
  private insertCharacter;
89
92
  private handlePaste;
93
+ private handleLargePaste;
94
+ private handleSingleLinePaste;
95
+ private handleMultiLinePaste;
90
96
  private addNewLine;
91
97
  private handleBackspace;
92
98
  private moveToLineStart;
@@ -95,6 +101,10 @@ export declare class Editor implements Component {
95
101
  private deleteToStartOfLine;
96
102
  private deleteToEndOfLine;
97
103
  private deleteWordBackwards;
104
+ private mergeLineWithPrevious;
105
+ private deleteWordOnCurrentLine;
106
+ private findWordBoundaryBackwards;
107
+ private isWordBoundaryChar;
98
108
  /**
99
109
  * Build a mapping from visual lines to logical positions.
100
110
  * Returns an array where each element represents a visual line with:
@@ -108,6 +118,8 @@ export declare class Editor implements Component {
108
118
  */
109
119
  private findCurrentVisualLine;
110
120
  private moveCursor;
121
+ private moveCursorVertical;
122
+ private moveCursorHorizontal;
111
123
  private isWordBoundary;
112
124
  private moveWordBackwards;
113
125
  private moveWordForwards;
@@ -1 +1 @@
1
- {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"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"}
@@ -261,6 +261,35 @@ export class Editor {
261
261
  invalidate() {
262
262
  // No cached state to invalidate currently
263
263
  }
264
+ renderCursorOnLine(displayText, lineVisibleWidth, layoutLine, width) {
265
+ const before = displayText.slice(0, layoutLine.cursorPos);
266
+ const after = displayText.slice(layoutLine.cursorPos);
267
+ if (after.length > 0) {
268
+ const afterGraphemes = [...getSegmenter().segment(after)];
269
+ const firstGrapheme = afterGraphemes[0]?.segment || "";
270
+ const restAfter = after.slice(firstGrapheme.length);
271
+ const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
272
+ return { displayText: before + cursor + restAfter, lineVisibleWidth };
273
+ }
274
+ if (lineVisibleWidth < width) {
275
+ const cursor = "\x1b[7m \x1b[0m";
276
+ return {
277
+ displayText: before + cursor,
278
+ lineVisibleWidth: lineVisibleWidth + 1,
279
+ };
280
+ }
281
+ const beforeGraphemes = [...getSegmenter().segment(before)];
282
+ if (beforeGraphemes.length > 0) {
283
+ const lastGrapheme = beforeGraphemes[beforeGraphemes.length - 1]?.segment || "";
284
+ const cursor = `\x1b[7m${lastGrapheme}\x1b[0m`;
285
+ const beforeWithoutLast = beforeGraphemes
286
+ .slice(0, -1)
287
+ .map((g) => g.segment)
288
+ .join("");
289
+ return { displayText: beforeWithoutLast + cursor, lineVisibleWidth };
290
+ }
291
+ return { displayText, lineVisibleWidth };
292
+ }
264
293
  render(width) {
265
294
  // Store width for cursor navigation
266
295
  this.lastWidth = width;
@@ -274,50 +303,12 @@ export class Editor {
274
303
  for (const layoutLine of layoutLines) {
275
304
  let displayText = layoutLine.text;
276
305
  let lineVisibleWidth = layoutLine.width;
277
- // Add cursor if this line has it
278
306
  if (layoutLine.hasCursor && layoutLine.cursorPos !== undefined) {
279
- const before = displayText.slice(0, layoutLine.cursorPos);
280
- const after = displayText.slice(layoutLine.cursorPos);
281
- if (after.length > 0) {
282
- // Cursor is on a character (grapheme) - replace it with highlighted version
283
- // Get the first grapheme from 'after'
284
- const afterGraphemes = [...getSegmenter().segment(after)];
285
- const firstGrapheme = afterGraphemes[0]?.segment || "";
286
- const restAfter = after.slice(firstGrapheme.length);
287
- const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
288
- displayText = before + cursor + restAfter;
289
- // lineVisibleWidth stays the same - we're replacing, not adding
290
- }
291
- else {
292
- // Cursor is at the end - check if we have room for the space
293
- if (lineVisibleWidth < width) {
294
- // We have room - add highlighted space
295
- const cursor = "\x1b[7m \x1b[0m";
296
- displayText = before + cursor;
297
- // lineVisibleWidth increases by 1 - we're adding a space
298
- lineVisibleWidth = lineVisibleWidth + 1;
299
- }
300
- else {
301
- // Line is at full width - use reverse video on last grapheme if possible
302
- // or just show cursor at the end without adding space
303
- const beforeGraphemes = [...getSegmenter().segment(before)];
304
- if (beforeGraphemes.length > 0) {
305
- const lastGrapheme = beforeGraphemes[beforeGraphemes.length - 1]?.segment || "";
306
- const cursor = `\x1b[7m${lastGrapheme}\x1b[0m`;
307
- // Rebuild 'before' without the last grapheme
308
- const beforeWithoutLast = beforeGraphemes
309
- .slice(0, -1)
310
- .map((g) => g.segment)
311
- .join("");
312
- displayText = beforeWithoutLast + cursor;
313
- }
314
- // lineVisibleWidth stays the same
315
- }
316
- }
307
+ const cursorResult = this.renderCursorOnLine(displayText, lineVisibleWidth, layoutLine, width);
308
+ displayText = cursorResult.displayText;
309
+ lineVisibleWidth = cursorResult.lineVisibleWidth;
317
310
  }
318
- // Calculate padding based on actual visible width
319
311
  const padding = " ".repeat(Math.max(0, width - lineVisibleWidth));
320
- // Render the line (no side borders, just horizontal lines above and below)
321
312
  result.push(displayText + padding);
322
313
  }
323
314
  // Render bottom border
@@ -624,58 +615,62 @@ export class Editor {
624
615
  const metrics = lineMetricsCache.get(line);
625
616
  const lineVisibleWidth = metrics.totalWidth;
626
617
  if (lineVisibleWidth <= contentWidth) {
627
- // Line fits in one layout line
628
- if (isCurrentLine) {
629
- layoutLines.push({
630
- text: line,
631
- hasCursor: true,
632
- cursorPos: this.state.cursorCol,
633
- width: lineVisibleWidth,
634
- });
635
- }
636
- else {
637
- layoutLines.push({
638
- text: line,
639
- hasCursor: false,
640
- width: lineVisibleWidth,
641
- });
642
- }
618
+ this.pushSingleLayoutLine(layoutLines, line, isCurrentLine, lineVisibleWidth);
643
619
  }
644
620
  else {
645
- // Line needs wrapping - use shared helper
646
621
  const chunks = computeLineChunks(line, contentWidth);
647
- for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
648
- const chunk = chunks[chunkIndex];
649
- if (!chunk)
650
- continue;
651
- const cursorPos = this.state.cursorCol;
652
- const isLastChunk = chunkIndex === chunks.length - 1;
653
- // For non-last chunks, cursor at endIndex belongs to the next chunk
654
- const hasCursorInChunk = isCurrentLine &&
655
- cursorPos >= chunk.startIndex &&
656
- (isLastChunk
657
- ? cursorPos <= chunk.endIndex
658
- : cursorPos < chunk.endIndex);
659
- if (hasCursorInChunk) {
660
- layoutLines.push({
661
- text: chunk.text,
662
- hasCursor: true,
663
- cursorPos: cursorPos - chunk.startIndex,
664
- width: chunk.width,
665
- });
666
- }
667
- else {
668
- layoutLines.push({
669
- text: chunk.text,
670
- hasCursor: false,
671
- width: chunk.width,
672
- });
673
- }
674
- }
622
+ this.pushWrappedLayoutLines(layoutLines, chunks, isCurrentLine);
675
623
  }
676
624
  }
677
625
  return layoutLines;
678
626
  }
627
+ pushSingleLayoutLine(layoutLines, line, isCurrentLine, width) {
628
+ if (isCurrentLine) {
629
+ layoutLines.push({
630
+ text: line,
631
+ hasCursor: true,
632
+ cursorPos: this.state.cursorCol,
633
+ width,
634
+ });
635
+ }
636
+ else {
637
+ layoutLines.push({
638
+ text: line,
639
+ hasCursor: false,
640
+ width,
641
+ });
642
+ }
643
+ }
644
+ pushWrappedLayoutLines(layoutLines, chunks, isCurrentLine) {
645
+ const cursorPos = this.state.cursorCol;
646
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
647
+ const chunk = chunks[chunkIndex];
648
+ if (!chunk)
649
+ continue;
650
+ const isLastChunk = chunkIndex === chunks.length - 1;
651
+ // For non-last chunks, cursor at endIndex belongs to the next chunk
652
+ const hasCursorInChunk = isCurrentLine &&
653
+ cursorPos >= chunk.startIndex &&
654
+ (isLastChunk
655
+ ? cursorPos <= chunk.endIndex
656
+ : cursorPos < chunk.endIndex);
657
+ if (hasCursorInChunk) {
658
+ layoutLines.push({
659
+ text: chunk.text,
660
+ hasCursor: true,
661
+ cursorPos: cursorPos - chunk.startIndex,
662
+ width: chunk.width,
663
+ });
664
+ }
665
+ else {
666
+ layoutLines.push({
667
+ text: chunk.text,
668
+ hasCursor: false,
669
+ width: chunk.width,
670
+ });
671
+ }
672
+ }
673
+ }
679
674
  getText() {
680
675
  return this.state.lines.join("\n");
681
676
  }
@@ -713,69 +708,59 @@ export class Editor {
713
708
  }
714
709
  }
715
710
  handlePaste(pastedText) {
716
- // Clean the pasted text
717
711
  const cleanText = pastedText.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
718
- // Convert tabs to spaces (4 spaces per tab)
719
712
  const tabExpandedText = cleanText.replace(/\t/g, " ");
720
- // Filter out non-printable characters except newlines
721
713
  const filteredText = tabExpandedText
722
714
  .split("")
723
715
  .filter((char) => char === "\n" || (char >= " " && char <= "~"))
724
716
  .join("");
725
- // Split into lines
726
717
  const pastedLines = filteredText.split("\n");
727
- // Check if this is a large paste (> 10 lines or > 1000 characters)
728
718
  const totalChars = filteredText.length;
729
719
  if (pastedLines.length > 10 || totalChars > 1000) {
730
- // Store the paste and insert a marker
731
- this.pasteCounter++;
732
- const pasteId = this.pasteCounter;
733
- this.pastes.set(pasteId, filteredText);
734
- // Insert marker like "[paste #1 +123 lines]" or "[paste #1 1234 chars]"
735
- const marker = pastedLines.length > 10
736
- ? `[paste #${pasteId} +${pastedLines.length} lines]`
737
- : `[paste #${pasteId} ${totalChars} chars]`;
738
- for (const char of marker) {
739
- this.insertCharacter(char, true);
740
- }
720
+ this.handleLargePaste(filteredText, pastedLines, totalChars);
741
721
  return;
742
722
  }
743
723
  if (pastedLines.length === 1) {
744
- // Single line - just insert each character
745
- const text = pastedLines[0] || "";
746
- for (const char of text) {
747
- this.insertCharacter(char, true);
748
- }
724
+ this.handleSingleLinePaste(pastedLines[0] || "");
749
725
  return;
750
726
  }
751
- // Multi-line paste - be very careful with array manipulation
727
+ this.handleMultiLinePaste(pastedLines);
728
+ }
729
+ handleLargePaste(filteredText, pastedLines, totalChars) {
730
+ this.pasteCounter++;
731
+ const pasteId = this.pasteCounter;
732
+ this.pastes.set(pasteId, filteredText);
733
+ const marker = pastedLines.length > 10
734
+ ? `[paste #${pasteId} +${pastedLines.length} lines]`
735
+ : `[paste #${pasteId} ${totalChars} chars]`;
736
+ for (const char of marker) {
737
+ this.insertCharacter(char, true);
738
+ }
739
+ }
740
+ handleSingleLinePaste(text) {
741
+ for (const char of text) {
742
+ this.insertCharacter(char, true);
743
+ }
744
+ }
745
+ handleMultiLinePaste(pastedLines) {
752
746
  const currentLine = this.state.lines[this.state.cursorLine] || "";
753
747
  const beforeCursor = currentLine.slice(0, this.state.cursorCol);
754
748
  const afterCursor = currentLine.slice(this.state.cursorCol);
755
- // Build the new lines array step by step
756
749
  const newLines = [];
757
- // Add all lines before current line
758
750
  for (let i = 0; i < this.state.cursorLine; i++) {
759
751
  newLines.push(this.state.lines[i] || "");
760
752
  }
761
- // Add the first pasted line merged with before cursor text
762
753
  newLines.push(beforeCursor + (pastedLines[0] || ""));
763
- // Add all middle pasted lines
764
754
  for (let i = 1; i < pastedLines.length - 1; i++) {
765
755
  newLines.push(pastedLines[i] || "");
766
756
  }
767
- // Add the last pasted line with after cursor text
768
757
  newLines.push((pastedLines[pastedLines.length - 1] || "") + afterCursor);
769
- // Add all lines after current line
770
758
  for (let i = this.state.cursorLine + 1; i < this.state.lines.length; i++) {
771
759
  newLines.push(this.state.lines[i] || "");
772
760
  }
773
- // Replace the entire lines array
774
761
  this.state.lines = newLines;
775
- // Update cursor position to end of pasted content
776
762
  this.state.cursorLine += pastedLines.length - 1;
777
763
  this.state.cursorCol = (pastedLines[pastedLines.length - 1] || "").length;
778
- // Notify of change
779
764
  if (this.onChange) {
780
765
  this.onChange(this.getText());
781
766
  }
@@ -892,49 +877,54 @@ export class Editor {
892
877
  deleteWordBackwards() {
893
878
  this.historyIndex = -1; // Exit history browsing mode
894
879
  const currentLine = this.state.lines[this.state.cursorLine] || "";
895
- // If at start of line, behave like backspace at column 0 (merge with previous line)
896
880
  if (this.state.cursorCol === 0) {
897
- if (this.state.cursorLine > 0) {
898
- const previousLine = this.state.lines[this.state.cursorLine - 1] || "";
899
- this.state.lines[this.state.cursorLine - 1] =
900
- previousLine + currentLine;
901
- this.state.lines.splice(this.state.cursorLine, 1);
902
- this.state.cursorLine--;
903
- this.state.cursorCol = previousLine.length;
904
- }
881
+ this.mergeLineWithPrevious(currentLine);
905
882
  }
906
883
  else {
907
- const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
908
- const isWhitespace = (char) => /\s/.test(char);
909
- const isPunctuation = (char) => {
910
- // Treat obvious code punctuation as boundaries
911
- return /[(){}[\]<>.,;:'"!?+\-=*/\\|&%^$#@~`]/.test(char);
912
- };
913
- let deleteFrom = this.state.cursorCol;
914
- const lastChar = textBeforeCursor[deleteFrom - 1] ?? "";
915
- // If immediately on whitespace or punctuation, delete that single boundary char
916
- if (isWhitespace(lastChar) || isPunctuation(lastChar)) {
917
- deleteFrom -= 1;
918
- }
919
- else {
920
- // Otherwise, delete a run of non-boundary characters (the "word")
921
- while (deleteFrom > 0) {
922
- const ch = textBeforeCursor[deleteFrom - 1] ?? "";
923
- if (isWhitespace(ch) || isPunctuation(ch)) {
924
- break;
925
- }
926
- deleteFrom -= 1;
927
- }
928
- }
929
- this.state.lines[this.state.cursorLine] =
930
- currentLine.slice(0, deleteFrom) +
931
- currentLine.slice(this.state.cursorCol);
932
- this.state.cursorCol = deleteFrom;
884
+ this.deleteWordOnCurrentLine(currentLine);
933
885
  }
934
886
  if (this.onChange) {
935
887
  this.onChange(this.getText());
936
888
  }
937
889
  }
890
+ mergeLineWithPrevious(currentLine) {
891
+ if (this.state.cursorLine <= 0)
892
+ return;
893
+ const previousLine = this.state.lines[this.state.cursorLine - 1] || "";
894
+ this.state.lines[this.state.cursorLine - 1] = previousLine + currentLine;
895
+ this.state.lines.splice(this.state.cursorLine, 1);
896
+ this.state.cursorLine--;
897
+ this.state.cursorCol = previousLine.length;
898
+ }
899
+ deleteWordOnCurrentLine(currentLine) {
900
+ const deleteFrom = this.findWordBoundaryBackwards(currentLine, this.state.cursorCol);
901
+ this.state.lines[this.state.cursorLine] =
902
+ currentLine.slice(0, deleteFrom) +
903
+ currentLine.slice(this.state.cursorCol);
904
+ this.state.cursorCol = deleteFrom;
905
+ }
906
+ findWordBoundaryBackwards(text, fromIndex) {
907
+ const textBeforeCursor = text.slice(0, fromIndex);
908
+ let deleteFrom = fromIndex;
909
+ const lastChar = textBeforeCursor[deleteFrom - 1] ?? "";
910
+ if (this.isWordBoundaryChar(lastChar)) {
911
+ return deleteFrom - 1;
912
+ }
913
+ while (deleteFrom > 0) {
914
+ const ch = textBeforeCursor[deleteFrom - 1] ?? "";
915
+ if (this.isWordBoundaryChar(ch)) {
916
+ break;
917
+ }
918
+ deleteFrom -= 1;
919
+ }
920
+ return deleteFrom;
921
+ }
922
+ isWordBoundaryChar(char) {
923
+ if (/\s/.test(char))
924
+ return true;
925
+ // Treat obvious code punctuation as boundaries
926
+ return /[(){}[\]<>.,;:'"!?+\-=*/\\|&%^$#@~`]/.test(char);
927
+ }
938
928
  /**
939
929
  * Build a mapping from visual lines to logical positions.
940
930
  * Returns an array where each element represents a visual line with:
@@ -994,53 +984,49 @@ export class Editor {
994
984
  return visualLines.length - 1;
995
985
  }
996
986
  moveCursor(deltaLine, deltaCol) {
997
- const width = this.lastWidth;
998
987
  if (deltaLine !== 0) {
999
- // Build visual line map for navigation
1000
- const visualLines = this.buildVisualLineMap(width);
1001
- const currentVisualLine = this.findCurrentVisualLine(visualLines);
1002
- // Calculate column position within current visual line
1003
- const currentVl = visualLines[currentVisualLine];
1004
- const visualCol = currentVl
1005
- ? this.state.cursorCol - currentVl.startCol
1006
- : 0;
1007
- // Move to target visual line
1008
- const targetVisualLine = currentVisualLine + deltaLine;
1009
- if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
1010
- const targetVl = visualLines[targetVisualLine];
1011
- if (targetVl) {
1012
- this.state.cursorLine = targetVl.logicalLine;
1013
- // Try to maintain visual column position, clamped to line length
1014
- const targetCol = targetVl.startCol + Math.min(visualCol, targetVl.length);
1015
- const logicalLine = this.state.lines[targetVl.logicalLine] || "";
1016
- this.state.cursorCol = Math.min(targetCol, logicalLine.length);
1017
- }
1018
- }
988
+ this.moveCursorVertical(deltaLine);
1019
989
  }
1020
990
  if (deltaCol !== 0) {
1021
- const currentLine = this.state.lines[this.state.cursorLine] || "";
1022
- if (deltaCol > 0) {
1023
- // Moving right
1024
- if (this.state.cursorCol < currentLine.length) {
1025
- this.state.cursorCol++;
1026
- }
1027
- else if (this.state.cursorLine < this.state.lines.length - 1) {
1028
- // Wrap to start of next logical line
1029
- this.state.cursorLine++;
1030
- this.state.cursorCol = 0;
1031
- }
991
+ this.moveCursorHorizontal(deltaCol);
992
+ }
993
+ }
994
+ moveCursorVertical(deltaLine) {
995
+ const width = this.lastWidth;
996
+ const visualLines = this.buildVisualLineMap(width);
997
+ const currentVisualLine = this.findCurrentVisualLine(visualLines);
998
+ const currentVl = visualLines[currentVisualLine];
999
+ const visualCol = currentVl ? this.state.cursorCol - currentVl.startCol : 0;
1000
+ const targetVisualLine = currentVisualLine + deltaLine;
1001
+ if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
1002
+ const targetVl = visualLines[targetVisualLine];
1003
+ if (targetVl) {
1004
+ this.state.cursorLine = targetVl.logicalLine;
1005
+ const targetCol = targetVl.startCol + Math.min(visualCol, targetVl.length);
1006
+ const logicalLine = this.state.lines[targetVl.logicalLine] || "";
1007
+ this.state.cursorCol = Math.min(targetCol, logicalLine.length);
1032
1008
  }
1033
- else {
1034
- // Moving left
1035
- if (this.state.cursorCol > 0) {
1036
- this.state.cursorCol--;
1037
- }
1038
- else if (this.state.cursorLine > 0) {
1039
- // Wrap to end of previous logical line
1040
- this.state.cursorLine--;
1041
- const prevLine = this.state.lines[this.state.cursorLine] || "";
1042
- this.state.cursorCol = prevLine.length;
1043
- }
1009
+ }
1010
+ }
1011
+ moveCursorHorizontal(deltaCol) {
1012
+ const currentLine = this.state.lines[this.state.cursorLine] || "";
1013
+ if (deltaCol > 0) {
1014
+ if (this.state.cursorCol < currentLine.length) {
1015
+ this.state.cursorCol++;
1016
+ }
1017
+ else if (this.state.cursorLine < this.state.lines.length - 1) {
1018
+ this.state.cursorLine++;
1019
+ this.state.cursorCol = 0;
1020
+ }
1021
+ }
1022
+ else {
1023
+ if (this.state.cursorCol > 0) {
1024
+ this.state.cursorCol--;
1025
+ }
1026
+ else if (this.state.cursorLine > 0) {
1027
+ this.state.cursorLine--;
1028
+ const prevLine = this.state.lines[this.state.cursorLine] || "";
1029
+ this.state.cursorCol = prevLine.length;
1044
1030
  }
1045
1031
  }
1046
1032
  }
@@ -8,7 +8,6 @@ type State = {
8
8
  currentContextWindow: number;
9
9
  contextWindow: number;
10
10
  agentState?: AgentState;
11
- currentMode?: string;
12
11
  };
13
12
  export declare class FooterComponent implements Component {
14
13
  private modelManager;
@@ -16,7 +15,6 @@ export declare class FooterComponent implements Component {
16
15
  private state;
17
16
  private progressBar;
18
17
  private agentState?;
19
- private currentMode;
20
18
  constructor(modelManager: ModelManager, tokenTracker: TokenTracker | undefined, state: State);
21
19
  setState(state: State): void;
22
20
  resetState(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA2CF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,WAAW,CAAY;gBAE7B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,KAAK,EAAE,KAAK;IAad,QAAQ,CAAC,KAAK,EAAE,KAAK;IAYrB,UAAU;IAIV,gBAAgB,IAAI,iBAAiB;IAIrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAiFhC"}
1
+ {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AA2CF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;gBAE9B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,KAAK,EAAE,KAAK;IAad,QAAQ,CAAC,KAAK,EAAE,KAAK;IASrB,UAAU;IAIV,gBAAgB,IAAI,iBAAiB;IAIrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAkEhC"}
@@ -41,7 +41,6 @@ export class FooterComponent {
41
41
  state;
42
42
  progressBar;
43
43
  agentState;
44
- currentMode = "Normal";
45
44
  constructor(modelManager, tokenTracker, state) {
46
45
  this.modelManager = modelManager;
47
46
  this.tokenTracker = tokenTracker;
@@ -53,9 +52,6 @@ export class FooterComponent {
53
52
  if (state.agentState) {
54
53
  this.agentState = state.agentState;
55
54
  }
56
- if (state.currentMode !== undefined) {
57
- this.currentMode = state.currentMode;
58
- }
59
55
  this.state = state;
60
56
  this.progressBar.setCurrent(state.currentContextWindow);
61
57
  this.progressBar.setTotal(state.contextWindow);
@@ -72,20 +68,8 @@ export class FooterComponent {
72
68
  const [pathLine, gitLine] = formatProjectStatus(this.state.projectStatus);
73
69
  const padding = Math.max(0, width - visibleWidth(pathLine) - modelInfo.length);
74
70
  results.push(pathLine + " ".repeat(padding) + style.dim(modelInfo));
75
- const modeDisplay = this.currentMode !== "Normal"
76
- ? style.magenta(`[${this.currentMode}]`)
77
- : "";
78
71
  if (gitLine) {
79
- if (modeDisplay) {
80
- const gitPadding = Math.max(0, width - visibleWidth(gitLine) - visibleWidth(modeDisplay));
81
- results.push(`${gitLine}${" ".repeat(gitPadding)}${modeDisplay}`);
82
- }
83
- else {
84
- results.push(gitLine);
85
- }
86
- }
87
- else if (modeDisplay) {
88
- results.push(modeDisplay);
72
+ results.push(gitLine);
89
73
  }
90
74
  // Line 3: Total session usage from token tracker (accumulated across all turns)
91
75
  if (this.tokenTracker) {
@@ -9,6 +9,10 @@ export declare class Input implements Component {
9
9
  getValue(): string;
10
10
  setValue(value: string): void;
11
11
  handleInput(data: string): void;
12
+ private handleSpecialKey;
13
+ private backspace;
14
+ private deleteForward;
15
+ private insertCharacter;
12
16
  render(width: number): string[];
13
17
  }
14
18
  //# sourceMappingURL=input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../source/tui/components/input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,KAAM,YAAW,SAAS;IACrC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,MAAM,CAAK;IACZ,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiE/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAuDhC"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../source/tui/components/input.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,KAAM,YAAW,SAAS;IACrC,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,MAAM,CAAK;IACZ,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAE1C,QAAQ,IAAI,MAAM;IAIlB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/B,OAAO,CAAC,gBAAgB;IAgCxB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,eAAe;IAQvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAuDhC"}