@travisennis/acai 0.0.9 → 0.0.10

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 (371) hide show
  1. package/README.md +49 -762
  2. package/bin/acai +52 -0
  3. package/dist/agent/index.d.ts +12 -2
  4. package/dist/agent/index.d.ts.map +1 -1
  5. package/dist/agent/index.js +378 -199
  6. package/dist/agent/sub-agent.d.ts +23 -0
  7. package/dist/agent/sub-agent.d.ts.map +1 -0
  8. package/dist/agent/sub-agent.js +109 -0
  9. package/dist/cli/index.d.ts +26 -0
  10. package/dist/cli/index.d.ts.map +1 -0
  11. package/dist/{cli.js → cli/index.js} +84 -77
  12. package/dist/cli/stdin.d.ts.map +1 -0
  13. package/dist/{stdin.js → cli/stdin.js} +11 -0
  14. package/dist/commands/copy/index.js +2 -2
  15. package/dist/commands/copy/utils.d.ts.map +1 -1
  16. package/dist/commands/copy/utils.js +15 -13
  17. package/dist/commands/generate-rules/index.d.ts +1 -1
  18. package/dist/commands/generate-rules/index.d.ts.map +1 -1
  19. package/dist/commands/generate-rules/index.js +16 -101
  20. package/dist/commands/generate-rules/service.d.ts +21 -0
  21. package/dist/commands/generate-rules/service.d.ts.map +1 -0
  22. package/dist/commands/generate-rules/service.js +103 -0
  23. package/dist/commands/handoff/index.js +2 -2
  24. package/dist/commands/health/index.js +1 -1
  25. package/dist/commands/health/utils.d.ts.map +1 -1
  26. package/dist/commands/health/utils.js +6 -0
  27. package/dist/commands/history/index.d.ts +1 -1
  28. package/dist/commands/history/index.d.ts.map +1 -1
  29. package/dist/commands/history/index.js +17 -18
  30. package/dist/commands/history/types.d.ts +38 -0
  31. package/dist/commands/history/types.d.ts.map +1 -1
  32. package/dist/commands/history/utils.d.ts.map +1 -1
  33. package/dist/commands/history/utils.js +63 -58
  34. package/dist/commands/init/index.d.ts.map +1 -1
  35. package/dist/commands/init/index.js +3 -8
  36. package/dist/commands/init-project/index.d.ts.map +1 -1
  37. package/dist/commands/init-project/index.js +3 -3
  38. package/dist/commands/init-project/utils.d.ts.map +1 -1
  39. package/dist/commands/init-project/utils.js +10 -2
  40. package/dist/commands/list-tools/index.d.ts.map +1 -1
  41. package/dist/commands/list-tools/index.js +7 -31
  42. package/dist/commands/manager.d.ts +2 -2
  43. package/dist/commands/manager.d.ts.map +1 -1
  44. package/dist/commands/manager.js +55 -33
  45. package/dist/commands/model/index.d.ts.map +1 -1
  46. package/dist/commands/model/index.js +20 -151
  47. package/dist/commands/model/model-panel.d.ts +4 -0
  48. package/dist/commands/model/model-panel.d.ts.map +1 -0
  49. package/dist/commands/model/model-panel.js +144 -0
  50. package/dist/commands/paste/index.d.ts.map +1 -1
  51. package/dist/commands/paste/index.js +59 -62
  52. package/dist/commands/paste/utils.d.ts.map +1 -1
  53. package/dist/commands/paste/utils.js +88 -58
  54. package/dist/commands/pickup/index.d.ts.map +1 -1
  55. package/dist/commands/pickup/index.js +6 -3
  56. package/dist/commands/pickup/utils.js +3 -3
  57. package/dist/commands/resources/index.d.ts.map +1 -1
  58. package/dist/commands/resources/index.js +33 -50
  59. package/dist/commands/review/index.d.ts.map +1 -1
  60. package/dist/commands/review/index.js +3 -117
  61. package/dist/commands/review/review-panel.d.ts +3 -0
  62. package/dist/commands/review/review-panel.d.ts.map +1 -0
  63. package/dist/commands/review/review-panel.js +186 -0
  64. package/dist/commands/review/utils.d.ts +9 -0
  65. package/dist/commands/review/utils.d.ts.map +1 -1
  66. package/dist/commands/review/utils.js +127 -68
  67. package/dist/commands/session/index.d.ts +1 -1
  68. package/dist/commands/session/index.d.ts.map +1 -1
  69. package/dist/commands/session/index.js +124 -135
  70. package/dist/commands/shell/index.d.ts.map +1 -1
  71. package/dist/commands/shell/index.js +16 -1
  72. package/dist/commands/types.d.ts +2 -2
  73. package/dist/commands/types.d.ts.map +1 -1
  74. package/dist/{config.d.ts → config/index.d.ts} +20 -9
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/{config.js → config/index.js} +43 -42
  77. package/dist/execution/index.d.ts.map +1 -1
  78. package/dist/execution/index.js +75 -55
  79. package/dist/index.d.ts +1 -0
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +148 -141
  82. package/dist/middleware/cache.d.ts.map +1 -1
  83. package/dist/middleware/cache.js +18 -36
  84. package/dist/models/ai-config.d.ts +1 -0
  85. package/dist/models/ai-config.d.ts.map +1 -1
  86. package/dist/models/ai-config.js +4 -3
  87. package/dist/models/anthropic-provider.d.ts +2 -5
  88. package/dist/models/anthropic-provider.d.ts.map +1 -1
  89. package/dist/models/anthropic-provider.js +3 -70
  90. package/dist/models/deepseek-provider.d.ts +1 -0
  91. package/dist/models/deepseek-provider.d.ts.map +1 -1
  92. package/dist/models/google-provider.d.ts +2 -3
  93. package/dist/models/google-provider.d.ts.map +1 -1
  94. package/dist/models/google-provider.js +0 -26
  95. package/dist/models/groq-provider.d.ts +1 -0
  96. package/dist/models/groq-provider.d.ts.map +1 -1
  97. package/dist/models/manager.d.ts +13 -2
  98. package/dist/models/manager.d.ts.map +1 -1
  99. package/dist/models/manager.js +20 -8
  100. package/dist/models/openai-provider.d.ts +2 -5
  101. package/dist/models/openai-provider.d.ts.map +1 -1
  102. package/dist/models/openai-provider.js +0 -52
  103. package/dist/models/opencode-zen-provider.d.ts +7 -3
  104. package/dist/models/opencode-zen-provider.d.ts.map +1 -1
  105. package/dist/models/opencode-zen-provider.js +49 -10
  106. package/dist/models/openrouter-provider.d.ts +24 -31
  107. package/dist/models/openrouter-provider.d.ts.map +1 -1
  108. package/dist/models/openrouter-provider.js +84 -182
  109. package/dist/models/providers.d.ts +1 -1
  110. package/dist/models/providers.d.ts.map +1 -1
  111. package/dist/models/xai-provider.d.ts +4 -3
  112. package/dist/models/xai-provider.d.ts.map +1 -1
  113. package/dist/models/xai-provider.js +18 -18
  114. package/dist/modes/manager.d.ts +23 -0
  115. package/dist/modes/manager.d.ts.map +1 -0
  116. package/dist/modes/manager.js +77 -0
  117. package/dist/modes/prompts.d.ts +2 -0
  118. package/dist/modes/prompts.d.ts.map +1 -0
  119. package/dist/modes/prompts.js +143 -0
  120. package/dist/prompts/mentions.d.ts +11 -0
  121. package/dist/prompts/mentions.d.ts.map +1 -0
  122. package/dist/{mentions.js → prompts/mentions.js} +21 -80
  123. package/dist/{prompts.d.ts → prompts/system-prompt.d.ts} +7 -2
  124. package/dist/prompts/system-prompt.d.ts.map +1 -0
  125. package/dist/{prompts.js → prompts/system-prompt.js} +31 -16
  126. package/dist/repl/index.d.ts +174 -0
  127. package/dist/repl/index.d.ts.map +1 -0
  128. package/dist/{repl-new.js → repl/index.js} +389 -76
  129. package/dist/repl/project-status.d.ts +1 -0
  130. package/dist/repl/project-status.d.ts.map +1 -1
  131. package/dist/repl/project-status.js +4 -1
  132. package/dist/sessions/manager.d.ts +93 -1
  133. package/dist/sessions/manager.d.ts.map +1 -1
  134. package/dist/sessions/manager.js +262 -9
  135. package/dist/sessions/summary.d.ts +4 -0
  136. package/dist/sessions/summary.d.ts.map +1 -0
  137. package/dist/sessions/summary.js +30 -0
  138. package/dist/{skills.d.ts → skills/index.d.ts} +14 -2
  139. package/dist/skills/index.d.ts.map +1 -0
  140. package/dist/skills/index.js +294 -0
  141. package/dist/subagents/index.d.ts +15 -0
  142. package/dist/subagents/index.d.ts.map +1 -0
  143. package/dist/subagents/index.js +231 -0
  144. package/dist/terminal/control.d.ts +1 -1
  145. package/dist/terminal/control.d.ts.map +1 -1
  146. package/dist/terminal/control.js +3 -3
  147. package/dist/terminal/east-asian-width.d.ts.map +1 -1
  148. package/dist/terminal/east-asian-width.js +404 -351
  149. package/dist/terminal/keys.d.ts +17 -0
  150. package/dist/terminal/keys.d.ts.map +1 -1
  151. package/dist/terminal/keys.js +37 -0
  152. package/dist/terminal/select-prompt.d.ts.map +1 -1
  153. package/dist/terminal/select-prompt.js +24 -12
  154. package/dist/terminal/string-width.d.ts.map +1 -1
  155. package/dist/terminal/string-width.js +25 -27
  156. package/dist/terminal/style.d.ts.map +1 -1
  157. package/dist/terminal/style.js +4 -7
  158. package/dist/terminal/supports-color.d.ts.map +1 -1
  159. package/dist/terminal/supports-color.js +41 -27
  160. package/dist/terminal/table/cell.d.ts +12 -0
  161. package/dist/terminal/table/cell.d.ts.map +1 -1
  162. package/dist/terminal/table/cell.js +40 -25
  163. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  164. package/dist/terminal/table/layout-manager.js +100 -68
  165. package/dist/terminal/table/utils.d.ts.map +1 -1
  166. package/dist/terminal/table/utils.js +17 -10
  167. package/dist/terminal/wrap-ansi.d.ts.map +1 -1
  168. package/dist/terminal/wrap-ansi.js +172 -103
  169. package/dist/tokens/tracker.d.ts +1 -0
  170. package/dist/tokens/tracker.d.ts.map +1 -1
  171. package/dist/tokens/tracker.js +3 -0
  172. package/dist/tools/agent.d.ts +27 -0
  173. package/dist/tools/agent.d.ts.map +1 -0
  174. package/dist/tools/agent.js +81 -0
  175. package/dist/tools/bash.d.ts +4 -3
  176. package/dist/tools/bash.d.ts.map +1 -1
  177. package/dist/tools/bash.js +324 -137
  178. package/dist/tools/code-search.d.ts +41 -0
  179. package/dist/tools/code-search.d.ts.map +1 -0
  180. package/dist/tools/code-search.js +195 -0
  181. package/dist/tools/directory-tree.d.ts +3 -3
  182. package/dist/tools/directory-tree.d.ts.map +1 -1
  183. package/dist/tools/directory-tree.js +8 -5
  184. package/dist/tools/dynamic-tool-loader.d.ts +2 -5
  185. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  186. package/dist/tools/dynamic-tool-loader.js +20 -4
  187. package/dist/tools/edit-file.d.ts +7 -7
  188. package/dist/tools/edit-file.d.ts.map +1 -1
  189. package/dist/tools/edit-file.js +164 -66
  190. package/dist/tools/glob.d.ts +6 -6
  191. package/dist/tools/glob.d.ts.map +1 -1
  192. package/dist/tools/glob.js +95 -55
  193. package/dist/tools/grep.d.ts +15 -12
  194. package/dist/tools/grep.d.ts.map +1 -1
  195. package/dist/tools/grep.js +300 -192
  196. package/dist/tools/index.d.ts +143 -5
  197. package/dist/tools/index.d.ts.map +1 -1
  198. package/dist/tools/index.js +39 -24
  199. package/dist/tools/ls.d.ts +2 -2
  200. package/dist/tools/ls.d.ts.map +1 -1
  201. package/dist/tools/ls.js +7 -5
  202. package/dist/tools/read-file.d.ts +3 -3
  203. package/dist/tools/read-file.d.ts.map +1 -1
  204. package/dist/tools/read-file.js +74 -34
  205. package/dist/tools/save-file.d.ts +3 -3
  206. package/dist/tools/save-file.d.ts.map +1 -1
  207. package/dist/tools/save-file.js +11 -11
  208. package/dist/tools/skill.d.ts +23 -0
  209. package/dist/tools/skill.d.ts.map +1 -0
  210. package/dist/tools/skill.js +65 -0
  211. package/dist/tools/think.d.ts.map +1 -1
  212. package/dist/tools/think.js +2 -9
  213. package/dist/tools/utils.d.ts +2 -0
  214. package/dist/tools/utils.d.ts.map +1 -1
  215. package/dist/tools/utils.js +12 -0
  216. package/dist/tools/web-fetch.d.ts +62 -0
  217. package/dist/tools/web-fetch.d.ts.map +1 -0
  218. package/dist/tools/web-fetch.js +429 -0
  219. package/dist/tools/web-search.d.ts +62 -0
  220. package/dist/tools/web-search.d.ts.map +1 -0
  221. package/dist/tools/web-search.js +226 -0
  222. package/dist/tui/autocomplete/attachment-provider.d.ts +3 -6
  223. package/dist/tui/autocomplete/attachment-provider.d.ts.map +1 -1
  224. package/dist/tui/autocomplete/attachment-provider.js +25 -78
  225. package/dist/tui/autocomplete/base-provider.d.ts +1 -0
  226. package/dist/tui/autocomplete/base-provider.d.ts.map +1 -1
  227. package/dist/tui/autocomplete/combined-provider.d.ts +1 -4
  228. package/dist/tui/autocomplete/combined-provider.d.ts.map +1 -1
  229. package/dist/tui/autocomplete/combined-provider.js +3 -17
  230. package/dist/tui/autocomplete/command-provider.d.ts +1 -0
  231. package/dist/tui/autocomplete/command-provider.d.ts.map +1 -1
  232. package/dist/tui/autocomplete/command-provider.js +3 -0
  233. package/dist/tui/autocomplete/file-search-provider.d.ts +2 -1
  234. package/dist/tui/autocomplete/file-search-provider.d.ts.map +1 -1
  235. package/dist/tui/autocomplete/file-search-provider.js +36 -16
  236. package/dist/tui/autocomplete/skill-provider.d.ts +17 -0
  237. package/dist/tui/autocomplete/skill-provider.d.ts.map +1 -0
  238. package/dist/tui/autocomplete/skill-provider.js +49 -0
  239. package/dist/tui/autocomplete.d.ts +2 -2
  240. package/dist/tui/autocomplete.d.ts.map +1 -1
  241. package/dist/tui/autocomplete.js +3 -5
  242. package/dist/tui/components/assistant-message.d.ts.map +1 -1
  243. package/dist/tui/components/assistant-message.js +0 -4
  244. package/dist/tui/components/editor.d.ts +16 -2
  245. package/dist/tui/components/editor.d.ts.map +1 -1
  246. package/dist/tui/components/editor.js +211 -237
  247. package/dist/tui/components/footer.d.ts +6 -4
  248. package/dist/tui/components/footer.d.ts.map +1 -1
  249. package/dist/tui/components/footer.js +49 -25
  250. package/dist/tui/components/markdown.d.ts +8 -5
  251. package/dist/tui/components/markdown.d.ts.map +1 -1
  252. package/dist/tui/components/markdown.js +57 -39
  253. package/dist/tui/components/modal.d.ts.map +1 -1
  254. package/dist/tui/components/modal.js +35 -33
  255. package/dist/tui/components/notification.d.ts +13 -2
  256. package/dist/tui/components/notification.d.ts.map +1 -1
  257. package/dist/tui/components/notification.js +36 -2
  258. package/dist/tui/components/progress-bar.js +1 -1
  259. package/dist/tui/components/select-list.d.ts +1 -0
  260. package/dist/tui/components/select-list.d.ts.map +1 -1
  261. package/dist/tui/components/select-list.js +14 -11
  262. package/dist/tui/components/text.d.ts +16 -0
  263. package/dist/tui/components/text.d.ts.map +1 -1
  264. package/dist/tui/components/text.js +72 -57
  265. package/dist/tui/components/thinking-block.d.ts +9 -0
  266. package/dist/tui/components/thinking-block.d.ts.map +1 -1
  267. package/dist/tui/components/thinking-block.js +43 -11
  268. package/dist/tui/components/tool-execution.d.ts +5 -1
  269. package/dist/tui/components/tool-execution.d.ts.map +1 -1
  270. package/dist/tui/components/tool-execution.js +19 -10
  271. package/dist/tui/components/user-message.d.ts.map +1 -1
  272. package/dist/tui/components/user-message.js +0 -3
  273. package/dist/tui/components/welcome.js +2 -2
  274. package/dist/tui/terminal.d.ts.map +1 -1
  275. package/dist/tui/terminal.js +10 -2
  276. package/dist/tui/tui.d.ts +42 -0
  277. package/dist/tui/tui.d.ts.map +1 -1
  278. package/dist/tui/tui.js +157 -41
  279. package/dist/utils/bash/parse.d.ts +19 -0
  280. package/dist/utils/bash/parse.d.ts.map +1 -0
  281. package/dist/utils/bash/parse.js +223 -0
  282. package/dist/utils/bash/quote.d.ts +6 -0
  283. package/dist/utils/bash/quote.d.ts.map +1 -0
  284. package/dist/utils/bash/quote.js +23 -0
  285. package/dist/utils/bash.d.ts.map +1 -1
  286. package/dist/utils/bash.js +211 -126
  287. package/dist/utils/command-protection.d.ts +28 -0
  288. package/dist/utils/command-protection.d.ts.map +1 -0
  289. package/dist/utils/command-protection.js +324 -0
  290. package/dist/utils/dedent.d.ts.map +1 -0
  291. package/dist/utils/env-expand.d.ts +2 -0
  292. package/dist/utils/env-expand.d.ts.map +1 -0
  293. package/dist/utils/env-expand.js +8 -0
  294. package/dist/utils/filesystem/path-display.d.ts +11 -0
  295. package/dist/utils/filesystem/path-display.d.ts.map +1 -0
  296. package/dist/utils/filesystem/path-display.js +32 -0
  297. package/dist/utils/filesystem/security.d.ts +2 -2
  298. package/dist/utils/filesystem/security.d.ts.map +1 -1
  299. package/dist/utils/filesystem/security.js +28 -30
  300. package/dist/utils/formatting.d.ts.map +1 -0
  301. package/dist/{formatting.js → utils/formatting.js} +1 -1
  302. package/dist/utils/git.d.ts +4 -0
  303. package/dist/utils/git.d.ts.map +1 -1
  304. package/dist/utils/git.js +30 -0
  305. package/dist/utils/glob.d.ts +1 -1
  306. package/dist/utils/glob.d.ts.map +1 -1
  307. package/dist/utils/logger.d.ts.map +1 -0
  308. package/dist/{logger.js → utils/logger.js} +1 -1
  309. package/dist/utils/parsing.d.ts.map +1 -0
  310. package/dist/utils/process.d.ts.map +1 -1
  311. package/dist/utils/process.js +90 -37
  312. package/dist/utils/templates.d.ts +2 -0
  313. package/dist/utils/templates.d.ts.map +1 -0
  314. package/dist/utils/templates.js +24 -0
  315. package/dist/utils/version.d.ts.map +1 -0
  316. package/dist/{version.js → utils/version.js} +1 -1
  317. package/package.json +34 -25
  318. package/dist/cli.d.ts +0 -23
  319. package/dist/cli.d.ts.map +0 -1
  320. package/dist/commands/exit/index.d.ts +0 -10
  321. package/dist/commands/exit/index.d.ts.map +0 -1
  322. package/dist/commands/exit/index.js +0 -21
  323. package/dist/commands/exit/types.d.ts +0 -8
  324. package/dist/commands/exit/types.d.ts.map +0 -1
  325. package/dist/commands/exit/types.js +0 -1
  326. package/dist/commands/exit/utils.d.ts +0 -2
  327. package/dist/commands/exit/utils.d.ts.map +0 -1
  328. package/dist/commands/exit/utils.js +0 -13
  329. package/dist/commands/prompt/index.d.ts +0 -5
  330. package/dist/commands/prompt/index.d.ts.map +0 -1
  331. package/dist/commands/prompt/index.js +0 -122
  332. package/dist/commands/prompt/types.d.ts +0 -15
  333. package/dist/commands/prompt/types.d.ts.map +0 -1
  334. package/dist/commands/prompt/types.js +0 -1
  335. package/dist/commands/prompt/utils.d.ts +0 -12
  336. package/dist/commands/prompt/utils.d.ts.map +0 -1
  337. package/dist/commands/prompt/utils.js +0 -107
  338. package/dist/commands/reset/index.d.ts +0 -3
  339. package/dist/commands/reset/index.d.ts.map +0 -1
  340. package/dist/commands/reset/index.js +0 -25
  341. package/dist/commands/reset/types.d.ts +0 -1
  342. package/dist/commands/reset/types.d.ts.map +0 -1
  343. package/dist/commands/reset/types.js +0 -3
  344. package/dist/commands/save/index.d.ts +0 -3
  345. package/dist/commands/save/index.d.ts.map +0 -1
  346. package/dist/commands/save/index.js +0 -19
  347. package/dist/config.d.ts.map +0 -1
  348. package/dist/dedent.d.ts.map +0 -1
  349. package/dist/formatting.d.ts.map +0 -1
  350. package/dist/logger.d.ts.map +0 -1
  351. package/dist/mentions.d.ts +0 -14
  352. package/dist/mentions.d.ts.map +0 -1
  353. package/dist/parsing.d.ts.map +0 -1
  354. package/dist/prompts.d.ts.map +0 -1
  355. package/dist/repl-new.d.ts +0 -65
  356. package/dist/repl-new.d.ts.map +0 -1
  357. package/dist/skills.d.ts.map +0 -1
  358. package/dist/skills.js +0 -233
  359. package/dist/stdin.d.ts.map +0 -1
  360. package/dist/tui/autocomplete/path-provider.d.ts +0 -21
  361. package/dist/tui/autocomplete/path-provider.d.ts.map +0 -1
  362. package/dist/tui/autocomplete/path-provider.js +0 -164
  363. package/dist/version.d.ts.map +0 -1
  364. /package/dist/{stdin.d.ts → cli/stdin.d.ts} +0 -0
  365. /package/dist/{dedent.d.ts → utils/dedent.d.ts} +0 -0
  366. /package/dist/{dedent.js → utils/dedent.js} +0 -0
  367. /package/dist/{formatting.d.ts → utils/formatting.d.ts} +0 -0
  368. /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
  369. /package/dist/{parsing.d.ts → utils/parsing.d.ts} +0 -0
  370. /package/dist/{parsing.js → utils/parsing.js} +0 -0
  371. /package/dist/{version.d.ts → utils/version.d.ts} +0 -0
