@ebowwa/coder 0.2.1 → 0.7.64

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 (401) hide show
  1. package/README.md +31 -32
  2. package/dist/core/__tests__/permissions.test.d.ts +12 -0
  3. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  4. package/dist/core/__tests__/permissions.test.js +851 -0
  5. package/dist/core/agent-loop/__tests__/compaction.test.d.ts +5 -0
  6. package/dist/core/agent-loop/__tests__/compaction.test.d.ts.map +1 -0
  7. package/dist/core/agent-loop/__tests__/compaction.test.js +209 -0
  8. package/dist/core/agent-loop/__tests__/formatters.test.d.ts +5 -0
  9. package/dist/core/agent-loop/__tests__/formatters.test.d.ts.map +1 -0
  10. package/dist/core/agent-loop/__tests__/formatters.test.js +195 -0
  11. package/dist/core/agent-loop/__tests__/index.test.d.ts +5 -0
  12. package/dist/core/agent-loop/__tests__/index.test.d.ts.map +1 -0
  13. package/dist/core/agent-loop/__tests__/index.test.js +121 -0
  14. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts +5 -0
  15. package/dist/core/agent-loop/__tests__/loop-state.test.d.ts.map +1 -0
  16. package/dist/core/agent-loop/__tests__/loop-state.test.js +340 -0
  17. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts +5 -0
  18. package/dist/core/agent-loop/__tests__/message-builder.test.d.ts.map +1 -0
  19. package/dist/core/agent-loop/__tests__/message-builder.test.js +178 -0
  20. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts +5 -0
  21. package/dist/core/agent-loop/__tests__/tool-executor.test.d.ts.map +1 -0
  22. package/dist/core/agent-loop/__tests__/tool-executor.test.js +331 -0
  23. package/dist/core/agent-loop/compaction.d.ts +39 -0
  24. package/dist/core/agent-loop/compaction.d.ts.map +1 -0
  25. package/dist/core/agent-loop/compaction.js +51 -0
  26. package/dist/core/agent-loop/formatters.d.ts +21 -0
  27. package/dist/core/agent-loop/formatters.d.ts.map +1 -0
  28. package/dist/core/agent-loop/formatters.js +42 -0
  29. package/dist/core/agent-loop/index.d.ts +25 -0
  30. package/dist/core/agent-loop/index.d.ts.map +1 -0
  31. package/dist/core/agent-loop/index.js +83 -0
  32. package/dist/core/agent-loop/loop-state.d.ts +74 -0
  33. package/dist/core/agent-loop/loop-state.d.ts.map +1 -0
  34. package/dist/core/agent-loop/loop-state.js +147 -0
  35. package/dist/core/agent-loop/message-builder.d.ts +13 -0
  36. package/dist/core/agent-loop/message-builder.d.ts.map +1 -0
  37. package/dist/core/agent-loop/message-builder.js +49 -0
  38. package/dist/core/agent-loop/tool-executor.d.ts +23 -0
  39. package/dist/core/agent-loop/tool-executor.d.ts.map +1 -0
  40. package/dist/core/agent-loop/tool-executor.js +152 -0
  41. package/dist/core/agent-loop/turn-executor.d.ts +57 -0
  42. package/dist/core/agent-loop/turn-executor.d.ts.map +1 -0
  43. package/dist/core/agent-loop/turn-executor.js +124 -0
  44. package/dist/core/agent-loop/types.d.ts +141 -0
  45. package/dist/core/agent-loop/types.d.ts.map +1 -0
  46. package/dist/core/agent-loop/types.js +4 -0
  47. package/dist/core/agent-loop.d.ts +17 -0
  48. package/dist/core/agent-loop.d.ts.map +1 -0
  49. package/dist/core/agent-loop.js +16 -0
  50. package/dist/core/api-client-impl.d.ts +62 -0
  51. package/dist/core/api-client-impl.d.ts.map +1 -0
  52. package/dist/core/api-client-impl.js +479 -0
  53. package/dist/core/api-client.d.ts +6 -0
  54. package/dist/core/api-client.d.ts.map +1 -0
  55. package/dist/core/api-client.js +5 -0
  56. package/dist/core/checkpoints.d.ts +128 -0
  57. package/dist/core/checkpoints.d.ts.map +1 -0
  58. package/dist/core/checkpoints.js +438 -0
  59. package/dist/core/claude-md.d.ts +71 -0
  60. package/dist/core/claude-md.d.ts.map +1 -0
  61. package/dist/core/claude-md.js +198 -0
  62. package/dist/core/cognitive-security/hooks.d.ts +138 -0
  63. package/dist/core/cognitive-security/hooks.d.ts.map +1 -0
  64. package/dist/core/cognitive-security/hooks.js +389 -0
  65. package/dist/core/cognitive-security/index.d.ts +751 -0
  66. package/dist/core/cognitive-security/index.d.ts.map +1 -0
  67. package/dist/core/cognitive-security/index.js +1123 -0
  68. package/dist/core/cognitive-security/middleware.d.ts +136 -0
  69. package/dist/core/cognitive-security/middleware.d.ts.map +1 -0
  70. package/dist/core/cognitive-security/middleware.js +376 -0
  71. package/dist/core/config-loader.d.ts +127 -0
  72. package/dist/core/config-loader.d.ts.map +1 -0
  73. package/dist/core/config-loader.js +219 -0
  74. package/dist/core/context-compaction.d.ts +87 -0
  75. package/dist/core/context-compaction.d.ts.map +1 -0
  76. package/dist/core/context-compaction.js +428 -0
  77. package/dist/core/git-status.d.ts +25 -0
  78. package/dist/core/git-status.d.ts.map +1 -0
  79. package/dist/core/git-status.js +204 -0
  80. package/dist/core/image.d.ts +69 -0
  81. package/dist/core/image.d.ts.map +1 -0
  82. package/dist/core/image.js +290 -0
  83. package/dist/core/image.test.d.ts +2 -0
  84. package/dist/core/image.test.d.ts.map +1 -0
  85. package/dist/core/image.test.js +149 -0
  86. package/dist/core/models.d.ts +123 -0
  87. package/dist/core/models.d.ts.map +1 -0
  88. package/dist/core/models.js +325 -0
  89. package/dist/core/permissions.d.ts +81 -0
  90. package/dist/core/permissions.d.ts.map +1 -0
  91. package/dist/core/permissions.js +327 -0
  92. package/dist/core/retry.d.ts +25 -0
  93. package/dist/core/retry.d.ts.map +1 -0
  94. package/dist/core/retry.js +121 -0
  95. package/dist/core/session-store.d.ts +9 -0
  96. package/dist/core/session-store.d.ts.map +1 -0
  97. package/dist/core/session-store.js +10 -0
  98. package/dist/core/sessions/export.d.ts +47 -0
  99. package/dist/core/sessions/export.d.ts.map +1 -0
  100. package/dist/core/sessions/export.js +256 -0
  101. package/dist/core/sessions/index.d.ts +132 -0
  102. package/dist/core/sessions/index.d.ts.map +1 -0
  103. package/dist/core/sessions/index.js +442 -0
  104. package/dist/core/sessions/metadata.d.ts +77 -0
  105. package/dist/core/sessions/metadata.d.ts.map +1 -0
  106. package/dist/core/sessions/metadata.js +233 -0
  107. package/dist/core/sessions/persistence.d.ts +72 -0
  108. package/dist/core/sessions/persistence.d.ts.map +1 -0
  109. package/dist/core/sessions/persistence.js +201 -0
  110. package/dist/core/sessions/types.d.ts +110 -0
  111. package/dist/core/sessions/types.d.ts.map +1 -0
  112. package/dist/core/sessions/types.js +4 -0
  113. package/dist/core/stream-highlighter.d.ts +18 -0
  114. package/dist/core/stream-highlighter.d.ts.map +1 -0
  115. package/dist/core/stream-highlighter.js +916 -0
  116. package/dist/core/system-reminders.d.ts +89 -0
  117. package/dist/core/system-reminders.d.ts.map +1 -0
  118. package/dist/core/system-reminders.js +285 -0
  119. package/dist/ecosystem/hooks/__tests__/index.test.d.ts +5 -0
  120. package/dist/ecosystem/hooks/__tests__/index.test.d.ts.map +1 -0
  121. package/dist/ecosystem/hooks/__tests__/index.test.js +458 -0
  122. package/dist/ecosystem/hooks/index.d.ts +59 -0
  123. package/dist/ecosystem/hooks/index.d.ts.map +1 -0
  124. package/dist/ecosystem/hooks/index.js +294 -0
  125. package/dist/ecosystem/hooks/prompt-evaluator.d.ts +32 -0
  126. package/dist/ecosystem/hooks/prompt-evaluator.d.ts.map +1 -0
  127. package/dist/ecosystem/hooks/prompt-evaluator.js +229 -0
  128. package/dist/ecosystem/skills/index.d.ts +55 -0
  129. package/dist/ecosystem/skills/index.d.ts.map +1 -0
  130. package/dist/ecosystem/skills/index.js +258 -0
  131. package/dist/ecosystem/tools/__tests__/index.test.d.ts +7 -0
  132. package/dist/ecosystem/tools/__tests__/index.test.d.ts.map +1 -0
  133. package/dist/ecosystem/tools/__tests__/index.test.js +856 -0
  134. package/dist/ecosystem/tools/index.d.ts +24 -0
  135. package/dist/ecosystem/tools/index.d.ts.map +1 -0
  136. package/dist/ecosystem/tools/index.js +1709 -0
  137. package/dist/index.d.ts +24 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +32 -2
  140. package/dist/interfaces/mcp/client.d.ts +40 -0
  141. package/dist/interfaces/mcp/client.d.ts.map +1 -0
  142. package/dist/interfaces/mcp/client.js +309 -0
  143. package/dist/interfaces/ui/index.d.ts +36 -0
  144. package/dist/interfaces/ui/index.d.ts.map +1 -0
  145. package/dist/interfaces/ui/index.js +61 -0
  146. package/dist/interfaces/ui/spinner.d.ts +140 -0
  147. package/dist/interfaces/ui/spinner.d.ts.map +1 -0
  148. package/dist/interfaces/ui/spinner.js +342 -0
  149. package/dist/interfaces/ui/terminal/cli/index.d.ts +12 -0
  150. package/dist/interfaces/ui/terminal/cli/index.d.ts.map +1 -0
  151. package/dist/interfaces/ui/terminal/cli/index.js +167 -0
  152. package/dist/interfaces/ui/terminal/shared/args.d.ts +39 -0
  153. package/dist/interfaces/ui/terminal/shared/args.d.ts.map +1 -0
  154. package/dist/interfaces/ui/terminal/shared/args.js +176 -0
  155. package/dist/interfaces/ui/terminal/shared/index.d.ts +11 -0
  156. package/dist/interfaces/ui/terminal/shared/index.d.ts.map +1 -0
  157. package/dist/interfaces/ui/terminal/shared/index.js +16 -0
  158. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts +124 -0
  159. package/dist/interfaces/ui/terminal/shared/loading-state.d.ts.map +1 -0
  160. package/dist/interfaces/ui/terminal/shared/loading-state.js +246 -0
  161. package/dist/interfaces/ui/terminal/shared/query.d.ts +22 -0
  162. package/dist/interfaces/ui/terminal/shared/query.d.ts.map +1 -0
  163. package/dist/interfaces/ui/terminal/shared/query.js +100 -0
  164. package/dist/interfaces/ui/terminal/shared/setup.d.ts +33 -0
  165. package/dist/interfaces/ui/terminal/shared/setup.d.ts.map +1 -0
  166. package/dist/interfaces/ui/terminal/shared/setup.js +226 -0
  167. package/dist/interfaces/ui/terminal/shared/status-line.d.ts +117 -0
  168. package/dist/interfaces/ui/terminal/shared/status-line.d.ts.map +1 -0
  169. package/dist/interfaces/ui/terminal/shared/status-line.js +267 -0
  170. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts +38 -0
  171. package/dist/interfaces/ui/terminal/shared/system-prompt.d.ts.map +1 -0
  172. package/dist/interfaces/ui/terminal/shared/system-prompt.js +102 -0
  173. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts +39 -0
  174. package/dist/interfaces/ui/terminal/tui/HelpPanel.d.ts.map +1 -0
  175. package/dist/interfaces/ui/terminal/tui/HelpPanel.js +215 -0
  176. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts +91 -0
  177. package/dist/interfaces/ui/terminal/tui/InputContext.d.ts.map +1 -0
  178. package/dist/interfaces/ui/terminal/tui/InputContext.js +154 -0
  179. package/dist/interfaces/ui/terminal/tui/InputField.d.ts +18 -0
  180. package/dist/interfaces/ui/terminal/tui/InputField.d.ts.map +1 -0
  181. package/dist/interfaces/ui/terminal/tui/InputField.js +41 -0
  182. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts +16 -0
  183. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.d.ts.map +1 -0
  184. package/dist/interfaces/ui/terminal/tui/InteractiveTUI.js +451 -0
  185. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts +10 -0
  186. package/dist/interfaces/ui/terminal/tui/MessageArea.d.ts.map +1 -0
  187. package/dist/interfaces/ui/terminal/tui/MessageArea.js +91 -0
  188. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts +48 -0
  189. package/dist/interfaces/ui/terminal/tui/MessageStore.d.ts.map +1 -0
  190. package/dist/interfaces/ui/terminal/tui/MessageStore.js +151 -0
  191. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts +9 -0
  192. package/dist/interfaces/ui/terminal/tui/StatusBar.d.ts.map +1 -0
  193. package/dist/interfaces/ui/terminal/tui/StatusBar.js +36 -0
  194. package/dist/interfaces/ui/terminal/tui/commands.d.ts +21 -0
  195. package/dist/interfaces/ui/terminal/tui/commands.d.ts.map +1 -0
  196. package/dist/interfaces/ui/terminal/tui/commands.js +359 -0
  197. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts +115 -0
  198. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.d.ts.map +1 -0
  199. package/dist/interfaces/ui/terminal/tui/components/InteractiveElements.js +306 -0
  200. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts +92 -0
  201. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.d.ts.map +1 -0
  202. package/dist/interfaces/ui/terminal/tui/components/MultilineInput.js +399 -0
  203. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts +59 -0
  204. package/dist/interfaces/ui/terminal/tui/components/PaneManager.d.ts.map +1 -0
  205. package/dist/interfaces/ui/terminal/tui/components/PaneManager.js +139 -0
  206. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts +68 -0
  207. package/dist/interfaces/ui/terminal/tui/components/Sidebar.d.ts.map +1 -0
  208. package/dist/interfaces/ui/terminal/tui/components/Sidebar.js +340 -0
  209. package/dist/interfaces/ui/terminal/tui/components/index.d.ts +23 -0
  210. package/dist/interfaces/ui/terminal/tui/components/index.d.ts.map +1 -0
  211. package/dist/interfaces/ui/terminal/tui/components/index.js +51 -0
  212. package/dist/interfaces/ui/terminal/tui/console.d.ts +20 -0
  213. package/dist/interfaces/ui/terminal/tui/console.d.ts.map +1 -0
  214. package/dist/interfaces/ui/terminal/tui/console.js +46 -0
  215. package/dist/interfaces/ui/terminal/tui/index.d.ts +20 -0
  216. package/dist/interfaces/ui/terminal/tui/index.d.ts.map +1 -0
  217. package/dist/interfaces/ui/terminal/tui/index.js +28 -0
  218. package/dist/interfaces/ui/terminal/tui/run.d.ts +13 -0
  219. package/dist/interfaces/ui/terminal/tui/run.d.ts.map +1 -0
  220. package/dist/interfaces/ui/terminal/tui/run.js +31 -0
  221. package/dist/interfaces/ui/terminal/tui/spinner.d.ts +44 -0
  222. package/dist/interfaces/ui/terminal/tui/spinner.d.ts.map +1 -0
  223. package/dist/interfaces/ui/terminal/tui/spinner.js +59 -0
  224. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts +39 -0
  225. package/dist/interfaces/ui/terminal/tui/tui-app.d.ts.map +1 -0
  226. package/dist/interfaces/ui/terminal/tui/tui-app.js +198 -0
  227. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts +167 -0
  228. package/dist/interfaces/ui/terminal/tui/tui-footer.d.ts.map +1 -0
  229. package/dist/interfaces/ui/terminal/tui/tui-footer.js +330 -0
  230. package/dist/interfaces/ui/terminal/tui/types.d.ts +165 -0
  231. package/dist/interfaces/ui/terminal/tui/types.d.ts.map +1 -0
  232. package/dist/interfaces/ui/terminal/tui/types.js +5 -0
  233. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts +23 -0
  234. package/dist/interfaces/ui/terminal/tui/useInputHandler.d.ts.map +1 -0
  235. package/dist/interfaces/ui/terminal/tui/useInputHandler.js +72 -0
  236. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts +90 -0
  237. package/dist/interfaces/ui/terminal/tui/useNativeInput.d.ts.map +1 -0
  238. package/dist/interfaces/ui/terminal/tui/useNativeInput.js +188 -0
  239. package/dist/native/index.d.ts +480 -0
  240. package/dist/native/index.d.ts.map +1 -0
  241. package/dist/native/index.js +1625 -0
  242. package/dist/teammates/index.d.ts +161 -0
  243. package/dist/teammates/index.d.ts.map +1 -0
  244. package/dist/teammates/index.js +827 -0
  245. package/dist/types/index.d.ts +482 -0
  246. package/dist/types/index.d.ts.map +1 -0
  247. package/dist/types/index.js +52 -0
  248. package/native/README.md +5 -5
  249. package/native/index.darwin-arm64.node +0 -0
  250. package/native/index.node +0 -0
  251. package/native/package.json +4 -4
  252. package/package.json +33 -16
  253. package/packages/src/core/__tests__/permissions.test.ts +1091 -0
  254. package/packages/src/core/agent-loop/__tests__/compaction.test.ts +280 -0
  255. package/packages/src/core/agent-loop/__tests__/formatters.test.ts +234 -0
  256. package/packages/src/core/agent-loop/__tests__/index.test.ts +162 -0
  257. package/packages/src/core/agent-loop/__tests__/loop-state.test.ts +413 -0
  258. package/packages/src/core/agent-loop/__tests__/message-builder.test.ts +229 -0
  259. package/packages/src/core/agent-loop/__tests__/tool-executor.test.ts +457 -0
  260. package/packages/src/core/agent-loop/compaction.ts +88 -0
  261. package/packages/src/core/agent-loop/formatters.ts +50 -0
  262. package/packages/src/core/agent-loop/index.ts +135 -0
  263. package/packages/src/core/agent-loop/loop-state.ts +187 -0
  264. package/packages/src/core/agent-loop/message-builder.ts +62 -0
  265. package/packages/src/core/agent-loop/tool-executor.ts +211 -0
  266. package/packages/src/core/agent-loop/turn-executor.ts +222 -0
  267. package/packages/src/core/agent-loop/types.ts +148 -0
  268. package/packages/src/core/agent-loop.ts +18 -0
  269. package/packages/src/core/api-client-impl.ts +619 -0
  270. package/packages/src/core/api-client.ts +6 -0
  271. package/packages/src/core/checkpoints.ts +606 -0
  272. package/packages/src/core/claude-md.ts +272 -0
  273. package/packages/src/core/cognitive-security/hooks.ts +590 -0
  274. package/packages/src/core/cognitive-security/index.ts +2041 -0
  275. package/packages/src/core/cognitive-security/middleware.ts +536 -0
  276. package/packages/src/core/config-loader.ts +324 -0
  277. package/packages/src/core/context-compaction.ts +578 -0
  278. package/packages/src/core/git-status.ts +262 -0
  279. package/packages/src/core/image.test.ts +180 -0
  280. package/packages/src/core/image.ts +350 -0
  281. package/packages/src/core/lmdb.db +0 -0
  282. package/packages/src/core/lmdb.db-lock +0 -0
  283. package/packages/src/core/models.ts +430 -0
  284. package/packages/src/core/normalizers/todo +4 -0
  285. package/packages/src/core/permissions.ts +431 -0
  286. package/packages/src/core/retry.ts +170 -0
  287. package/packages/src/core/session-store.ts +36 -0
  288. package/packages/src/core/sessions/export.ts +329 -0
  289. package/packages/src/core/sessions/index.ts +587 -0
  290. package/packages/src/core/sessions/metadata.ts +309 -0
  291. package/packages/src/core/sessions/persistence.ts +244 -0
  292. package/packages/src/core/sessions/types.ts +169 -0
  293. package/packages/src/core/stream-highlighter.ts +1123 -0
  294. package/packages/src/core/system-reminders.ts +402 -0
  295. package/packages/src/core/todo +8 -0
  296. package/packages/src/ecosystem/hooks/__tests__/index.test.ts +561 -0
  297. package/packages/src/ecosystem/hooks/index.ts +341 -0
  298. package/packages/src/ecosystem/hooks/prompt-evaluator.ts +300 -0
  299. package/packages/src/ecosystem/skills/index.ts +295 -0
  300. package/packages/src/ecosystem/tools/__tests__/index.test.ts +1335 -0
  301. package/packages/src/ecosystem/tools/index.ts +1877 -0
  302. package/packages/src/index.ts +120 -0
  303. package/packages/src/interfaces/mcp/client.ts +389 -0
  304. package/packages/src/interfaces/ui/Screenshot 2026-03-02 at 9.23.10/342/200/257PM.png +0 -0
  305. package/packages/src/interfaces/ui/Screenshot 2026-03-03 at 10.55.11/342/200/257AM.png +0 -0
  306. package/packages/src/interfaces/ui/index.ts +161 -0
  307. package/packages/src/interfaces/ui/lmdb.db +0 -0
  308. package/packages/src/interfaces/ui/lmdb.db-lock +0 -0
  309. package/packages/src/interfaces/ui/spinner.ts +451 -0
  310. package/packages/src/interfaces/ui/terminal/cli/index.ts +228 -0
  311. package/packages/src/interfaces/ui/terminal/lmdb.db +0 -0
  312. package/packages/src/interfaces/ui/terminal/lmdb.db-lock +0 -0
  313. package/packages/src/interfaces/ui/terminal/shared/args.ts +222 -0
  314. package/packages/src/interfaces/ui/terminal/shared/index.ts +71 -0
  315. package/packages/src/interfaces/ui/terminal/shared/loading-state.ts +322 -0
  316. package/packages/src/interfaces/ui/terminal/shared/query.ts +146 -0
  317. package/packages/src/interfaces/ui/terminal/shared/setup.ts +295 -0
  318. package/packages/src/interfaces/ui/terminal/shared/status-line.ts +358 -0
  319. package/packages/src/interfaces/ui/terminal/shared/system-prompt.ts +146 -0
  320. package/packages/src/interfaces/ui/terminal/tui/HelpPanel.tsx +262 -0
  321. package/packages/src/interfaces/ui/terminal/tui/InputContext.tsx +232 -0
  322. package/packages/src/interfaces/ui/terminal/tui/InputField.tsx +62 -0
  323. package/packages/src/interfaces/ui/terminal/tui/InteractiveTUI.tsx +537 -0
  324. package/packages/src/interfaces/ui/terminal/tui/MessageArea.tsx +107 -0
  325. package/packages/src/interfaces/ui/terminal/tui/MessageStore.tsx +240 -0
  326. package/packages/src/interfaces/ui/terminal/tui/StatusBar.tsx +54 -0
  327. package/packages/src/interfaces/ui/terminal/tui/commands.ts +438 -0
  328. package/packages/src/interfaces/ui/terminal/tui/components/InteractiveElements.tsx +584 -0
  329. package/packages/src/interfaces/ui/terminal/tui/components/MultilineInput.tsx +614 -0
  330. package/packages/src/interfaces/ui/terminal/tui/components/PaneManager.tsx +333 -0
  331. package/packages/src/interfaces/ui/terminal/tui/components/Sidebar.tsx +604 -0
  332. package/packages/src/interfaces/ui/terminal/tui/components/index.ts +118 -0
  333. package/packages/src/interfaces/ui/terminal/tui/console.ts +49 -0
  334. package/packages/src/interfaces/ui/terminal/tui/index.ts +90 -0
  335. package/packages/src/interfaces/ui/terminal/tui/run.tsx +42 -0
  336. package/packages/src/interfaces/ui/terminal/tui/spinner.ts +69 -0
  337. package/packages/src/interfaces/ui/terminal/tui/tui-app.tsx +390 -0
  338. package/packages/src/interfaces/ui/terminal/tui/tui-footer.ts +422 -0
  339. package/packages/src/interfaces/ui/terminal/tui/types.ts +186 -0
  340. package/packages/src/interfaces/ui/terminal/tui/useInputHandler.ts +104 -0
  341. package/packages/src/interfaces/ui/terminal/tui/useNativeInput.ts +239 -0
  342. package/packages/src/lmdb.db +0 -0
  343. package/packages/src/lmdb.db-lock +0 -0
  344. package/packages/src/native/index.ts +2345 -0
  345. package/packages/src/teammates/index.ts +982 -0
  346. package/packages/src/types/index.ts +722 -0
  347. package/dist/cli.js +0 -148
  348. package/dist/index-0pkak453.js +0 -136
  349. package/dist/index-0qd0x8b4.js +0 -110
  350. package/dist/index-0x3kprq6.js +0 -240
  351. package/dist/index-1eawy937.js +0 -308
  352. package/dist/index-24m2aygy.js +0 -240
  353. package/dist/index-29xcjnne.js +0 -280
  354. package/dist/index-2avyytn5.js +0 -349
  355. package/dist/index-4ms367ey.js +0 -136
  356. package/dist/index-4w2t3b0m.js +0 -240
  357. package/dist/index-4xfgd8nz.js +0 -261
  358. package/dist/index-5acjp9gc.js +0 -157
  359. package/dist/index-5s15hr56.js +0 -136
  360. package/dist/index-6e4wf341.js +0 -349
  361. package/dist/index-6fvnkedw.js +0 -240
  362. package/dist/index-6rqpmd4g.js +0 -128
  363. package/dist/index-77ckwnbm.js +0 -280
  364. package/dist/index-9knxy49k.js +0 -128
  365. package/dist/index-9zrnw4zx.js +0 -128
  366. package/dist/index-bk21w99v.js +0 -280
  367. package/dist/index-c41n76fv.js +0 -240
  368. package/dist/index-cb4ppjdt.js +0 -255
  369. package/dist/index-cfb2edt6.js +0 -240
  370. package/dist/index-cmfa38hh.js +0 -308
  371. package/dist/index-datjz8q1.js +0 -257
  372. package/dist/index-eadf4wvn.js +0 -240
  373. package/dist/index-em5k0m3z.js +0 -345
  374. package/dist/index-gh8r333a.js +0 -110
  375. package/dist/index-gkx6k2tr.js +0 -261
  376. package/dist/index-h5cabfks.js +0 -155
  377. package/dist/index-hcrpwyy3.js +0 -261
  378. package/dist/index-hk7fwwa8.js +0 -257
  379. package/dist/index-jb8cw7f8.js +0 -136
  380. package/dist/index-kbyw4th1.js +0 -347
  381. package/dist/index-kgj5gqnm.js +0 -345
  382. package/dist/index-mdf6xp1z.js +0 -255
  383. package/dist/index-mrhv8kvc.js +0 -280
  384. package/dist/index-mt4743dd.js +0 -161
  385. package/dist/index-qnwsg97q.js +0 -240
  386. package/dist/index-qwdy6x44.js +0 -261
  387. package/dist/index-rmj77261.js +0 -157
  388. package/dist/index-sbbw1a61.js +0 -349
  389. package/dist/index-svy5bcpn.js +0 -345
  390. package/dist/index-tvmy7tm9.js +0 -261
  391. package/dist/index-tzz4vzkj.js +0 -312
  392. package/dist/index-vz80zmhe.js +0 -110
  393. package/dist/index-wed2fk67.js +0 -240
  394. package/dist/index-wksgzz8e.js +0 -280
  395. package/dist/index-wn2m4wma.js +0 -240
  396. package/dist/index-xha05vjc.js +0 -257
  397. package/dist/index-yc6eh8p8.js +0 -136
  398. package/dist/index-ycjxx9ft.js +0 -240
  399. package/dist/index-z0gzd0fc.js +0 -110
  400. package/dist/index-z8cwtf8j.js +0 -240
  401. package/dist/index-zy5mtt00.js +0 -128
