@machina.ai/cell-cli 1.10.0-rc1 → 1.13.0-rc1

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 (813) hide show
  1. package/dist/index.js +5 -5
  2. package/dist/index.js.map +1 -1
  3. package/dist/package.json +14 -12
  4. package/dist/src/commands/extensions/disable.d.ts +1 -1
  5. package/dist/src/commands/extensions/disable.js +19 -8
  6. package/dist/src/commands/extensions/disable.js.map +1 -1
  7. package/dist/src/commands/extensions/enable.d.ts +1 -1
  8. package/dist/src/commands/extensions/enable.js +19 -9
  9. package/dist/src/commands/extensions/enable.js.map +1 -1
  10. package/dist/src/commands/extensions/examples/mcp-server/example.js +46 -0
  11. package/dist/src/commands/extensions/examples/mcp-server/example.js.map +1 -0
  12. package/dist/src/commands/extensions/install.d.ts +1 -0
  13. package/dist/src/commands/extensions/install.js +29 -4
  14. package/dist/src/commands/extensions/install.js.map +1 -1
  15. package/dist/src/commands/extensions/install.test.js +39 -19
  16. package/dist/src/commands/extensions/install.test.js.map +1 -1
  17. package/dist/src/commands/extensions/link.js +16 -4
  18. package/dist/src/commands/extensions/link.js.map +1 -1
  19. package/dist/src/commands/extensions/list.js +17 -6
  20. package/dist/src/commands/extensions/list.js.map +1 -1
  21. package/dist/src/commands/extensions/new.js +14 -20
  22. package/dist/src/commands/extensions/new.js.map +1 -1
  23. package/dist/src/commands/extensions/uninstall.js +16 -4
  24. package/dist/src/commands/extensions/uninstall.js.map +1 -1
  25. package/dist/src/commands/extensions/update.js +28 -23
  26. package/dist/src/commands/extensions/update.js.map +1 -1
  27. package/dist/src/commands/extensions/validate.d.ts +12 -0
  28. package/dist/src/commands/extensions/validate.js +83 -0
  29. package/dist/src/commands/extensions/validate.js.map +1 -0
  30. package/dist/src/commands/extensions/validate.test.d.ts +6 -0
  31. package/dist/src/commands/extensions/validate.test.js +93 -0
  32. package/dist/src/commands/extensions/validate.test.js.map +1 -0
  33. package/dist/src/commands/extensions.js +3 -0
  34. package/dist/src/commands/extensions.js.map +1 -1
  35. package/dist/src/commands/mcp/add.js +7 -4
  36. package/dist/src/commands/mcp/add.js.map +1 -1
  37. package/dist/src/commands/mcp/add.test.d.ts +6 -0
  38. package/dist/src/commands/mcp/add.test.js +247 -0
  39. package/dist/src/commands/mcp/add.test.js.map +1 -0
  40. package/dist/src/commands/mcp/list.js +18 -9
  41. package/dist/src/commands/mcp/list.js.map +1 -1
  42. package/dist/src/commands/mcp/list.test.d.ts +6 -0
  43. package/dist/src/commands/mcp/list.test.js +128 -0
  44. package/dist/src/commands/mcp/list.test.js.map +1 -0
  45. package/dist/src/commands/mcp/remove.js +3 -2
  46. package/dist/src/commands/mcp/remove.js.map +1 -1
  47. package/dist/src/commands/mcp/remove.test.d.ts +6 -0
  48. package/dist/src/commands/mcp/remove.test.js +175 -0
  49. package/dist/src/commands/mcp/remove.test.js.map +1 -0
  50. package/dist/src/commands/mcp.test.d.ts +6 -0
  51. package/dist/src/commands/mcp.test.js +62 -0
  52. package/dist/src/commands/mcp.test.js.map +1 -0
  53. package/dist/src/config/auth.js +0 -3
  54. package/dist/src/config/auth.js.map +1 -1
  55. package/dist/src/config/config.d.ts +6 -15
  56. package/dist/src/config/config.integration.test.d.ts +6 -0
  57. package/dist/src/config/config.integration.test.js +321 -0
  58. package/dist/src/config/config.integration.test.js.map +1 -0
  59. package/dist/src/config/config.js +85 -164
  60. package/dist/src/config/config.js.map +1 -1
  61. package/dist/src/config/config.test.d.ts +6 -0
  62. package/dist/src/config/config.test.js +1972 -0
  63. package/dist/src/config/config.test.js.map +1 -0
  64. package/dist/src/config/extension-manager.d.ts +63 -0
  65. package/dist/src/config/extension-manager.js +450 -0
  66. package/dist/src/config/extension-manager.js.map +1 -0
  67. package/dist/src/config/extension.d.ts +4 -61
  68. package/dist/src/config/extension.js +1 -538
  69. package/dist/src/config/extension.js.map +1 -1
  70. package/dist/src/config/extension.test.d.ts +6 -0
  71. package/dist/src/config/extension.test.js +1412 -0
  72. package/dist/src/config/extension.test.js.map +1 -0
  73. package/dist/src/config/extensions/consent.d.ts +38 -0
  74. package/dist/src/config/extensions/consent.js +123 -0
  75. package/dist/src/config/extensions/consent.js.map +1 -0
  76. package/dist/src/config/extensions/extensionEnablement.d.ts +2 -2
  77. package/dist/src/config/extensions/extensionEnablement.js +7 -5
  78. package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
  79. package/dist/src/config/extensions/extensionEnablement.test.js +31 -28
  80. package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
  81. package/dist/src/config/extensions/extensionSettings.d.ts +15 -0
  82. package/dist/src/config/extensions/extensionSettings.js +113 -0
  83. package/dist/src/config/extensions/extensionSettings.js.map +1 -0
  84. package/dist/src/config/extensions/extensionSettings.test.d.ts +6 -0
  85. package/dist/src/config/extensions/extensionSettings.test.js +254 -0
  86. package/dist/src/config/extensions/extensionSettings.test.js.map +1 -0
  87. package/dist/src/config/extensions/github.d.ts +18 -9
  88. package/dist/src/config/extensions/github.js +108 -36
  89. package/dist/src/config/extensions/github.js.map +1 -1
  90. package/dist/src/config/extensions/github.test.js +158 -164
  91. package/dist/src/config/extensions/github.test.js.map +1 -1
  92. package/dist/src/config/extensions/github_fetch.d.ts +1 -1
  93. package/dist/src/config/extensions/github_fetch.js +13 -1
  94. package/dist/src/config/extensions/github_fetch.js.map +1 -1
  95. package/dist/src/config/extensions/github_fetch.test.d.ts +6 -0
  96. package/dist/src/config/extensions/github_fetch.test.js +169 -0
  97. package/dist/src/config/extensions/github_fetch.test.js.map +1 -0
  98. package/dist/src/config/extensions/storage.d.ts +14 -0
  99. package/dist/src/config/extensions/storage.js +32 -0
  100. package/dist/src/config/extensions/storage.js.map +1 -0
  101. package/dist/src/config/extensions/update.d.ts +5 -4
  102. package/dist/src/config/extensions/update.js +41 -37
  103. package/dist/src/config/extensions/update.js.map +1 -1
  104. package/dist/src/config/extensions/update.test.js +72 -74
  105. package/dist/src/config/extensions/update.test.js.map +1 -1
  106. package/dist/src/config/extensions/variableSchema.d.ts +0 -4
  107. package/dist/src/config/extensions/variableSchema.js.map +1 -1
  108. package/dist/src/config/extensions/variables.d.ts +4 -0
  109. package/dist/src/config/extensions/variables.js +6 -0
  110. package/dist/src/config/extensions/variables.js.map +1 -1
  111. package/dist/src/config/keyBindings.d.ts +5 -1
  112. package/dist/src/config/keyBindings.js +34 -10
  113. package/dist/src/config/keyBindings.js.map +1 -1
  114. package/dist/src/config/keyBindings.test.js +17 -0
  115. package/dist/src/config/keyBindings.test.js.map +1 -1
  116. package/dist/src/config/policies/read-only.toml +56 -0
  117. package/dist/src/config/policies/write.toml +63 -0
  118. package/dist/src/config/policies/yolo.toml +31 -0
  119. package/dist/src/config/policy-engine.integration.test.js +41 -38
  120. package/dist/src/config/policy-engine.integration.test.js.map +1 -1
  121. package/dist/src/config/policy.d.ts +4 -3
  122. package/dist/src/config/policy.js +13 -142
  123. package/dist/src/config/policy.js.map +1 -1
  124. package/dist/src/config/sandboxConfig.d.ts +1 -2
  125. package/dist/src/config/sandboxConfig.js +7 -6
  126. package/dist/src/config/sandboxConfig.js.map +1 -1
  127. package/dist/src/config/settings.d.ts +2 -1
  128. package/dist/src/config/settings.js +59 -15
  129. package/dist/src/config/settings.js.map +1 -1
  130. package/dist/src/config/settings.test.d.ts +6 -0
  131. package/dist/src/config/settings.test.js +2000 -0
  132. package/dist/src/config/settings.test.js.map +1 -0
  133. package/dist/src/config/settingsSchema.d.ts +170 -28
  134. package/dist/src/config/settingsSchema.js +418 -27
  135. package/dist/src/config/settingsSchema.js.map +1 -1
  136. package/dist/src/config/settingsSchema.test.js +42 -1
  137. package/dist/src/config/settingsSchema.test.js.map +1 -1
  138. package/dist/src/config/trustedFolders.d.ts +1 -1
  139. package/dist/src/config/trustedFolders.js +4 -2
  140. package/dist/src/config/trustedFolders.js.map +1 -1
  141. package/dist/src/core/initializer.js +2 -1
  142. package/dist/src/core/initializer.js.map +1 -1
  143. package/dist/src/gemini.d.ts +1 -1
  144. package/dist/src/gemini.js +63 -27
  145. package/dist/src/gemini.js.map +1 -1
  146. package/dist/src/gemini.test.js +123 -34
  147. package/dist/src/gemini.test.js.map +1 -1
  148. package/dist/src/generated/git-commit.d.ts +2 -2
  149. package/dist/src/generated/git-commit.js +2 -2
  150. package/dist/src/nonInteractiveCli.d.ts +9 -1
  151. package/dist/src/nonInteractiveCli.js +205 -10
  152. package/dist/src/nonInteractiveCli.js.map +1 -1
  153. package/dist/src/nonInteractiveCli.test.d.ts +6 -0
  154. package/dist/src/nonInteractiveCli.test.js +984 -0
  155. package/dist/src/nonInteractiveCli.test.js.map +1 -0
  156. package/dist/src/nonInteractiveCliCommands.js +2 -2
  157. package/dist/src/nonInteractiveCliCommands.js.map +1 -1
  158. package/dist/src/services/BuiltinCommandLoader.js +4 -0
  159. package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
  160. package/dist/src/services/BuiltinCommandLoader.test.js +22 -0
  161. package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
  162. package/dist/src/services/CommandService.js +2 -1
  163. package/dist/src/services/CommandService.js.map +1 -1
  164. package/dist/src/services/FeedbackService.js +2 -2
  165. package/dist/src/services/FeedbackService.js.map +1 -1
  166. package/dist/src/services/FileCommandLoader.test.d.ts +6 -0
  167. package/dist/src/services/FileCommandLoader.test.js +971 -0
  168. package/dist/src/services/FileCommandLoader.test.js.map +1 -0
  169. package/dist/src/services/McpPromptLoader.js +2 -2
  170. package/dist/src/services/McpPromptLoader.js.map +1 -1
  171. package/dist/src/services/McpPromptLoader.test.js +4 -2
  172. package/dist/src/services/McpPromptLoader.test.js.map +1 -1
  173. package/dist/src/services/prompt-processors/argumentProcessor.test.d.ts +6 -0
  174. package/dist/src/services/prompt-processors/argumentProcessor.test.js +40 -0
  175. package/dist/src/services/prompt-processors/argumentProcessor.test.js.map +1 -0
  176. package/dist/src/services/prompt-processors/atFileProcessor.js +3 -2
  177. package/dist/src/services/prompt-processors/atFileProcessor.js.map +1 -1
  178. package/dist/src/services/prompt-processors/shellProcessor.test.d.ts +6 -0
  179. package/dist/src/services/prompt-processors/shellProcessor.test.js +482 -0
  180. package/dist/src/services/prompt-processors/shellProcessor.test.js.map +1 -0
  181. package/dist/src/test-utils/async.d.ts +9 -0
  182. package/dist/src/test-utils/async.js +29 -0
  183. package/dist/src/test-utils/async.js.map +1 -0
  184. package/dist/src/test-utils/createExtension.d.ts +3 -1
  185. package/dist/src/test-utils/createExtension.js +3 -3
  186. package/dist/src/test-utils/createExtension.js.map +1 -1
  187. package/dist/src/test-utils/render.d.ts +17 -2
  188. package/dist/src/test-utils/render.js +69 -4
  189. package/dist/src/test-utils/render.js.map +1 -1
  190. package/dist/src/test-utils/render.test.d.ts +6 -0
  191. package/dist/src/test-utils/render.test.js +79 -0
  192. package/dist/src/test-utils/render.test.js.map +1 -0
  193. package/dist/src/ui/App.test.d.ts +6 -0
  194. package/dist/src/ui/App.test.js +110 -0
  195. package/dist/src/ui/App.test.js.map +1 -0
  196. package/dist/src/ui/AppContainer.js +223 -92
  197. package/dist/src/ui/AppContainer.js.map +1 -1
  198. package/dist/src/ui/AppContainer.test.js +531 -147
  199. package/dist/src/ui/AppContainer.test.js.map +1 -1
  200. package/dist/src/ui/IdeIntegrationNudge.js +1 -1
  201. package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
  202. package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
  203. package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
  204. package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
  205. package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
  206. package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
  207. package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
  208. package/dist/src/ui/auth/AuthDialog.d.ts +1 -1
  209. package/dist/src/ui/auth/AuthDialog.js +9 -3
  210. package/dist/src/ui/auth/AuthDialog.js.map +1 -1
  211. package/dist/src/ui/auth/useAuth.d.ts +3 -1
  212. package/dist/src/ui/auth/useAuth.js +35 -4
  213. package/dist/src/ui/auth/useAuth.js.map +1 -1
  214. package/dist/src/ui/colors.js +3 -0
  215. package/dist/src/ui/colors.js.map +1 -1
  216. package/dist/src/ui/commands/aboutCommand.js +1 -1
  217. package/dist/src/ui/commands/aboutCommand.test.d.ts +6 -0
  218. package/dist/src/ui/commands/aboutCommand.test.js +130 -0
  219. package/dist/src/ui/commands/aboutCommand.test.js.map +1 -0
  220. package/dist/src/ui/commands/authCommand.js +1 -1
  221. package/dist/src/ui/commands/authCommand.test.d.ts +6 -0
  222. package/dist/src/ui/commands/authCommand.test.js +30 -0
  223. package/dist/src/ui/commands/authCommand.test.js.map +1 -0
  224. package/dist/src/ui/commands/bugCommand.js +1 -1
  225. package/dist/src/ui/commands/bugCommand.test.d.ts +6 -0
  226. package/dist/src/ui/commands/bugCommand.test.js +105 -0
  227. package/dist/src/ui/commands/bugCommand.test.js.map +1 -0
  228. package/dist/src/ui/commands/chatCommand.js +1 -1
  229. package/dist/src/ui/commands/chatCommand.js.map +1 -1
  230. package/dist/src/ui/commands/chatCommand.test.d.ts +6 -0
  231. package/dist/src/ui/commands/chatCommand.test.js +555 -0
  232. package/dist/src/ui/commands/chatCommand.test.js.map +1 -0
  233. package/dist/src/ui/commands/clearCommand.js +1 -1
  234. package/dist/src/ui/commands/clearCommand.test.d.ts +6 -0
  235. package/dist/src/ui/commands/clearCommand.test.js +76 -0
  236. package/dist/src/ui/commands/clearCommand.test.js.map +1 -0
  237. package/dist/src/ui/commands/compressCommand.js +1 -1
  238. package/dist/src/ui/commands/compressCommand.js.map +1 -1
  239. package/dist/src/ui/commands/compressCommand.test.d.ts +6 -0
  240. package/dist/src/ui/commands/compressCommand.test.js +98 -0
  241. package/dist/src/ui/commands/compressCommand.test.js.map +1 -0
  242. package/dist/src/ui/commands/copyCommand.js +2 -1
  243. package/dist/src/ui/commands/copyCommand.js.map +1 -1
  244. package/dist/src/ui/commands/copyCommand.test.d.ts +6 -0
  245. package/dist/src/ui/commands/copyCommand.test.js +242 -0
  246. package/dist/src/ui/commands/copyCommand.test.js.map +1 -0
  247. package/dist/src/ui/commands/corgiCommand.js +1 -1
  248. package/dist/src/ui/commands/corgiCommand.js.map +1 -1
  249. package/dist/src/ui/commands/corgiCommand.test.d.ts +6 -0
  250. package/dist/src/ui/commands/corgiCommand.test.js +28 -0
  251. package/dist/src/ui/commands/corgiCommand.test.js.map +1 -0
  252. package/dist/src/ui/commands/directoryCommand.js +1 -1
  253. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  254. package/dist/src/ui/commands/directoryCommand.test.d.ts +6 -0
  255. package/dist/src/ui/commands/directoryCommand.test.js +144 -0
  256. package/dist/src/ui/commands/directoryCommand.test.js.map +1 -0
  257. package/dist/src/ui/commands/docsCommand.js +1 -1
  258. package/dist/src/ui/commands/docsCommand.test.d.ts +6 -0
  259. package/dist/src/ui/commands/docsCommand.test.js +72 -0
  260. package/dist/src/ui/commands/docsCommand.test.js.map +1 -0
  261. package/dist/src/ui/commands/editorCommand.js +1 -1
  262. package/dist/src/ui/commands/editorCommand.test.d.ts +6 -0
  263. package/dist/src/ui/commands/editorCommand.test.js +27 -0
  264. package/dist/src/ui/commands/editorCommand.test.js.map +1 -0
  265. package/dist/src/ui/commands/extensionsCommand.js +64 -11
  266. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  267. package/dist/src/ui/commands/extensionsCommand.test.d.ts +6 -0
  268. package/dist/src/ui/commands/extensionsCommand.test.js +315 -0
  269. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -0
  270. package/dist/src/ui/commands/helpCommand.js +1 -1
  271. package/dist/src/ui/commands/helpCommand.test.d.ts +6 -0
  272. package/dist/src/ui/commands/helpCommand.test.js +42 -0
  273. package/dist/src/ui/commands/helpCommand.test.js.map +1 -0
  274. package/dist/src/ui/commands/ideCommand.js +6 -6
  275. package/dist/src/ui/commands/ideCommand.test.d.ts +6 -0
  276. package/dist/src/ui/commands/ideCommand.test.js +205 -0
  277. package/dist/src/ui/commands/ideCommand.test.js.map +1 -0
  278. package/dist/src/ui/commands/initCommand.js +1 -1
  279. package/dist/src/ui/commands/initCommand.js.map +1 -1
  280. package/dist/src/ui/commands/initCommand.test.d.ts +6 -0
  281. package/dist/src/ui/commands/initCommand.test.js +80 -0
  282. package/dist/src/ui/commands/initCommand.test.js.map +1 -0
  283. package/dist/src/ui/commands/mcpCommand.js +110 -100
  284. package/dist/src/ui/commands/mcpCommand.js.map +1 -1
  285. package/dist/src/ui/commands/mcpCommand.test.d.ts +6 -0
  286. package/dist/src/ui/commands/mcpCommand.test.js +152 -0
  287. package/dist/src/ui/commands/mcpCommand.test.js.map +1 -0
  288. package/dist/src/ui/commands/memoryCommand.js +6 -6
  289. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  290. package/dist/src/ui/commands/memoryCommand.test.d.ts +6 -0
  291. package/dist/src/ui/commands/memoryCommand.test.js +268 -0
  292. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -0
  293. package/dist/src/ui/commands/policiesCommand.d.ts +7 -0
  294. package/dist/src/ui/commands/policiesCommand.js +59 -0
  295. package/dist/src/ui/commands/policiesCommand.js.map +1 -0
  296. package/dist/src/ui/commands/policiesCommand.test.d.ts +6 -0
  297. package/dist/src/ui/commands/policiesCommand.test.js +83 -0
  298. package/dist/src/ui/commands/policiesCommand.test.js.map +1 -0
  299. package/dist/src/ui/commands/privacyCommand.js +1 -1
  300. package/dist/src/ui/commands/privacyCommand.test.d.ts +6 -0
  301. package/dist/src/ui/commands/privacyCommand.test.js +32 -0
  302. package/dist/src/ui/commands/privacyCommand.test.js.map +1 -0
  303. package/dist/src/ui/commands/quitCommand.js +1 -1
  304. package/dist/src/ui/commands/quitCommand.test.d.ts +6 -0
  305. package/dist/src/ui/commands/quitCommand.test.js +50 -0
  306. package/dist/src/ui/commands/quitCommand.test.js.map +1 -0
  307. package/dist/src/ui/commands/restoreCommand.test.d.ts +6 -0
  308. package/dist/src/ui/commands/restoreCommand.test.js +190 -0
  309. package/dist/src/ui/commands/restoreCommand.test.js.map +1 -0
  310. package/dist/src/ui/commands/settingsCommand.test.d.ts +6 -0
  311. package/dist/src/ui/commands/settingsCommand.test.js +30 -0
  312. package/dist/src/ui/commands/settingsCommand.test.js.map +1 -0
  313. package/dist/src/ui/commands/setupGithubCommand.js +4 -3
  314. package/dist/src/ui/commands/setupGithubCommand.js.map +1 -1
  315. package/dist/src/ui/commands/setupGithubCommand.test.js +1 -2
  316. package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -1
  317. package/dist/src/ui/commands/statsCommand.js +3 -3
  318. package/dist/src/ui/commands/statsCommand.js.map +1 -1
  319. package/dist/src/ui/commands/statsCommand.test.d.ts +6 -0
  320. package/dist/src/ui/commands/statsCommand.test.js +53 -0
  321. package/dist/src/ui/commands/statsCommand.test.js.map +1 -0
  322. package/dist/src/ui/commands/terminalSetupCommand.test.d.ts +6 -0
  323. package/dist/src/ui/commands/terminalSetupCommand.test.js +66 -0
  324. package/dist/src/ui/commands/terminalSetupCommand.test.js.map +1 -0
  325. package/dist/src/ui/commands/themeCommand.js +1 -1
  326. package/dist/src/ui/commands/themeCommand.test.d.ts +6 -0
  327. package/dist/src/ui/commands/themeCommand.test.js +32 -0
  328. package/dist/src/ui/commands/themeCommand.test.js.map +1 -0
  329. package/dist/src/ui/commands/toolsCommand.js +1 -1
  330. package/dist/src/ui/commands/toolsCommand.test.d.ts +6 -0
  331. package/dist/src/ui/commands/toolsCommand.test.js +100 -0
  332. package/dist/src/ui/commands/toolsCommand.test.js.map +1 -0
  333. package/dist/src/ui/commands/types.d.ts +1 -0
  334. package/dist/src/ui/commands/vimCommand.js +1 -1
  335. package/dist/src/ui/components/AnsiOutput.test.js +1 -1
  336. package/dist/src/ui/components/AnsiOutput.test.js.map +1 -1
  337. package/dist/src/ui/components/AsciiArt.d.ts +3 -3
  338. package/dist/src/ui/components/AsciiArt.js +3 -3
  339. package/dist/src/ui/components/Composer.js +6 -4
  340. package/dist/src/ui/components/Composer.js.map +1 -1
  341. package/dist/src/ui/components/Composer.test.js +21 -3
  342. package/dist/src/ui/components/Composer.test.js.map +1 -1
  343. package/dist/src/ui/components/ConfigInitDisplay.js +4 -6
  344. package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
  345. package/dist/src/ui/components/ConsentPrompt.test.js +18 -8
  346. package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -1
  347. package/dist/src/ui/components/ConsoleSummaryDisplay.js +1 -1
  348. package/dist/src/ui/components/ConsoleSummaryDisplay.js.map +1 -1
  349. package/dist/src/ui/components/ContextSummaryDisplay.d.ts +0 -1
  350. package/dist/src/ui/components/ContextSummaryDisplay.js +2 -12
  351. package/dist/src/ui/components/ContextSummaryDisplay.js.map +1 -1
  352. package/dist/src/ui/components/ContextSummaryDisplay.test.d.ts +6 -0
  353. package/dist/src/ui/components/ContextSummaryDisplay.test.js +71 -0
  354. package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +1 -0
  355. package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
  356. package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
  357. package/dist/src/ui/components/DialogManager.js +5 -5
  358. package/dist/src/ui/components/DialogManager.js.map +1 -1
  359. package/dist/src/ui/components/EditorSettingsDialog.js +1 -1
  360. package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
  361. package/dist/src/ui/components/FolderTrustDialog.test.js +8 -3
  362. package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
  363. package/dist/src/ui/components/Footer.js +4 -3
  364. package/dist/src/ui/components/Footer.js.map +1 -1
  365. package/dist/src/ui/components/Footer.test.d.ts +6 -0
  366. package/dist/src/ui/components/Footer.test.js +314 -0
  367. package/dist/src/ui/components/Footer.test.js.map +1 -0
  368. package/dist/src/ui/components/Header.test.js +13 -5
  369. package/dist/src/ui/components/Header.test.js.map +1 -1
  370. package/dist/src/ui/components/Help.test.js +5 -4
  371. package/dist/src/ui/components/Help.test.js.map +1 -1
  372. package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
  373. package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
  374. package/dist/src/ui/components/InputPrompt.d.ts +4 -0
  375. package/dist/src/ui/components/InputPrompt.js +80 -12
  376. package/dist/src/ui/components/InputPrompt.js.map +1 -1
  377. package/dist/src/ui/components/InputPrompt.test.d.ts +6 -0
  378. package/dist/src/ui/components/InputPrompt.test.js +1786 -0
  379. package/dist/src/ui/components/InputPrompt.test.js.map +1 -0
  380. package/dist/src/ui/components/LoadingIndicator.js +2 -2
  381. package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
  382. package/dist/src/ui/components/LoadingIndicator.test.js +28 -15
  383. package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
  384. package/dist/src/ui/components/LoopDetectionConfirmation.js +1 -1
  385. package/dist/src/ui/components/LoopDetectionConfirmation.js.map +1 -1
  386. package/dist/src/ui/components/LoopDetectionConfirmation.test.js +2 -2
  387. package/dist/src/ui/components/LoopDetectionConfirmation.test.js.map +1 -1
  388. package/dist/src/ui/components/MainContent.js +15 -4
  389. package/dist/src/ui/components/MainContent.js.map +1 -1
  390. package/dist/src/ui/components/ModelDialog.js +1 -1
  391. package/dist/src/ui/components/ModelDialog.js.map +1 -1
  392. package/dist/src/ui/components/ModelDialog.test.js +23 -13
  393. package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
  394. package/dist/src/ui/components/ModelStatsDisplay.test.d.ts +6 -0
  395. package/dist/src/ui/components/ModelStatsDisplay.test.js +285 -0
  396. package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -0
  397. package/dist/src/ui/components/Notifications.js +38 -5
  398. package/dist/src/ui/components/Notifications.js.map +1 -1
  399. package/dist/src/ui/components/PermissionsModifyTrustDialog.js +22 -18
  400. package/dist/src/ui/components/PermissionsModifyTrustDialog.js.map +1 -1
  401. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +12 -4
  402. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
  403. package/dist/src/ui/components/PrepareLabel.test.js +14 -8
  404. package/dist/src/ui/components/PrepareLabel.test.js.map +1 -1
  405. package/dist/src/ui/components/ProQuotaDialog.test.js +14 -6
  406. package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
  407. package/dist/src/ui/components/QueuedMessageDisplay.js +3 -3
  408. package/dist/src/ui/components/QueuedMessageDisplay.js.map +1 -1
  409. package/dist/src/ui/components/QueuedMessageDisplay.test.js +15 -6
  410. package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +1 -1
  411. package/dist/src/ui/components/RawMarkdownIndicator.d.ts +7 -0
  412. package/dist/src/ui/components/RawMarkdownIndicator.js +8 -0
  413. package/dist/src/ui/components/RawMarkdownIndicator.js.map +1 -0
  414. package/dist/src/ui/components/SessionSummaryDisplay.test.d.ts +6 -0
  415. package/dist/src/ui/components/SessionSummaryDisplay.test.js +74 -0
  416. package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -0
  417. package/dist/src/ui/components/SettingsDialog.js +43 -35
  418. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  419. package/dist/src/ui/components/SettingsDialog.test.js +554 -545
  420. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  421. package/dist/src/ui/components/ShellConfirmationDialog.js +1 -1
  422. package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
  423. package/dist/src/ui/components/ShellConfirmationDialog.test.js +2 -2
  424. package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -1
  425. package/dist/src/ui/components/StatsDisplay.test.d.ts +6 -0
  426. package/dist/src/ui/components/StatsDisplay.test.js +351 -0
  427. package/dist/src/ui/components/StatsDisplay.test.js.map +1 -0
  428. package/dist/src/ui/components/SuggestionsDisplay.js +1 -1
  429. package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
  430. package/dist/src/ui/components/ThemeDialog.d.ts +4 -2
  431. package/dist/src/ui/components/ThemeDialog.js +3 -3
  432. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  433. package/dist/src/ui/components/ThemeDialog.test.js +14 -1
  434. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
  435. package/dist/src/ui/components/ToolStatsDisplay.test.d.ts +6 -0
  436. package/dist/src/ui/components/ToolStatsDisplay.test.js +227 -0
  437. package/dist/src/ui/components/ToolStatsDisplay.test.js.map +1 -0
  438. package/dist/src/ui/components/messages/CompressionMessage.test.js +25 -17
  439. package/dist/src/ui/components/messages/CompressionMessage.test.js.map +1 -1
  440. package/dist/src/ui/components/messages/DiffRenderer.test.js +1 -1
  441. package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
  442. package/dist/src/ui/components/messages/GeminiMessage.js +3 -1
  443. package/dist/src/ui/components/messages/GeminiMessage.js.map +1 -1
  444. package/dist/src/ui/components/messages/GeminiMessage.test.d.ts +6 -0
  445. package/dist/src/ui/components/messages/GeminiMessage.test.js +35 -0
  446. package/dist/src/ui/components/messages/GeminiMessage.test.js.map +1 -0
  447. package/dist/src/ui/components/messages/GeminiMessageContent.js +3 -1
  448. package/dist/src/ui/components/messages/GeminiMessageContent.js.map +1 -1
  449. package/dist/src/ui/components/messages/InfoMessage.js +1 -1
  450. package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
  451. package/dist/src/ui/components/messages/Todo.d.ts +7 -0
  452. package/dist/src/ui/components/messages/Todo.js +91 -0
  453. package/dist/src/ui/components/messages/Todo.js.map +1 -0
  454. package/dist/src/ui/components/messages/Todo.test.d.ts +6 -0
  455. package/dist/src/ui/components/messages/Todo.test.js +114 -0
  456. package/dist/src/ui/components/messages/Todo.test.js.map +1 -0
  457. package/dist/src/ui/components/messages/ToolConfirmationMessage.js +1 -1
  458. package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
  459. package/dist/src/ui/components/messages/ToolGroupMessage.js +1 -1
  460. package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
  461. package/dist/src/ui/components/messages/ToolGroupMessage.test.js +29 -15
  462. package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
  463. package/dist/src/ui/components/messages/ToolMessage.js +8 -3
  464. package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
  465. package/dist/src/ui/components/messages/ToolMessage.test.js +2 -2
  466. package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -1
  467. package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.d.ts +6 -0
  468. package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js +30 -0
  469. package/dist/src/ui/components/messages/ToolMessageRawMarkdown.test.js.map +1 -0
  470. package/dist/src/ui/components/messages/UserShellMessage.js +1 -1
  471. package/dist/src/ui/components/messages/UserShellMessage.js.map +1 -1
  472. package/dist/src/ui/components/messages/WarningMessage.js +2 -2
  473. package/dist/src/ui/components/messages/WarningMessage.js.map +1 -1
  474. package/dist/src/ui/components/shared/BaseSelectionList.test.js +34 -25
  475. package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
  476. package/dist/src/ui/components/shared/MaxSizedBox.test.js +43 -22
  477. package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -1
  478. package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
  479. package/dist/src/ui/components/shared/TextInput.js +38 -0
  480. package/dist/src/ui/components/shared/TextInput.js.map +1 -0
  481. package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
  482. package/dist/src/ui/components/shared/TextInput.test.js +242 -0
  483. package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
  484. package/dist/src/ui/components/shared/text-buffer.d.ts +9 -2
  485. package/dist/src/ui/components/shared/text-buffer.js +52 -14
  486. package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
  487. package/dist/src/ui/components/shared/text-buffer.test.d.ts +6 -0
  488. package/dist/src/ui/components/shared/text-buffer.test.js +1761 -0
  489. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -0
  490. package/dist/src/ui/components/shared/vim-buffer-actions.test.d.ts +6 -0
  491. package/dist/src/ui/components/shared/vim-buffer-actions.test.js +951 -0
  492. package/dist/src/ui/components/shared/vim-buffer-actions.test.js.map +1 -0
  493. package/dist/src/ui/components/views/ChatList.test.js +7 -4
  494. package/dist/src/ui/components/views/ChatList.test.js.map +1 -1
  495. package/dist/src/ui/components/views/ExtensionsList.d.ts +7 -1
  496. package/dist/src/ui/components/views/ExtensionsList.js +12 -15
  497. package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
  498. package/dist/src/ui/components/views/ExtensionsList.test.js +43 -29
  499. package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
  500. package/dist/src/ui/components/views/McpStatus.d.ts +0 -1
  501. package/dist/src/ui/components/views/McpStatus.js +4 -4
  502. package/dist/src/ui/components/views/McpStatus.js.map +1 -1
  503. package/dist/src/ui/components/views/McpStatus.test.js +23 -17
  504. package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
  505. package/dist/src/ui/components/views/ToolsList.test.js +4 -4
  506. package/dist/src/ui/components/views/ToolsList.test.js.map +1 -1
  507. package/dist/src/ui/contexts/KeypressContext.d.ts +4 -2
  508. package/dist/src/ui/contexts/KeypressContext.js +635 -439
  509. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  510. package/dist/src/ui/contexts/KeypressContext.test.js +634 -515
  511. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  512. package/dist/src/ui/contexts/MouseContext.d.ts +21 -0
  513. package/dist/src/ui/contexts/MouseContext.js +89 -0
  514. package/dist/src/ui/contexts/MouseContext.js.map +1 -0
  515. package/dist/src/ui/contexts/MouseContext.test.d.ts +6 -0
  516. package/dist/src/ui/contexts/MouseContext.test.js +164 -0
  517. package/dist/src/ui/contexts/MouseContext.test.js.map +1 -0
  518. package/dist/src/ui/contexts/SessionContext.test.d.ts +6 -0
  519. package/dist/src/ui/contexts/SessionContext.test.js +195 -0
  520. package/dist/src/ui/contexts/SessionContext.test.js.map +1 -0
  521. package/dist/src/ui/contexts/UIActionsContext.d.ts +7 -4
  522. package/dist/src/ui/contexts/UIStateContext.d.ts +5 -3
  523. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  524. package/dist/src/ui/hooks/atCommandProcessor.js +33 -11
  525. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  526. package/dist/src/ui/hooks/atCommandProcessor.test.js +163 -64
  527. package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
  528. package/dist/src/ui/hooks/shellCommandProcessor.js +0 -1
  529. package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
  530. package/dist/src/ui/hooks/shellCommandProcessor.test.js +64 -35
  531. package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
  532. package/dist/src/ui/hooks/slashCommandProcessor.js +2 -0
  533. package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
  534. package/dist/src/ui/hooks/slashCommandProcessor.test.d.ts +6 -0
  535. package/dist/src/ui/hooks/slashCommandProcessor.test.js +807 -0
  536. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -0
  537. package/dist/src/ui/hooks/useAtCompletion.js +2 -2
  538. package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
  539. package/dist/src/ui/hooks/useAtCompletion.test.d.ts +6 -0
  540. package/dist/src/ui/hooks/useAtCompletion.test.js +396 -0
  541. package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -0
  542. package/dist/src/ui/hooks/useAutoAcceptIndicator.js +10 -0
  543. package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
  544. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +32 -2
  545. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
  546. package/dist/src/ui/hooks/useCommandCompletion.d.ts +1 -1
  547. package/dist/src/ui/hooks/useCommandCompletion.js +5 -3
  548. package/dist/src/ui/hooks/useCommandCompletion.js.map +1 -1
  549. package/dist/src/ui/hooks/useCommandCompletion.test.d.ts +6 -0
  550. package/dist/src/ui/hooks/useCommandCompletion.test.js +377 -0
  551. package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -0
  552. package/dist/src/ui/hooks/useConsoleMessages.test.d.ts +6 -0
  553. package/dist/src/ui/hooks/useConsoleMessages.test.js +127 -0
  554. package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -0
  555. package/dist/src/ui/hooks/useEditorSettings.test.js +40 -34
  556. package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
  557. package/dist/src/ui/hooks/useExtensionUpdates.d.ts +14 -4
  558. package/dist/src/ui/hooks/useExtensionUpdates.js +18 -11
  559. package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
  560. package/dist/src/ui/hooks/useExtensionUpdates.test.js +52 -35
  561. package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
  562. package/dist/src/ui/hooks/useFlickerDetector.test.js +9 -5
  563. package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -1
  564. package/dist/src/ui/hooks/useFocus.test.d.ts +6 -0
  565. package/dist/src/ui/hooks/useFocus.test.js +131 -0
  566. package/dist/src/ui/hooks/useFocus.test.js.map +1 -0
  567. package/dist/src/ui/hooks/useFolderTrust.test.d.ts +6 -0
  568. package/dist/src/ui/hooks/useFolderTrust.test.js +188 -0
  569. package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -0
  570. package/dist/src/ui/hooks/useGeminiStream.js +119 -74
  571. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  572. package/dist/src/ui/hooks/useGeminiStream.test.d.ts +6 -0
  573. package/dist/src/ui/hooks/useGeminiStream.test.js +1820 -0
  574. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -0
  575. package/dist/src/ui/hooks/useGitBranchName.js +4 -0
  576. package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
  577. package/dist/src/ui/hooks/useGitBranchName.test.js +46 -34
  578. package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
  579. package/dist/src/ui/hooks/useHistoryManager.test.js +2 -1
  580. package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -1
  581. package/dist/src/ui/hooks/useIdeTrustListener.test.js +40 -9
  582. package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
  583. package/dist/src/ui/hooks/useInputHistory.test.js +2 -1
  584. package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -1
  585. package/dist/src/ui/hooks/useInputHistoryStore.js +2 -1
  586. package/dist/src/ui/hooks/useInputHistoryStore.js.map +1 -1
  587. package/dist/src/ui/hooks/useInputHistoryStore.test.js +2 -1
  588. package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
  589. package/dist/src/ui/hooks/useKeypress.test.d.ts +6 -0
  590. package/dist/src/ui/hooks/useKeypress.test.js +223 -0
  591. package/dist/src/ui/hooks/useKeypress.test.js.map +1 -0
  592. package/dist/src/ui/hooks/useLoadingIndicator.test.js +29 -6
  593. package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
  594. package/dist/src/ui/hooks/useMemoryMonitor.test.js +10 -5
  595. package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
  596. package/dist/src/ui/hooks/useMessageQueue.d.ts +1 -0
  597. package/dist/src/ui/hooks/useMessageQueue.js +14 -0
  598. package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
  599. package/dist/src/ui/hooks/useMessageQueue.test.js +173 -35
  600. package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
  601. package/dist/src/ui/hooks/useModelCommand.test.js +21 -11
  602. package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
  603. package/dist/src/ui/hooks/useMouse.d.ts +17 -0
  604. package/dist/src/ui/hooks/useMouse.js +27 -0
  605. package/dist/src/ui/hooks/useMouse.js.map +1 -0
  606. package/dist/src/ui/hooks/useMouse.test.d.ts +6 -0
  607. package/dist/src/ui/hooks/useMouse.test.js +57 -0
  608. package/dist/src/ui/hooks/useMouse.test.js.map +1 -0
  609. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +2 -2
  610. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
  611. package/dist/src/ui/hooks/usePhraseCycler.d.ts +1 -0
  612. package/dist/src/ui/hooks/usePhraseCycler.js +156 -5
  613. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  614. package/dist/src/ui/hooks/usePhraseCycler.test.d.ts +6 -0
  615. package/dist/src/ui/hooks/usePhraseCycler.test.js +158 -0
  616. package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -0
  617. package/dist/src/ui/hooks/usePrivacySettings.test.js +26 -6
  618. package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
  619. package/dist/src/ui/hooks/usePromptCompletion.js +2 -2
  620. package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
  621. package/dist/src/ui/hooks/useQuotaAndFallback.js +13 -14
  622. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
  623. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +55 -48
  624. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
  625. package/dist/src/ui/hooks/useReactToolScheduler.d.ts +8 -1
  626. package/dist/src/ui/hooks/useReactToolScheduler.js +61 -36
  627. package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
  628. package/dist/src/ui/hooks/useReactToolScheduler.test.d.ts +6 -0
  629. package/dist/src/ui/hooks/useReactToolScheduler.test.js +65 -0
  630. package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -0
  631. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +2 -2
  632. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
  633. package/dist/src/ui/hooks/useSelectionList.js +5 -4
  634. package/dist/src/ui/hooks/useSelectionList.js.map +1 -1
  635. package/dist/src/ui/hooks/useSelectionList.test.js +272 -183
  636. package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
  637. package/dist/src/ui/hooks/useShellHistory.test.js +52 -20
  638. package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
  639. package/dist/src/ui/hooks/useShowMemoryCommand.d.ts +1 -1
  640. package/dist/src/ui/hooks/useShowMemoryCommand.js +4 -3
  641. package/dist/src/ui/hooks/useShowMemoryCommand.js.map +1 -1
  642. package/dist/src/ui/hooks/useSlashCompletion.js +20 -8
  643. package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
  644. package/dist/src/ui/hooks/useSlashCompletion.test.js +275 -137
  645. package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
  646. package/dist/src/ui/hooks/useThemeCommand.d.ts +2 -1
  647. package/dist/src/ui/hooks/useThemeCommand.js +6 -0
  648. package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
  649. package/dist/src/ui/hooks/useTimer.test.js +43 -14
  650. package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
  651. package/dist/src/ui/hooks/useToolScheduler.test.js +229 -242
  652. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  653. package/dist/src/ui/hooks/vim.js +2 -1
  654. package/dist/src/ui/hooks/vim.js.map +1 -1
  655. package/dist/src/ui/hooks/vim.test.d.ts +6 -0
  656. package/dist/src/ui/hooks/vim.test.js +1269 -0
  657. package/dist/src/ui/hooks/vim.test.js.map +1 -0
  658. package/dist/src/ui/keyMatchers.test.js +39 -6
  659. package/dist/src/ui/keyMatchers.test.js.map +1 -1
  660. package/dist/src/ui/state/extensions.d.ts +1 -0
  661. package/dist/src/ui/state/extensions.js +1 -0
  662. package/dist/src/ui/state/extensions.js.map +1 -1
  663. package/dist/src/ui/themes/ansi-light.js +1 -0
  664. package/dist/src/ui/themes/ansi-light.js.map +1 -1
  665. package/dist/src/ui/themes/ansi.js +1 -0
  666. package/dist/src/ui/themes/ansi.js.map +1 -1
  667. package/dist/src/ui/themes/atom-one-dark.js +2 -0
  668. package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
  669. package/dist/src/ui/themes/ayu-light.js +2 -0
  670. package/dist/src/ui/themes/ayu-light.js.map +1 -1
  671. package/dist/src/ui/themes/ayu.js +2 -0
  672. package/dist/src/ui/themes/ayu.js.map +1 -1
  673. package/dist/src/ui/themes/color-utils.d.ts +1 -0
  674. package/dist/src/ui/themes/color-utils.js +8 -1
  675. package/dist/src/ui/themes/color-utils.js.map +1 -1
  676. package/dist/src/ui/themes/color-utils.test.js +13 -1
  677. package/dist/src/ui/themes/color-utils.test.js.map +1 -1
  678. package/dist/src/ui/themes/dracula.js +2 -0
  679. package/dist/src/ui/themes/dracula.js.map +1 -1
  680. package/dist/src/ui/themes/github-dark.js +2 -0
  681. package/dist/src/ui/themes/github-dark.js.map +1 -1
  682. package/dist/src/ui/themes/github-light.js +2 -0
  683. package/dist/src/ui/themes/github-light.js.map +1 -1
  684. package/dist/src/ui/themes/googlecode.js +2 -0
  685. package/dist/src/ui/themes/googlecode.js.map +1 -1
  686. package/dist/src/ui/themes/no-color.js +3 -0
  687. package/dist/src/ui/themes/no-color.js.map +1 -1
  688. package/dist/src/ui/themes/semantic-tokens.d.ts +2 -0
  689. package/dist/src/ui/themes/semantic-tokens.js +6 -0
  690. package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
  691. package/dist/src/ui/themes/shades-of-purple.js +2 -0
  692. package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
  693. package/dist/src/ui/themes/theme-manager.js +8 -7
  694. package/dist/src/ui/themes/theme-manager.js.map +1 -1
  695. package/dist/src/ui/themes/theme.d.ts +3 -0
  696. package/dist/src/ui/themes/theme.js +14 -3
  697. package/dist/src/ui/themes/theme.js.map +1 -1
  698. package/dist/src/ui/themes/theme.test.d.ts +6 -0
  699. package/dist/src/ui/themes/theme.test.js +151 -0
  700. package/dist/src/ui/themes/theme.test.js.map +1 -0
  701. package/dist/src/ui/themes/xcode.js +2 -0
  702. package/dist/src/ui/themes/xcode.js.map +1 -1
  703. package/dist/src/ui/types.d.ts +3 -2
  704. package/dist/src/ui/types.js +2 -0
  705. package/dist/src/ui/types.js.map +1 -1
  706. package/dist/src/ui/utils/CodeColorizer.d.ts +1 -1
  707. package/dist/src/ui/utils/CodeColorizer.js +6 -3
  708. package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
  709. package/dist/src/ui/utils/InlineMarkdownRenderer.d.ts +1 -0
  710. package/dist/src/ui/utils/InlineMarkdownRenderer.js +11 -10
  711. package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
  712. package/dist/src/ui/utils/MarkdownDisplay.d.ts +1 -0
  713. package/dist/src/ui/utils/MarkdownDisplay.js +19 -10
  714. package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
  715. package/dist/src/ui/utils/clipboardUtils.js +2 -2
  716. package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
  717. package/dist/src/ui/utils/commandUtils.js +20 -3
  718. package/dist/src/ui/utils/commandUtils.js.map +1 -1
  719. package/dist/src/ui/utils/commandUtils.test.js +61 -6
  720. package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
  721. package/dist/src/ui/utils/computeStats.js +5 -2
  722. package/dist/src/ui/utils/computeStats.js.map +1 -1
  723. package/dist/src/ui/utils/computeStats.test.d.ts +6 -0
  724. package/dist/src/ui/utils/computeStats.test.js +262 -0
  725. package/dist/src/ui/utils/computeStats.test.js.map +1 -0
  726. package/dist/src/ui/utils/input.d.ts +17 -0
  727. package/dist/src/ui/utils/input.js +51 -0
  728. package/dist/src/ui/utils/input.js.map +1 -0
  729. package/dist/src/ui/utils/input.test.d.ts +6 -0
  730. package/dist/src/ui/utils/input.test.js +44 -0
  731. package/dist/src/ui/utils/input.test.js.map +1 -0
  732. package/dist/src/ui/utils/kittyProtocolDetector.js +13 -4
  733. package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
  734. package/dist/src/ui/utils/mouse.d.ts +31 -0
  735. package/dist/src/ui/utils/mouse.js +164 -0
  736. package/dist/src/ui/utils/mouse.js.map +1 -0
  737. package/dist/src/ui/utils/mouse.test.d.ts +6 -0
  738. package/dist/src/ui/utils/mouse.test.js +131 -0
  739. package/dist/src/ui/utils/mouse.test.js.map +1 -0
  740. package/dist/src/ui/utils/terminalSetup.js +3 -2
  741. package/dist/src/ui/utils/terminalSetup.js.map +1 -1
  742. package/dist/src/ui/utils/textOutput.d.ts +25 -0
  743. package/dist/src/ui/utils/textOutput.js +49 -0
  744. package/dist/src/ui/utils/textOutput.js.map +1 -0
  745. package/dist/src/ui/utils/textOutput.test.d.ts +6 -0
  746. package/dist/src/ui/utils/textOutput.test.js +79 -0
  747. package/dist/src/ui/utils/textOutput.test.js.map +1 -0
  748. package/dist/src/ui/utils/updateCheck.d.ts +9 -2
  749. package/dist/src/ui/utils/updateCheck.js +38 -30
  750. package/dist/src/ui/utils/updateCheck.js.map +1 -1
  751. package/dist/src/ui/utils/updateCheck.test.js +48 -59
  752. package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
  753. package/dist/src/utils/cleanup.test.d.ts +6 -0
  754. package/dist/src/utils/cleanup.test.js +49 -0
  755. package/dist/src/utils/cleanup.test.js.map +1 -0
  756. package/dist/src/utils/commentJson.js +2 -2
  757. package/dist/src/utils/commentJson.js.map +1 -1
  758. package/dist/src/utils/commentJson.test.js +7 -6
  759. package/dist/src/utils/commentJson.test.js.map +1 -1
  760. package/dist/src/utils/envVarResolver.d.ts +2 -2
  761. package/dist/src/utils/envVarResolver.js +10 -7
  762. package/dist/src/utils/envVarResolver.js.map +1 -1
  763. package/dist/src/utils/errors.d.ts +1 -0
  764. package/dist/src/utils/errors.js +66 -5
  765. package/dist/src/utils/errors.js.map +1 -1
  766. package/dist/src/utils/events.d.ts +11 -2
  767. package/dist/src/utils/events.js +1 -0
  768. package/dist/src/utils/events.js.map +1 -1
  769. package/dist/src/utils/gitUtils.js +3 -2
  770. package/dist/src/utils/gitUtils.js.map +1 -1
  771. package/dist/src/utils/handleAutoUpdate.js +9 -3
  772. package/dist/src/utils/handleAutoUpdate.js.map +1 -1
  773. package/dist/src/utils/handleAutoUpdate.test.d.ts +6 -0
  774. package/dist/src/utils/handleAutoUpdate.test.js +225 -0
  775. package/dist/src/utils/handleAutoUpdate.test.js.map +1 -0
  776. package/dist/src/utils/installationInfo.js +2 -2
  777. package/dist/src/utils/installationInfo.js.map +1 -1
  778. package/dist/src/utils/installationInfo.test.js +8 -4
  779. package/dist/src/utils/installationInfo.test.js.map +1 -1
  780. package/dist/src/utils/readStdin.js +2 -1
  781. package/dist/src/utils/readStdin.js.map +1 -1
  782. package/dist/src/utils/sandbox-macos-permissive-open.sb +2 -0
  783. package/dist/src/utils/sandbox.js +28 -30
  784. package/dist/src/utils/sandbox.js.map +1 -1
  785. package/dist/src/utils/sessionCleanup.js +4 -4
  786. package/dist/src/utils/sessionCleanup.js.map +1 -1
  787. package/dist/src/utils/startupWarnings.test.d.ts +6 -0
  788. package/dist/src/utils/startupWarnings.test.js +61 -0
  789. package/dist/src/utils/startupWarnings.test.js.map +1 -0
  790. package/dist/src/utils/version.js +6 -2
  791. package/dist/src/utils/version.js.map +1 -1
  792. package/dist/src/validateNonInterActiveAuth.js +2 -2
  793. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  794. package/dist/src/zed-integration/acp.js +2 -1
  795. package/dist/src/zed-integration/acp.js.map +1 -1
  796. package/dist/src/zed-integration/schema.d.ts +4 -4
  797. package/dist/src/zed-integration/zedIntegration.d.ts +2 -2
  798. package/dist/src/zed-integration/zedIntegration.js +16 -25
  799. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  800. package/dist/tsconfig.tsbuildinfo +1 -1
  801. package/package.json +17 -17
  802. package/dist/src/config/policy.test.js +0 -336
  803. package/dist/src/config/policy.test.js.map +0 -1
  804. package/dist/src/ui/components/WorkspaceMigrationDialog.d.ts +0 -11
  805. package/dist/src/ui/components/WorkspaceMigrationDialog.js +0 -44
  806. package/dist/src/ui/components/WorkspaceMigrationDialog.js.map +0 -1
  807. package/dist/src/ui/hooks/useWorkspaceMigration.d.ts +0 -13
  808. package/dist/src/ui/hooks/useWorkspaceMigration.js +0 -59
  809. package/dist/src/ui/hooks/useWorkspaceMigration.js.map +0 -1
  810. package/dist/src/utils/package.d.ts +0 -12
  811. package/dist/src/utils/package.js +0 -24
  812. package/dist/src/utils/package.js.map +0 -1
  813. /package/dist/src/{config/policy.test.d.ts → commands/extensions/examples/mcp-server/example.d.ts} +0 -0
