@deepseek-harness-tui/dsh-tui 0.5.0

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 (638) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/bin/dsh-tui.js +95 -0
  4. package/cordis.patch.yml +218 -0
  5. package/cordis.yml +185 -0
  6. package/lib/invariant.js +28 -0
  7. package/lib/types/activityPrefs.d.ts +29 -0
  8. package/lib/types/activityPrefs.d.ts.map +1 -0
  9. package/lib/types/activityPrefs.js +60 -0
  10. package/lib/types/bootstrap/state.d.ts +13 -0
  11. package/lib/types/bootstrap/state.d.ts.map +1 -0
  12. package/lib/types/bootstrap/state.js +12 -0
  13. package/lib/types/cc/cliHighlight.d.ts +20 -0
  14. package/lib/types/cc/cliHighlight.d.ts.map +1 -0
  15. package/lib/types/cc/cliHighlight.js +53 -0
  16. package/lib/types/cc/figures.d.ts +59 -0
  17. package/lib/types/cc/figures.d.ts.map +1 -0
  18. package/lib/types/cc/figures.js +69 -0
  19. package/lib/types/cc/format.d.ts +26 -0
  20. package/lib/types/cc/format.d.ts.map +1 -0
  21. package/lib/types/cc/format.js +55 -0
  22. package/lib/types/cc/hash.d.ts +25 -0
  23. package/lib/types/cc/hash.d.ts.map +1 -0
  24. package/lib/types/cc/hash.js +41 -0
  25. package/lib/types/cc/hyperlink.d.ts +21 -0
  26. package/lib/types/cc/hyperlink.d.ts.map +1 -0
  27. package/lib/types/cc/hyperlink.js +31 -0
  28. package/lib/types/cc/markdown.d.ts +43 -0
  29. package/lib/types/cc/markdown.d.ts.map +1 -0
  30. package/lib/types/cc/markdown.js +345 -0
  31. package/lib/types/cc/spinnerVerbs.d.ts +3 -0
  32. package/lib/types/cc/spinnerVerbs.d.ts.map +1 -0
  33. package/lib/types/cc/spinnerVerbs.js +190 -0
  34. package/lib/types/cc/terminal.d.ts +15 -0
  35. package/lib/types/cc/terminal.d.ts.map +1 -0
  36. package/lib/types/cc/terminal.js +84 -0
  37. package/lib/types/channel.d.ts +672 -0
  38. package/lib/types/channel.d.ts.map +1 -0
  39. package/lib/types/channel.js +2427 -0
  40. package/lib/types/childStderr.d.ts +63 -0
  41. package/lib/types/childStderr.d.ts.map +1 -0
  42. package/lib/types/childStderr.js +161 -0
  43. package/lib/types/commands.d.ts +55 -0
  44. package/lib/types/commands.d.ts.map +1 -0
  45. package/lib/types/commands.js +101 -0
  46. package/lib/types/components/ActivityLine.d.ts +29 -0
  47. package/lib/types/components/ActivityLine.d.ts.map +1 -0
  48. package/lib/types/components/ActivityLine.js +47 -0
  49. package/lib/types/components/ActivityPicker.d.ts +13 -0
  50. package/lib/types/components/ActivityPicker.d.ts.map +1 -0
  51. package/lib/types/components/ActivityPicker.js +24 -0
  52. package/lib/types/components/CommandSuggestions.d.ts +14 -0
  53. package/lib/types/components/CommandSuggestions.d.ts.map +1 -0
  54. package/lib/types/components/CommandSuggestions.js +33 -0
  55. package/lib/types/components/FileSuggestions.d.ts +12 -0
  56. package/lib/types/components/FileSuggestions.d.ts.map +1 -0
  57. package/lib/types/components/FileSuggestions.js +26 -0
  58. package/lib/types/components/GoalTodoPanel.d.ts +13 -0
  59. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -0
  60. package/lib/types/components/GoalTodoPanel.js +57 -0
  61. package/lib/types/components/HelpMenu.d.ts +12 -0
  62. package/lib/types/components/HelpMenu.d.ts.map +1 -0
  63. package/lib/types/components/HelpMenu.js +12 -0
  64. package/lib/types/components/HistorySearchDialog.d.ts +16 -0
  65. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -0
  66. package/lib/types/components/HistorySearchDialog.js +31 -0
  67. package/lib/types/components/InterruptedByUser.d.ts +7 -0
  68. package/lib/types/components/InterruptedByUser.d.ts.map +1 -0
  69. package/lib/types/components/InterruptedByUser.js +9 -0
  70. package/lib/types/components/LoadedContextPanel.d.ts +20 -0
  71. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -0
  72. package/lib/types/components/LoadedContextPanel.js +30 -0
  73. package/lib/types/components/LogoV2.d.ts +23 -0
  74. package/lib/types/components/LogoV2.d.ts.map +1 -0
  75. package/lib/types/components/LogoV2.js +95 -0
  76. package/lib/types/components/Markdown.d.ts +24 -0
  77. package/lib/types/components/Markdown.d.ts.map +1 -0
  78. package/lib/types/components/Markdown.js +106 -0
  79. package/lib/types/components/MarkdownTable.d.ts +17 -0
  80. package/lib/types/components/MarkdownTable.d.ts.map +1 -0
  81. package/lib/types/components/MarkdownTable.js +272 -0
  82. package/lib/types/components/MessageList.d.ts +41 -0
  83. package/lib/types/components/MessageList.d.ts.map +1 -0
  84. package/lib/types/components/MessageList.js +303 -0
  85. package/lib/types/components/ModelPicker.d.ts +14 -0
  86. package/lib/types/components/ModelPicker.d.ts.map +1 -0
  87. package/lib/types/components/ModelPicker.js +15 -0
  88. package/lib/types/components/PresetPicker.d.ts +17 -0
  89. package/lib/types/components/PresetPicker.d.ts.map +1 -0
  90. package/lib/types/components/PresetPicker.js +25 -0
  91. package/lib/types/components/PromptInput.d.ts +67 -0
  92. package/lib/types/components/PromptInput.d.ts.map +1 -0
  93. package/lib/types/components/PromptInput.js +778 -0
  94. package/lib/types/components/ResumePicker.d.ts +15 -0
  95. package/lib/types/components/ResumePicker.d.ts.map +1 -0
  96. package/lib/types/components/ResumePicker.js +34 -0
  97. package/lib/types/components/RewindPicker.d.ts +14 -0
  98. package/lib/types/components/RewindPicker.d.ts.map +1 -0
  99. package/lib/types/components/RewindPicker.js +23 -0
  100. package/lib/types/components/SearchBox.d.ts +20 -0
  101. package/lib/types/components/SearchBox.d.ts.map +1 -0
  102. package/lib/types/components/SearchBox.js +33 -0
  103. package/lib/types/components/Select.d.ts +22 -0
  104. package/lib/types/components/Select.d.ts.map +1 -0
  105. package/lib/types/components/Select.js +19 -0
  106. package/lib/types/components/Spinner/GlimmerMessage.d.ts +19 -0
  107. package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -0
  108. package/lib/types/components/Spinner/GlimmerMessage.js +78 -0
  109. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +31 -0
  110. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -0
  111. package/lib/types/components/Spinner/SpinnerAnimationRow.js +162 -0
  112. package/lib/types/components/Spinner/SpinnerGlyph.d.ts +16 -0
  113. package/lib/types/components/Spinner/SpinnerGlyph.d.ts.map +1 -0
  114. package/lib/types/components/Spinner/SpinnerGlyph.js +36 -0
  115. package/lib/types/components/Spinner/spinnerMode.d.ts +6 -0
  116. package/lib/types/components/Spinner/spinnerMode.d.ts.map +1 -0
  117. package/lib/types/components/Spinner/spinnerMode.js +1 -0
  118. package/lib/types/components/Spinner/spinnerUtils.d.ts +41 -0
  119. package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -0
  120. package/lib/types/components/Spinner/spinnerUtils.js +104 -0
  121. package/lib/types/components/Spinner/useStalledAnimation.d.ts +16 -0
  122. package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -0
  123. package/lib/types/components/Spinner/useStalledAnimation.js +71 -0
  124. package/lib/types/components/StreamingMarkdown.d.ts +12 -0
  125. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -0
  126. package/lib/types/components/StreamingMarkdown.js +39 -0
  127. package/lib/types/components/ThemePicker.d.ts +22 -0
  128. package/lib/types/components/ThemePicker.d.ts.map +1 -0
  129. package/lib/types/components/ThemePicker.js +51 -0
  130. package/lib/types/components/ThinkingToggle.d.ts +17 -0
  131. package/lib/types/components/ThinkingToggle.d.ts.map +1 -0
  132. package/lib/types/components/ThinkingToggle.js +30 -0
  133. package/lib/types/components/ToolUseLoader.d.ts +13 -0
  134. package/lib/types/components/ToolUseLoader.d.ts.map +1 -0
  135. package/lib/types/components/ToolUseLoader.js +17 -0
  136. package/lib/types/components/Whale.d.ts +22 -0
  137. package/lib/types/components/Whale.d.ts.map +1 -0
  138. package/lib/types/components/Whale.js +78 -0
  139. package/lib/types/components/WorkingSpinner.d.ts +26 -0
  140. package/lib/types/components/WorkingSpinner.d.ts.map +1 -0
  141. package/lib/types/components/WorkingSpinner.js +68 -0
  142. package/lib/types/components/activityFrames.d.ts +31 -0
  143. package/lib/types/components/activityFrames.d.ts.map +1 -0
  144. package/lib/types/components/activityFrames.js +83 -0
  145. package/lib/types/components/bigfont.d.ts +28 -0
  146. package/lib/types/components/bigfont.d.ts.map +1 -0
  147. package/lib/types/components/bigfont.js +91 -0
  148. package/lib/types/components/design-system/Byline.d.ts +14 -0
  149. package/lib/types/components/design-system/Byline.d.ts.map +1 -0
  150. package/lib/types/components/design-system/Byline.js +17 -0
  151. package/lib/types/components/design-system/Divider.d.ts +40 -0
  152. package/lib/types/components/design-system/Divider.d.ts.map +1 -0
  153. package/lib/types/components/design-system/Divider.js +24 -0
  154. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +19 -0
  155. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +1 -0
  156. package/lib/types/components/design-system/KeyboardShortcutHint.js +14 -0
  157. package/lib/types/components/design-system/ListItem.d.ts +36 -0
  158. package/lib/types/components/design-system/ListItem.d.ts.map +1 -0
  159. package/lib/types/components/design-system/ListItem.js +48 -0
  160. package/lib/types/components/design-system/LoadingState.d.ts +19 -0
  161. package/lib/types/components/design-system/LoadingState.d.ts.map +1 -0
  162. package/lib/types/components/design-system/LoadingState.js +22 -0
  163. package/lib/types/components/design-system/Pane.d.ts +17 -0
  164. package/lib/types/components/design-system/Pane.d.ts.map +1 -0
  165. package/lib/types/components/design-system/Pane.js +15 -0
  166. package/lib/types/components/design-system/ProgressBar.d.ts +22 -0
  167. package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -0
  168. package/lib/types/components/design-system/ProgressBar.js +27 -0
  169. package/lib/types/components/design-system/StatusIcon.d.ts +15 -0
  170. package/lib/types/components/design-system/StatusIcon.d.ts.map +1 -0
  171. package/lib/types/components/design-system/StatusIcon.js +20 -0
  172. package/lib/types/components/design-system/ThemeProvider.d.ts +11 -0
  173. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -0
  174. package/lib/types/components/design-system/ThemeProvider.js +135 -0
  175. package/lib/types/components/design-system/ThemedBox.d.ts +37 -0
  176. package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -0
  177. package/lib/types/components/design-system/ThemedBox.js +26 -0
  178. package/lib/types/components/design-system/ThemedText.d.ts +56 -0
  179. package/lib/types/components/design-system/ThemedText.d.ts.map +1 -0
  180. package/lib/types/components/design-system/ThemedText.js +45 -0
  181. package/lib/types/components/messages/AssistantTextMessage.d.ts +18 -0
  182. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -0
  183. package/lib/types/components/messages/AssistantTextMessage.js +15 -0
  184. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +23 -0
  185. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -0
  186. package/lib/types/components/messages/AssistantThinkingMessage.js +23 -0
  187. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +23 -0
  188. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -0
  189. package/lib/types/components/messages/AssistantToolUseMessage.js +220 -0
  190. package/lib/types/components/messages/MessageMetadata.d.ts +15 -0
  191. package/lib/types/components/messages/MessageMetadata.d.ts.map +1 -0
  192. package/lib/types/components/messages/MessageMetadata.js +20 -0
  193. package/lib/types/components/messages/UserPromptMessage.d.ts +19 -0
  194. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -0
  195. package/lib/types/components/messages/UserPromptMessage.js +15 -0
  196. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +39 -0
  197. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -0
  198. package/lib/types/components/questions/AskUserQuestionPanel.js +228 -0
  199. package/lib/types/components/shimmer.d.ts +35 -0
  200. package/lib/types/components/shimmer.d.ts.map +1 -0
  201. package/lib/types/components/shimmer.js +43 -0
  202. package/lib/types/components/whaleFrames.d.ts +25 -0
  203. package/lib/types/components/whaleFrames.d.ts.map +1 -0
  204. package/lib/types/components/whaleFrames.js +419 -0
  205. package/lib/types/customTheme.d.ts +104 -0
  206. package/lib/types/customTheme.d.ts.map +1 -0
  207. package/lib/types/customTheme.js +268 -0
  208. package/lib/types/effortPrefs.d.ts +22 -0
  209. package/lib/types/effortPrefs.d.ts.map +1 -0
  210. package/lib/types/effortPrefs.js +45 -0
  211. package/lib/types/history.d.ts +24 -0
  212. package/lib/types/history.d.ts.map +1 -0
  213. package/lib/types/history.js +75 -0
  214. package/lib/types/hooks/useBlink.d.ts +11 -0
  215. package/lib/types/hooks/useBlink.d.ts.map +1 -0
  216. package/lib/types/hooks/useBlink.js +20 -0
  217. package/lib/types/i18n.d.ts +926 -0
  218. package/lib/types/i18n.d.ts.map +1 -0
  219. package/lib/types/i18n.js +356 -0
  220. package/lib/types/index.d.ts +70 -0
  221. package/lib/types/index.d.ts.map +1 -0
  222. package/lib/types/index.js +31 -0
  223. package/lib/types/ink/Ansi.d.ts +11 -0
  224. package/lib/types/ink/Ansi.d.ts.map +1 -0
  225. package/lib/types/ink/Ansi.js +269 -0
  226. package/lib/types/ink/bidi.d.ts +18 -0
  227. package/lib/types/ink/bidi.d.ts.map +1 -0
  228. package/lib/types/ink/bidi.js +119 -0
  229. package/lib/types/ink/clearTerminal.d.ts +22 -0
  230. package/lib/types/ink/clearTerminal.d.ts.map +1 -0
  231. package/lib/types/ink/clearTerminal.js +72 -0
  232. package/lib/types/ink/colorize.d.ts +33 -0
  233. package/lib/types/ink/colorize.d.ts.map +1 -0
  234. package/lib/types/ink/colorize.js +213 -0
  235. package/lib/types/ink/components/AlternateScreen.d.ts +22 -0
  236. package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -0
  237. package/lib/types/ink/components/AlternateScreen.js +74 -0
  238. package/lib/types/ink/components/App.d.ts +73 -0
  239. package/lib/types/ink/components/App.d.ts.map +1 -0
  240. package/lib/types/ink/components/App.js +597 -0
  241. package/lib/types/ink/components/AppContext.d.ts +15 -0
  242. package/lib/types/ink/components/AppContext.d.ts.map +1 -0
  243. package/lib/types/ink/components/AppContext.js +11 -0
  244. package/lib/types/ink/components/Box.d.ts +49 -0
  245. package/lib/types/ink/components/Box.d.ts.map +1 -0
  246. package/lib/types/ink/components/Box.js +153 -0
  247. package/lib/types/ink/components/Button.d.ts +37 -0
  248. package/lib/types/ink/components/Button.d.ts.map +1 -0
  249. package/lib/types/ink/components/Button.js +166 -0
  250. package/lib/types/ink/components/ClockContext.d.ts +10 -0
  251. package/lib/types/ink/components/ClockContext.d.ts.map +1 -0
  252. package/lib/types/ink/components/ClockContext.js +108 -0
  253. package/lib/types/ink/components/CursorDeclarationContext.d.ts +30 -0
  254. package/lib/types/ink/components/CursorDeclarationContext.d.ts.map +1 -0
  255. package/lib/types/ink/components/CursorDeclarationContext.js +6 -0
  256. package/lib/types/ink/components/ErrorOverview.d.ts +7 -0
  257. package/lib/types/ink/components/ErrorOverview.d.ts.map +1 -0
  258. package/lib/types/ink/components/ErrorOverview.js +49 -0
  259. package/lib/types/ink/components/Link.d.ts +8 -0
  260. package/lib/types/ink/components/Link.d.ts.map +1 -0
  261. package/lib/types/ink/components/Link.js +33 -0
  262. package/lib/types/ink/components/Newline.d.ts +13 -0
  263. package/lib/types/ink/components/Newline.d.ts.map +1 -0
  264. package/lib/types/ink/components/Newline.js +29 -0
  265. package/lib/types/ink/components/NoSelect.d.ts +20 -0
  266. package/lib/types/ink/components/NoSelect.d.ts.map +1 -0
  267. package/lib/types/ink/components/NoSelect.js +56 -0
  268. package/lib/types/ink/components/RawAnsi.d.ts +17 -0
  269. package/lib/types/ink/components/RawAnsi.d.ts.map +1 -0
  270. package/lib/types/ink/components/RawAnsi.js +45 -0
  271. package/lib/types/ink/components/ScrollBox.d.ts +78 -0
  272. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -0
  273. package/lib/types/ink/components/ScrollBox.js +174 -0
  274. package/lib/types/ink/components/Spacer.d.ts +6 -0
  275. package/lib/types/ink/components/Spacer.d.ts.map +1 -0
  276. package/lib/types/ink/components/Spacer.js +19 -0
  277. package/lib/types/ink/components/StdinContext.d.ts +32 -0
  278. package/lib/types/ink/components/StdinContext.d.ts.map +1 -0
  279. package/lib/types/ink/components/StdinContext.js +16 -0
  280. package/lib/types/ink/components/TerminalFocusContext.d.ts +11 -0
  281. package/lib/types/ink/components/TerminalFocusContext.d.ts.map +1 -0
  282. package/lib/types/ink/components/TerminalFocusContext.js +45 -0
  283. package/lib/types/ink/components/TerminalSizeContext.d.ts +6 -0
  284. package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -0
  285. package/lib/types/ink/components/TerminalSizeContext.js +3 -0
  286. package/lib/types/ink/components/Text.d.ts +56 -0
  287. package/lib/types/ink/components/Text.d.ts.map +1 -0
  288. package/lib/types/ink/components/Text.js +194 -0
  289. package/lib/types/ink/constants.d.ts +3 -0
  290. package/lib/types/ink/constants.d.ts.map +1 -0
  291. package/lib/types/ink/constants.js +2 -0
  292. package/lib/types/ink/cursor.d.ts +11 -0
  293. package/lib/types/ink/cursor.d.ts.map +1 -0
  294. package/lib/types/ink/cursor.js +1 -0
  295. package/lib/types/ink/devtools.d.ts +7 -0
  296. package/lib/types/ink/devtools.d.ts.map +1 -0
  297. package/lib/types/ink/devtools.js +1 -0
  298. package/lib/types/ink/dom.d.ts +178 -0
  299. package/lib/types/ink/dom.d.ts.map +1 -0
  300. package/lib/types/ink/dom.js +424 -0
  301. package/lib/types/ink/events/click-event.d.ts +32 -0
  302. package/lib/types/ink/events/click-event.d.ts.map +1 -0
  303. package/lib/types/ink/events/click-event.js +36 -0
  304. package/lib/types/ink/events/dispatcher.d.ts +63 -0
  305. package/lib/types/ink/events/dispatcher.d.ts.map +1 -0
  306. package/lib/types/ink/events/dispatcher.js +194 -0
  307. package/lib/types/ink/events/emitter.d.ts +20 -0
  308. package/lib/types/ink/events/emitter.d.ts.map +1 -0
  309. package/lib/types/ink/events/emitter.js +43 -0
  310. package/lib/types/ink/events/event-handlers.d.ts +47 -0
  311. package/lib/types/ink/events/event-handlers.d.ts.map +1 -0
  312. package/lib/types/ink/events/event-handlers.js +30 -0
  313. package/lib/types/ink/events/event.d.ts +19 -0
  314. package/lib/types/ink/events/event.d.ts.map +1 -0
  315. package/lib/types/ink/events/event.js +22 -0
  316. package/lib/types/ink/events/focus-event.d.ts +19 -0
  317. package/lib/types/ink/events/focus-event.d.ts.map +1 -0
  318. package/lib/types/ink/events/focus-event.js +21 -0
  319. package/lib/types/ink/events/input-event.d.ts +53 -0
  320. package/lib/types/ink/events/input-event.d.ts.map +1 -0
  321. package/lib/types/ink/events/input-event.js +180 -0
  322. package/lib/types/ink/events/keyboard-event.d.ts +40 -0
  323. package/lib/types/ink/events/keyboard-event.d.ts.map +1 -0
  324. package/lib/types/ink/events/keyboard-event.js +65 -0
  325. package/lib/types/ink/events/paste-event.d.ts +11 -0
  326. package/lib/types/ink/events/paste-event.d.ts.map +1 -0
  327. package/lib/types/ink/events/paste-event.js +13 -0
  328. package/lib/types/ink/events/resize-event.d.ts +13 -0
  329. package/lib/types/ink/events/resize-event.d.ts.map +1 -0
  330. package/lib/types/ink/events/resize-event.js +16 -0
  331. package/lib/types/ink/events/terminal-event.d.ts +112 -0
  332. package/lib/types/ink/events/terminal-event.d.ts.map +1 -0
  333. package/lib/types/ink/events/terminal-event.js +131 -0
  334. package/lib/types/ink/events/terminal-focus-event.d.ts +21 -0
  335. package/lib/types/ink/events/terminal-focus-event.d.ts.map +1 -0
  336. package/lib/types/ink/events/terminal-focus-event.js +18 -0
  337. package/lib/types/ink/focus.d.ts +74 -0
  338. package/lib/types/ink/focus.d.ts.map +1 -0
  339. package/lib/types/ink/focus.js +188 -0
  340. package/lib/types/ink/frame.d.ts +119 -0
  341. package/lib/types/ink/frame.d.ts.map +1 -0
  342. package/lib/types/ink/frame.js +43 -0
  343. package/lib/types/ink/get-max-width.d.ts +20 -0
  344. package/lib/types/ink/get-max-width.d.ts.map +1 -0
  345. package/lib/types/ink/get-max-width.js +25 -0
  346. package/lib/types/ink/hit-test.d.ts +47 -0
  347. package/lib/types/ink/hit-test.d.ts.map +1 -0
  348. package/lib/types/ink/hit-test.js +126 -0
  349. package/lib/types/ink/hooks/use-animation-frame.d.ts +27 -0
  350. package/lib/types/ink/hooks/use-animation-frame.d.ts.map +1 -0
  351. package/lib/types/ink/hooks/use-animation-frame.js +48 -0
  352. package/lib/types/ink/hooks/use-app.d.ts +8 -0
  353. package/lib/types/ink/hooks/use-app.d.ts.map +1 -0
  354. package/lib/types/ink/hooks/use-app.js +8 -0
  355. package/lib/types/ink/hooks/use-copy-on-select.d.ts +22 -0
  356. package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -0
  357. package/lib/types/ink/hooks/use-copy-on-select.js +40 -0
  358. package/lib/types/ink/hooks/use-declared-cursor.d.ts +31 -0
  359. package/lib/types/ink/hooks/use-declared-cursor.d.ts.map +1 -0
  360. package/lib/types/ink/hooks/use-declared-cursor.js +65 -0
  361. package/lib/types/ink/hooks/use-input.d.ts +41 -0
  362. package/lib/types/ink/hooks/use-input.d.ts.map +1 -0
  363. package/lib/types/ink/hooks/use-input.js +73 -0
  364. package/lib/types/ink/hooks/use-interval.d.ts +23 -0
  365. package/lib/types/ink/hooks/use-interval.d.ts.map +1 -0
  366. package/lib/types/ink/hooks/use-interval.js +58 -0
  367. package/lib/types/ink/hooks/use-search-highlight.d.ts +34 -0
  368. package/lib/types/ink/hooks/use-search-highlight.d.ts.map +1 -0
  369. package/lib/types/ink/hooks/use-search-highlight.js +35 -0
  370. package/lib/types/ink/hooks/use-selection.d.ts +44 -0
  371. package/lib/types/ink/hooks/use-selection.d.ts.map +1 -0
  372. package/lib/types/ink/hooks/use-selection.js +64 -0
  373. package/lib/types/ink/hooks/use-stdin.d.ts +8 -0
  374. package/lib/types/ink/hooks/use-stdin.d.ts.map +1 -0
  375. package/lib/types/ink/hooks/use-stdin.js +8 -0
  376. package/lib/types/ink/hooks/use-tab-status.d.ts +18 -0
  377. package/lib/types/ink/hooks/use-tab-status.d.ts.map +1 -0
  378. package/lib/types/ink/hooks/use-tab-status.js +58 -0
  379. package/lib/types/ink/hooks/use-terminal-focus.d.ts +11 -0
  380. package/lib/types/ink/hooks/use-terminal-focus.d.ts.map +1 -0
  381. package/lib/types/ink/hooks/use-terminal-focus.js +15 -0
  382. package/lib/types/ink/hooks/use-terminal-size.d.ts +6 -0
  383. package/lib/types/ink/hooks/use-terminal-size.d.ts.map +1 -0
  384. package/lib/types/ink/hooks/use-terminal-size.js +12 -0
  385. package/lib/types/ink/hooks/use-terminal-title.d.ts +14 -0
  386. package/lib/types/ink/hooks/use-terminal-title.d.ts.map +1 -0
  387. package/lib/types/ink/hooks/use-terminal-title.js +30 -0
  388. package/lib/types/ink/hooks/use-terminal-viewport.d.ts +32 -0
  389. package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
  390. package/lib/types/ink/hooks/use-terminal-viewport.js +79 -0
  391. package/lib/types/ink/ink.d.ts +370 -0
  392. package/lib/types/ink/ink.d.ts.map +1 -0
  393. package/lib/types/ink/ink.js +1665 -0
  394. package/lib/types/ink/instances.d.ts +10 -0
  395. package/lib/types/ink/instances.d.ts.map +1 -0
  396. package/lib/types/ink/instances.js +13 -0
  397. package/lib/types/ink/layout/engine.d.ts +7 -0
  398. package/lib/types/ink/layout/engine.d.ts.map +1 -0
  399. package/lib/types/ink/layout/engine.js +8 -0
  400. package/lib/types/ink/layout/geometry.d.ts +86 -0
  401. package/lib/types/ink/layout/geometry.d.ts.map +1 -0
  402. package/lib/types/ink/layout/geometry.js +95 -0
  403. package/lib/types/ink/layout/node.d.ts +151 -0
  404. package/lib/types/ink/layout/node.d.ts.map +1 -0
  405. package/lib/types/ink/layout/node.js +72 -0
  406. package/lib/types/ink/layout/yoga.d.ts +69 -0
  407. package/lib/types/ink/layout/yoga.d.ts.map +1 -0
  408. package/lib/types/ink/layout/yoga.js +249 -0
  409. package/lib/types/ink/line-width-cache.d.ts +9 -0
  410. package/lib/types/ink/line-width-cache.d.ts.map +1 -0
  411. package/lib/types/ink/line-width-cache.js +45 -0
  412. package/lib/types/ink/log-update.d.ts +57 -0
  413. package/lib/types/ink/log-update.d.ts.map +1 -0
  414. package/lib/types/ink/log-update.js +710 -0
  415. package/lib/types/ink/measure-element.d.ts +19 -0
  416. package/lib/types/ink/measure-element.d.ts.map +1 -0
  417. package/lib/types/ink/measure-element.js +10 -0
  418. package/lib/types/ink/measure-text.d.ts +13 -0
  419. package/lib/types/ink/measure-text.d.ts.map +1 -0
  420. package/lib/types/ink/measure-text.js +38 -0
  421. package/lib/types/ink/node-cache.d.ts +33 -0
  422. package/lib/types/ink/node-cache.d.ts.map +1 -0
  423. package/lib/types/ink/node-cache.js +42 -0
  424. package/lib/types/ink/optimizer.d.ts +18 -0
  425. package/lib/types/ink/optimizer.d.ts.map +1 -0
  426. package/lib/types/ink/optimizer.js +83 -0
  427. package/lib/types/ink/output.d.ts +200 -0
  428. package/lib/types/ink/output.d.ts.map +1 -0
  429. package/lib/types/ink/output.js +663 -0
  430. package/lib/types/ink/parse-keypress.d.ts +132 -0
  431. package/lib/types/ink/parse-keypress.d.ts.map +1 -0
  432. package/lib/types/ink/parse-keypress.js +707 -0
  433. package/lib/types/ink/reconciler.d.ts +43 -0
  434. package/lib/types/ink/reconciler.d.ts.map +1 -0
  435. package/lib/types/ink/reconciler.js +413 -0
  436. package/lib/types/ink/render-border.d.ts +36 -0
  437. package/lib/types/ink/render-border.d.ts.map +1 -0
  438. package/lib/types/ink/render-border.js +143 -0
  439. package/lib/types/ink/render-node-to-output.d.ts +93 -0
  440. package/lib/types/ink/render-node-to-output.d.ts.map +1 -0
  441. package/lib/types/ink/render-node-to-output.js +1290 -0
  442. package/lib/types/ink/render-to-screen.d.ts +65 -0
  443. package/lib/types/ink/render-to-screen.d.ts.map +1 -0
  444. package/lib/types/ink/render-to-screen.js +189 -0
  445. package/lib/types/ink/renderer.d.ts +24 -0
  446. package/lib/types/ink/renderer.d.ts.map +1 -0
  447. package/lib/types/ink/renderer.js +136 -0
  448. package/lib/types/ink/root.d.ts +91 -0
  449. package/lib/types/ink/root.d.ts.map +1 -0
  450. package/lib/types/ink/root.js +93 -0
  451. package/lib/types/ink/screen.d.ts +443 -0
  452. package/lib/types/ink/screen.d.ts.map +1 -0
  453. package/lib/types/ink/screen.js +1295 -0
  454. package/lib/types/ink/searchHighlight.d.ts +25 -0
  455. package/lib/types/ink/searchHighlight.d.ts.map +1 -0
  456. package/lib/types/ink/searchHighlight.js +82 -0
  457. package/lib/types/ink/selection.d.ts +323 -0
  458. package/lib/types/ink/selection.d.ts.map +1 -0
  459. package/lib/types/ink/selection.js +881 -0
  460. package/lib/types/ink/squash-text-nodes.d.ts +30 -0
  461. package/lib/types/ink/squash-text-nodes.d.ts.map +1 -0
  462. package/lib/types/ink/squash-text-nodes.js +63 -0
  463. package/lib/types/ink/stringWidth.d.ts +11 -0
  464. package/lib/types/ink/stringWidth.d.ts.map +1 -0
  465. package/lib/types/ink/stringWidth.js +209 -0
  466. package/lib/types/ink/styles.d.ts +324 -0
  467. package/lib/types/ink/styles.d.ts.map +1 -0
  468. package/lib/types/ink/styles.js +307 -0
  469. package/lib/types/ink/supports-hyperlinks.d.ts +20 -0
  470. package/lib/types/ink/supports-hyperlinks.d.ts.map +1 -0
  471. package/lib/types/ink/supports-hyperlinks.js +44 -0
  472. package/lib/types/ink/tabstops.d.ts +9 -0
  473. package/lib/types/ink/tabstops.d.ts.map +1 -0
  474. package/lib/types/ink/tabstops.js +46 -0
  475. package/lib/types/ink/terminal-focus-state.d.ts +35 -0
  476. package/lib/types/ink/terminal-focus-state.d.ts.map +1 -0
  477. package/lib/types/ink/terminal-focus-state.js +57 -0
  478. package/lib/types/ink/terminal-querier.d.ts +161 -0
  479. package/lib/types/ink/terminal-querier.d.ts.map +1 -0
  480. package/lib/types/ink/terminal-querier.js +204 -0
  481. package/lib/types/ink/terminal.d.ts +80 -0
  482. package/lib/types/ink/terminal.d.ts.map +1 -0
  483. package/lib/types/ink/terminal.js +268 -0
  484. package/lib/types/ink/termio/ansi.d.ts +75 -0
  485. package/lib/types/ink/termio/ansi.d.ts.map +1 -0
  486. package/lib/types/ink/termio/ansi.js +79 -0
  487. package/lib/types/ink/termio/csi.d.ts +253 -0
  488. package/lib/types/ink/termio/csi.d.ts.map +1 -0
  489. package/lib/types/ink/termio/csi.js +347 -0
  490. package/lib/types/ink/termio/dec.d.ts +61 -0
  491. package/lib/types/ink/termio/dec.d.ts.map +1 -0
  492. package/lib/types/ink/termio/dec.js +76 -0
  493. package/lib/types/ink/termio/esc.d.ts +15 -0
  494. package/lib/types/ink/termio/esc.d.ts.map +1 -0
  495. package/lib/types/ink/termio/esc.js +57 -0
  496. package/lib/types/ink/termio/osc.d.ts +208 -0
  497. package/lib/types/ink/termio/osc.d.ts.map +1 -0
  498. package/lib/types/ink/termio/osc.js +466 -0
  499. package/lib/types/ink/termio/parser.d.ts +46 -0
  500. package/lib/types/ink/termio/parser.d.ts.map +1 -0
  501. package/lib/types/ink/termio/parser.js +366 -0
  502. package/lib/types/ink/termio/sgr.d.ts +17 -0
  503. package/lib/types/ink/termio/sgr.d.ts.map +1 -0
  504. package/lib/types/ink/termio/sgr.js +300 -0
  505. package/lib/types/ink/termio/tokenize.d.ts +50 -0
  506. package/lib/types/ink/termio/tokenize.d.ts.map +1 -0
  507. package/lib/types/ink/termio/tokenize.js +266 -0
  508. package/lib/types/ink/termio/types.d.ts +211 -0
  509. package/lib/types/ink/termio/types.d.ts.map +1 -0
  510. package/lib/types/ink/termio/types.js +68 -0
  511. package/lib/types/ink/termio.d.ts +25 -0
  512. package/lib/types/ink/termio.d.ts.map +1 -0
  513. package/lib/types/ink/termio.js +24 -0
  514. package/lib/types/ink/truncateToWidth.d.ts +7 -0
  515. package/lib/types/ink/truncateToWidth.d.ts.map +1 -0
  516. package/lib/types/ink/truncateToWidth.js +18 -0
  517. package/lib/types/ink/useTerminalNotification.d.ts +45 -0
  518. package/lib/types/ink/useTerminalNotification.d.ts.map +1 -0
  519. package/lib/types/ink/useTerminalNotification.js +70 -0
  520. package/lib/types/ink/warn.d.ts +7 -0
  521. package/lib/types/ink/warn.d.ts.map +1 -0
  522. package/lib/types/ink/warn.js +15 -0
  523. package/lib/types/ink/widest-line.d.ts +7 -0
  524. package/lib/types/ink/widest-line.d.ts.map +1 -0
  525. package/lib/types/ink/widest-line.js +19 -0
  526. package/lib/types/ink/wrap-text.d.ts +10 -0
  527. package/lib/types/ink/wrap-text.d.ts.map +1 -0
  528. package/lib/types/ink/wrap-text.js +61 -0
  529. package/lib/types/ink/wrapAnsi.d.ts +18 -0
  530. package/lib/types/ink/wrapAnsi.d.ts.map +1 -0
  531. package/lib/types/ink/wrapAnsi.js +16 -0
  532. package/lib/types/invariant.d.ts +20 -0
  533. package/lib/types/invariant.d.ts.map +1 -0
  534. package/lib/types/invariant.js +26 -0
  535. package/lib/types/modelPrefs.d.ts +37 -0
  536. package/lib/types/modelPrefs.d.ts.map +1 -0
  537. package/lib/types/modelPrefs.js +66 -0
  538. package/lib/types/modelRoute.d.ts +79 -0
  539. package/lib/types/modelRoute.d.ts.map +1 -0
  540. package/lib/types/modelRoute.js +96 -0
  541. package/lib/types/native-ts/yoga-layout/enums.d.ts +183 -0
  542. package/lib/types/native-ts/yoga-layout/enums.d.ts.map +1 -0
  543. package/lib/types/native-ts/yoga-layout/enums.js +150 -0
  544. package/lib/types/native-ts/yoga-layout/index.d.ts +788 -0
  545. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -0
  546. package/lib/types/native-ts/yoga-layout/index.js +2571 -0
  547. package/lib/types/packaged-skills.d.ts +10 -0
  548. package/lib/types/packaged-skills.d.ts.map +1 -0
  549. package/lib/types/packaged-skills.js +63 -0
  550. package/lib/types/plugin.d.ts +33 -0
  551. package/lib/types/plugin.d.ts.map +1 -0
  552. package/lib/types/plugin.js +454 -0
  553. package/lib/types/presetPrefs.d.ts +29 -0
  554. package/lib/types/presetPrefs.d.ts.map +1 -0
  555. package/lib/types/presetPrefs.js +61 -0
  556. package/lib/types/presets.d.ts +110 -0
  557. package/lib/types/presets.d.ts.map +1 -0
  558. package/lib/types/presets.js +114 -0
  559. package/lib/types/questions.d.ts +97 -0
  560. package/lib/types/questions.d.ts.map +1 -0
  561. package/lib/types/questions.js +201 -0
  562. package/lib/types/screens/Chat.d.ts +23 -0
  563. package/lib/types/screens/Chat.d.ts.map +1 -0
  564. package/lib/types/screens/Chat.js +1263 -0
  565. package/lib/types/screens/StatusLine.d.ts +16 -0
  566. package/lib/types/screens/StatusLine.d.ts.map +1 -0
  567. package/lib/types/screens/StatusLine.js +105 -0
  568. package/lib/types/screens/StatusMetrics.d.ts +87 -0
  569. package/lib/types/screens/StatusMetrics.d.ts.map +1 -0
  570. package/lib/types/screens/StatusMetrics.js +252 -0
  571. package/lib/types/sessionHistory.d.ts +32 -0
  572. package/lib/types/sessionHistory.d.ts.map +1 -0
  573. package/lib/types/sessionHistory.js +87 -0
  574. package/lib/types/theme.d.ts +115 -0
  575. package/lib/types/theme.d.ts.map +1 -0
  576. package/lib/types/theme.js +300 -0
  577. package/lib/types/themePrefs.d.ts +28 -0
  578. package/lib/types/themePrefs.d.ts.map +1 -0
  579. package/lib/types/themePrefs.js +59 -0
  580. package/lib/types/ui.d.ts +28 -0
  581. package/lib/types/ui.d.ts.map +1 -0
  582. package/lib/types/ui.js +25 -0
  583. package/lib/types/update.d.ts +76 -0
  584. package/lib/types/update.d.ts.map +1 -0
  585. package/lib/types/update.js +203 -0
  586. package/lib/types/utils/clipboard.d.ts +43 -0
  587. package/lib/types/utils/clipboard.d.ts.map +1 -0
  588. package/lib/types/utils/clipboard.js +82 -0
  589. package/lib/types/utils/debug.d.ts +8 -0
  590. package/lib/types/utils/debug.d.ts.map +1 -0
  591. package/lib/types/utils/debug.js +12 -0
  592. package/lib/types/utils/earlyInput.d.ts +7 -0
  593. package/lib/types/utils/earlyInput.d.ts.map +1 -0
  594. package/lib/types/utils/earlyInput.js +6 -0
  595. package/lib/types/utils/env.d.ts +10 -0
  596. package/lib/types/utils/env.d.ts.map +1 -0
  597. package/lib/types/utils/env.js +9 -0
  598. package/lib/types/utils/envUtils.d.ts +8 -0
  599. package/lib/types/utils/envUtils.d.ts.map +1 -0
  600. package/lib/types/utils/envUtils.js +13 -0
  601. package/lib/types/utils/execFileNoThrow.d.ts +34 -0
  602. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -0
  603. package/lib/types/utils/execFileNoThrow.js +31 -0
  604. package/lib/types/utils/fullscreen.d.ts +8 -0
  605. package/lib/types/utils/fullscreen.d.ts.map +1 -0
  606. package/lib/types/utils/fullscreen.js +10 -0
  607. package/lib/types/utils/intl.d.ts +7 -0
  608. package/lib/types/utils/intl.d.ts.map +1 -0
  609. package/lib/types/utils/intl.js +9 -0
  610. package/lib/types/utils/loaded-context.d.ts +20 -0
  611. package/lib/types/utils/loaded-context.d.ts.map +1 -0
  612. package/lib/types/utils/loaded-context.js +36 -0
  613. package/lib/types/utils/log.d.ts +7 -0
  614. package/lib/types/utils/log.d.ts.map +1 -0
  615. package/lib/types/utils/log.js +9 -0
  616. package/lib/types/utils/mentions.d.ts +30 -0
  617. package/lib/types/utils/mentions.d.ts.map +1 -0
  618. package/lib/types/utils/mentions.js +72 -0
  619. package/lib/types/utils/narration.d.ts +11 -0
  620. package/lib/types/utils/narration.d.ts.map +1 -0
  621. package/lib/types/utils/narration.js +16 -0
  622. package/lib/types/utils/semver.d.ts +9 -0
  623. package/lib/types/utils/semver.d.ts.map +1 -0
  624. package/lib/types/utils/semver.js +24 -0
  625. package/lib/types/utils/sliceAnsi.d.ts +12 -0
  626. package/lib/types/utils/sliceAnsi.d.ts.map +1 -0
  627. package/lib/types/utils/sliceAnsi.js +79 -0
  628. package/lib/types/working-activity.d.ts +19 -0
  629. package/lib/types/working-activity.d.ts.map +1 -0
  630. package/lib/types/working-activity.js +18 -0
  631. package/package.json +141 -0
  632. package/skills/audit/SKILL.md +24 -0
  633. package/skills/bug/SKILL.md +27 -0
  634. package/skills/pr-comments/SKILL.md +20 -0
  635. package/skills/practice/SKILL.md +22 -0
  636. package/skills/release-notes/SKILL.md +25 -0
  637. package/skills/review/SKILL.md +25 -0
  638. package/skills/vuln-check/SKILL.md +25 -0