@@ -0,0 +1,614 @@
1
+ /** @jsx React.createElement */
2
+ /**
3
+ * Multiline Input Component
4
+ * Enhanced text input with:
5
+ * - Multi-line support (Ctrl+Enter for newline)
6
+ * - Command autocomplete
7
+ * - Input history navigation
8
+ * - Syntax highlighting for input
9
+ */
10
+
11
+ import React, { useState, useCallback, useRef, useEffect } from "react";
12
+ import { Box, Text, useStdout } from "ink";
13
+
14
+ // ============================================
15
+ // TYPES
16
+ // ============================================
17
+
18
+ export interface AutocompleteSuggestion {
19
+ id: string;
20
+ label: string;
21
+ description?: string;
22
+ category?: string;
23
+ }
24
+
25
+ export interface MultilineInputProps {
26
+ /** Current input value */
27
+ value: string;
28
+ /** Cursor position (0 = start) */
29
+ cursorPos: number;
30
+ /** Current line for multiline (0-based) */
31
+ currentLine?: number;
32
+ /** Placeholder text */
33
+ placeholder?: string;
34
+ /** Whether input is active */
35
+ isActive?: boolean;
36
+ /** Whether to show autocomplete */
37
+ showAutocomplete?: boolean;
38
+ /** Autocomplete suggestions */
39
+ autocompleteSuggestions?: AutocompleteSuggestion[];
40
+ /** Selected autocomplete index */
41
+ autocompleteIndex?: number;
42
+ /** Input history for navigation */
43
+ inputHistory?: string[];
44
+ /** History index (-1 = none) */
45
+ historyIndex?: number;
46
+ /** Called when input changes */
47
+ onChange?: (value: string, cursorPos: number, currentLine: number) => void;
48
+ /** Called when submit (Enter on single line, Ctrl+Enter on multiline) */
49
+ onSubmit?: (value: string) => void;
50
+ /** Called when requesting autocomplete */
51
+ onRequestAutocomplete?: (prefix: string) => AutocompleteSuggestion[];
52
+ /** Max lines before scrolling */
53
+ maxLines?: number;
54
+ /** Show line numbers */
55
+ showLineNumbers?: boolean;
56
+ /** Width override */
57
+ width?: number;
58
+ }
59
+
60
+ export interface MultilineInputState {
61
+ value: string;
62
+ cursorPos: number;
63
+ currentLine: number;
64
+ historyIndex: number;
65
+ savedInput: string;
66
+ showAutocomplete: boolean;
67
+ autocompleteSuggestions: AutocompleteSuggestion[];
68
+ autocompleteIndex: number;
69
+ }
70
+
71
+ export interface UseMultilineInputOptions {
72
+ isActive?: boolean;
73
+ onSubmit?: (value: string) => void;
74
+ onRequestAutocomplete?: (prefix: string) => AutocompleteSuggestion[];
75
+ inputHistory?: string[];
76
+ initialHistory?: string[];
77
+ }
78
+
79
+ // ============================================
80
+ // COMMAND AUTOCOMPLETE DEFINITIONS
81
+ // ============================================
82
+
83
+ const COMMAND_SUGGESTIONS: AutocompleteSuggestion[] = [
84
+ // Session commands
85
+ { id: "/help", label: "/help", description: "Show help", category: "session" },
86
+ { id: "/exit", label: "/exit", description: "Exit session", category: "session" },
87
+ { id: "/new", label: "/new", description: "Start new session", category: "session" },
88
+ { id: "/clear", label: "/clear", description: "Clear conversation", category: "session" },
89
+ { id: "/status", label: "/status", description: "Show session status", category: "session" },
90
+ { id: "/cost", label: "/cost", description: "Show total cost", category: "session" },
91
+
92
+ // Model commands
93
+ { id: "/model", label: "/model", description: "Switch model", category: "model" },
94
+ { id: "/models", label: "/models", description: "List available models", category: "model" },
95
+ { id: "/tools", label: "/tools", description: "List available tools", category: "model" },
96
+
97
+ // Context commands
98
+ { id: "/compact", label: "/compact", description: "Force context compaction", category: "context" },
99
+ { id: "/export", label: "/export", description: "Export session", category: "context" },
100
+ { id: "/checkpoint", label: "/checkpoint", description: "Save checkpoint", category: "context" },
101
+ { id: "/checkpoints", label: "/checkpoints", description: "List checkpoints", category: "context" },
102
+ { id: "/restore", label: "/restore", description: "Restore checkpoint", category: "context" },
103
+ { id: "/undo", label: "/undo", description: "Undo last action", category: "context" },
104
+ { id: "/redo", label: "/redo", description: "Redo action", category: "context" },
105
+
106
+ // Session management
107
+ { id: "/resume", label: "/resume", description: "Resume session", category: "sessions" },
108
+ { id: "/sessions", label: "/sessions", description: "List sessions", category: "sessions" },
109
+ ];
110
+
111
+ /**
112
+ * Filter autocomplete suggestions based on prefix
113
+ */
114
+ export function filterSuggestions(prefix: string): AutocompleteSuggestion[] {
115
+ if (!prefix || !prefix.startsWith("/")) {
116
+ return [];
117
+ }
118
+
119
+ const query = prefix.toLowerCase();
120
+ return COMMAND_SUGGESTIONS.filter((cmd) => {
121
+ return (
122
+ cmd.id.toLowerCase().startsWith(query) ||
123
+ cmd.label.toLowerCase().includes(query) ||
124
+ (cmd.description?.toLowerCase().includes(query) ?? false)
125
+ );
126
+ }).slice(0, 5);
127
+ }
128
+
129
+ /**
130
+ * Syntax highlight code block
131
+ * Returns highlighted segments for display
132
+ */
133
+ export function highlightSyntax(
134
+ text: string
135
+ ): Array<{ text: string; color: string }> {
136
+ const segments: Array<{ text: string; color: string }> = [];
137
+
138
+ // Code block detection (``` ... ```)
139
+ const codeBlockRegex = /```[\s\S]*?```/g;
140
+
141
+ // Keywords
142
+ const keywords =
143
+ /\b(const|let|var|function|return|if|else|for|while|class|interface|type|import|export|from|async|await)\b/g;
144
+
145
+ // Strings
146
+ const strings = /(["'`])(?:(?!\1)[\s\S])*?\1/g;
147
+
148
+ // Numbers
149
+ const numbers = /\b(\d+\.?\d*)\b/g;
150
+
151
+ // Comments
152
+ const comments = /(\/\/.*$|\/\*[\s\S]*?\*\/|#.*$)/gm;
153
+
154
+ // Check for code blocks first
155
+ if (codeBlockRegex.test(text)) {
156
+ segments.push({ text, color: "green" });
157
+ return segments;
158
+ }
159
+
160
+ // Otherwise return as-is
161
+ segments.push({ text, color: "white" });
162
+ return segments;
163
+ }
164
+
165
+ // ============================================
166
+ // MULTILINE INPUT COMPONENT
167
+ // ============================================
168
+
169
+ export function MultilineInput({
170
+ value,
171
+ cursorPos,
172
+ currentLine = 0,
173
+ placeholder = "Type your message... (/help for commands)",
174
+ isActive = true,
175
+ showAutocomplete = false,
176
+ autocompleteSuggestions = [],
177
+ autocompleteIndex = 0,
178
+ inputHistory = [],
179
+ historyIndex = -1,
180
+ onChange,
181
+ onSubmit,
182
+ maxLines = 5,
183
+ showLineNumbers = false,
184
+ width: propWidth,
185
+ }: MultilineInputProps) {
186
+ const { stdout } = useStdout();
187
+ const width = propWidth ?? stdout.columns ?? 80;
188
+
189
+ // Split value into lines
190
+ const lines = value.split("\n");
191
+ const displayLines = lines.slice(-maxLines);
192
+
193
+ // Calculate cursor display position
194
+ const cursorLineIndex = Math.min(currentLine, displayLines.length - 1);
195
+ const currentLineText = displayLines[cursorLineIndex] ?? "";
196
+ const cursorColInLine = cursorPos;
197
+
198
+ // Build line display
199
+ const renderLines = displayLines.map((line, i) => {
200
+ const lineNum = showLineNumbers
201
+ ? `${String(lines.length - displayLines.length + i + 1).padStart(3, " ")} `
202
+ : "";
203
+ const isCurrentLine = i === cursorLineIndex;
204
+
205
+ if (isCurrentLine) {
206
+ const beforeCursor = line.slice(0, cursorColInLine);
207
+ const cursorChar = line[cursorColInLine] ?? " ";
208
+ const afterCursor = line.slice(cursorColInLine + 1);
209
+
210
+ return (
211
+ <Box key={i}>
212
+ <Text dimColor>{lineNum}</Text>
213
+ <Text>{beforeCursor}</Text>
214
+ <Text backgroundColor="cyan" color="black">
215
+ {cursorChar}
216
+ </Text>
217
+ <Text>{afterCursor}</Text>
218
+ </Box>
219
+ );
220
+ }
221
+
222
+ return (
223
+ <Box key={i}>
224
+ <Text dimColor>{lineNum}</Text>
225
+ <Text dimColor={line.length === 0}>{line || " "}</Text>
226
+ </Box>
227
+ );
228
+ });
229
+
230
+ // Render autocomplete dropdown
231
+ const renderAutocomplete = () => {
232
+ if (!showAutocomplete || autocompleteSuggestions.length === 0) {
233
+ return null;
234
+ }
235
+
236
+ return (
237
+ <Box
238
+ flexDirection="column"
239
+ borderStyle="round"
240
+ borderColor="yellow"
241
+ paddingX={1}
242
+ marginTop={1}
243
+ >
244
+ <Text dimColor>Suggestions (Tab to select):</Text>
245
+ {autocompleteSuggestions.map((suggestion, i) => (
246
+ <Box key={suggestion.id}>
247
+ <Text
248
+ color={i === autocompleteIndex ? "yellow" : "white"}
249
+ bold={i === autocompleteIndex}
250
+ >
251
+ {suggestion.label}
252
+ </Text>
253
+ {suggestion.description && (
254
+ <Text dimColor> - {suggestion.description}</Text>
255
+ )}
256
+ </Box>
257
+ ))}
258
+ </Box>
259
+ );
260
+ };
261
+
262
+ // Line indicator
263
+ const lineIndicator =
264
+ lines.length > 1 ? (
265
+ <Text dimColor> [Line {currentLine + 1}/{lines.length}]</Text>
266
+ ) : null;
267
+
268
+ return (
269
+ <Box
270
+ flexDirection="column"
271
+ width="100%"
272
+ borderStyle="round"
273
+ borderColor={isActive ? "cyan" : "gray"}
274
+ paddingX={1}
275
+ >
276
+ {/* Input prompt */}
277
+ <Box>
278
+ <Text bold color="cyan">
279
+ You:
280
+ </Text>
281
+ {lineIndicator}
282
+ </Box>
283
+
284
+ {/* Multiline content */}
285
+ <Box flexDirection="column">
286
+ {lines.length === 0 || (lines.length === 1 && lines[0] === "") ? (
287
+ <Text dimColor>{placeholder}</Text>
288
+ ) : (
289
+ renderLines
290
+ )}
291
+ </Box>
292
+
293
+ {/* Autocomplete dropdown */}
294
+ {renderAutocomplete()}
295
+
296
+ {/* Footer hints */}
297
+ <Box marginTop={1}>
298
+ <Text dimColor>
299
+ Ctrl+Enter: newline | up/down: history | Tab: autocomplete
300
+ </Text>
301
+ </Box>
302
+ </Box>
303
+ );
304
+ }
305
+
306
+ // ============================================
307
+ // INPUT HANDLER HOOK
308
+ // ============================================
309
+
310
+ export function useMultilineInputHandler({
311
+ isActive = true,
312
+ onSubmit,
313
+ onRequestAutocomplete,
314
+ inputHistory = [],
315
+ }: UseMultilineInputOptions) {
316
+ const [state, setState] = useState<MultilineInputState>({
317
+ value: "",
318
+ cursorPos: 0,
319
+ currentLine: 0,
320
+ historyIndex: -1,
321
+ savedInput: "",
322
+ showAutocomplete: false,
323
+ autocompleteSuggestions: [],
324
+ autocompleteIndex: 0,
325
+ });
326
+
327
+ const handleKeyEvent = useCallback(
328
+ (event: { code: string; ctrl?: boolean; shift?: boolean }) => {
329
+ if (!isActive) return "unhandled";
330
+
331
+ const { code, ctrl, shift } = event;
332
+
333
+ // Update helper
334
+ const update = (updates: Partial<MultilineInputState>) => {
335
+ setState((prev) => ({ ...prev, ...updates }));
336
+ };
337
+
338
+ // Get current state
339
+ const { value, cursorPos, currentLine, historyIndex, showAutocomplete } =
340
+ state;
341
+
342
+ // Split into lines for calculations
343
+ const lines = value.split("\n");
344
+
345
+ // Autocomplete navigation
346
+ if (showAutocomplete) {
347
+ if (code === "tab" || code === "down") {
348
+ const suggestions = state.autocompleteSuggestions;
349
+ const newIndex =
350
+ (state.autocompleteIndex + 1) % suggestions.length;
351
+ update({ autocompleteIndex: newIndex });
352
+ return "handled";
353
+ }
354
+
355
+ if (code === "up") {
356
+ const suggestions = state.autocompleteSuggestions;
357
+ const newIndex =
358
+ (state.autocompleteIndex - 1 + suggestions.length) %
359
+ suggestions.length;
360
+ update({ autocompleteIndex: newIndex });
361
+ return "handled";
362
+ }
363
+
364
+ if (code === "enter" || code === "return") {
365
+ const suggestion =
366
+ state.autocompleteSuggestions[state.autocompleteIndex];
367
+ if (suggestion) {
368
+ // Replace current word with suggestion
369
+ const words = value.split(" ");
370
+ words[words.length - 1] = suggestion.id;
371
+ const newValue = words.join(" ");
372
+ update({
373
+ value: newValue,
374
+ cursorPos: newValue.length,
375
+ showAutocomplete: false,
376
+ autocompleteSuggestions: [],
377
+ });
378
+ }
379
+ return "handled";
380
+ }
381
+
382
+ if (code === "escape") {
383
+ update({ showAutocomplete: false, autocompleteSuggestions: [] });
384
+ return "handled";
385
+ }
386
+ }
387
+
388
+ // Submit (Enter without Ctrl = submit if single line, with Ctrl = always submit)
389
+ if (code === "enter" || code === "return") {
390
+ if (ctrl) {
391
+ // Ctrl+Enter = submit even in multiline
392
+ if (value.trim() && onSubmit) {
393
+ onSubmit(value);
394
+ update({
395
+ value: "",
396
+ cursorPos: 0,
397
+ currentLine: 0,
398
+ historyIndex: -1,
399
+ savedInput: "",
400
+ });
401
+ }
402
+ return "handled";
403
+ }
404
+
405
+ // Regular Enter
406
+ if (lines.length === 1) {
407
+ // Single line mode - submit
408
+ if (value.trim() && onSubmit) {
409
+ onSubmit(value);
410
+ update({
411
+ value: "",
412
+ cursorPos: 0,
413
+ currentLine: 0,
414
+ historyIndex: -1,
415
+ savedInput: "",
416
+ });
417
+ }
418
+ } else {
419
+ // Multiline mode - insert newline
420
+ const newValue =
421
+ value.slice(0, cursorPos) + "\n" + value.slice(cursorPos);
422
+ const newCursorPos = cursorPos + 1;
423
+ update({
424
+ value: newValue,
425
+ cursorPos: newCursorPos,
426
+ currentLine: currentLine + 1,
427
+ });
428
+ }
429
+ return "handled";
430
+ }
431
+
432
+ // Backspace
433
+ if (code === "backspace") {
434
+ if (cursorPos > 0) {
435
+ const newValue =
436
+ value.slice(0, cursorPos - 1) + value.slice(cursorPos);
437
+ const newCursorPos = cursorPos - 1;
438
+ const newCurrentLine =
439
+ newValue.slice(0, newCursorPos).split("\n").length - 1;
440
+ update({
441
+ value: newValue,
442
+ cursorPos: newCursorPos,
443
+ currentLine: newCurrentLine,
444
+ });
445
+
446
+ // Check for autocomplete
447
+ if (newValue.startsWith("/") && onRequestAutocomplete) {
448
+ const suggestions = onRequestAutocomplete(newValue);
449
+ update({
450
+ showAutocomplete: suggestions.length > 0,
451
+ autocompleteSuggestions: suggestions,
452
+ autocompleteIndex: 0,
453
+ });
454
+ }
455
+ }
456
+ return "handled";
457
+ }
458
+
459
+ // Delete
460
+ if (code === "delete") {
461
+ if (cursorPos < value.length) {
462
+ const newValue =
463
+ value.slice(0, cursorPos) + value.slice(cursorPos + 1);
464
+ update({ value: newValue });
465
+ }
466
+ return "handled";
467
+ }
468
+
469
+ // Arrow keys
470
+ if (code === "left") {
471
+ update({ cursorPos: Math.max(0, cursorPos - 1) });
472
+ return "handled";
473
+ }
474
+
475
+ if (code === "right") {
476
+ update({ cursorPos: Math.min(value.length, cursorPos + 1) });
477
+ return "handled";
478
+ }
479
+
480
+ if (code === "up") {
481
+ // History navigation
482
+ if (inputHistory.length > 0) {
483
+ const newIndex =
484
+ historyIndex === -1 ? 0 : Math.min(historyIndex + 1, inputHistory.length - 1);
485
+ const historyValue = inputHistory[newIndex] ?? "";
486
+ update({
487
+ historyIndex: newIndex,
488
+ value: historyValue,
489
+ cursorPos: historyValue.length,
490
+ currentLine: historyValue.split("\n").length - 1,
491
+ });
492
+ }
493
+ return "handled";
494
+ }
495
+
496
+ if (code === "down") {
497
+ if (historyIndex > 0) {
498
+ const newIndex = historyIndex - 1;
499
+ const historyValue = inputHistory[newIndex] ?? "";
500
+ update({
501
+ historyIndex: newIndex,
502
+ value: historyValue,
503
+ cursorPos: historyValue.length,
504
+ currentLine: historyValue.split("\n").length - 1,
505
+ });
506
+ } else if (historyIndex === 0) {
507
+ // Restore saved input
508
+ update({
509
+ historyIndex: -1,
510
+ value: state.savedInput,
511
+ cursorPos: state.savedInput.length,
512
+ currentLine: state.savedInput.split("\n").length - 1,
513
+ });
514
+ }
515
+ return "handled";
516
+ }
517
+
518
+ // Home/End
519
+ if (code === "home" || (code === "a" && ctrl)) {
520
+ // Go to start of current line
521
+ const lineStart =
522
+ value.slice(0, cursorPos).lastIndexOf("\n") + 1;
523
+ update({ cursorPos: lineStart });
524
+ return "handled";
525
+ }
526
+
527
+ if (code === "end" || (code === "e" && ctrl)) {
528
+ // Go to end of current line
529
+ const lineEnd = value.indexOf("\n", cursorPos);
530
+ update({ cursorPos: lineEnd === -1 ? value.length : lineEnd });
531
+ return "handled";
532
+ }
533
+
534
+ // Ctrl+U - clear line
535
+ if (code === "u" && ctrl) {
536
+ const lineStart =
537
+ value.slice(0, cursorPos).lastIndexOf("\n") + 1;
538
+ const lineEnd = value.indexOf("\n", cursorPos);
539
+ const newValue =
540
+ value.slice(0, lineStart) +
541
+ (lineEnd === -1 ? "" : value.slice(lineEnd + 1));
542
+ update({
543
+ value: newValue,
544
+ cursorPos: lineStart,
545
+ });
546
+ return "handled";
547
+ }
548
+
549
+ // Ctrl+W - delete word
550
+ if (code === "w" && ctrl) {
551
+ const beforeCursor = value
552
+ .slice(0, cursorPos)
553
+ .replace(/\s+\S*$/, "");
554
+ const newValue = beforeCursor + value.slice(cursorPos);
555
+ update({
556
+ value: newValue,
557
+ cursorPos: beforeCursor.length,
558
+ });
559
+ return "handled";
560
+ }
561
+
562
+ // Regular printable character
563
+ if (code.length === 1 && !ctrl) {
564
+ const newValue =
565
+ value.slice(0, cursorPos) + code + value.slice(cursorPos);
566
+ const newCursorPos = cursorPos + 1;
567
+
568
+ update({
569
+ value: newValue,
570
+ cursorPos: newCursorPos,
571
+ historyIndex: -1, // Reset history navigation on typing
572
+ });
573
+
574
+ // Check for autocomplete trigger
575
+ if (newValue.startsWith("/") && onRequestAutocomplete) {
576
+ const suggestions = onRequestAutocomplete(newValue);
577
+ update({
578
+ showAutocomplete: suggestions.length > 0,
579
+ autocompleteSuggestions: suggestions,
580
+ autocompleteIndex: 0,
581
+ });
582
+ } else {
583
+ update({ showAutocomplete: false });
584
+ }
585
+
586
+ return "handled";
587
+ }
588
+
589
+ return "unhandled";
590
+ },
591
+ [isActive, onSubmit, onRequestAutocomplete, inputHistory, state]
592
+ );
593
+
594
+ return {
595
+ state,
596
+ handleKeyEvent,
597
+ // Convenience helpers
598
+ setValue: (value: string) =>
599
+ setState((prev) => ({ ...prev, value })),
600
+ reset: () =>
601
+ setState({
602
+ value: "",
603
+ cursorPos: 0,
604
+ currentLine: 0,
605
+ historyIndex: -1,
606
+ savedInput: "",
607
+ showAutocomplete: false,
608
+ autocompleteSuggestions: [],
609
+ autocompleteIndex: 0,
610
+ }),
611
+ };
612
+ }
613
+
614
+ export default MultilineInput;