@@ -1,179 +1,215 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { KittySequenceOverflowEvent, logKittySequenceOverflow, } from '@google/gemini-cli-core';
2
+ import { debugLogger, KittySequenceOverflowEvent, logKittySequenceOverflow, } from '@google/gemini-cli-core';
3
3
  import { useStdin } from 'ink';
4
4
  import { createContext, useCallback, useContext, useEffect, useRef, } from 'react';
5
5
  import readline from 'node:readline';
6
6
  import { PassThrough } from 'node:stream';
7
7
  import { BACKSLASH_ENTER_DETECTION_WINDOW_MS, CHAR_CODE_ESC, KITTY_CTRL_C, KITTY_KEYCODE_BACKSPACE, KITTY_KEYCODE_ENTER, KITTY_KEYCODE_NUMPAD_ENTER, KITTY_KEYCODE_TAB, MAX_KITTY_SEQUENCE_LENGTH, KITTY_MODIFIER_BASE, KITTY_MODIFIER_EVENT_TYPES_OFFSET, MODIFIER_SHIFT_BIT, MODIFIER_ALT_BIT, MODIFIER_CTRL_BIT, } from '../utils/platformConstants.js';
8
+ import { ESC, couldBeMouseSequence } from '../utils/input.js';
8
9
  import { FOCUS_IN, FOCUS_OUT } from '../hooks/useFocus.js';