@@ -182,6 +182,12 @@ export class Editor {
182
182
  };
183
183
  this.borderColor = this.theme.borderColor;
184
184
  }
185
+ /**
186
+ * Get the current history (for testing purposes).
187
+ */
188
+ getHistory() {
189
+ return this.history;
190
+ }
185
191
  /**
186
192
  * Add a prompt to history for up/down arrow navigation.
187
193
  * Called after successful submission.
@@ -324,198 +330,247 @@ export class Editor {
324
330
  return result;
325
331
  }
326
332
  handleInput(data) {
327
- // Handle bracketed paste mode
328
- // Start of paste: \x1b[200~
329
- // End of paste: \x1b[201~
330
- // Check if we're starting a bracketed paste
331
- if (data.includes("\x1b[200~")) {
332
- this.isInPaste = true;
333
- this.pasteBuffer = "";
334
- // Remove the start marker and keep the rest
335
- const cleanedData = data.replace("\x1b[200~", "");
336
- // Process the remaining data
337
- this.processInputData(cleanedData);
338
- return;
339
- }
340
- // If we're in a paste, buffer the data
341
- if (this.isInPaste) {
342
- // Append data to buffer first (end marker could be split across chunks)
343
- this.pasteBuffer += data;
344
- // Check if the accumulated buffer contains the end marker
345
- const endIndex = this.pasteBuffer.indexOf("\x1b[201~");
346
- if (endIndex !== -1) {
347
- // Extract content before the end marker
348
- const pasteContent = this.pasteBuffer.substring(0, endIndex);
349
- // Process the complete paste
350
- this.handlePaste(pasteContent);
351
- // Reset paste state
352
- this.isInPaste = false;
353
- // Process any remaining data after the end marker
354
- const remaining = this.pasteBuffer.substring(endIndex + 6); // 6 = length of \x1b[201~
355
- this.pasteBuffer = "";
356
- if (remaining.length > 0) {
357
- this.handleInput(remaining);
333
+ const pasteStart = "\x1b[200~";
334
+ const pasteEnd = "\x1b[201~";
335
+ let input = data;
336
+ while (input.length > 0) {
337
+ if (!this.isInPaste) {
338
+ const startIndex = input.indexOf(pasteStart);
339
+ if (startIndex === -1)
340
+ break;
341
+ const before = input.slice(0, startIndex);
342
+ if (before.length > 0) {
343
+ this.processInputData(before);
358
344
  }
359
- return;
345
+ this.isInPaste = true;
346
+ this.pasteBuffer = "";
347
+ input = input.slice(startIndex + pasteStart.length);
348
+ continue;
360
349
  }
361
- // Still accumulating, wait for more data
362
- return;
350
+ this.pasteBuffer += input;
351
+ const endIndex = this.pasteBuffer.indexOf(pasteEnd);
352
+ if (endIndex === -1)
353
+ return;
354
+ const pasteContent = this.pasteBuffer.slice(0, endIndex);
355
+ const remaining = this.pasteBuffer.slice(endIndex + pasteEnd.length);
356
+ this.handlePaste(pasteContent);
357
+ this.isInPaste = false;
358
+ this.pasteBuffer = "";
359
+ input = remaining;
363
360
  }
364
- // Intercept Escape key - but only if autocomplete is NOT active
365
- // (let parent handle escape for autocomplete cancellation)
366
- if (isEscape(data) && this.onEscape && !this.isShowingAutocomplete()) {
361
+ if (input.length === 0)
362
+ return;
363
+ if (isEscape(input) && this.onEscape && !this.isShowingAutocomplete()) {
367
364
  this.onEscape();
368
365
  return;
369
366
  }
370
- // Intercept Ctrl+C
371
- if (isCtrlC(data)) {
367
+ if (isCtrlC(input)) {
372
368
  return;
373
369
  }
374
- // Process regular input data
375
- this.processInputData(data);
370
+ this.processInputData(input);
376
371
  }
377
372
  processInputData(data) {
378
- // Handle special key combinations first
379
373
  // Ctrl+C - Exit (let parent handle this)
380
374
  if (data.charCodeAt(0) === 3) {
381
375
  return;
382
376
  }
383
- // Handle autocomplete special keys first (but don't block other input)
384
- if (this.isAutocompleting && this.autocompleteList) {
385
- // Escape - cancel autocomplete
386
- if (isEscape(data)) {
377
+ // Delegate to specialized handlers - return true if input was handled
378
+ if (this.handleAutocompleteInput(data))
379
+ return;
380
+ if (this.handleTabKey(data))
381
+ return;
382
+ if (this.handleExternalEditor(data))
383
+ return;
384
+ if (this.handleControlKey(data))
385
+ return;
386
+ if (this.handlePlainEnter(data))
387
+ return;
388
+ if (this.handleModifiedEnterKey(data))
389
+ return;
390
+ if (this.handleBackspaceKey(data))
391
+ return;
392
+ if (this.handleHomeEndKeys(data))
393
+ return;
394
+ if (this.handleForwardDeleteKey(data))
395
+ return;
396
+ if (this.handleWordNavigation(data))
397
+ return;
398
+ if (this.handleArrowKeys(data))
399
+ return;
400
+ // Default: insert printable character
401
+ if (data.charCodeAt(0) >= 32) {
402
+ this.insertCharacter(data);
403
+ }
404
+ }
405
+ handleAutocompleteInput(data) {
406
+ if (!this.isAutocompleting || !this.autocompleteList) {
407
+ return false;
408
+ }
409
+ // Escape - cancel autocomplete
410
+ if (isEscape(data)) {
411
+ this.cancelAutocomplete();
412
+ return true;
413
+ }
414
+ // Enter - apply selection
415
+ if (isEnter(data)) {
416
+ const selected = this.autocompleteList.getSelectedItem();
417
+ if (selected && this.autocompleteProvider) {
418
+ const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
419
+ this.state.lines = result.lines;
420
+ this.state.cursorLine = result.cursorLine;
421
+ this.state.cursorCol = result.cursorCol;
387
422
  this.cancelAutocomplete();
388
- return;
389
- }
390
- // Enter - apply selection
391
- if (isEnter(data)) {
392
- const selected = this.autocompleteList.getSelectedItem();
393
- if (selected && this.autocompleteProvider) {
394
- const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
395
- this.state.lines = result.lines;
396
- this.state.cursorLine = result.cursorLine;
397
- this.state.cursorCol = result.cursorCol;
398
- this.cancelAutocomplete();
399
- if (this.onChange) {
400
- this.onChange(this.getText());
401
- }
423
+ if (this.onChange) {
424
+ this.onChange(this.getText());
402
425
  }
403
- return;
404
- }
405
- // Navigation keys (arrows, Tab, Shift+Tab) - pass to autocomplete list
406
- if (isNavigationKey(data)) {
407
- this.autocompleteList.handleInput(data);
408
- return;
409
426
  }
410
- // For other keys (like regular typing), DON'T return here
411
- // Let them fall through to normal character handling
427
+ return true;
412
428
  }
413
- // Tab key - context-aware completion (but not when already autocompleting)
429
+ // Navigation keys (arrows, Tab, Shift+Tab) - pass to autocomplete list
430
+ if (isNavigationKey(data)) {
431
+ this.autocompleteList.handleInput(data);
432
+ return true;
433
+ }
434
+ return false;
435
+ }
436
+ handleTabKey(data) {
414
437
  if (isTab(data) && !this.isAutocompleting) {
415
438
  void this.handleTabCompletion();
416
- return;
439
+ return true;
417
440
  }
418
- // Ctrl+G - launch external editor
441
+ return false;
442
+ }
443
+ handleExternalEditor(data) {
419
444
  if (isCtrlG(data) && this.onExternalEditor) {
420
445
  void this.launchExternalEditor();
421
- return;
446
+ return true;
422
447
  }
423
- // Continue with rest of input handling
448
+ return false;
449
+ }
450
+ handleControlKey(data) {
451
+ const charCode = data.charCodeAt(0);
424
452
  // Ctrl+K - Delete to end of line
425
- if (data.charCodeAt(0) === 11) {
453
+ if (charCode === 11) {
426
454
  this.deleteToEndOfLine();
455
+ return true;
427
456
  }
428
457
  // Ctrl+U - Delete to start of line
429
- else if (data.charCodeAt(0) === 21) {
458
+ if (charCode === 21) {
430
459
  this.deleteToStartOfLine();
460
+ return true;
431
461
  }
432
462
  // Ctrl+W - Delete word backwards
433
- else if (data.charCodeAt(0) === 23) {
463
+ if (charCode === 23) {
434
464
  this.deleteWordBackwards();
465
+ return true;
435
466
  }
436
467
  // Option/Alt+Backspace (e.g. Ghostty sends ESC + DEL)
437
- else if (data === "\x1b\x7f") {
468
+ if (data === "\x1b\x7f") {
438
469
  this.deleteWordBackwards();
470
+ return true;
439
471
  }
440
472
  // Ctrl+A - Move to start of line
441
- else if (data.charCodeAt(0) === 1) {
473
+ if (charCode === 1) {
442
474
  this.moveToLineStart();
475
+ return true;
443
476
  }
444
477
  // Ctrl+E - Move to end of line
445
- else if (data.charCodeAt(0) === 5) {
478
+ if (charCode === 5) {
446
479
  this.moveToLineEnd();
480
+ return true;
447
481
  }
482
+ return false;
483
+ }
484
+ handlePlainEnter(data) {
448
485
  // Plain Enter (char code 13 for CR) - create new line
449
- else if (data.charCodeAt(0) === 13 && data.length === 1) {
486
+ if (data.charCodeAt(0) === 13 && data.length === 1) {
450
487
  this.addNewLine();
488
+ return true;
451
489
  }
452
- // Modified Enter keys (Shift+Enter, Ctrl+Enter, etc.) - submit
453
- else if (this.isModifiedEnter(data)) {
454
- // If submit is disabled, do nothing
455
- if (this.disableSubmit) {
456
- return;
457
- }
458
- // Get text and substitute paste markers with actual content
459
- let result = this.state.lines.join("\n").trim();
460
- // Replace all [paste #N +xxx lines] or [paste #N xxx chars] markers with actual paste content
461
- for (const [pasteId, pasteContent] of this.pastes) {
462
- // Match formats: [paste #N], [paste #N +xxx lines], or [paste #N xxx chars]
463
- const markerRegex = new RegExp(`\\[paste #${pasteId}( (\\+\\d+ lines|\\d+ chars))?\\]`, "g");
464
- result = result.replace(markerRegex, pasteContent);
465
- }
466
- // Reset editor and clear pastes
467
- this.state = {
468
- lines: [""],
469
- cursorLine: 0,
470
- cursorCol: 0,
471
- };
472
- this.pastes.clear();
473
- this.pasteCounter = 0;
474
- this.historyIndex = -1; // Exit history browsing mode
475
- // Notify that editor is now empty
476
- if (this.onChange) {
477
- this.onChange("");
478
- }
479
- if (this.onSubmit) {
480
- this.onSubmit(result);
481
- }
490
+ return false;
491
+ }
492
+ handleModifiedEnterKey(data) {
493
+ if (!this.isModifiedEnter(data)) {
494
+ return false;
495
+ }
496
+ // If submit is disabled, do nothing
497
+ if (this.disableSubmit) {
498
+ return true;
499
+ }
500
+ // Get text and substitute paste markers with actual content
501
+ let result = this.state.lines.join("\n").trim();
502
+ // Replace all [paste #N +xxx lines] or [paste #N xxx chars] markers with actual paste content
503
+ for (const [pasteId, pasteContent] of this.pastes) {
504
+ // Match formats: [paste #N], [paste #N +xxx lines], or [paste #N xxx chars]
505
+ const markerRegex = new RegExp(`\\[paste #${pasteId}( (\\+\\d+ lines|\\d+ chars))?\\]`, "g");
506
+ result = result.replace(markerRegex, pasteContent);
507
+ }
508
+ // Reset editor and clear pastes
509
+ this.state = {
510
+ lines: [""],
511
+ cursorLine: 0,
512
+ cursorCol: 0,
513
+ };
514
+ this.pastes.clear();
515
+ this.pasteCounter = 0;
516
+ this.historyIndex = -1; // Exit history browsing mode
517
+ this.addToHistory(result); // Save submitted text to history
518
+ // Notify that editor is now empty
519
+ if (this.onChange) {
520
+ this.onChange("");
521
+ }
522
+ if (this.onSubmit) {
523
+ this.onSubmit(result);
482
524
  }
483
- // Backspace
484
- else if (data.charCodeAt(0) === 127 || data.charCodeAt(0) === 8) {
525
+ return true;
526
+ }
527
+ handleBackspaceKey(data) {
528
+ if (data.charCodeAt(0) === 127 || data.charCodeAt(0) === 8) {
485
529
  this.handleBackspace();
530
+ return true;
486
531
  }
487
- // Line navigation shortcuts (Home/End keys)
488
- else if (data === "\x1b[H" || data === "\x1b[1~" || data === "\x1b[7~") {
489
- // Home key
532
+ return false;
533
+ }
534
+ handleHomeEndKeys(data) {
535
+ // Home key: \x1b[H, \x1b[1~, or \x1b[7~
536
+ if (data === "\x1b[H" || data === "\x1b[1~" || data === "\x1b[7~") {
490
537
  this.moveToLineStart();
538
+ return true;
491
539
  }
492
- else if (data === "\x1b[F" || data === "\x1b[4~" || data === "\x1b[8~") {
493
- // End key
540
+ // End key: \x1b[F, \x1b[4~, or \x1b[8~
541
+ if (data === "\x1b[F" || data === "\x1b[4~" || data === "\x1b[8~") {
494
542
  this.moveToLineEnd();
543
+ return true;
495
544
  }
545
+ return false;
546
+ }
547
+ handleForwardDeleteKey(data) {
496
548
  // Forward delete (Fn+Backspace or Delete key)
497
- else if (data === "\x1b[3~") {
498
- // Delete key
549
+ if (data === "\x1b[3~") {
499
550
  this.handleForwardDelete();
551
+ return true;
500
552
  }
553
+ return false;
554
+ }
555
+ handleWordNavigation(data) {
501
556
  // Word navigation (Option/Alt + Arrow or Ctrl + Arrow)
502
557
  // Option+Left: \x1b[1;3D or \x1bb
503
558
  // Option+Right: \x1b[1;3C or \x1bf
504
559
  // Ctrl+Left: \x1b[1;5D
505
560
  // Ctrl+Right: \x1b[1;5C
506
- else if (data === "\x1b[1;3D" || data === "\x1bb" || data === "\x1b[1;5D") {
507
- // Word left
561
+ if (data === "\x1b[1;3D" || data === "\x1bb" || data === "\x1b[1;5D") {
508
562
  this.moveWordBackwards();
563
+ return true;
509
564
  }
510
- else if (data === "\x1b[1;3C" ||
511
- data === "\x1bf" ||
512
- data === "\x1b[1;5C") {
513
- // Word right
565
+ if (data === "\x1b[1;3C" || data === "\x1bf" || data === "\x1b[1;5C") {
514
566
  this.moveWordForwards();
567
+ return true;
515
568
  }
516
- // Arrow keys
517
- else if (data === "\x1b[A") {
518
- // Up - history navigation or cursor movement
569
+ return false;
570
+ }
571
+ handleArrowKeys(data) {
572
+ // Up arrow
573
+ if (data === "\x1b[A") {
519
574
  if (this.isEditorEmpty()) {
520
575
  this.navigateHistory(-1); // Start browsing history
521
576
  }
@@ -525,28 +580,29 @@ export class Editor {
525
580
  else {
526
581
  this.moveCursor(-1, 0); // Cursor movement (within text or history entry)
527
582
  }
583
+ return true;
528
584
  }
529
- else if (data === "\x1b[B") {
530
- // Down - history navigation or cursor movement
585
+ // Down arrow
586
+ if (data === "\x1b[B") {
531
587
  if (this.historyIndex > -1 && this.isOnLastVisualLine()) {
532
588
  this.navigateHistory(1); // Navigate to newer history entry or clear
533
589
  }
534
590
  else {
535
591
  this.moveCursor(1, 0); // Cursor movement (within text or history entry)
536
592
  }
593
+ return true;
537
594
  }
538
- else if (data === "\x1b[C") {
539
- // Right
595
+ // Right arrow
596
+ if (data === "\x1b[C") {
540
597
  this.moveCursor(0, 1);
598
+ return true;
541
599
  }
542
- else if (data === "\x1b[D") {
543
- // Left
600
+ // Left arrow
601
+ if (data === "\x1b[D") {
544
602
  this.moveCursor(0, -1);
603
+ return true;
545
604
  }
546
- // Regular characters (printable characters and unicode, but not control characters)
547
- else if (data.charCodeAt(0) >= 32) {
548
- this.insertCharacter(data);
549
- }
605
+ return false;
550
606
  }
551
607
  layoutText(contentWidth) {
552
608
  const layoutLines = [];
@@ -628,7 +684,7 @@ export class Editor {
628
684
  this.setTextInternal(text);
629
685
  }
630
686
  // All the editor methods from before...
631
- insertCharacter(char) {
687
+ insertCharacter(char, suppressAutocomplete = false) {
632
688
  this.historyIndex = -1; // Exit history browsing mode
633
689
  const line = this.state.lines[this.state.cursorLine] || "";
634
690
  const before = line.slice(0, this.state.cursorCol);
@@ -638,50 +694,16 @@ export class Editor {
638
694
  if (this.onChange) {
639
695
  this.onChange(this.getText());
640
696
  }
697
+ // Skip autocomplete triggering during paste operations
698
+ if (suppressAutocomplete) {
699
+ return;
700
+ }
641
701
  // Check if we should trigger or update autocomplete
642
702
  if (!this.isAutocompleting) {
643
- // Auto-trigger for "/" at the start of a line (slash commands)
644
- if (char === "/" && this.isAtStartOfMessage()) {
645
- void this.tryTriggerAutocomplete();
646
- }
647
- // Auto-trigger for "@" file reference (fuzzy search)
648
- else if (char === "@") {
703
+ if (this.autocompleteProvider) {
649
704
  const currentLine = this.state.lines[this.state.cursorLine] || "";
650
705
  const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
651
- // Only trigger if @ is after whitespace or at start of line
652
- const charBeforeAt = textBeforeCursor[textBeforeCursor.length - 2];
653
- if (textBeforeCursor.length === 1 ||
654
- charBeforeAt === " " ||
655
- charBeforeAt === "\t") {
656
- void this.tryTriggerAutocomplete();
657
- }
658
- }
659
- // Auto-trigger for "#" file search
660
- else if (char === "#") {
661
- const currentLine = this.state.lines[this.state.cursorLine] || "";
662
- const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
663
- // Only trigger if # is after whitespace or at start of line
664
- const charBeforeHash = textBeforeCursor[textBeforeCursor.length - 2];
665
- if (textBeforeCursor.length === 1 ||
666
- charBeforeHash === " " ||
667
- charBeforeHash === "\t") {
668
- void this.tryTriggerAutocomplete();
669
- }
670
- }
671
- // Also auto-trigger when typing letters in a slash command context
672
- else if (/[a-zA-Z0-9]/.test(char)) {
673
- const currentLine = this.state.lines[this.state.cursorLine] || "";
674
- const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
675
- // Check if we're in a slash command (with or without space for arguments)
676
- if (textBeforeCursor.trimStart().startsWith("/")) {
677
- void this.tryTriggerAutocomplete();
678
- }
679
- // Check if we're in an @ file reference context
680
- else if (textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/)) {
681
- void this.tryTriggerAutocomplete();
682
- }
683
- // Check if we're in a # file search context
684
- else if (textBeforeCursor.match(/(?:^|[\s])#[^\s]*$/)) {
706
+ if (this.autocompleteProvider.matchesContext(textBeforeCursor)) {
685
707
  void this.tryTriggerAutocomplete();
686
708
  }
687
709
  }
@@ -714,7 +736,7 @@ export class Editor {
714
736
  ? `[paste #${pasteId} +${pastedLines.length} lines]`
715
737
  : `[paste #${pasteId} ${totalChars} chars]`;
716
738
  for (const char of marker) {
717
- this.insertCharacter(char);
739
+ this.insertCharacter(char, true);
718
740
  }
719
741
  return;
720
742
  }
@@ -722,7 +744,7 @@ export class Editor {
722
744
  // Single line - just insert each character
723
745
  const text = pastedLines[0] || "";
724
746
  for (const char of text) {
725
- this.insertCharacter(char);
747
+ this.insertCharacter(char, true);
726
748
  }
727
749
  return;
728
750
  }
@@ -797,12 +819,10 @@ export class Editor {
797
819
  if (this.isAutocompleting) {
798
820
  void this.updateAutocomplete();
799
821
  }
800
- else {
801
- // Check if we should trigger autocomplete after backspace in slash command context
822
+ else if (this.autocompleteProvider) {
802
823
  const currentLine = this.state.lines[this.state.cursorLine] || "";
803
824
  const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
804
- // Trigger autocomplete if we're in a slash command context (typing command name)
805
- if (textBeforeCursor.startsWith("/") && !textBeforeCursor.includes(" ")) {
825
+ if (this.autocompleteProvider.matchesContext(textBeforeCursor)) {
806
826
  void this.tryTriggerAutocomplete();
807
827
  }
808
828
  }
@@ -1081,13 +1101,6 @@ export class Editor {
1081
1101
  }
1082
1102
  this.state.cursorCol = newCol;
1083
1103
  }
1084
- // Helper method to check if cursor is at start of message (for slash command detection)
1085
- isAtStartOfMessage() {
1086
- const currentLine = this.state.lines[this.state.cursorLine] || "";
1087
- const beforeCursor = currentLine.slice(0, this.state.cursorCol);
1088
- // At start if line is empty, only contains whitespace, or is just "/"
1089
- return beforeCursor.trim() === "" || beforeCursor.trim() === "/";
1090
- }
1091
1104
  // Autocomplete methods
1092
1105
  async tryTriggerAutocomplete(explicitTab = false) {
1093
1106
  if (!this.autocompleteProvider)
@@ -1129,41 +1142,12 @@ export class Editor {
1129
1142
  if (beforeCursor.trimStart().startsWith("/")) {
1130
1143
  await this.handleSlashCommandCompletion();
1131
1144
  }
1132
- else {
1133
- await this.forceFileAutocomplete();
1134
- }
1135
1145
  }
1136
1146
  async handleSlashCommandCompletion() {
1137
1147
  // For now, fall back to regular autocomplete (slash commands)
1138
1148
  // This can be extended later to handle command-specific argument completion
1139
1149
  await this.tryTriggerAutocomplete(true);
1140
1150
  }
1141
- async forceFileAutocomplete() {
1142
- if (!this.autocompleteProvider)
1143
- return;
1144
- // Check if provider has the force method
1145
- const provider = this.autocompleteProvider;
1146
- if (!provider.getForceFileSuggestions) {
1147
- await this.tryTriggerAutocomplete(true);
1148
- return;
1149
- }
1150
- const suggestions = await provider.getForceFileSuggestions(this.state.lines, this.state.cursorLine, this.state.cursorCol);
1151
- if (suggestions && suggestions.items.length > 0) {
1152
- this.autocompletePrefix = suggestions.prefix;
1153
- if (this.autocompleteList) {
1154
- this.autocompleteList.updateItems(suggestions.items);
1155
- }
1156
- else {
1157
- this.autocompleteList = new SelectList(suggestions.items, 5, this.theme.selectList);
1158
- }
1159
- this.isAutocompleting = true;
1160
- // Request re-render to show autocomplete list
1161
- this.onRenderRequested?.();
1162
- }
1163
- else {
1164
- this.cancelAutocomplete();
1165
- }
1166
- }
1167
1151
  cancelAutocomplete() {
1168
1152
  this.isAutocompleting = false;
1169
1153
  this.autocompleteList = undefined;
@@ -1176,28 +1160,18 @@ export class Editor {
1176
1160
  isShowingAutocomplete() {
1177
1161
  return this.isAutocompleting;
1178
1162
  }
1163
+ wantsNavigationKeys() {
1164
+ return this.isAutocompleting;
1165
+ }
1179
1166
  async updateAutocomplete() {
1180
1167
  if (!this.isAutocompleting || !this.autocompleteProvider)
1181
1168
  return;
1182
1169
  // Check if the current text still matches our autocomplete context
1183
- // This prevents unnecessary updates when typing unrelated text
1184
1170
  const currentLine = this.state.lines[this.state.cursorLine] || "";
1185
1171
  const textBeforeCursor = currentLine.slice(0, this.state.cursorCol);
1186
- // If we're no longer in the context that triggered autocomplete, cancel it
1187
- // For slash commands, @ file attachments, and # file search, allow progressive typing
1188
- // For other file paths, check if we're still in the same path context
1189
- if (textBeforeCursor.startsWith("/") ||
1190
- textBeforeCursor.match(/(?:^|[\s])@[^\s]*$/) ||
1191
- textBeforeCursor.match(/(?:^|[\s])#[^\s]*$/)) {
1192
- // For slash commands, @ file attachments, and # file search,
1193
- // continue autocomplete as long as we're in the right context
1194
- }
1195
- else {
1196
- // For other file paths, check if we're still in the same path context
1197
- if (!textBeforeCursor.endsWith(this.autocompletePrefix)) {
1198
- this.cancelAutocomplete();
1199
- return;
1200
- }
1172
+ if (!this.autocompleteProvider.matchesContext(textBeforeCursor)) {
1173
+ this.cancelAutocomplete();
1174
+ return;
1201
1175
  }
1202
1176
  // Clear any existing debounce timer
1203
1177
  if (this.autocompleteDebounceTimer) {
@@ -1,24 +1,26 @@
1
- import type { LanguageModelUsage } from "ai";
2
1
  import type { AgentState } from "../../agent/index.ts";
3
2
  import type { ModelManager } from "../../models/manager.ts";
4
3
  import type { ProjectStatusData } from "../../repl/project-status.ts";
4
+ import type { TokenTracker } from "../../tokens/tracker.ts";
5
5
  import { type Component } from "../tui.ts";
6
6
  type State = {
7
7
  projectStatus: ProjectStatusData;
8
8
  currentContextWindow: number;
9
9
  contextWindow: number;
10
- usage?: LanguageModelUsage;
11
10
  agentState?: AgentState;
11
+ currentMode?: string;
12
12
  };
13
13
  export declare class FooterComponent implements Component {
14
14
  private modelManager;
15
+ private tokenTracker?;
15
16
  private state;
16
17
  private progressBar;
17
- private usage?;
18
18
  private agentState?;
19
- constructor(modelManager: ModelManager, state: State);
19
+ private currentMode;
20
+ constructor(modelManager: ModelManager, tokenTracker: TokenTracker | undefined, state: State);
20
21
  setState(state: State): void;
21
22
  resetState(): void;
23
+ getProjectStatus(): ProjectStatusData;
22
24
  render(width: number): string[];
23
25
  }
24
26
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,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,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAqCF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,KAAK,CAAC,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAC,CAAa;gBACpB,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;IAWpD,QAAQ,CAAC,KAAK,EAAE,KAAK;IAYrB,UAAU;IAKV,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CA+DhC"}
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"}