@@ -0,0 +1,778 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { t } from '../i18n.js';
4
+ import { Box, Text, useInput, useTerminalSize } from '../ui.js';
5
+ import { useDeclaredCursor } from '../ink/hooks/use-declared-cursor.js';
6
+ import { stringWidth } from '../ink/stringWidth.js';
7
+ import { formatClipboardInsert, readClipboard } from '../utils/clipboard.js';
8
+ import { filterCommands, parseCommandName } from '../commands.js';
9
+ import { appendHistory } from '../history.js';
10
+ import { mentionAtCaret } from '../utils/mentions.js';
11
+ import { CommandSuggestions } from './CommandSuggestions.js';
12
+ import { FileSuggestions } from './FileSuggestions.js';
13
+ import { HelpMenu } from './HelpMenu.js';
14
+ const HISTORY_LIMIT = 50;
15
+ /** Index of the word boundary at or before `cursor` (readline alt+b). */
16
+ function wordBoundaryLeft(text, cursor) {
17
+ let index = cursor;
18
+ while (index > 0 && /\s/.test(text[index - 1]))
19
+ index--;
20
+ while (index > 0 && !/\s/.test(text[index - 1]))
21
+ index--;
22
+ return index;
23
+ }
24
+ /** Index of the word boundary after `cursor` (readline alt+f). */
25
+ function wordBoundaryRight(text, cursor) {
26
+ const length = text.length;
27
+ let index = cursor;
28
+ while (index < length && !/\s/.test(text[index]))
29
+ index++;
30
+ while (index < length && /\s/.test(text[index]))
31
+ index++;
32
+ return index;
33
+ }
34
+ /**
35
+ * The empty input deliberately shows NO placeholder text: terminal emulators
36
+ * paint the IME preedit (pinyin) at the physical cursor, which the app parks
37
+ * on the caret's cell, and the app receives no input events while a
38
+ * composition is active (Windows Terminal suppresses key events during TSF
39
+ * composition) — so it can never hide a placeholder in time. Keeping the row
40
+ * blank while empty is what guarantees the preedit has nothing to overlay.
41
+ */
42
+ /** Max input rows before the visible viewport starts scrolling (CC's
43
+ * maxVisibleLines behavior — the box keeps a stable height). */
44
+ const MAX_VISIBLE_LINES = 5;
45
+ /**
46
+ * Claude Code style prompt input: rounded border box (top+bottom borders
47
+ * only), `❯ ` prompt char (dimmed while a turn is working), the text with a
48
+ * block cursor at the cursor position, and below it the slash-command
49
+ * suggestion overlay (name column + description, selected row in the
50
+ * `suggestion` color — ported from the leak's PromptInputFooterSuggestions).
51
+ *
52
+ * Empty input: a solid block caret on a blank cell and nothing else — no
53
+ * placeholder text, so the terminal-painted IME preedit (pinyin) at the
54
+ * parked cursor can never be overlaid on anything.
55
+ *
56
+ * Multi-line: Shift+Enter inserts a newline; ↑/↓ move between lines while
57
+ * the input spans multiple lines (history/command selection otherwise); the
58
+ * visible window scrolls to keep the caret row on screen past
59
+ * MAX_VISIBLE_LINES. Enter submits, backspace/delete edit, ←/→ move the
60
+ * cursor, Tab completes the selected command, Escape clears (or closes the
61
+ * help menu), `?` toggles the help menu. Windows ConPTY pipelines deliver
62
+ * whole lines with the Enter key lost: a trailing CR/LF in the input marks
63
+ * a complete line to submit.
64
+ *
65
+ * Enter submits immediately even while the model is streaming — as a STEER
66
+ * (Codex/pi semantics): the message is injected at the next step boundary
67
+ * of the running turn and the agent continues without aborting; Tab instead
68
+ * queues the message for after the turn (followup). Both appear in a
69
+ * pending preview above the input until delivered. Alt+Up pulls the last
70
+ * pending message back for editing; Esc (with pending messages while
71
+ * working) interrupts the turn and delivers them right away; Ctrl+Enter
72
+ * aborts the turn and sends the current input immediately.
73
+ */
74
+ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, selectionActive, fillText, onFillConsumed, onRewindRequest, controllerRef, }) {
75
+ const [value, setValue] = React.useState('');
76
+ const [cursor, setCursor] = React.useState(0);
77
+ // Publish the live controller (fresh closure over `value` every render).
78
+ // clear() mirrors the double-tap-Esc clear: text + caret reset.
79
+ React.useEffect(() => {
80
+ if (!controllerRef)
81
+ return;
82
+ controllerRef.current = {
83
+ hasText: () => value.length > 0,
84
+ clear: () => {
85
+ setValue('');
86
+ setCursor(0);
87
+ },
88
+ };
89
+ return () => {
90
+ controllerRef.current = null;
91
+ };
92
+ });
93
+ const [selectedCommand, setSelectedCommand] = React.useState(0);
94
+ const history = React.useRef([]);
95
+ const historyIndex = React.useRef(-1);
96
+ // ctrl+r history fill: replace the input when a new fill arrives, then
97
+ // tell the caller to clear it.
98
+ const lastFill = React.useRef(null);
99
+ React.useEffect(() => {
100
+ if (fillText && fillText !== lastFill.current) {
101
+ lastFill.current = fillText;
102
+ setValue(fillText);
103
+ setCursor(fillText.length);
104
+ onFillConsumed?.();
105
+ }
106
+ }, [fillText, onFillConsumed]);
107
+ // Double-tap Esc to clear (CC semantics).
108
+ const escPendingRef = React.useRef(false);
109
+ const escTimerRef = React.useRef(null);
110
+ /** True while a Ctrl+V clipboard read is in flight (ignore repeat keys). */
111
+ const clipboardBusyRef = React.useRef(false);
112
+ /** Enter dedupe window: cmd pipelines can deliver one Enter as `\r`+`\n`. */
113
+ const lastEnterAtRef = React.useRef(0);
114
+ React.useEffect(() => {
115
+ return () => {
116
+ if (escTimerRef.current)
117
+ clearTimeout(escTimerRef.current);
118
+ };
119
+ }, []);
120
+ const { columns } = useTerminalSize();
121
+ const suggestions = value.startsWith('/')
122
+ ? filterCommands(value, channel.commandList)
123
+ : [];
124
+ const overlayOpen = suggestions.length > 0 &&
125
+ !helpOpen &&
126
+ !selectionActive &&
127
+ !value.includes('\n');
128
+ // `@` file completion (issue #15): the trigger is the mention token at the
129
+ // CARET, so `@` works mid-message (`看看 @src/a.ts 这个`), not only when it
130
+ // is the input's first character. The cwd listing loads when the trigger
131
+ // appears.
132
+ const [fileList, setFileList] = React.useState([]);
133
+ const [fileSelected, setFileSelected] = React.useState(0);
134
+ const mention = mentionAtCaret(value, cursor);
135
+ const atTrigger = mention !== undefined;
136
+ React.useEffect(() => {
137
+ if (atTrigger) {
138
+ void channel.listFiles().then(setFileList);
139
+ }
140
+ }, [atTrigger, channel]);
141
+ const atRest = (mention?.query ?? '').toLowerCase();
142
+ // Match the relative path prefix OR the basename (CC's IDE suggestions do
143
+ // both): `@src/ink` and `@ink` both find `src/ink/Box.js`.
144
+ const fileMatches = atTrigger
145
+ ? fileList.filter(file => {
146
+ const lower = file.toLowerCase();
147
+ if (lower.startsWith(atRest))
148
+ return true;
149
+ if (atRest.includes('/'))
150
+ return false;
151
+ const base = lower.split('/').pop() ?? '';
152
+ return base.startsWith(atRest);
153
+ })
154
+ : [];
155
+ // Esc dismisses the overlay for the token being edited (it reopens once the
156
+ // text changes); it must NOT clear a mid-message input.
157
+ const fileEscRef = React.useRef(-1);
158
+ React.useEffect(() => {
159
+ fileEscRef.current = -1;
160
+ }, [value]);
161
+ const fileOverlayOpen = fileMatches.length > 0 &&
162
+ !helpOpen &&
163
+ !selectionActive &&
164
+ fileEscRef.current !== mention?.start;
165
+ /**
166
+ * Accept the selected file suggestion: replace ONLY the mention token at
167
+ * the caret (prefix/suffix text survives), quoting whitespace paths. A
168
+ * directory inserts `@dir/` without a trailing space so completion
169
+ * continues into it; a file completes the token with a space.
170
+ */
171
+ const acceptFile = (file) => {
172
+ if (!mention)
173
+ return;
174
+ const body = /\s/.test(file) ? `@"${file}"` : `@${file}`;
175
+ const insert = file.endsWith('/') ? body : `${body} `;
176
+ const next = value.slice(0, mention.start) + insert + value.slice(mention.end);
177
+ setInput(next, mention.start + insert.length);
178
+ setFileSelected(0);
179
+ };
180
+ const submitText = (text, notice) => {
181
+ const trimmed = text.trim();
182
+ if (!trimmed)
183
+ return;
184
+ history.current.push(trimmed);
185
+ if (history.current.length > HISTORY_LIMIT)
186
+ history.current.shift();
187
+ historyIndex.current = -1;
188
+ setValue('');
189
+ setCursor(0);
190
+ setSelectedCommand(0);
191
+ appendHistory(trimmed);
192
+ channel.submit(trimmed);
193
+ if (notice) {
194
+ channel.notify(notice, { timeoutMs: 2500 });
195
+ }
196
+ else if (channel.working) {
197
+ // While the model is streaming, the message joins the DSH inbox and is
198
+ // processed after the current turn — say so, or it looks "lost".
199
+ channel.notify(t('input-sent-after-turn'), { timeoutMs: 2500 });
200
+ }
201
+ };
202
+ /**
203
+ * Enter while the model is working = STEER (Codex/pi semantics): the
204
+ * message is injected at the next step boundary of the RUNNING turn and
205
+ * the agent continues without aborting — the "immediate" send.
206
+ */
207
+ const steerSend = (text) => {
208
+ const trimmed = text.trim();
209
+ if (!trimmed)
210
+ return;
211
+ history.current.push(trimmed);
212
+ if (history.current.length > HISTORY_LIMIT)
213
+ history.current.shift();
214
+ historyIndex.current = -1;
215
+ setValue('');
216
+ setCursor(0);
217
+ setSelectedCommand(0);
218
+ appendHistory(trimmed);
219
+ channel.steer(trimmed);
220
+ channel.notify(t('input-interrupted-next'), { timeoutMs: 2500 });
221
+ };
222
+ /**
223
+ * Tab while the model is working = plain queue (followup): the message
224
+ * waits for the running turn to end, then is processed in order.
225
+ */
226
+ const queueSend = (text) => {
227
+ const trimmed = text.trim();
228
+ if (!trimmed)
229
+ return;
230
+ history.current.push(trimmed);
231
+ if (history.current.length > HISTORY_LIMIT)
232
+ history.current.shift();
233
+ historyIndex.current = -1;
234
+ setValue('');
235
+ setCursor(0);
236
+ setSelectedCommand(0);
237
+ appendHistory(trimmed);
238
+ channel.submit(trimmed);
239
+ channel.notify(t('input-queued-after-turn'), { timeoutMs: 2500 });
240
+ };
241
+ /**
242
+ * Alt+Up: pull the last pending message back into the input for editing
243
+ * (never interrupts the running turn). Refused when the running dsh-agent
244
+ * cannot withdraw inbox messages (released package without the inbox API).
245
+ */
246
+ const pullBackLast = () => {
247
+ const item = channel.pending[channel.pending.length - 1];
248
+ if (!item)
249
+ return;
250
+ if (!channel.removePending(item.id)) {
251
+ channel.notify(t('input-cannot-retract'), { color: 'warning', timeoutMs: 2500 });
252
+ return;
253
+ }
254
+ setValue(item.text);
255
+ setCursor(item.text.length);
256
+ setSelectedCommand(0);
257
+ setFileSelected(0);
258
+ channel.notify(t('input-retracted'), { timeoutMs: 2000 });
259
+ };
260
+ /**
261
+ * Ctrl+Enter: abort the running turn and send the input immediately — the
262
+ * model stops what it is doing and starts on this message right away.
263
+ */
264
+ const interruptSend = () => {
265
+ const trimmed = value.trim();
266
+ if (!trimmed) {
267
+ channel.notify(t('input-empty'), { color: 'warning' });
268
+ return;
269
+ }
270
+ // Abort the running turn and deliver: previously queued pending
271
+ // messages first (FIFO), then the current input — all processed
272
+ // immediately once the abort settles.
273
+ const count = channel.interruptAndDeliver([...channel.pending.map(item => item.text), value]);
274
+ if (count === 0)
275
+ return;
276
+ history.current.push(trimmed);
277
+ if (history.current.length > HISTORY_LIMIT)
278
+ history.current.shift();
279
+ historyIndex.current = -1;
280
+ setValue('');
281
+ setCursor(0);
282
+ setSelectedCommand(0);
283
+ setFileSelected(0);
284
+ appendHistory(trimmed);
285
+ channel.notify(t('input-interrupt-immediate'), { timeoutMs: 2500 });
286
+ };
287
+ /**
288
+ * Execute a slash command (built-in or plugin-registered) when the input
289
+ * resolves to one: the name parses as the first token so `/plan off`
290
+ * dispatches `plan` with its argument text, and the merged command list
291
+ * (locals + registry) decides whether the line is a command at all.
292
+ */
293
+ const tryRunCommand = (text) => {
294
+ if (!text.startsWith('/'))
295
+ return false;
296
+ const parsed = parseCommandName(text);
297
+ if (parsed === undefined)
298
+ return false;
299
+ const known = channel.commandList.some(command => command.name === parsed.name);
300
+ if (!known)
301
+ return false;
302
+ const handled = onRunCommand(parsed.name, parsed.rawInput);
303
+ if (handled) {
304
+ history.current.push(text.trim());
305
+ if (history.current.length > HISTORY_LIMIT)
306
+ history.current.shift();
307
+ historyIndex.current = -1;
308
+ setValue('');
309
+ setCursor(0);
310
+ setSelectedCommand(0);
311
+ appendHistory(text.trim());
312
+ }
313
+ return handled;
314
+ };
315
+ const setInput = (next, cursorOffset = next.length) => {
316
+ setValue(next);
317
+ setCursor(Math.max(0, Math.min(cursorOffset, next.length)));
318
+ };
319
+ /** Line index of the cursor; -1 when the cursor is at the very end. */
320
+ const cursorLine = () => {
321
+ const before = value.slice(0, cursor);
322
+ return before.split('\n').length - 1;
323
+ };
324
+ /** Column of the cursor within its line. */
325
+ const cursorColumn = () => {
326
+ const before = value.slice(0, cursor);
327
+ const line = before.split('\n').pop() ?? '';
328
+ return line.length;
329
+ };
330
+ useInput((input, key, event) => {
331
+ if (selectionActive)
332
+ return;
333
+ /** Insert text at the caret (typing, paste) and dismiss overlays. */
334
+ const insertAtCaret = (text) => {
335
+ if (helpOpen)
336
+ onToggleHelp();
337
+ const next = value.slice(0, cursor) + text + value.slice(cursor);
338
+ setValue(next);
339
+ setCursor(cursor + text.length);
340
+ setSelectedCommand(0);
341
+ setFileSelected(0);
342
+ };
343
+ // Bracketed paste (terminal paste — Ctrl+Shift+V / right-click): insert
344
+ // verbatim at the caret. Paste content may contain newlines — that is
345
+ // NOT Enter — so this branch runs before the whole-line submit rule.
346
+ if (event?.isPasted && input.length > 0) {
347
+ insertAtCaret(input.replace(/\r\n/g, '\n').replace(/\r/g, '\n'));
348
+ return;
349
+ }
350
+ // Ctrl+V: raw mode hands the key to the app, so the clipboard is read
351
+ // here — text, or file paths when Explorer copied files (pasted files
352
+ // insert their paths).
353
+ if (key.ctrl && input === 'v') {
354
+ if (clipboardBusyRef.current)
355
+ return;
356
+ clipboardBusyRef.current = true;
357
+ void readClipboard().then(content => {
358
+ clipboardBusyRef.current = false;
359
+ if (content === null) {
360
+ channel.notify(t('input-clipboard-empty'), { color: 'warning' });
361
+ return;
362
+ }
363
+ insertAtCaret(formatClipboardInsert(content));
364
+ });
365
+ return;
366
+ }
367
+ /**
368
+ * Unified Enter semantics (both the parsed `return` key and the raw
369
+ * CR/LF line from Windows cmd pipelines):
370
+ * - command menu open → run the SELECTED command (never send `/mo`);
371
+ * - model working → STEER into the running turn (next step boundary,
372
+ * agent continues — the "immediate" send; Codex/pi semantics);
373
+ * - otherwise → submit directly (or run a unique command).
374
+ */
375
+ const handleEnter = () => {
376
+ // A single Enter can arrive as two events in cmd pipelines (`\r`
377
+ // parsed as return + a raw `\n` line): collapse them so one keypress
378
+ // never sends the message twice.
379
+ const now = Date.now();
380
+ if (now - lastEnterAtRef.current < 80)
381
+ return;
382
+ lastEnterAtRef.current = now;
383
+ if (overlayOpen) {
384
+ const command = suggestions[selectedCommand];
385
+ if (command) {
386
+ tryRunCommand(`/${command.name}`);
387
+ return;
388
+ }
389
+ }
390
+ // File-completion overlay open → Enter accepts the selection (same
391
+ // contract as the command menu: the overlay owns Enter while open).
392
+ if (fileOverlayOpen) {
393
+ const file = fileMatches[fileSelected];
394
+ if (file) {
395
+ acceptFile(file);
396
+ return;
397
+ }
398
+ }
399
+ if (channel.working && value.trim() !== '') {
400
+ steerSend(value);
401
+ return;
402
+ }
403
+ if (!tryRunCommand(value))
404
+ submitText(value);
405
+ };
406
+ // Whole-line input from Windows ConPTY pipelines (cmd batch -> node):
407
+ // the trailing CR/LF marks a complete line to submit. A bare Enter
408
+ // arrives as `\r`/`\n`/`\r\n` — treat it as Enter, NOT a direct
409
+ // submit. Only real multi-char piped lines keep the legacy
410
+ // direct-submit path.
411
+ if (input.includes('\n') || input.includes('\r')) {
412
+ if (/^[\r\n]+$/.test(input)) {
413
+ handleEnter();
414
+ return;
415
+ }
416
+ const line = (value + input).trim();
417
+ if (line.startsWith('/')) {
418
+ const matches = filterCommands(line, channel.commandList);
419
+ if (matches.length === 1) {
420
+ tryRunCommand(`/${matches[0].name}`);
421
+ return;
422
+ }
423
+ }
424
+ if (!tryRunCommand(line))
425
+ submitText(line);
426
+ return;
427
+ }
428
+ if (key.return && key.ctrl) {
429
+ // Ctrl+Enter: interrupt the running turn and process this message
430
+ // immediately (Windows Terminal sends CSI 13;5u / 13;1;5u).
431
+ interruptSend();
432
+ return;
433
+ }
434
+ if (key.return && key.shift) {
435
+ // Insert a newline at the caret (multi-line input).
436
+ const next = value.slice(0, cursor) + '\n' + value.slice(cursor);
437
+ setValue(next);
438
+ setCursor(cursor + 1);
439
+ setSelectedCommand(0);
440
+ return;
441
+ }
442
+ if (key.return) {
443
+ handleEnter();
444
+ return;
445
+ }
446
+ // Shift+Tab cycles the reasoning effort (dsh parity: the adapter's own
447
+ // level list, e.g. deepseek Off→High→Max). Must precede the plain-Tab
448
+ // arms — the parser reports backtab as key.tab + key.shift.
449
+ if (key.tab && key.shift) {
450
+ void channel.cycleEffort();
451
+ return;
452
+ }
453
+ if (key.tab && fileOverlayOpen) {
454
+ const file = fileMatches[fileSelected];
455
+ if (file)
456
+ acceptFile(file);
457
+ return;
458
+ }
459
+ if (key.tab && overlayOpen) {
460
+ const command = suggestions[selectedCommand];
461
+ if (command)
462
+ setInput(`/${command.name} `);
463
+ return;
464
+ }
465
+ // Tab while the model is working = queue for AFTER the turn (followup),
466
+ // distinct from Enter's steer (Codex's "tab to queue message").
467
+ if (key.tab && channel.working && value.trim() !== '') {
468
+ queueSend(value);
469
+ return;
470
+ }
471
+ if (key.meta && key.upArrow) {
472
+ // Alt+Up: pull the last pending message back for editing (pi/Codex).
473
+ pullBackLast();
474
+ return;
475
+ }
476
+ if (key.upArrow) {
477
+ if (fileOverlayOpen) {
478
+ setFileSelected(index => index <= 0 ? fileMatches.length - 1 : index - 1);
479
+ return;
480
+ }
481
+ const line = cursorLine();
482
+ if (line > 0) {
483
+ // Move to the previous line, clamping to its length.
484
+ const upToLineStart = value.lastIndexOf('\n', cursor - 1);
485
+ const prevLineStart = upToLineStart === -1 ? 0 : value.lastIndexOf('\n', upToLineStart - 1) + 1;
486
+ const prevLine = value.slice(prevLineStart, upToLineStart);
487
+ setCursor(prevLineStart + Math.min(cursorColumn(), prevLine.length));
488
+ return;
489
+ }
490
+ if (overlayOpen) {
491
+ setSelectedCommand(index => index <= 0 ? suggestions.length - 1 : index - 1);
492
+ return;
493
+ }
494
+ if (history.current.length === 0)
495
+ return;
496
+ historyIndex.current = historyIndex.current < 0
497
+ ? history.current.length - 1
498
+ : Math.max(0, historyIndex.current - 1);
499
+ const entry = history.current[historyIndex.current] ?? '';
500
+ setValue(entry);
501
+ setCursor(entry.length);
502
+ return;
503
+ }
504
+ if (key.downArrow) {
505
+ if (fileOverlayOpen) {
506
+ setFileSelected(index => index >= fileMatches.length - 1 ? 0 : index + 1);
507
+ return;
508
+ }
509
+ const line = cursorLine();
510
+ const lines = value.split('\n');
511
+ if (line < lines.length - 1) {
512
+ const nextLineStart = value.indexOf('\n', cursor) + 1;
513
+ const nextLineEnd = value.indexOf('\n', nextLineStart);
514
+ const nextLine = value.slice(nextLineStart, nextLineEnd === -1 ? value.length : nextLineEnd);
515
+ setCursor(nextLineStart + Math.min(cursorColumn(), nextLine.length));
516
+ return;
517
+ }
518
+ if (overlayOpen) {
519
+ setSelectedCommand(index => index >= suggestions.length - 1 ? 0 : index + 1);
520
+ return;
521
+ }
522
+ if (historyIndex.current < 0)
523
+ return;
524
+ historyIndex.current += 1;
525
+ const entry = historyIndex.current >= history.current.length
526
+ ? ''
527
+ : (history.current[historyIndex.current] ?? '');
528
+ setValue(entry);
529
+ setCursor(entry.length);
530
+ return;
531
+ }
532
+ if (key.leftArrow) {
533
+ setCursor(previous => Math.max(0, previous - 1));
534
+ return;
535
+ }
536
+ if (key.rightArrow) {
537
+ setCursor(previous => Math.min(value.length, previous + 1));
538
+ return;
539
+ }
540
+ if (key.ctrl && key.leftArrow) {
541
+ // Jump to the previous word boundary (readline alt+b).
542
+ setCursor(previous => wordBoundaryLeft(value, previous));
543
+ return;
544
+ }
545
+ if (key.ctrl && key.rightArrow) {
546
+ // Jump to the next word boundary (readline alt+f).
547
+ setCursor(previous => wordBoundaryRight(value, previous));
548
+ return;
549
+ }
550
+ if (key.backspace) {
551
+ if (cursor === 0)
552
+ return;
553
+ setValue(value.slice(0, cursor - 1) + value.slice(cursor));
554
+ setCursor(cursor - 1);
555
+ return;
556
+ }
557
+ if (key.delete) {
558
+ if (cursor >= value.length)
559
+ return;
560
+ setValue(value.slice(0, cursor) + value.slice(cursor + 1));
561
+ return;
562
+ }
563
+ if (key.home) {
564
+ // Start of the current line.
565
+ const lineStart = value.lastIndexOf('\n', cursor - 1) + 1;
566
+ setCursor(lineStart);
567
+ return;
568
+ }
569
+ if (key.end) {
570
+ // End of the current line.
571
+ const nextLine = value.indexOf('\n', cursor);
572
+ setCursor(nextLine === -1 ? value.length : nextLine);
573
+ return;
574
+ }
575
+ if (key.ctrl && input === 'a') {
576
+ const lineStart = value.lastIndexOf('\n', cursor - 1) + 1;
577
+ setCursor(lineStart);
578
+ return;
579
+ }
580
+ if (key.ctrl && input === 'e') {
581
+ const nextLine = value.indexOf('\n', cursor);
582
+ setCursor(nextLine === -1 ? value.length : nextLine);
583
+ return;
584
+ }
585
+ if (key.ctrl && input === 'u') {
586
+ // Delete to start of line.
587
+ const lineStart = value.lastIndexOf('\n', cursor - 1) + 1;
588
+ setValue(value.slice(0, lineStart) + value.slice(cursor));
589
+ setCursor(lineStart);
590
+ return;
591
+ }
592
+ if (key.ctrl && input === 'k') {
593
+ // Delete to end of line.
594
+ const nextLine = value.indexOf('\n', cursor);
595
+ const end = nextLine === -1 ? value.length : nextLine;
596
+ setValue(value.slice(0, cursor) + value.slice(end));
597
+ return;
598
+ }
599
+ if (key.ctrl && input === 'w') {
600
+ // Delete the word before the cursor (CC/readline behavior): skip
601
+ // trailing whitespace, then the whitespace-delimited word.
602
+ const before = value.slice(0, cursor);
603
+ let end = before.length;
604
+ while (end > 0 && /\s/.test(before[end - 1]))
605
+ end--;
606
+ let start = end;
607
+ while (start > 0 && !/\s/.test(before[start - 1]))
608
+ start--;
609
+ setValue(value.slice(0, start) + value.slice(cursor));
610
+ setCursor(start);
611
+ return;
612
+ }
613
+ if (key.escape) {
614
+ if (helpOpen) {
615
+ onToggleHelp();
616
+ return;
617
+ }
618
+ // A single Esc closes the open command menu first (CC/pi behavior);
619
+ // the double-tap-clear semantics only apply to ordinary input.
620
+ if (overlayOpen) {
621
+ setValue('');
622
+ setCursor(0);
623
+ setSelectedCommand(0);
624
+ setFileSelected(0);
625
+ return;
626
+ }
627
+ // File overlay: Esc dismisses the menu for THIS token only — clearing
628
+ // the input would nuke a mid-message `@` mention's surrounding text.
629
+ if (fileOverlayOpen) {
630
+ fileEscRef.current = mention?.start ?? -1;
631
+ return;
632
+ }
633
+ // With pending messages while working, Esc = interrupt and deliver
634
+ // them right away (Codex's "interrupt and send immediately"): the
635
+ // turn is aborted and each message is re-queued once it settles.
636
+ if (channel.working && channel.pending.length > 0) {
637
+ const count = channel.interruptAndDeliver(channel.pending.map(item => item.text));
638
+ channel.notify(t('interrupt-delivered', { n: count }), {
639
+ timeoutMs: 2500,
640
+ });
641
+ return;
642
+ }
643
+ // A single Esc clears the current input (if any); the double-tap
644
+ // path below handles rewind/clear on an already-empty input.
645
+ if (value.length > 0) {
646
+ setValue('');
647
+ setCursor(0);
648
+ setSelectedCommand(0);
649
+ setFileSelected(0);
650
+ return;
651
+ }
652
+ // Double-tap Esc: clear the input when it has content; when empty,
653
+ // open the rewind picker (CC's "Double-tap esc to rewind the code
654
+ // and/or conversation to a previous point in time").
655
+ if (escPendingRef.current) {
656
+ escPendingRef.current = false;
657
+ if (escTimerRef.current)
658
+ clearTimeout(escTimerRef.current);
659
+ if (value.length === 0) {
660
+ onRewindRequest?.();
661
+ }
662
+ else {
663
+ setValue('');
664
+ setCursor(0);
665
+ }
666
+ return;
667
+ }
668
+ escPendingRef.current = true;
669
+ channel.notify(value.length === 0
670
+ ? 'Press Esc again to rewind'
671
+ : 'Press Esc again to clear');
672
+ escTimerRef.current = setTimeout(() => {
673
+ escPendingRef.current = false;
674
+ }, 3000);
675
+ return;
676
+ }
677
+ if (input === '?' && value.length === 0) {
678
+ onToggleHelp();
679
+ return;
680
+ }
681
+ if (input && !key.ctrl && !key.meta && !key.tab && !key.escape) {
682
+ // Typing anything else dismisses the help menu (CC behavior).
683
+ if (helpOpen)
684
+ onToggleHelp();
685
+ const next = value.slice(0, cursor) + input + value.slice(cursor);
686
+ setValue(next);
687
+ setCursor(cursor + input.length);
688
+ setSelectedCommand(0);
689
+ setFileSelected(0);
690
+ }
691
+ });
692
+ // === Render: hard-wrap every logical line at the input width, then show
693
+ // the window of visual lines with the caret row always visible (CC's
694
+ // maxVisibleLines behavior with automatic wrapping).
695
+ const inputWidth = Math.max(10, columns - 3);
696
+ const visualLines = wrapToWidth(value, inputWidth);
697
+ const caretVisualLine = wrapToWidth(value.slice(0, cursor), inputWidth).length - 1;
698
+ const windowStart = Math.max(0, Math.min(caretVisualLine - MAX_VISIBLE_LINES + 1, visualLines.length - MAX_VISIBLE_LINES));
699
+ const visibleLines = visualLines.slice(windowStart, windowStart + MAX_VISIBLE_LINES);
700
+ // Caret position in the caret's visual row, in two units:
701
+ // - char index (for slicing the row's characters in the render below)
702
+ // - visual column (for the physical cursor declaration — CJK characters
703
+ // occupy TWO terminal columns, so the raw char count would park the
704
+ // cursor mid-character and Windows Terminal would paint the IME
705
+ // preedit (pinyin) over the surrounding text).
706
+ const caretCharCol = () => {
707
+ const before = value.slice(0, cursor);
708
+ const rows = wrapToWidth(before, inputWidth);
709
+ const last = rows[rows.length - 1] ?? '';
710
+ return last.length;
711
+ };
712
+ const caretVisualCol = () => {
713
+ const before = value.slice(0, cursor);
714
+ const rows = wrapToWidth(before, inputWidth);
715
+ const last = rows[rows.length - 1] ?? '';
716
+ return stringWidth(last);
717
+ };
718
+ const rendered = visibleLines.map((line, index) => {
719
+ const absoluteLine = windowStart + index;
720
+ if (absoluteLine !== caretVisualLine) {
721
+ return (_jsx(Text, { wrap: "truncate-end", children: line }, absoluteLine));
722
+ }
723
+ // Caret row: invert the char at the caret column (solid block).
724
+ const col = caretCharCol();
725
+ const before = line.slice(0, col);
726
+ const at = line[col] ?? ' ';
727
+ const after = line.slice(col + 1);
728
+ return (_jsxs(Text, { wrap: "truncate-end", children: [before, _jsx(Text, { inverse: true, children: at }), after] }, absoluteLine));
729
+ });
730
+ const lastNotification = channel.notifications[channel.notifications.length - 1];
731
+ // Park the native terminal cursor at the input caret (via the renderer's
732
+ // cursor-declaration mechanism). Terminal emulators render IME preedit
733
+ // text and screen-reader focus at the physical cursor, so parking it at
734
+ // the caret makes CJK/IME composition appear inline at the input instead
735
+ // of at the screen's bottom row; in line-mode terminals the console echo
736
+ // of typed characters lands at the same spot. `line`/`column` are
737
+ // relative to the value box the ref attaches to.
738
+ const valueBoxRef = useDeclaredCursor({
739
+ line: caretVisualLine - windowStart,
740
+ column: caretVisualCol(),
741
+ active: !selectionActive,
742
+ });
743
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [lastNotification && (_jsx(Box, { position: "absolute", marginTop: -1, height: 1, width: "100%", paddingLeft: 2, paddingRight: 1, flexDirection: "column", justifyContent: "flex-end", overflow: "hidden", children: _jsx(Box, { justifyContent: "flex-end", children: _jsx(Text, { color: lastNotification.color, dimColor: !lastNotification.color, wrap: "truncate", children: lastNotification.text }) }) })), helpOpen && (_jsx(Box, { marginBottom: 1, children: _jsx(HelpMenu, { commands: channel.commandList }) })), channel.pending.length > 0 && (_jsxs(Box, { flexDirection: "column", paddingLeft: 2, paddingBottom: 1, children: [channel.pending.some(item => item.placement === 'steer') && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["\u26A1 ", t('input-pending-steer-label')] }), channel.pending
744
+ .filter(item => item.placement === 'steer')
745
+ .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), channel.pending.some(item => item.placement === 'followup') && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { dimColor: true, children: ["\u23F3 ", t('input-pending-queue-label')] }), channel.pending
746
+ .filter(item => item.placement === 'followup')
747
+ .map(item => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [' ', "\u21B3 ", item.text] }, item.id)))] })), _jsxs(Text, { dimColor: true, children: ["Alt+\u2191 ", t('input-pending-actions-hint')] })] })), fileOverlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(FileSuggestions, { files: fileMatches, selectedIndex: fileSelected, columns: columns }) })), overlayOpen && (_jsx(Box, { paddingLeft: 2, paddingBottom: 1, children: _jsx(CommandSuggestions, { commands: suggestions, selectedIndex: selectedCommand, columns: columns }) })), _jsx(Box, { flexDirection: "column", alignItems: "flex-start", justifyContent: "flex-start", borderColor: "promptBorder", borderStyle: "round", borderLeft: false, borderRight: false, borderBottom: true, width: "100%", children: _jsxs(Box, { flexDirection: "row", alignItems: "flex-start", width: "100%", children: [_jsx(Text, { dimColor: channel.working, children: "\u276F " }), _jsx(Box, { ref: valueBoxRef, flexGrow: 1, flexShrink: 1, children: value.length === 0 ? (_jsx(Text, { inverse: true, children: " " })) : (_jsx(Box, { flexDirection: "column", children: rendered })) })] }) })] }));
748
+ }
749
+ /**
750
+ * Hard-wrap text into visual rows of at most `width` columns (CJK-aware via
751
+ * stringWidth). Used by the input renderer so long lines wrap instead of
752
+ * truncating, with exact caret-row mapping.
753
+ */
754
+ function wrapToWidth(text, width) {
755
+ const rows = [];
756
+ for (const line of text.split('\n')) {
757
+ if (line === '') {
758
+ rows.push('');
759
+ continue;
760
+ }
761
+ let current = '';
762
+ let currentWidth = 0;
763
+ for (const ch of line) {
764
+ const w = stringWidth(ch);
765
+ if (currentWidth + w > width && current !== '') {
766
+ rows.push(current);
767
+ current = ch;
768
+ currentWidth = w;
769
+ }
770
+ else {
771
+ current += ch;
772
+ currentWidth += w;
773
+ }
774
+ }
775
+ rows.push(current);
776
+ }
777
+ return rows;
778
+ }