9
- const ESC = '\u001B';
10
- export const PASTE_MODE_PREFIX = `${ESC}[200~`;
11
- export const PASTE_MODE_SUFFIX = `${ESC}[201~`;
10
+ import { isIncompleteMouseSequence, parseMouseEvent } from '../utils/mouse.js';
11
+ export const PASTE_MODE_START = `${ESC}[200~`;
12
+ export const PASTE_MODE_END = `${ESC}[201~`;
12
13
  export const DRAG_COMPLETION_TIMEOUT_MS = 100; // Broadcast full path after 100ms if no more input
14
+ export const KITTY_SEQUENCE_TIMEOUT_MS = 50; // Flush incomplete kitty sequences after 50ms
15
+ export const PASTE_CODE_TIMEOUT_MS = 50; // Flush incomplete paste code after 50ms
13
16
  export const SINGLE_QUOTE = "'";
14
17
  export const DOUBLE_QUOTE = '"';
15
- const ALT_KEY_CHARACTER_MAP = {
16
- '\u00E5': 'a',
17
- '\u222B': 'b',
18
- '\u00E7': 'c',
19
- '\u2202': 'd',
20
- '\u00B4': 'e',
21
- '\u0192': 'f',
22
- '\u00A9': 'g',
23
- '\u02D9': 'h',
24
- '\u02C6': 'i',
25
- '\u2206': 'j',
26
- '\u02DA': 'k',
27
- '\u00AC': 'l',
28
- '\u00B5': 'm',
29
- '\u02DC': 'n',
30
- '\u00F8': 'o',
31
- '\u03C0': 'p',
32
- '\u0153': 'q',
33
- '\u00AE': 'r',
34
- '\u00DF': 's',
35
- '\u2020': 't',
36
- '\u00A8': 'u',
37
- '\u221A': 'v',
38
- '\u2211': 'w',
39
- '\u2248': 'x',
40
- '\u00A5': 'y',
41
- '\u03A9': 'z',
18
+ // On Mac, hitting alt+char will yield funny characters.
19
+ // Remap these three since we listen for them.
20
+ const MAC_ALT_KEY_CHARACTER_MAP = {
21
+ '\u222B': 'b', // "∫" back one word
22
+ '\u0192': 'f', // "ƒ" forward one word
23
+ '\u00B5': 'm', // "µ" toggle markup view
42
24
  };
43
- const KeypressContext = createContext(undefined);
44
- export function useKeypressContext() {
45
- const context = useContext(KeypressContext);
46
- if (!context) {
47
- throw new Error('useKeypressContext must be used within a KeypressProvider');
48
- }
49
- return context;
25
+ /**
26
+ * Maps symbols from parameterized functional keys `\x1b[1;1<letter>`
27
+ * to their corresponding key names (e.g., 'up', 'f1').
28
+ */
29
+ const LEGACY_FUNC_TO_NAME = {
30
+ A: 'up',
31
+ B: 'down',
32
+ C: 'right',
33
+ D: 'left',
34
+ H: 'home',
35
+ F: 'end',
36
+ P: 'f1',
37
+ Q: 'f2',
38
+ R: 'f3',
39
+ S: 'f4',
40
+ };
41
+ /**
42
+ * Maps key codes from tilde-coded functional keys `\x1b[<code>~`
43
+ * to their corresponding key names.
44
+ */
45
+ const TILDE_KEYCODE_TO_NAME = {
46
+ 1: 'home',
47
+ 2: 'insert',
48
+ 3: 'delete',
49
+ 4: 'end',
50
+ 5: 'pageup',
51
+ 6: 'pagedown',
52
+ 11: 'f1',
53
+ 12: 'f2',
54
+ 13: 'f3',
55
+ 14: 'f4',
56
+ 15: 'f5',
57
+ 17: 'f6', // skipping 16 is intentional
58
+ 18: 'f7',
59
+ 19: 'f8',
60
+ 20: 'f9',
61
+ 21: 'f10',
62
+ 23: 'f11', // skipping 22 is intentional
63
+ 24: 'f12',
64
+ };
65
+ /**
66
+ * Check if a buffer could potentially be a valid kitty sequence or its prefix.
67
+ */
68
+ function couldBeKittySequence(buffer) {
69
+ // Kitty sequences always start with ESC[.
70
+ if (buffer.length === 0)
71
+ return true;
72
+ if (buffer === ESC || buffer === `${ESC}[`)
73
+ return true;
74
+ if (!buffer.startsWith(`${ESC}[`))
75
+ return false;
76
+ if (couldBeMouseSequence(buffer))
77
+ return true;
78
+ // Check for known kitty sequence patterns:
79
+ // 1. ESC[<digit> - could be CSI-u or tilde-coded
80
+ // 2. ESC[1;<digit> - parameterized functional
81
+ // 3. ESC[<letter> - legacy functional keys
82
+ // 4. ESC[Z - reverse tab
83
+ const afterCSI = buffer.slice(2);
84
+ // Check if it starts with a digit (could be CSI-u or parameterized)
85
+ if (/^\d/.test(afterCSI))
86
+ return true;
87
+ // Check for known single-letter sequences
88
+ if (/^[ABCDHFPQRSZ]/.test(afterCSI))
89
+ return true;
90
+ // Check for 1; pattern (parameterized sequences)
91
+ if (/^1;\d/.test(afterCSI))
92
+ return true;
93
+ // Anything else starting with ESC[ that doesn't match our patterns
94
+ // is likely not a kitty sequence we handle
95
+ return false;
50
96
  }
51
- export function KeypressProvider({ children, kittyProtocolEnabled, config, debugKeystrokeLogging, }) {
52
- const { stdin, setRawMode } = useStdin();
53
- const subscribers = useRef(new Set()).current;
54
- const isDraggingRef = useRef(false);
55
- const dragBufferRef = useRef('');
56
- const draggingTimerRef = useRef(null);
57
- const subscribe = useCallback((handler) => {
58
- subscribers.add(handler);
59
- }, [subscribers]);
60
- const unsubscribe = useCallback((handler) => {
61
- subscribers.delete(handler);
62
- }, [subscribers]);
63
- useEffect(() => {
64
- const clearDraggingTimer = () => {
65
- if (draggingTimerRef.current) {
66
- clearTimeout(draggingTimerRef.current);
67
- draggingTimerRef.current = null;
68
- }
97
+ /**
98
+ * Parses a single complete kitty/parameterized/legacy sequence from the start
99
+ * of the buffer.
100
+ *
101
+ * This enables peel-and-continue parsing for batched input, allowing us to
102
+ * "peel off" one complete event when multiple sequences arrive in a single
103
+ * chunk, preventing buffer overflow and fragmentation.
104
+ *
105
+ * @param buffer - The input buffer string to parse.
106
+ * @returns The parsed Key and the number of characters consumed, or null if
107
+ * no complete sequence is found at the start of the buffer.
108
+ */
109
+ function parseKittyPrefix(buffer) {
110
+ // In older terminals ESC [ Z was used as Cursor Backward Tabulation (CBT)
111
+ // In newer terminals the same functionality of key combination for moving
112
+ // backward through focusable elements is Shift+Tab, hence we will
113
+ // map ESC [ Z to Shift+Tab
114
+ // 0) Reverse Tab (legacy): ESC [ Z
115
+ // Treat as Shift+Tab for UI purposes.
116
+ // Regex parts:
117
+ // ^ - start of buffer
118
+ // ESC [ - CSI introducer
119
+ // Z - legacy reverse tab
120
+ const revTabLegacy = new RegExp(`^${ESC}\\[Z`);
121
+ let m = buffer.match(revTabLegacy);
122
+ if (m) {
123
+ return {
124
+ key: {
125
+ name: 'tab',
126
+ ctrl: false,
127
+ meta: false,
128
+ shift: true,
129
+ paste: false,
130
+ sequence: buffer.slice(0, m[0].length),
131
+ kittyProtocol: false,
132
+ },
133
+ length: m[0].length,
69
134
  };
70
- const wasRaw = stdin.isRaw;
71
- if (wasRaw === false) {
72
- setRawMode(true);
135
+ }
136
+ // 1) Reverse Tab (parameterized): ESC [ 1 ; <mods> Z
137
+ // Parameterized reverse Tab: ESC [ 1 ; <mods> Z
138
+ const revTabParam = new RegExp(`^${ESC}\\[1;(\\d+)Z`);
139
+ m = buffer.match(revTabParam);
140
+ if (m) {
141
+ let mods = parseInt(m[1], 10);
142
+ if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
143
+ mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
73
144
  }
74
- const keypressStream = new PassThrough();
75
- let usePassthrough = false;
76
- const nodeMajorVersion = parseInt(process.versions.node.split('.')[0], 10);
77
- if (nodeMajorVersion < 20 ||
78
- process.env['PASTE_WORKAROUND'] === '1' ||
79
- process.env['PASTE_WORKAROUND'] === 'true') {
80
- usePassthrough = true;
145
+ const bits = mods - KITTY_MODIFIER_BASE;
146
+ const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
147
+ const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
148
+ return {
149
+ key: {
150
+ name: 'tab',
151
+ ctrl,
152
+ meta: alt,
153
+ // Reverse tab implies Shift behavior; force shift regardless of mods
154
+ shift: true,
155
+ paste: false,
156
+ sequence: buffer.slice(0, m[0].length),
157
+ kittyProtocol: true,
158
+ },
159
+ length: m[0].length,
160
+ };
161
+ }
162
+ // 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
163
+ // 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
164
+ // Arrows, Home/End, F1–F4 with modifiers encoded in <mods>.
165
+ const arrowPrefix = new RegExp(`^${ESC}\\[1;(\\d+)([ABCDHFPQSR])`);
166
+ m = buffer.match(arrowPrefix);
167
+ if (m) {
168
+ let mods = parseInt(m[1], 10);
169
+ if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
170
+ mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
81
171
  }
82
- let isPaste = false;
83
- let pasteBuffer = Buffer.alloc(0);
84
- let kittySequenceBuffer = '';
85
- let backslashTimeout = null;
86
- let waitingForEnterAfterBackslash = false;
87
- // Parse a single complete kitty sequence from the start (prefix) of the
88
- // buffer and return both the Key and the number of characters consumed.
89
- // This lets us "peel off" one complete event when multiple sequences arrive
90
- // in a single chunk, preventing buffer overflow and fragmentation.
91
- // Parse a single complete kitty/parameterized/legacy sequence from the start
92
- // of the buffer and return both the parsed Key and the number of characters
93
- // consumed. This enables peel-and-continue parsing for batched input.
94
- const parseKittyPrefix = (buffer) => {
95
- // In older terminals ESC [ Z was used as Cursor Backward Tabulation (CBT)
96
- // In newer terminals the same functionality of key combination for moving
97
- // backward through focusable elements is Shift+Tab, hence we will
98
- // map ESC [ Z to Shift+Tab
99
- // 0) Reverse Tab (legacy): ESC [ Z
100
- // Treat as Shift+Tab for UI purposes.
101
- // Regex parts:
102
- // ^ - start of buffer
103
- // ESC [ - CSI introducer
104
- // Z - legacy reverse tab
105
- const revTabLegacy = new RegExp(`^${ESC}\\[Z`);
106
- let m = buffer.match(revTabLegacy);
107
- if (m) {
108
- return {
109
- key: {
110
- name: 'tab',
111
- ctrl: false,
112
- meta: false,
113
- shift: true,
114
- paste: false,
115
- sequence: buffer.slice(0, m[0].length),
116
- kittyProtocol: true,
117
- },
118
- length: m[0].length,
119
- };
120
- }
121
- // 1) Reverse Tab (parameterized): ESC [ 1 ; <mods> Z
122
- // Parameterized reverse Tab: ESC [ 1 ; <mods> Z
123
- const revTabParam = new RegExp(`^${ESC}\\[1;(\\d+)Z`);
124
- m = buffer.match(revTabParam);
125
- if (m) {
126
- let mods = parseInt(m[1], 10);
127
- if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
128
- mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
129
- }
130
- const bits = mods - KITTY_MODIFIER_BASE;
131
- const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
132
- const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
133
- return {
134
- key: {
135
- name: 'tab',
136
- ctrl,
137
- meta: alt,
138
- // Reverse tab implies Shift behavior; force shift regardless of mods
139
- shift: true,
140
- paste: false,
141
- sequence: buffer.slice(0, m[0].length),
142
- kittyProtocol: true,
143
- },
144
- length: m[0].length,
145
- };
146
- }
147
- // 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
148
- // 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
149
- // Arrows, Home/End, F1–F4 with modifiers encoded in <mods>.
150
- const arrowPrefix = new RegExp(`^${ESC}\\[1;(\\d+)([ABCDHFPQSR])`);
151
- m = buffer.match(arrowPrefix);
152
- if (m) {
153
- let mods = parseInt(m[1], 10);
154
- if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
155
- mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
156
- }
157
- const bits = mods - KITTY_MODIFIER_BASE;
158
- const shift = (bits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
159
- const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
160
- const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
161
- const sym = m[2];
162
- const symbolToName = {
163
- A: 'up',
164
- B: 'down',
165
- C: 'right',
166
- D: 'left',
167
- H: 'home',
168
- F: 'end',
169
- P: 'f1',
170
- Q: 'f2',
171
- R: 'f3',
172
- S: 'f4',
173
- };
174
- const name = symbolToName[sym] || '';
175
- if (!name)
176
- return null;
172
+ const bits = mods - KITTY_MODIFIER_BASE;
173
+ const shift = (bits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
174
+ const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
175
+ const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
176
+ const sym = m[2];
177
+ const name = LEGACY_FUNC_TO_NAME[sym] || '';
178
+ if (!name)
179
+ return null;
180
+ return {
181
+ key: {
182
+ name,
183
+ ctrl,
184
+ meta: alt,
185
+ shift,
186
+ paste: false,
187
+ sequence: buffer.slice(0, m[0].length),
188
+ kittyProtocol: true,
189
+ },
190
+ length: m[0].length,
191
+ };
192
+ }
193
+ // 3) CSI-u form: ESC [ <code> ; <mods> (u|~)
194
+ // 3) CSI-u and tilde-coded functional keys: ESC [ <code> ; <mods> (u|~)
195
+ // 'u' terminator: Kitty CSI-u; '~' terminator: tilde-coded function keys.
196
+ const csiUPrefix = new RegExp(`^${ESC}\\[(\\d+)(;(\\d+))?([u~])`);
197
+ m = buffer.match(csiUPrefix);
198
+ if (m) {
199
+ const keyCode = parseInt(m[1], 10);
200
+ let modifiers = m[3] ? parseInt(m[3], 10) : KITTY_MODIFIER_BASE;
201
+ if (modifiers >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
202
+ modifiers -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
203
+ }
204
+ const modifierBits = modifiers - KITTY_MODIFIER_BASE;
205
+ const shift = (modifierBits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
206
+ const alt = (modifierBits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
207
+ const ctrl = (modifierBits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
208
+ const terminator = m[4];
209
+ // Tilde-coded functional keys (Delete, Insert, PageUp/Down, Home/End)
210
+ if (terminator === '~') {
211
+ const name = TILDE_KEYCODE_TO_NAME[keyCode];
212
+ if (name) {
177
213
  return {
178
214
  key: {
179
215
  name,
@@ -182,202 +218,284 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
182
218
  shift,
183
219
  paste: false,
184
220
  sequence: buffer.slice(0, m[0].length),
185
- kittyProtocol: true,
221
+ kittyProtocol: false,
186
222
  },
187
223
  length: m[0].length,
188
224
  };
189
225
  }
190
- // 3) CSI-u form: ESC [ <code> ; <mods> (u|~)
191
- // 3) CSI-u and tilde-coded functional keys: ESC [ <code> ; <mods> (u|~)
192
- // 'u' terminator: Kitty CSI-u; '~' terminator: tilde-coded function keys.
193
- const csiUPrefix = new RegExp(`^${ESC}\\[(\\d+)(;(\\d+))?([u~])`);
194
- m = buffer.match(csiUPrefix);
195
- if (m) {
196
- const keyCode = parseInt(m[1], 10);
197
- let modifiers = m[3] ? parseInt(m[3], 10) : KITTY_MODIFIER_BASE;
198
- if (modifiers >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
199
- modifiers -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
200
- }
201
- const modifierBits = modifiers - KITTY_MODIFIER_BASE;
202
- const shift = (modifierBits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
203
- const alt = (modifierBits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
204
- const ctrl = (modifierBits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
205
- const terminator = m[4];
206
- // Tilde-coded functional keys (Delete, Insert, PageUp/Down, Home/End)
207
- if (terminator === '~') {
208
- let name = null;
209
- switch (keyCode) {
210
- case 1:
211
- name = 'home';
212
- break;
213
- case 2:
214
- name = 'insert';
215
- break;
216
- case 3:
217
- name = 'delete';
218
- break;
219
- case 4:
220
- name = 'end';
221
- break;
222
- case 5:
223
- name = 'pageup';
224
- break;
225
- case 6:
226
- name = 'pagedown';
227
- break;
228
- default:
229
- break;
230
- }
231
- if (name) {
232
- return {
233
- key: {
234
- name,
235
- ctrl,
236
- meta: alt,
237
- shift,
238
- paste: false,
239
- sequence: buffer.slice(0, m[0].length),
240
- kittyProtocol: true,
241
- },
242
- length: m[0].length,
243
- };
244
- }
245
- }
246
- const kittyKeyCodeToName = {
247
- [CHAR_CODE_ESC]: 'escape',
248
- [KITTY_KEYCODE_TAB]: 'tab',
249
- [KITTY_KEYCODE_BACKSPACE]: 'backspace',
250
- [KITTY_KEYCODE_ENTER]: 'return',
251
- [KITTY_KEYCODE_NUMPAD_ENTER]: 'return',
252
- };
253
- const name = kittyKeyCodeToName[keyCode];
254
- if (name) {
255
- return {
256
- key: {
257
- name,
258
- ctrl,
259
- meta: alt,
260
- shift,
261
- paste: false,
262
- sequence: buffer.slice(0, m[0].length),
263
- kittyProtocol: true,
264
- },
265
- length: m[0].length,
266
- };
267
- }
268
- // Ctrl+letters and Alt+letters
269
- if ((ctrl || alt) &&
270
- keyCode >= 'a'.charCodeAt(0) &&
271
- keyCode <= 'z'.charCodeAt(0)) {
272
- const letter = String.fromCharCode(keyCode);
273
- return {
274
- key: {
275
- name: letter,
276
- ctrl,
277
- meta: alt,
278
- shift,
279
- paste: false,
280
- sequence: buffer.slice(0, m[0].length),
281
- kittyProtocol: true,
282
- },
283
- length: m[0].length,
284
- };
226
+ }
227
+ const kittyKeyCodeToName = {
228
+ [CHAR_CODE_ESC]: 'escape',
229
+ [KITTY_KEYCODE_TAB]: 'tab',
230
+ [KITTY_KEYCODE_BACKSPACE]: 'backspace',
231
+ [KITTY_KEYCODE_ENTER]: 'return',
232
+ [KITTY_KEYCODE_NUMPAD_ENTER]: 'return',
233
+ };
234
+ const name = kittyKeyCodeToName[keyCode];
235
+ if (name) {
236
+ return {
237
+ key: {
238
+ name,
239
+ ctrl,
240
+ meta: alt,
241
+ shift,
242
+ paste: false,
243
+ sequence: buffer.slice(0, m[0].length),
244
+ kittyProtocol: true,
245
+ },
246
+ length: m[0].length,
247
+ };
248
+ }
249
+ // Ctrl+letters and Alt+letters
250
+ if ((ctrl || alt) &&
251
+ keyCode >= 'a'.charCodeAt(0) &&
252
+ keyCode <= 'z'.charCodeAt(0)) {
253
+ const letter = String.fromCharCode(keyCode);
254
+ return {
255
+ key: {
256
+ name: letter,
257
+ ctrl,
258
+ meta: alt,
259
+ shift,
260
+ paste: false,
261
+ sequence: buffer.slice(0, m[0].length),
262
+ kittyProtocol: true,
263
+ },
264
+ length: m[0].length,
265
+ };
266
+ }
267
+ }
268
+ // 4) Legacy function keys (no parameters): ESC [ (A|B|C|D|H|F)
269
+ // Arrows + Home/End without modifiers.
270
+ const legacyFuncKey = new RegExp(`^${ESC}\\[([ABCDHF])`);
271
+ m = buffer.match(legacyFuncKey);
272
+ if (m) {
273
+ const sym = m[1];
274
+ const name = LEGACY_FUNC_TO_NAME[sym];
275
+ return {
276
+ key: {
277
+ name,
278
+ ctrl: false,
279
+ meta: false,
280
+ shift: false,
281
+ paste: false,
282
+ sequence: buffer.slice(0, m[0].length),
283
+ kittyProtocol: false,
284
+ },
285
+ length: m[0].length,
286
+ };
287
+ }
288
+ return null;
289
+ }
290
+ /**
291
+ * Returns the first index before which we are certain there is no paste marker.
292
+ */
293
+ function earliestPossiblePasteMarker(data) {
294
+ // Check data for full start-paste or end-paste markers.
295
+ const startIndex = data.indexOf(PASTE_MODE_START);
296
+ const endIndex = data.indexOf(PASTE_MODE_END);
297
+ if (startIndex !== -1 && endIndex !== -1) {
298
+ return Math.min(startIndex, endIndex);
299
+ }
300
+ else if (startIndex !== -1) {
301
+ return startIndex;
302
+ }
303
+ else if (endIndex !== -1) {
304
+ return endIndex;
305
+ }
306
+ // data contains no full start-paste or end-paste.
307
+ // Check if data ends with a prefix of start-paste or end-paste.
308
+ const codeLength = PASTE_MODE_START.length;
309
+ for (let i = Math.min(data.length, codeLength - 1); i > 0; i--) {
310
+ const candidate = data.slice(data.length - i);
311
+ if (PASTE_MODE_START.indexOf(candidate) === 0 ||
312
+ PASTE_MODE_END.indexOf(candidate) === 0) {
313
+ return data.length - i;
314
+ }
315
+ }
316
+ return data.length;
317
+ }
318
+ /**
319
+ * A generator that takes in data chunks and spits out paste-start and
320
+ * paste-end keypresses. All non-paste marker data is passed to passthrough.
321
+ */
322
+ function* pasteMarkerParser(passthrough, keypressHandler) {
323
+ while (true) {
324
+ let data = yield;
325
+ if (data.length === 0) {
326
+ continue; // we timed out
327
+ }
328
+ while (true) {
329
+ const index = earliestPossiblePasteMarker(data);
330
+ if (index === data.length) {
331
+ // no possible paste markers were found
332
+ passthrough.write(data);
333
+ break;
334
+ }
335
+ if (index > 0) {
336
+ // snip off and send the part that doesn't have a paste marker
337
+ passthrough.write(data.slice(0, index));
338
+ data = data.slice(index);
339
+ }
340
+ // data starts with a possible paste marker
341
+ const codeLength = PASTE_MODE_START.length;
342
+ if (data.length < codeLength) {
343
+ // we have a prefix. Concat the next data and try again.
344
+ const newData = yield;
345
+ if (newData.length === 0) {
346
+ // we timed out. Just dump what we have and start over.
347
+ passthrough.write(data);
348
+ break;
285
349
  }
350
+ data += newData;
286
351
  }
287
- // 4) Legacy function keys (no parameters): ESC [ (A|B|C|D|H|F)
288
- // Arrows + Home/End without modifiers.
289
- const legacyFuncKey = new RegExp(`^${ESC}\\[([ABCDHF])`);
290
- m = buffer.match(legacyFuncKey);
291
- if (m) {
292
- const sym = m[1];
293
- const nameMap = {
294
- A: 'up',
295
- B: 'down',
296
- C: 'right',
297
- D: 'left',
298
- H: 'home',
299
- F: 'end',
300
- };
301
- const name = nameMap[sym];
302
- return {
303
- key: {
304
- name,
305
- ctrl: false,
306
- meta: false,
307
- shift: false,
308
- paste: false,
309
- sequence: buffer.slice(0, m[0].length),
310
- kittyProtocol: true,
311
- },
312
- length: m[0].length,
313
- };
352
+ else if (data.startsWith(PASTE_MODE_START)) {
353
+ keypressHandler(undefined, {
354
+ name: 'paste-start',
355
+ ctrl: false,
356
+ meta: false,
357
+ shift: false,
358
+ paste: false,
359
+ sequence: '',
360
+ });
361
+ data = data.slice(PASTE_MODE_START.length);
362
+ }
363
+ else if (data.startsWith(PASTE_MODE_END)) {
364
+ keypressHandler(undefined, {
365
+ name: 'paste-end',
366
+ ctrl: false,
367
+ meta: false,
368
+ shift: false,
369
+ paste: false,
370
+ sequence: '',
371
+ });
372
+ data = data.slice(PASTE_MODE_END.length);
373
+ }
374
+ else {
375
+ // This should never happen.
376
+ passthrough.write(data);
377
+ break;
378
+ }
379
+ }
380
+ }
381
+ }
382
+ const KeypressContext = createContext(undefined);
383
+ export function useKeypressContext() {
384
+ const context = useContext(KeypressContext);
385
+ if (!context) {
386
+ throw new Error('useKeypressContext must be used within a KeypressProvider');
387
+ }
388
+ return context;
389
+ }
390
+ function shouldUsePassthrough() {
391
+ return process.env['PASTE_WORKAROUND'] !== 'false';
392
+ }
393
+ export function KeypressProvider({ children, kittyProtocolEnabled, config, debugKeystrokeLogging, }) {
394
+ const { stdin, setRawMode } = useStdin();
395
+ const subscribers = useRef(new Set()).current;
396
+ const subscribe = useCallback((handler) => subscribers.add(handler), [subscribers]);
397
+ const unsubscribe = useCallback((handler) => subscribers.delete(handler), [subscribers]);
398
+ const broadcast = useCallback((key) => subscribers.forEach((handler) => handler(key)), [subscribers]);
399
+ useEffect(() => {
400
+ const wasRaw = stdin.isRaw;
401
+ if (wasRaw === false) {
402
+ setRawMode(true);
403
+ }
404
+ const keypressStream = shouldUsePassthrough() ? new PassThrough() : null;
405
+ // If non-null that means we are in paste mode
406
+ let pasteBuffer = null;
407
+ // Used to turn "\" quickly followed by a "enter" into a shift enter
408
+ let backslashTimeout = null;
409
+ // Buffers incomplete sequences (Kitty or Mouse) and timer to flush it
410
+ let inputBuffer = '';
411
+ let inputTimeout = null;
412
+ // Used to detect filename drag-and-drops.
413
+ let dragBuffer = '';
414
+ let draggingTimer = null;
415
+ const clearDraggingTimer = () => {
416
+ if (draggingTimer) {
417
+ clearTimeout(draggingTimer);
418
+ draggingTimer = null;
314
419
  }
315
- return null;
316
420
  };
317
- const broadcast = (key) => {
318
- for (const handler of subscribers) {
319
- handler(key);
421
+ const flushInputBufferOnInterrupt = (reason) => {
422
+ if (inputBuffer) {
423
+ if (debugKeystrokeLogging) {
424
+ debugLogger.log(`[DEBUG] Input sequence flushed due to ${reason}:`, JSON.stringify(inputBuffer));
425
+ }
426
+ broadcast({
427
+ name: '',
428
+ ctrl: false,
429
+ meta: false,
430
+ shift: false,
431
+ paste: false,
432
+ sequence: inputBuffer,
433
+ });
434
+ inputBuffer = '';
435
+ }
436
+ if (inputTimeout) {
437
+ clearTimeout(inputTimeout);
438
+ inputTimeout = null;
320
439
  }
321
440
  };
322
441
  const handleKeypress = (_, key) => {
323
442
  if (key.sequence === FOCUS_IN || key.sequence === FOCUS_OUT) {
443
+ flushInputBufferOnInterrupt('focus event');
324
444
  return;
325
445
  }
326
446
  if (key.name === 'paste-start') {
327
- isPaste = true;
447
+ flushInputBufferOnInterrupt('paste start');
448
+ pasteBuffer = Buffer.alloc(0);
328
449
  return;
329
450
  }
330
451
  if (key.name === 'paste-end') {
331
- isPaste = false;
332
- broadcast({
333
- name: '',
334
- ctrl: false,
335
- meta: false,
336
- shift: false,
337
- paste: true,
338
- sequence: pasteBuffer.toString(),
339
- });
340
- pasteBuffer = Buffer.alloc(0);
452
+ if (pasteBuffer !== null) {
453
+ broadcast({
454
+ name: '',
455
+ ctrl: false,
456
+ meta: false,
457
+ shift: false,
458
+ paste: true,
459
+ sequence: pasteBuffer.toString(),
460
+ });
461
+ }
462
+ pasteBuffer = null;
341
463
  return;
342
464
  }
343
- if (isPaste) {
465
+ if (pasteBuffer !== null) {
344
466
  pasteBuffer = Buffer.concat([pasteBuffer, Buffer.from(key.sequence)]);
345
467
  return;
346
468
  }
347
469
  if (key.sequence === SINGLE_QUOTE ||
348
470
  key.sequence === DOUBLE_QUOTE ||
349
- isDraggingRef.current) {
350
- isDraggingRef.current = true;
351
- dragBufferRef.current += key.sequence;
471
+ draggingTimer !== null) {
472
+ dragBuffer += key.sequence;
352
473
  clearDraggingTimer();
353
- draggingTimerRef.current = setTimeout(() => {
354
- isDraggingRef.current = false;
355
- const seq = dragBufferRef.current;
356
- dragBufferRef.current = '';
474
+ draggingTimer = setTimeout(() => {
475
+ draggingTimer = null;
476
+ const seq = dragBuffer;
477
+ dragBuffer = '';
357
478
  if (seq) {
358
479
  broadcast({ ...key, name: '', paste: true, sequence: seq });
359
480
  }
360
481
  }, DRAG_COMPLETION_TIMEOUT_MS);
361
482
  return;
362
483
  }
363
- const mappedLetter = ALT_KEY_CHARACTER_MAP[key.sequence];
364
- if (mappedLetter && !key.meta) {
484
+ const mappedLetter = MAC_ALT_KEY_CHARACTER_MAP[key.sequence];
485
+ if (process.platform === 'darwin' && mappedLetter && !key.meta) {
365
486
  broadcast({
366
487
  name: mappedLetter,
367
488
  ctrl: false,
368
489
  meta: true,
369
490
  shift: false,
370
- paste: isPaste,
491
+ paste: pasteBuffer !== null,
371
492
  sequence: key.sequence,
372
493
  });
373
494
  return;
374
495
  }
375
- if (key.name === 'return' && waitingForEnterAfterBackslash) {
376
- if (backslashTimeout) {
377
- clearTimeout(backslashTimeout);
378
- backslashTimeout = null;
379
- }
380
- waitingForEnterAfterBackslash = false;
496
+ if (key.name === 'return' && backslashTimeout !== null) {
497
+ clearTimeout(backslashTimeout);
498
+ backslashTimeout = null;
381
499
  broadcast({
382
500
  ...key,
383
501
  shift: true,
@@ -387,20 +505,15 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
387
505
  }
388
506
  if (key.sequence === '\\' && !key.name) {
389
507
  // Corrected escaping for backslash
390
- waitingForEnterAfterBackslash = true;
391
508
  backslashTimeout = setTimeout(() => {
392
- waitingForEnterAfterBackslash = false;
393
509
  backslashTimeout = null;
394
510
  broadcast(key);
395
511
  }, BACKSLASH_ENTER_DETECTION_WINDOW_MS);
396
512
  return;
397
513
  }
398
- if (waitingForEnterAfterBackslash && key.name !== 'return') {
399
- if (backslashTimeout) {
400
- clearTimeout(backslashTimeout);
401
- backslashTimeout = null;
402
- }
403
- waitingForEnterAfterBackslash = false;
514
+ if (backslashTimeout !== null && key.name !== 'return') {
515
+ clearTimeout(backslashTimeout);
516
+ backslashTimeout = null;
404
517
  broadcast({
405
518
  name: '',
406
519
  sequence: '\\',
@@ -416,10 +529,14 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
416
529
  }
417
530
  if ((key.ctrl && key.name === 'c') ||
418
531
  key.sequence === `${ESC}${KITTY_CTRL_C}`) {
419
- if (kittySequenceBuffer && debugKeystrokeLogging) {
420
- console.log('[DEBUG] Kitty buffer cleared on Ctrl+C:', kittySequenceBuffer);
532
+ if (inputBuffer && debugKeystrokeLogging) {
533
+ debugLogger.log('[DEBUG] Input buffer cleared on Ctrl+C:', inputBuffer);
534
+ }
535
+ inputBuffer = '';
536
+ if (inputTimeout) {
537
+ clearTimeout(inputTimeout);
538
+ inputTimeout = null;
421
539
  }
422
- kittySequenceBuffer = '';
423
540
  if (key.sequence === `${ESC}${KITTY_CTRL_C}`) {
424
541
  broadcast({
425
542
  name: 'c',
@@ -436,142 +553,209 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
436
553
  }
437
554
  return;
438
555
  }
439
- if (kittyProtocolEnabled) {
440
- if (kittySequenceBuffer ||
441
- (key.sequence.startsWith(`${ESC}[`) &&
442
- !key.sequence.startsWith(PASTE_MODE_PREFIX) &&
443
- !key.sequence.startsWith(PASTE_MODE_SUFFIX) &&
444
- !key.sequence.startsWith(FOCUS_IN) &&
445
- !key.sequence.startsWith(FOCUS_OUT))) {
446
- kittySequenceBuffer += key.sequence;
447
- if (debugKeystrokeLogging) {
448
- console.log('[DEBUG] Kitty buffer accumulating:', kittySequenceBuffer);
449
- }
450
- // Try to peel off as many complete sequences as are available at the
451
- // start of the buffer. This handles batched inputs cleanly. If the
452
- // prefix is incomplete or invalid, skip to the next CSI introducer
453
- // (ESC[) so that a following valid sequence can still be parsed.
454
- let parsedAny = false;
455
- while (kittySequenceBuffer) {
456
- const parsed = parseKittyPrefix(kittySequenceBuffer);
457
- if (!parsed) {
458
- // Look for the next potential CSI start beyond index 0
459
- const nextStart = kittySequenceBuffer.indexOf(`${ESC}[`, 1);
460
- if (nextStart > 0) {
461
- if (debugKeystrokeLogging) {
462
- console.log('[DEBUG] Skipping incomplete/invalid CSI prefix:', kittySequenceBuffer.slice(0, nextStart));
463
- }
464
- kittySequenceBuffer = kittySequenceBuffer.slice(nextStart);
465
- continue;
556
+ // Clear any pending timeout when new input arrives
557
+ if (inputTimeout) {
558
+ clearTimeout(inputTimeout);
559
+ inputTimeout = null;
560
+ }
561
+ // Always check if this could start a sequence we need to buffer (Kitty or Mouse)
562
+ // Other ESC sequences (like Alt+Key which is ESC+Key) should be let through if readline parsed them.
563
+ const shouldBuffer = couldBeKittySequence(key.sequence);
564
+ const isExcluded = [
565
+ PASTE_MODE_START,
566
+ PASTE_MODE_END,
567
+ FOCUS_IN,
568
+ FOCUS_OUT,
569
+ ].some((prefix) => key.sequence.startsWith(prefix));
570
+ if (inputBuffer || (shouldBuffer && !isExcluded)) {
571
+ inputBuffer += key.sequence;
572
+ if (debugKeystrokeLogging && !couldBeMouseSequence(inputBuffer)) {
573
+ debugLogger.log('[DEBUG] Input buffer accumulating:', JSON.stringify(inputBuffer));
574
+ }
575
+ // Try immediate parsing
576
+ let remainingBuffer = inputBuffer;
577
+ let parsedAny = false;
578
+ while (remainingBuffer) {
579
+ const parsed = parseKittyPrefix(remainingBuffer);
580
+ if (parsed) {
581
+ // If kitty protocol is disabled, only allow legacy/standard sequences.
582
+ // parseKittyPrefix returns true for kittyProtocol if it's a modern kitty sequence.
583
+ if (kittyProtocolEnabled || !parsed.key.kittyProtocol) {
584
+ if (debugKeystrokeLogging) {
585
+ const parsedSequence = remainingBuffer.slice(0, parsed.length);
586
+ debugLogger.log('[DEBUG] Sequence parsed successfully:', JSON.stringify(parsedSequence));
466
587
  }
467
- break;
588
+ broadcast(parsed.key);
589
+ remainingBuffer = remainingBuffer.slice(parsed.length);
590
+ parsedAny = true;
591
+ continue;
468
592
  }
469
- if (debugKeystrokeLogging) {
470
- const parsedSequence = kittySequenceBuffer.slice(0, parsed.length);
471
- if (kittySequenceBuffer.length > parsed.length) {
472
- console.log('[DEBUG] Kitty sequence parsed successfully (prefix):', parsedSequence);
593
+ }
594
+ const mouseParsed = parseMouseEvent(remainingBuffer);
595
+ if (mouseParsed) {
596
+ // These are handled by the separate mouse sequence parser.
597
+ // All we need to do is make sure we don't get confused by these
598
+ // sequences.
599
+ remainingBuffer = remainingBuffer.slice(mouseParsed.length);
600
+ parsedAny = true;
601
+ continue;
602
+ }
603
+ // If we can't parse a sequence at the start, check if there's
604
+ // another ESC later in the buffer. If so, the data before it
605
+ // is garbage/incomplete and should be dropped so we can
606
+ // process the next sequence.
607
+ const nextEscIndex = remainingBuffer.indexOf(ESC, 1);
608
+ if (nextEscIndex !== -1) {
609
+ const garbage = remainingBuffer.slice(0, nextEscIndex);
610
+ // Special case: if garbage is exactly ESC, it's likely a rapid ESC press.
611
+ if (garbage === ESC) {
612
+ if (debugKeystrokeLogging) {
613
+ debugLogger.log('[DEBUG] Flushing rapid ESC before next ESC:', JSON.stringify(garbage));
473
614
  }
474
- else {
475
- console.log('[DEBUG] Kitty sequence parsed successfully:', parsedSequence);
615
+ broadcast({
616
+ name: 'escape',
617
+ ctrl: false,
618
+ meta: true,
619
+ shift: false,
620
+ paste: false,
621
+ sequence: garbage,
622
+ });
623
+ }
624
+ else {
625
+ if (debugKeystrokeLogging) {
626
+ debugLogger.log('[DEBUG] Dropping incomplete sequence before next ESC:', JSON.stringify(garbage));
476
627
  }
477
628
  }
478
- // Consume the parsed prefix and broadcast it.
479
- kittySequenceBuffer = kittySequenceBuffer.slice(parsed.length);
480
- broadcast(parsed.key);
481
- parsedAny = true;
629
+ // Continue parsing from next ESC
630
+ remainingBuffer = remainingBuffer.slice(nextEscIndex);
631
+ // We made progress, so we can continue the loop to parse the next sequence
632
+ continue;
482
633
  }
483
- if (parsedAny)
484
- return;
485
- if (config?.getDebugMode() || debugKeystrokeLogging) {
486
- const codes = Array.from(kittySequenceBuffer).map((ch) => ch.charCodeAt(0));
487
- console.warn('Kitty sequence buffer has char codes:', codes);
634
+ // Check if buffer could become a valid sequence
635
+ const couldBeValidKitty = kittyProtocolEnabled && couldBeKittySequence(remainingBuffer);
636
+ const isMouse = isIncompleteMouseSequence(remainingBuffer);
637
+ const couldBeValid = couldBeValidKitty || isMouse;
638
+ if (!couldBeValid) {
639
+ // Not a valid sequence - flush as regular input immediately
640
+ if (debugKeystrokeLogging) {
641
+ debugLogger.log('[DEBUG] Not a valid sequence, flushing:', JSON.stringify(remainingBuffer));
642
+ }
643
+ broadcast({
644
+ name: '',
645
+ ctrl: false,
646
+ meta: false,
647
+ shift: false,
648
+ paste: false,
649
+ sequence: remainingBuffer,
650
+ });
651
+ remainingBuffer = '';
652
+ parsedAny = true;
488
653
  }
489
- if (kittySequenceBuffer.length > MAX_KITTY_SEQUENCE_LENGTH) {
654
+ else if (remainingBuffer.length > MAX_KITTY_SEQUENCE_LENGTH) {
655
+ // Buffer overflow - log and clear
490
656
  if (debugKeystrokeLogging) {
491
- console.log('[DEBUG] Kitty buffer overflow, clearing:', kittySequenceBuffer);
657
+ debugLogger.log('[DEBUG] Input buffer overflow, clearing:', JSON.stringify(remainingBuffer));
492
658
  }
493
- if (config) {
494
- const event = new KittySequenceOverflowEvent(kittySequenceBuffer.length, kittySequenceBuffer);
659
+ if (config && kittyProtocolEnabled) {
660
+ const event = new KittySequenceOverflowEvent(remainingBuffer.length, remainingBuffer);
495
661
  logKittySequenceOverflow(config, event);
496
662
  }
497
- kittySequenceBuffer = '';
663
+ // Flush as regular input
664
+ broadcast({
665
+ name: '',
666
+ ctrl: false,
667
+ meta: false,
668
+ shift: false,
669
+ paste: false,
670
+ sequence: remainingBuffer,
671
+ });
672
+ remainingBuffer = '';
673
+ parsedAny = true;
498
674
  }
499
675
  else {
500
- return;
676
+ if ((config?.getDebugMode() || debugKeystrokeLogging) &&
677
+ !couldBeMouseSequence(inputBuffer)) {
678
+ debugLogger.warn('Input sequence buffer has content:', JSON.stringify(inputBuffer));
679
+ }
680
+ // Could be valid but incomplete - set timeout
681
+ // Only set timeout if it's NOT a mouse sequence.
682
+ // Mouse sequences might be slow (e.g. over network) and we don't want to
683
+ // flush them as garbage keypresses.
684
+ // However, if it's just ESC or ESC[, it might be a user typing slowly,
685
+ // so we should still timeout in that case.
686
+ const isAmbiguousPrefix = remainingBuffer === ESC || remainingBuffer === `${ESC}[`;
687
+ if (!isMouse || isAmbiguousPrefix) {
688
+ inputTimeout = setTimeout(() => {
689
+ if (inputBuffer) {
690
+ if (debugKeystrokeLogging) {
691
+ debugLogger.log('[DEBUG] Input sequence timeout, flushing:', JSON.stringify(inputBuffer));
692
+ }
693
+ const isEscape = inputBuffer === ESC;
694
+ broadcast({
695
+ name: isEscape ? 'escape' : '',
696
+ ctrl: false,
697
+ meta: isEscape,
698
+ shift: false,
699
+ paste: false,
700
+ sequence: inputBuffer,
701
+ });
702
+ inputBuffer = '';
703
+ }
704
+ inputTimeout = null;
705
+ }, KITTY_SEQUENCE_TIMEOUT_MS);
706
+ }
707
+ else {
708
+ // It IS a mouse sequence and it's long enough to be unambiguously NOT just a user hitting ESC slowly.
709
+ // We just wait for more data.
710
+ if (inputTimeout) {
711
+ clearTimeout(inputTimeout);
712
+ inputTimeout = null;
713
+ }
714
+ }
715
+ break;
501
716
  }
502
717
  }
718
+ inputBuffer = remainingBuffer;
719
+ if (parsedAny || inputBuffer)
720
+ return;
503
721
  }
504
722
  if (key.name === 'return' && key.sequence === `${ESC}\r`) {
505
723
  key.meta = true;
506
724
  }
507
- broadcast({ ...key, paste: isPaste });
508
- };
509
- const handleRawKeypress = (data) => {
510
- const pasteModePrefixBuffer = Buffer.from(PASTE_MODE_PREFIX);
511
- const pasteModeSuffixBuffer = Buffer.from(PASTE_MODE_SUFFIX);
512
- let pos = 0;
513
- while (pos < data.length) {
514
- const prefixPos = data.indexOf(pasteModePrefixBuffer, pos);
515
- const suffixPos = data.indexOf(pasteModeSuffixBuffer, pos);
516
- const isPrefixNext = prefixPos !== -1 && (suffixPos === -1 || prefixPos < suffixPos);
517
- const isSuffixNext = suffixPos !== -1 && (prefixPos === -1 || suffixPos < prefixPos);
518
- let nextMarkerPos = -1;
519
- let markerLength = 0;
520
- if (isPrefixNext) {
521
- nextMarkerPos = prefixPos;
522
- }
523
- else if (isSuffixNext) {
524
- nextMarkerPos = suffixPos;
525
- }
526
- markerLength = pasteModeSuffixBuffer.length;
527
- if (nextMarkerPos === -1) {
528
- keypressStream.write(data.slice(pos));
529
- return;
530
- }
531
- const nextData = data.slice(pos, nextMarkerPos);
532
- if (nextData.length > 0) {
533
- keypressStream.write(nextData);
534
- }
535
- const createPasteKeyEvent = (name) => ({
536
- name,
537
- ctrl: false,
538
- meta: false,
539
- shift: false,
540
- paste: false,
541
- sequence: '',
542
- });
543
- if (isPrefixNext) {
544
- handleKeypress(undefined, createPasteKeyEvent('paste-start'));
545
- }
546
- else if (isSuffixNext) {
547
- handleKeypress(undefined, createPasteKeyEvent('paste-end'));
548
- }
549
- pos = nextMarkerPos + markerLength;
550
- }
725
+ broadcast({ ...key, paste: pasteBuffer !== null });
551
726
  };
727
+ let cleanup = () => { };
552
728
  let rl;
553
- if (usePassthrough) {
729
+ if (keypressStream !== null) {
554
730
  rl = readline.createInterface({
555
731
  input: keypressStream,
556
732
  escapeCodeTimeout: 0,
557
733
  });
558
734
  readline.emitKeypressEvents(keypressStream, rl);
735
+ const parser = pasteMarkerParser(keypressStream, handleKeypress);
736
+ parser.next(); // prime the generator so it starts listening.
737
+ let timeoutId;
738
+ const handleRawKeypress = (data) => {
739
+ clearTimeout(timeoutId);
740
+ parser.next(data);
741
+ timeoutId = setTimeout(() => parser.next(''), PASTE_CODE_TIMEOUT_MS);
742
+ };
559
743
  keypressStream.on('keypress', handleKeypress);
744
+ process.stdin.setEncoding('utf8'); // so handleRawKeypress gets strings
560
745
  stdin.on('data', handleRawKeypress);
746
+ cleanup = () => {
747
+ keypressStream.removeListener('keypress', handleKeypress);
748
+ stdin.removeListener('data', handleRawKeypress);
749
+ };
561
750
  }
562
751
  else {
563
752
  rl = readline.createInterface({ input: stdin, escapeCodeTimeout: 0 });
564
753
  readline.emitKeypressEvents(stdin, rl);
565
754
  stdin.on('keypress', handleKeypress);
755
+ cleanup = () => stdin.removeListener('keypress', handleKeypress);
566
756
  }
567
757
  return () => {
568
- if (usePassthrough) {
569
- keypressStream.removeListener('keypress', handleKeypress);
570
- stdin.removeListener('data', handleRawKeypress);
571
- }
572
- else {
573
- stdin.removeListener('keypress', handleKeypress);
574
- }
758
+ cleanup();
575
759
  rl.close();
576
760
  // Restore the terminal to its original state.
577
761
  if (wasRaw === false) {
@@ -581,8 +765,24 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
581
765
  clearTimeout(backslashTimeout);
582
766
  backslashTimeout = null;
583
767
  }
768
+ if (inputTimeout) {
769
+ clearTimeout(inputTimeout);
770
+ inputTimeout = null;
771
+ }
772
+ // Flush any pending kitty sequence data to avoid data loss on exit.
773
+ if (inputBuffer) {
774
+ broadcast({
775
+ name: '',
776
+ ctrl: false,
777
+ meta: false,
778
+ shift: false,
779
+ paste: false,
780
+ sequence: inputBuffer,
781
+ });
782
+ inputBuffer = '';
783
+ }
584
784
  // Flush any pending paste data to avoid data loss on exit.
585
- if (isPaste) {
785
+ if (pasteBuffer !== null) {
586
786
  broadcast({
587
787
  name: '',
588
788
  ctrl: false,
@@ -591,23 +791,19 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
591
791
  paste: true,
592
792
  sequence: pasteBuffer.toString(),
593
793
  });
594
- pasteBuffer = Buffer.alloc(0);
595
- }
596
- if (draggingTimerRef.current) {
597
- clearTimeout(draggingTimerRef.current);
598
- draggingTimerRef.current = null;
794
+ pasteBuffer = null;
599
795
  }
600
- if (isDraggingRef.current && dragBufferRef.current) {
796
+ clearDraggingTimer();
797
+ if (dragBuffer) {
601
798
  broadcast({
602
799
  name: '',
603
800
  ctrl: false,
604
801
  meta: false,
605
802
  shift: false,
606
803
  paste: true,
607
- sequence: dragBufferRef.current,
804
+ sequence: dragBuffer,
608
805
  });
609
- isDraggingRef.current = false;
610
- dragBufferRef.current = '';
806
+ dragBuffer = '';
611
807
  }
612
808
  };
613
809
  }, [
@@ -615,8 +811,8 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
615
811
  setRawMode,
616
812
  kittyProtocolEnabled,
617
813
  config,
618
- subscribers,
619
814
  debugKeystrokeLogging,
815
+ broadcast,
620
816
  ]);
621
817
  return (_jsx(KeypressContext.Provider, { value: { subscribe, unsubscribe }, children: children }));
622
818
  }