@deepseek-harness-tui/dsh-tui 0.8.8 → 0.9.1

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 (467) hide show
  1. package/README.md +60 -238
  2. package/bin/dsh-tui.js +172 -5
  3. package/cordis.patch.yml +16 -4
  4. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
  5. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
  6. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
  7. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
  8. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
  9. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
  10. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
  11. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
  12. package/dsh-ecosystem-spec/registry/README.md +14 -14
  13. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
  14. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
  15. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
  16. package/lib/types/cc/hyperlink.d.ts +7 -1
  17. package/lib/types/cc/hyperlink.d.ts.map +1 -1
  18. package/lib/types/cc/hyperlink.js +3 -2
  19. package/lib/types/cc/markdown.d.ts.map +1 -1
  20. package/lib/types/cc/markdown.js +33 -3
  21. package/lib/types/cc/sessionColors.d.ts +27 -0
  22. package/lib/types/cc/sessionColors.d.ts.map +1 -0
  23. package/lib/types/cc/sessionColors.js +39 -0
  24. package/lib/types/commands.d.ts.map +1 -1
  25. package/lib/types/commands.js +10 -2
  26. package/lib/types/components/ActivityPicker.d.ts +4 -1
  27. package/lib/types/components/ActivityPicker.d.ts.map +1 -1
  28. package/lib/types/components/ActivityPicker.js +2 -2
  29. package/lib/types/components/AutoRecapRow.d.ts +23 -0
  30. package/lib/types/components/AutoRecapRow.d.ts.map +1 -0
  31. package/lib/types/components/AutoRecapRow.js +23 -0
  32. package/lib/types/components/BtwPanel.d.ts.map +1 -1
  33. package/lib/types/components/BtwPanel.js +1 -1
  34. package/lib/types/components/Chat/SubagentMessage.d.ts +2 -1
  35. package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -1
  36. package/lib/types/components/Chat/SubagentMessage.js +11 -3
  37. package/lib/types/components/ColorPicker.d.ts +17 -0
  38. package/lib/types/components/ColorPicker.d.ts.map +1 -0
  39. package/lib/types/components/ColorPicker.js +20 -0
  40. package/lib/types/components/CommandSuggestions.d.ts +23 -4
  41. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  42. package/lib/types/components/CommandSuggestions.js +41 -14
  43. package/lib/types/components/ContextBarView.d.ts +33 -0
  44. package/lib/types/components/ContextBarView.d.ts.map +1 -0
  45. package/lib/types/components/ContextBarView.js +46 -0
  46. package/lib/types/components/EffortInputBorder.d.ts +12 -1
  47. package/lib/types/components/EffortInputBorder.d.ts.map +1 -1
  48. package/lib/types/components/EffortInputBorder.js +22 -5
  49. package/lib/types/components/EffortSlider.d.ts +4 -1
  50. package/lib/types/components/EffortSlider.d.ts.map +1 -1
  51. package/lib/types/components/EffortSlider.js +4 -2
  52. package/lib/types/components/ExtensionDialog.js +6 -2
  53. package/lib/types/components/FileActionsPanel.d.ts +22 -0
  54. package/lib/types/components/FileActionsPanel.d.ts.map +1 -0
  55. package/lib/types/components/FileActionsPanel.js +28 -0
  56. package/lib/types/components/FileSuggestions.d.ts +26 -7
  57. package/lib/types/components/FileSuggestions.d.ts.map +1 -1
  58. package/lib/types/components/FileSuggestions.js +39 -12
  59. package/lib/types/components/GoalTodoPanel.d.ts +26 -2
  60. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
  61. package/lib/types/components/GoalTodoPanel.js +86 -17
  62. package/lib/types/components/HelpMenu.d.ts +7 -1
  63. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  64. package/lib/types/components/HelpMenu.js +12 -4
  65. package/lib/types/components/HistorySearchDialog.d.ts +4 -1
  66. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
  67. package/lib/types/components/HistorySearchDialog.js +2 -2
  68. package/lib/types/components/LangPicker.d.ts +14 -0
  69. package/lib/types/components/LangPicker.d.ts.map +1 -0
  70. package/lib/types/components/LangPicker.js +17 -0
  71. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  72. package/lib/types/components/LoadedContextPanel.js +3 -1
  73. package/lib/types/components/Markdown.d.ts.map +1 -1
  74. package/lib/types/components/Markdown.js +12 -3
  75. package/lib/types/components/MessageList.d.ts +45 -2
  76. package/lib/types/components/MessageList.d.ts.map +1 -1
  77. package/lib/types/components/MessageList.js +560 -41
  78. package/lib/types/components/ModelPicker.d.ts +27 -2
  79. package/lib/types/components/ModelPicker.d.ts.map +1 -1
  80. package/lib/types/components/ModelPicker.js +26 -6
  81. package/lib/types/components/PermissionsPicker.d.ts +21 -0
  82. package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
  83. package/lib/types/components/PermissionsPicker.js +27 -0
  84. package/lib/types/components/PlanPicker.d.ts +15 -0
  85. package/lib/types/components/PlanPicker.d.ts.map +1 -0
  86. package/lib/types/components/PlanPicker.js +18 -0
  87. package/lib/types/components/PresetPicker.d.ts +4 -1
  88. package/lib/types/components/PresetPicker.d.ts.map +1 -1
  89. package/lib/types/components/PresetPicker.js +2 -2
  90. package/lib/types/components/PromptInput.d.ts +4 -3
  91. package/lib/types/components/PromptInput.d.ts.map +1 -1
  92. package/lib/types/components/PromptInput.js +602 -75
  93. package/lib/types/components/RecapPanel.d.ts +25 -0
  94. package/lib/types/components/RecapPanel.d.ts.map +1 -0
  95. package/lib/types/components/RecapPanel.js +55 -0
  96. package/lib/types/components/RewindPicker.d.ts +12 -1
  97. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  98. package/lib/types/components/RewindPicker.js +6 -4
  99. package/lib/types/components/ScrollbarGutter.d.ts +28 -0
  100. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
  101. package/lib/types/components/ScrollbarGutter.js +119 -0
  102. package/lib/types/components/Select.d.ts +8 -1
  103. package/lib/types/components/Select.d.ts.map +1 -1
  104. package/lib/types/components/Select.js +4 -2
  105. package/lib/types/components/SkillsPicker.d.ts +4 -1
  106. package/lib/types/components/SkillsPicker.d.ts.map +1 -1
  107. package/lib/types/components/SkillsPicker.js +2 -2
  108. package/lib/types/components/SubagentCard.d.ts +2 -1
  109. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  110. package/lib/types/components/SubagentCard.js +9 -2
  111. package/lib/types/components/SubagentDashboard.d.ts +4 -0
  112. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  113. package/lib/types/components/SubagentDashboard.js +9 -1
  114. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  115. package/lib/types/components/SubagentDetailScene.js +5 -4
  116. package/lib/types/components/SuggestionCard.d.ts +65 -0
  117. package/lib/types/components/SuggestionCard.d.ts.map +1 -0
  118. package/lib/types/components/SuggestionCard.js +77 -0
  119. package/lib/types/components/ThemePicker.d.ts +4 -1
  120. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  121. package/lib/types/components/ThemePicker.js +2 -2
  122. package/lib/types/components/ThinkingToggle.d.ts +4 -1
  123. package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
  124. package/lib/types/components/ThinkingToggle.js +2 -2
  125. package/lib/types/components/TimelineRail.d.ts +53 -0
  126. package/lib/types/components/TimelineRail.d.ts.map +1 -0
  127. package/lib/types/components/TimelineRail.js +197 -0
  128. package/lib/types/components/WorkspaceFlowPicker.d.ts +6 -1
  129. package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -1
  130. package/lib/types/components/WorkspaceFlowPicker.js +4 -2
  131. package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
  132. package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
  133. package/lib/types/components/WorkspaceMenuPicker.js +19 -0
  134. package/lib/types/components/WorkspacePicker.d.ts +4 -1
  135. package/lib/types/components/WorkspacePicker.d.ts.map +1 -1
  136. package/lib/types/components/WorkspacePicker.js +2 -2
  137. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
  138. package/lib/types/components/approvals/ApprovalPanel.js +5 -1
  139. package/lib/types/components/design-system/ListItem.d.ts +8 -1
  140. package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
  141. package/lib/types/components/design-system/ListItem.js +8 -3
  142. package/lib/types/components/design-system/ThemeProvider.d.ts +7 -0
  143. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  144. package/lib/types/components/design-system/ThemeProvider.js +2 -1
  145. package/lib/types/components/messages/AssistantTextMessage.d.ts +5 -2
  146. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
  147. package/lib/types/components/messages/AssistantTextMessage.js +6 -2
  148. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  149. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  150. package/lib/types/components/messages/AssistantThinkingMessage.js +10 -4
  151. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +15 -1
  152. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  153. package/lib/types/components/messages/AssistantToolUseMessage.js +37 -7
  154. package/lib/types/components/messages/UserPromptMessage.d.ts +2 -1
  155. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  156. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +7 -3
  157. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  158. package/lib/types/components/questions/AskUserQuestionPanel.js +75 -11
  159. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  160. package/lib/types/components/questions/PlanReviewPanel.js +13 -2
  161. package/lib/types/components/sessions/SessionListRow.d.ts +4 -1
  162. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
  163. package/lib/types/components/sessions/SessionListRow.js +4 -2
  164. package/lib/types/components/trajectory/HotspotView.d.ts +7 -1
  165. package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -1
  166. package/lib/types/components/trajectory/HotspotView.js +8 -2
  167. package/lib/types/components/trajectory/Ledger.d.ts +9 -1
  168. package/lib/types/components/trajectory/Ledger.d.ts.map +1 -1
  169. package/lib/types/components/trajectory/Ledger.js +23 -5
  170. package/lib/types/components/trajectory/WaveBand.d.ts +10 -1
  171. package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -1
  172. package/lib/types/components/trajectory/WaveBand.js +7 -2
  173. package/lib/types/dsh-adapter/channel.d.ts +117 -7
  174. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  175. package/lib/types/dsh-adapter/channel.js +1301 -122
  176. package/lib/types/dsh-adapter/compat/index.d.ts +8 -6
  177. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  178. package/lib/types/dsh-adapter/compat/index.js +8 -6
  179. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +150 -0
  180. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  181. package/lib/types/dsh-adapter/compat/sessionLog.js +518 -41
  182. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  183. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  184. package/lib/types/dsh-adapter/contract.js +1 -0
  185. package/lib/types/dsh-adapter/extension-events.d.ts +1 -1
  186. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
  187. package/lib/types/dsh-adapter/index.d.ts +20 -2
  188. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  189. package/lib/types/dsh-adapter/index.js +9 -1
  190. package/lib/types/dsh-adapter/plugin.d.ts +0 -9
  191. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  192. package/lib/types/dsh-adapter/plugin.js +453 -14
  193. package/lib/types/dsh-adapter/presets.d.ts +18 -0
  194. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  195. package/lib/types/dsh-adapter/presets.js +31 -0
  196. package/lib/types/dsh-adapter/providerWizard.d.ts +29 -1
  197. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  198. package/lib/types/dsh-adapter/providerWizard.js +89 -5
  199. package/lib/types/dsh-adapter/questions.d.ts +19 -2
  200. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  201. package/lib/types/dsh-adapter/questions.js +53 -10
  202. package/lib/types/dsh-adapter/recap.d.ts +49 -0
  203. package/lib/types/dsh-adapter/recap.d.ts.map +1 -0
  204. package/lib/types/dsh-adapter/recap.js +121 -0
  205. package/lib/types/dsh-adapter/sessionTree.d.ts +314 -0
  206. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -0
  207. package/lib/types/dsh-adapter/sessionTree.js +954 -0
  208. package/lib/types/dsh-adapter/shortcuts.d.ts +15 -44
  209. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
  210. package/lib/types/dsh-adapter/shortcuts.js +28 -165
  211. package/lib/types/dsh-adapter/types.d.ts +1 -1
  212. package/lib/types/dsh-adapter/types.d.ts.map +1 -1
  213. package/lib/types/herdr.js +1 -1
  214. package/lib/types/i18n.d.ts +770 -181
  215. package/lib/types/i18n.d.ts.map +1 -1
  216. package/lib/types/i18n.js +257 -80
  217. package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -1
  218. package/lib/types/ink/components/AlternateScreen.js +13 -1
  219. package/lib/types/ink/components/App.d.ts +12 -1
  220. package/lib/types/ink/components/App.d.ts.map +1 -1
  221. package/lib/types/ink/components/App.js +101 -4
  222. package/lib/types/ink/components/ClockContext.d.ts.map +1 -1
  223. package/lib/types/ink/components/ClockContext.js +2 -0
  224. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  225. package/lib/types/ink/components/ScrollBox.js +170 -91
  226. package/lib/types/ink/constants.d.ts +9 -0
  227. package/lib/types/ink/constants.d.ts.map +1 -1
  228. package/lib/types/ink/constants.js +9 -0
  229. package/lib/types/ink/events/click-event.d.ts +7 -16
  230. package/lib/types/ink/events/click-event.d.ts.map +1 -1
  231. package/lib/types/ink/events/click-event.js +16 -19
  232. package/lib/types/ink/events/event-handlers.d.ts +11 -1
  233. package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
  234. package/lib/types/ink/events/event-handlers.js +2 -0
  235. package/lib/types/ink/events/input-event.d.ts +9 -0
  236. package/lib/types/ink/events/input-event.d.ts.map +1 -1
  237. package/lib/types/ink/events/input-event.js +4 -0
  238. package/lib/types/ink/events/pointer-event.d.ts +61 -0
  239. package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
  240. package/lib/types/ink/events/pointer-event.js +61 -0
  241. package/lib/types/ink/events/wheel-event.d.ts +17 -0
  242. package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
  243. package/lib/types/ink/events/wheel-event.js +20 -0
  244. package/lib/types/ink/geometry-trace.d.ts +51 -0
  245. package/lib/types/ink/geometry-trace.d.ts.map +1 -0
  246. package/lib/types/ink/geometry-trace.js +83 -0
  247. package/lib/types/ink/hit-test.d.ts +56 -1
  248. package/lib/types/ink/hit-test.d.ts.map +1 -1
  249. package/lib/types/ink/hit-test.js +146 -8
  250. package/lib/types/ink/ink.d.ts +58 -1
  251. package/lib/types/ink/ink.d.ts.map +1 -1
  252. package/lib/types/ink/ink.js +230 -29
  253. package/lib/types/ink/log-update.d.ts.map +1 -1
  254. package/lib/types/ink/log-update.js +21 -0
  255. package/lib/types/ink/node-cache.d.ts +5 -0
  256. package/lib/types/ink/node-cache.d.ts.map +1 -1
  257. package/lib/types/ink/parse-keypress.d.ts +8 -0
  258. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  259. package/lib/types/ink/parse-keypress.js +101 -12
  260. package/lib/types/ink/render-node-to-output.d.ts +10 -0
  261. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  262. package/lib/types/ink/render-node-to-output.js +111 -18
  263. package/lib/types/ink/timeline-rail.d.ts +138 -0
  264. package/lib/types/ink/timeline-rail.d.ts.map +1 -0
  265. package/lib/types/ink/timeline-rail.js +179 -0
  266. package/lib/types/ink/wrap-text.d.ts.map +1 -1
  267. package/lib/types/ink/wrap-text.js +47 -5
  268. package/lib/types/migrationPrefs.d.ts +60 -0
  269. package/lib/types/migrationPrefs.d.ts.map +1 -0
  270. package/lib/types/migrationPrefs.js +97 -0
  271. package/lib/types/modelGroups.d.ts +72 -0
  272. package/lib/types/modelGroups.d.ts.map +1 -0
  273. package/lib/types/modelGroups.js +97 -0
  274. package/lib/types/modelRecents.d.ts +39 -0
  275. package/lib/types/modelRecents.d.ts.map +1 -0
  276. package/lib/types/modelRecents.js +97 -0
  277. package/lib/types/native-ts/yoga-layout/index.d.ts +11 -0
  278. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
  279. package/lib/types/native-ts/yoga-layout/index.js +31 -1
  280. package/lib/types/oauth.d.ts +15 -0
  281. package/lib/types/oauth.d.ts.map +1 -0
  282. package/lib/types/oauth.js +14 -0
  283. package/lib/types/reload.d.ts +109 -0
  284. package/lib/types/reload.d.ts.map +1 -0
  285. package/lib/types/reload.js +118 -0
  286. package/lib/types/screens/Chat.d.ts +3 -1
  287. package/lib/types/screens/Chat.d.ts.map +1 -1
  288. package/lib/types/screens/Chat.js +1377 -371
  289. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  290. package/lib/types/screens/SessionBrowser.js +56 -29
  291. package/lib/types/screens/SessionTree.d.ts +27 -0
  292. package/lib/types/screens/SessionTree.d.ts.map +1 -0
  293. package/lib/types/screens/SessionTree.js +555 -0
  294. package/lib/types/screens/Settings.d.ts.map +1 -1
  295. package/lib/types/screens/Settings.js +64 -22
  296. package/lib/types/screens/StatusLine.d.ts +0 -8
  297. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  298. package/lib/types/screens/StatusLine.js +224 -45
  299. package/lib/types/screens/StatusMetrics.d.ts +35 -3
  300. package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
  301. package/lib/types/screens/StatusMetrics.js +63 -8
  302. package/lib/types/screens/TrajectoryScene.d.ts.map +1 -1
  303. package/lib/types/screens/TrajectoryScene.js +81 -14
  304. package/lib/types/screens/chatOverlay.d.ts +237 -0
  305. package/lib/types/screens/chatOverlay.d.ts.map +1 -0
  306. package/lib/types/screens/chatOverlay.js +116 -0
  307. package/lib/types/tips.d.ts.map +1 -1
  308. package/lib/types/tips.js +64 -10
  309. package/lib/types/tuiDisplayPrefs.d.ts +15 -0
  310. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  311. package/lib/types/tuiDisplayPrefs.js +9 -0
  312. package/lib/types/update.d.ts +139 -0
  313. package/lib/types/update.d.ts.map +1 -1
  314. package/lib/types/update.js +382 -30
  315. package/lib/types/utils/debug.d.ts +10 -0
  316. package/lib/types/utils/debug.d.ts.map +1 -1
  317. package/lib/types/utils/debug.js +24 -0
  318. package/lib/types/utils/fileTarget.d.ts +46 -0
  319. package/lib/types/utils/fileTarget.d.ts.map +1 -0
  320. package/lib/types/utils/fileTarget.js +178 -0
  321. package/lib/types/utils/keymap.d.ts +134 -0
  322. package/lib/types/utils/keymap.d.ts.map +1 -0
  323. package/lib/types/utils/keymap.js +311 -0
  324. package/lib/types/utils/mentions.d.ts +25 -2
  325. package/lib/types/utils/mentions.d.ts.map +1 -1
  326. package/lib/types/utils/mentions.js +69 -10
  327. package/lib/types/utils/openExternal.d.ts +50 -0
  328. package/lib/types/utils/openExternal.d.ts.map +1 -0
  329. package/lib/types/utils/openExternal.js +170 -0
  330. package/lib/types/utils/paths.d.ts.map +1 -1
  331. package/lib/types/utils/paths.js +1 -0
  332. package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +21 -0
  333. package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +140 -0
  334. package/node_modules/@deepseek-harness-tui/dsh-auth/cordis.patch.yml +11 -0
  335. package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +44 -0
  336. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/command.d.ts +14 -0
  337. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/command.js +67 -0
  338. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/credentials.d.ts +64 -0
  339. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/credentials.js +170 -0
  340. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.d.ts +79 -0
  341. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.js +196 -0
  342. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.d.ts +68 -0
  343. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.js +193 -0
  344. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/opener.d.ts +32 -0
  345. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/opener.js +101 -0
  346. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.d.ts +31 -0
  347. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.js +68 -0
  348. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/service.d.ts +69 -0
  349. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/service.js +129 -0
  350. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +70 -0
  351. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
  352. package/node_modules/@dsh-std/command/LICENSE +21 -21
  353. package/node_modules/@dsh-std/command/README.md +26 -26
  354. package/node_modules/@dsh-std/command/README.zh.md +28 -28
  355. package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
  356. package/node_modules/@dsh-std/command/package.json +22 -22
  357. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  358. package/node_modules/@dsh-std/connection/LICENSE +21 -21
  359. package/node_modules/@dsh-std/connection/README.md +42 -42
  360. package/node_modules/@dsh-std/connection/README.zh.md +42 -42
  361. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  362. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  363. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  364. package/node_modules/@dsh-std/connection/package.json +20 -20
  365. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  366. package/node_modules/@dsh-std/core/LICENSE +21 -21
  367. package/node_modules/@dsh-std/core/README.md +13 -13
  368. package/node_modules/@dsh-std/core/README.zh.md +13 -13
  369. package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  370. package/node_modules/@dsh-std/core/package.json +21 -21
  371. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  372. package/node_modules/@dsh-std/manifest/LICENSE +21 -21
  373. package/node_modules/@dsh-std/manifest/README.md +5 -5
  374. package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  375. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  376. package/node_modules/@dsh-std/manifest/package.json +20 -20
  377. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  378. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
  379. package/node_modules/@dsh-std/messages/LICENSE +21 -21
  380. package/node_modules/@dsh-std/messages/README.md +5 -5
  381. package/node_modules/@dsh-std/messages/README.zh.md +7 -7
  382. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
  383. package/node_modules/@dsh-std/messages/package.json +20 -20
  384. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
  385. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  386. package/node_modules/@dsh-std/presentation/LICENSE +21 -21
  387. package/node_modules/@dsh-std/presentation/README.md +27 -27
  388. package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  389. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  390. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  391. package/node_modules/@dsh-std/presentation/package.json +25 -25
  392. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
  393. package/node_modules/@dsh-std/storage/LICENSE +21 -21
  394. package/node_modules/@dsh-std/storage/README.md +5 -5
  395. package/node_modules/@dsh-std/storage/README.zh.md +7 -7
  396. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
  397. package/node_modules/@dsh-std/storage/package.json +20 -20
  398. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
  399. package/package.json +19 -5
  400. package/presets/liangshen/.dsh-tui-managed.json +1 -1
  401. package/presets/liangshen/instruction-hint.mjs +8 -0
  402. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  403. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
  404. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
  405. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
  406. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  407. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  408. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  409. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
  410. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  411. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
  412. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
  413. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
  414. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  415. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
  416. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  417. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
  418. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
  419. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  420. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  421. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
  422. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  423. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  424. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
  425. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
  426. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  427. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  428. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  429. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
  430. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  431. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
  432. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
  433. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
  434. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  435. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
  436. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  437. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
  438. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
  439. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
  440. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  441. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
  442. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  443. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
  444. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
  445. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
  446. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  447. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
  448. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  449. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
  450. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
  451. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
  452. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  453. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  454. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  455. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
  456. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  457. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
  458. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
  459. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
  460. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  461. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
  462. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  463. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
  464. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
  465. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
  466. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  467. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
@@ -20,6 +20,9 @@ import { POINTER } from '../../cc/figures.js';
20
20
  const OUTCOMES = ['allowed-once', 'rejected'];
21
21
  export function ApprovalPanel({ approval, onDecide }) {
22
22
  const [focusIndex, setFocusIndex] = React.useState(0);
23
+ // Hover highlight per decision row (mouse affordance; the click handler
24
+ // below mirrors the keyboard Enter on the focused row).
25
+ const [hoverIndex, setHoverIndex] = React.useState(-1);
23
26
  useInput((input, key) => {
24
27
  if (key.escape || (key.ctrl && input === 'c')) {
25
28
  onDecide('rejected');
@@ -44,6 +47,7 @@ export function ApprovalPanel({ approval, onDecide }) {
44
47
  const optionLabels = [t('approval-yes'), t('approval-no')];
45
48
  return (_jsxs(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 2, paddingRight: 2, width: "100%", children: [_jsx(Divider, { color: "permission", title: t('approval-waiting', { tool: approval.toolName }), padding: 4 }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [approval.command !== undefined && (_jsx(Box, { flexDirection: "column", paddingX: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: approval.command }) })), approval.reason !== undefined && (_jsx(Text, { dimColor: true, wrap: "wrap", children: approval.reason })), _jsx(Text, { dimColor: true, children: t('approval-proceed') })] }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: optionLabels.map((label, index) => {
46
49
  const focused = index === focusIndex;
47
- return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Text, { bold: focused, color: focused ? 'claude' : undefined, wrap: "wrap", children: [index + 1, ". ", label] })] }, label));
50
+ const hovered = index === hoverIndex;
51
+ return (_jsxs(Box, { flexDirection: "row", marginTop: focused ? 1 : 0, onClick: () => onDecide(OUTCOMES[index]), onMouseEnter: () => setHoverIndex(index), onMouseLeave: () => setHoverIndex(current => (current === index ? -1 : current)), backgroundColor: hovered && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: focused ? POINTER : ' ' }) }), _jsxs(Text, { bold: focused, color: focused ? 'claude' : undefined, wrap: "wrap", children: [index + 1, ". ", label] })] }, label));
48
52
  }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('approval-hint') }) })] }));
49
53
  }
@@ -1,4 +1,5 @@
1
1
  import React, { type ReactNode } from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
2
3
  export type ListItemProps = {
3
4
  /** Whether this item is currently focused (keyboard selection).
4
5
  * Shows the pointer indicator (❯) when true. */
@@ -24,6 +25,12 @@ export type ListItemProps = {
24
25
  * @default true
25
26
  */
26
27
  declareCursor?: boolean;
28
+ /**
29
+ * Mouse click handler (fullscreen mode). When provided the row becomes
30
+ * clickable and gains a subtle hover background so the affordance is
31
+ * visible; when absent the row renders exactly as before.
32
+ */
33
+ onClick?: (event: ClickEvent) => void;
27
34
  };
28
35
  /**
29
36
  * A list item for selection UIs, mirroring Claude Code's
@@ -32,5 +39,5 @@ export type ListItemProps = {
32
39
  * and CC's color states (focused = suggestion blue, selected = success
33
40
  * green).
34
41
  */
35
- export declare function ListItem({ isFocused, isSelected, children, description, showScrollDown, showScrollUp, styled, disabled, declareCursor, }: ListItemProps): React.ReactNode;
42
+ export declare function ListItem({ isFocused, isSelected, children, description, showScrollDown, showScrollUp, styled, disabled, declareCursor, onClick, }: ListItemProps): React.ReactNode;
36
43
  //# sourceMappingURL=ListItem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7C,MAAM,MAAM,aAAa,GAAG;IAC1B;qDACiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB;uDACmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAA;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAa,EACb,QAAgB,EAChB,aAAa,GACd,EAAE,aAAa,GAAG,KAAK,CAAC,SAAS,CAwEjC"}
1
+ {"version":3,"file":"ListItem.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAA;AAGvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAGjE,MAAM,MAAM,aAAa,GAAG;IAC1B;qDACiD;IACjD,SAAS,EAAE,OAAO,CAAA;IAClB;uDACmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,EAAE,SAAS,CAAA;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oEAAoE;IACpE,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,yEAAyE;IACzE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,EACvB,SAAS,EACT,UAAkB,EAClB,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,EACZ,MAAa,EACb,QAAgB,EAChB,aAAa,EACb,OAAO,GACR,EAAE,aAAa,GAAG,KAAK,CAAC,SAAS,CAoFjC"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from 'react';
2
+ import React, { useState } from 'react';
3
3
  import { Box, Text } from '../../ui.js';
4
4
  import { useDeclaredCursor } from '../../ink/hooks/use-declared-cursor.js';
5
5
  import { POINTER, DOWN_ARROW, UP_ARROW, TICK } from '../../cc/figures.js';
@@ -10,7 +10,7 @@ import { POINTER, DOWN_ARROW, UP_ARROW, TICK } from '../../cc/figures.js';
10
10
  * and CC's color states (focused = suggestion blue, selected = success
11
11
  * green).
12
12
  */
13
- export function ListItem({ isFocused, isSelected = false, children, description, showScrollDown, showScrollUp, styled = true, disabled = false, declareCursor, }) {
13
+ export function ListItem({ isFocused, isSelected = false, children, description, showScrollDown, showScrollUp, styled = true, disabled = false, declareCursor, onClick, }) {
14
14
  // Park the native terminal cursor on the pointer indicator so screen
15
15
  // readers / magnifiers track the focused item (CC behavior). (0,0) is the
16
16
  // top-left of this Box, where the pointer renders.
@@ -19,6 +19,11 @@ export function ListItem({ isFocused, isSelected = false, children, description,
19
19
  column: 0,
20
20
  active: isFocused && !disabled && declareCursor !== false,
21
21
  });
22
+ // Hover highlight only when the row is actually clickable — the extra
23
+ // background is the mouse affordance (there is no cursor-shape feedback
24
+ // in a terminal).
25
+ const [hovered, setHovered] = useState(false);
26
+ const clickable = Boolean(onClick) && !disabled;
22
27
  function renderIndicator() {
23
28
  if (disabled) {
24
29
  return _jsx(Text, { children: " " });
@@ -54,7 +59,7 @@ export function ListItem({ isFocused, isSelected = false, children, description,
54
59
  // 非 Fragment 的 element(如调用方自己的 <Text>)保留原样——其子树高度
55
60
  // 由调用方负责。
56
61
  const flatChildren = flattenDeep(children);
57
- return (_jsxs(Box, { ref: cursorRef, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", gap: 1, height: 1, flexShrink: 0, overflow: "hidden", width: "100%", children: [renderIndicator(), styled ? (_jsx(Text, { color: getTextColor(), dimColor: disabled, wrap: "truncate-end", children: flatChildren })) : (flatChildren), isSelected && !disabled && _jsx(Text, { color: "success", children: TICK })] }), description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "inactive", wrap: "truncate", children: flattenLine(description) }) }))] }));
62
+ return (_jsxs(Box, { ref: cursorRef, flexDirection: "column", onClick: clickable ? onClick : undefined, onMouseEnter: clickable ? () => setHovered(true) : undefined, onMouseLeave: clickable ? () => setHovered(false) : undefined, backgroundColor: clickable && hovered ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", gap: 1, height: 1, flexShrink: 0, overflow: "hidden", width: "100%", children: [renderIndicator(), styled ? (_jsx(Text, { color: getTextColor(), dimColor: disabled, wrap: "truncate-end", children: flatChildren })) : (flatChildren), isSelected && !disabled && _jsx(Text, { color: "success", children: TICK })] }), description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "inactive", wrap: "truncate", children: flattenLine(description) }) }))] }));
58
63
  }
59
64
  /** 单行化:内嵌换行折叠为空格(行尾/行首换行随之消除)。 */
60
65
  function flattenLine(s) {
@@ -1,4 +1,11 @@
1
1
  import React from 'react';
2
+ /**
3
+ * DSH_TUI_THEME skips terminal detection (tests, debugging). Accepts a
4
+ * built-in name (auto|light|dark|dark-ansi) or a user theme name; invalid
5
+ * values are warned and ignored by the caller, falling back to detection.
6
+ * Exported for /reload, which must respect the env override's precedence.
7
+ */
8
+ export declare function envThemeOverride(): string | undefined;
2
9
  export declare function ThemeProvider({ children, theme, }: {
3
10
  children: React.ReactNode;
4
11
  theme?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAA;AA4F7E,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CAuIlB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAG9D"}
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAA;AAsE7E;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAcD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CAuIlB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAG9D"}
@@ -47,8 +47,9 @@ const ThemeContext = createContext({
47
47
  * DSH_TUI_THEME skips terminal detection (tests, debugging). Accepts a
48
48
  * built-in name (auto|light|dark|dark-ansi) or a user theme name; invalid
49
49
  * values are warned and ignored by the caller, falling back to detection.
50
+ * Exported for /reload, which must respect the env override's precedence.
50
51
  */
51
- function envThemeOverride() {
52
+ export function envThemeOverride() {
52
53
  const v = process.env.DSH_TUI_THEME;
53
54
  return v === undefined || v === '' ? undefined : v;
54
55
  }
@@ -7,11 +7,14 @@ type Props = {
7
7
  isSelected?: boolean;
8
8
  /** Row expanded on its own (persistent hover-grey background, CC). */
9
9
  isExpanded?: boolean;
10
- onClick?(): void;
11
10
  };
12
11
  /**
13
12
  * Assistant text message: bullet + markdown body (mirroring Claude Code's default branch).
13
+ *
14
+ * Deliberately not clickable: the transcript is reading material and the
15
+ * mouse's job there is text selection (user feedback — row hover tints and
16
+ * fold toggling were noise, not affordance).
14
17
  */
15
- export declare function AssistantTextMessage({ text, addMargin, isSelected, isExpanded, onClick, }: Props): React.ReactNode;
18
+ export declare function AssistantTextMessage({ text, addMargin, isSelected, isExpanded, }: Props): React.ReactNode;
16
19
  export {};
17
20
  //# sourceMappingURL=AssistantTextMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantTextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantTextMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,SAAS,EACT,UAAkB,EAClB,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA2BzB"}
1
+ {"version":3,"file":"AssistantTextMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantTextMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,SAAS,EACT,UAAkB,EAClB,UAAkB,GACnB,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA0BzB"}
@@ -4,11 +4,15 @@ import { BLACK_CIRCLE } from '../../cc/figures.js';
4
4
  import { Markdown } from '../Markdown.js';
5
5
  /**
6
6
  * Assistant text message: bullet + markdown body (mirroring Claude Code's default branch).
7
+ *
8
+ * Deliberately not clickable: the transcript is reading material and the
9
+ * mouse's job there is text selection (user feedback — row hover tints and
10
+ * fold toggling were noise, not affordance).
7
11
  */
8
- export function AssistantTextMessage({ text, addMargin, isSelected = false, isExpanded = false, onClick, }) {
12
+ export function AssistantTextMessage({ text, addMargin, isSelected = false, isExpanded = false, }) {
9
13
  return (_jsx(Box, { alignItems: "flex-start", flexDirection: "row", justifyContent: "space-between", marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: isSelected
10
14
  ? 'messageActionsBackground'
11
15
  : isExpanded
12
16
  ? 'userMessageBackgroundHover'
13
- : undefined, onClick: onClick, children: _jsxs(Box, { flexDirection: "row", children: [_jsx(NoSelect, { fromLeftEdge: true, minWidth: 2, children: _jsx(Text, { color: isSelected ? 'suggestion' : 'text', children: BLACK_CIRCLE }) }), _jsx(Box, { flexDirection: "column", children: _jsx(Markdown, { children: text }) })] }) }));
17
+ : undefined, children: _jsxs(Box, { flexDirection: "row", children: [_jsx(NoSelect, { fromLeftEdge: true, minWidth: 2, children: _jsx(Text, { color: isSelected ? 'suggestion' : 'text', children: BLACK_CIRCLE }) }), _jsx(Box, { flexDirection: "column", children: _jsx(Markdown, { children: text }) })] }) }));
14
18
  }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
2
3
  type Props = {
3
4
  thinking: string;
4
5
  /** Adds the top margin between messages (CC: addMargin). */
@@ -17,7 +18,7 @@ type Props = {
17
18
  durationMs?: number;
18
19
  /** Message-selection mode highlight. */
19
20
  isSelected?: boolean;
20
- onClick?(): void;
21
+ onClick?(event: ClickEvent): void;
21
22
  };
22
23
  /**
23
24
  * Thinking block: folded `⚓ Thinking (ctrl+o to expand)`, expanded shows the
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAuBzB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,SAAiB,EACjB,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAwHzB"}
1
+ {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAUjE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB;;4CAEwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,SAAiB,EACjB,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAkIzB"}
@@ -49,7 +49,13 @@ export function AssistantThinkingMessage({ thinking, addMargin, verbose, streami
49
49
  const pulse = (Math.sin(frame * 0.9) + 1) / 2;
50
50
  const pulseColor = interpolateColor(BRAND, ICE, pulse);
51
51
  const frameText = THINKING_SPINNER_FRAMES[frame % THINKING_SPINNER_FRAMES.length];
52
- const header = streaming ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { children: minimal ? frameText : chalk.rgb(pulseColor.r, pulseColor.g, pulseColor.b).bold(frameText) }), _jsx(Text, { dimColor: true, italic: true, children: ` ${label}` })] })) : (_jsx(Text, { dimColor: true, italic: true, children: `${minimal ? '*' : THINKING_SETTLED_MARKER} ${label}` }));
52
+ // Hover 轻指示:可点击折叠时折叠头从 dim 提亮为正常色(不刷整行背景,
53
+ // 转录视觉保持安静)。
54
+ const [hovered, setHovered] = React.useState(false);
55
+ const hoverProps = onClick !== undefined
56
+ ? { onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false) }
57
+ : {};
58
+ const header = streaming ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { children: minimal ? frameText : chalk.rgb(pulseColor.r, pulseColor.g, pulseColor.b).bold(frameText) }), _jsx(Text, { dimColor: !hovered, color: hovered ? 'text' : undefined, italic: true, children: ` ${label}` })] })) : (_jsx(Text, { italic: true, dimColor: !hovered, color: hovered ? 'text' : undefined, children: `${minimal ? '*' : THINKING_SETTLED_MARKER} ${label}` }));
53
59
  if (preview) {
54
60
  // Live ticker: the model's last few reasoning lines, dimmed, one Text
55
61
  // per row so each truncates to the width independently, padded to a
@@ -64,10 +70,10 @@ export function AssistantThinkingMessage({ thinking, addMargin, verbose, streami
64
70
  // Pad with single spaces — an empty-string Text renders with zero
65
71
  // height in ink, so '' padding would not hold the row open.
66
72
  const rows = Array.from({ length: PREVIEW_ROWS }, (_, i) => visible[i] ?? ' ');
67
- return (_jsxs(Box, { flexDirection: "column", marginTop: addMargin ? 1 : 0, backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, children: [header, _jsx(Box, { flexDirection: "column", paddingLeft: 2, height: PREVIEW_ROWS, flexShrink: 0, overflow: "hidden", children: rows.map((line, i) => (_jsxs(Box, { flexDirection: "row", height: 1, children: [_jsx(Text, { dimColor: true, italic: true, children: '│ ' }), _jsx(Box, { flexDirection: "row", flexGrow: 1, children: _jsx(Text, { dimColor: true, italic: true, wrap: i === rows.length - 1 ? 'truncate-start' : 'truncate', children: i === 0 && clipped ? `…${line}` : line }) })] }, i))) })] }));
73
+ return (_jsxs(Box, { flexDirection: "column", marginTop: addMargin ? 1 : 0, backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, ...hoverProps, children: [header, _jsx(Box, { flexDirection: "column", paddingLeft: 2, height: PREVIEW_ROWS, flexShrink: 0, overflow: "hidden", children: rows.map((line, i) => (_jsxs(Box, { flexDirection: "row", height: 1, children: [_jsx(Text, { dimColor: true, italic: true, children: '│ ' }), _jsx(Box, { flexDirection: "row", flexGrow: 1, children: _jsx(Text, { dimColor: true, italic: true, wrap: i === rows.length - 1 ? 'truncate-start' : 'truncate', children: i === 0 && clipped ? `…${line}` : line }) })] }, i))) })] }));
68
74
  }
69
75
  if (!verbose) {
70
- return (_jsx(Box, { marginTop: addMargin ? 1 : 0, backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, children: header }));
76
+ return (_jsx(Box, { marginTop: addMargin ? 1 : 0, backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, ...hoverProps, children: header }));
71
77
  }
72
- return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, children: [header, _jsx(Box, { paddingLeft: 2, children: _jsx(StreamingMarkdown, { dimColor: true, children: thinking }) })] }));
78
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: isSelected ? 'messageActionsBackground' : undefined, onClick: onClick, ...hoverProps, children: [header, _jsx(Box, { paddingLeft: 2, children: _jsx(StreamingMarkdown, { dimColor: true, children: thinking }) })] }));
73
79
  }
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import type { ToolRow } from '../../dsh-adapter/channel.js';
3
3
  import type { ToolBackground } from '../../tuiDisplayPrefs.js';
4
4
  import type { Theme } from '../../theme.js';
5
+ import type { ClickEvent } from '../../ink/events/click-event.js';
5
6
  type Props = {
6
7
  tool: ToolRow;
7
8
  /** Adds the top margin between messages (CC: addMargin). */
@@ -12,6 +13,12 @@ type Props = {
12
13
  isSelected?: boolean;
13
14
  /** Row expanded on its own (persistent hover-grey background, CC). */
14
15
  isExpanded?: boolean;
16
+ /**
17
+ * Mouse click (fullscreen): toggles the row's expansion — same action as
18
+ * clicking other transcript rows. Also makes the `(ctrl+o to expand)`
19
+ * hint actionable with the mouse.
20
+ */
21
+ onClick?(event: ClickEvent): void;
15
22
  /**
16
23
  * Trajectory pointer, rendered as one more `⎿` line under a failed call.
17
24
  *
@@ -25,6 +32,13 @@ type Props = {
25
32
  diffLayout?: 'auto' | 'split' | 'unified';
26
33
  /** Background treatment for the ordinary, unselected tool card surface. */
27
34
  toolBackground?: ToolBackground;
35
+ /**
36
+ * Click-to-act (fullscreen): opens the file-action menu for the tool's
37
+ * file path. When provided, the path in the card header (and diff path
38
+ * rows) renders underlined and clickable; the click stops propagation so
39
+ * the row's own fold-toggle does not fire.
40
+ */
41
+ onOpenFile?: (path: string) => void;
28
42
  };
29
43
  export declare function toolNameColor(raw: string): keyof Theme;
30
44
  /**
@@ -33,6 +47,6 @@ export declare function toolNameColor(raw: string): keyof Theme;
33
47
  * output, read content — instead of the raw result dump (mirroring Claude Code's `AssistantToolUseMessage.tsx` + the dsh-tools presentation views the
34
48
  * channel captures per call).
35
49
  */
36
- export declare function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected, isExpanded, footnote, diffLayout, toolBackground, }: Props): React.ReactNode;
50
+ export declare function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected, isExpanded, onClick, footnote, diffLayout, toolBackground, onOpenFile, }: Props): React.ReactNode;
37
51
  export {};
38
52
  //# sourceMappingURL=AssistantToolUseMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAKvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3C,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC,CAAA;AAgFD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAKtD;AAwKD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,SAAS,EACT,OAAO,EACP,UAAkB,EAClB,UAAkB,EAClB,QAAQ,EACR,UAAmB,EACnB,cAAuB,GACxB,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAmKzB"}
1
+ {"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAKvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,CAAA;AAsFD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAKtD;AAsMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,SAAS,EACT,OAAO,EACP,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAmB,EACnB,cAAuB,EACvB,UAAU,GACX,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAkMzB"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from 'react';
2
3
  import { extname } from 'node:path';
3
4
  import { Box, Text, useTerminalSize } from '../../ui.js';
4
5
  import { stringWidth } from '../../ink/stringWidth.js';
@@ -180,7 +181,7 @@ function capLines(lines, max, verbose) {
180
181
  return lines;
181
182
  return [
182
183
  ...lines.slice(0, max),
183
- dim(`… +${lines.length - max} lines (ctrl+o to expand)`),
184
+ { ...dim(`… +${lines.length - max} lines (ctrl+o to expand)`), revealOnHover: true },
184
185
  ];
185
186
  }
186
187
  /** Header title from the presentation view: terminal cards keep the
@@ -199,7 +200,7 @@ function clipHeaderArgs(args) {
199
200
  return args;
200
201
  return `${args.slice(0, HEADER_ARGS_BUDGET)}…`;
201
202
  }
202
- function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameColor }) {
203
+ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameColor, filePath, onOpenFile }) {
203
204
  if (title === undefined) {
204
205
  return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), displayArgs !== '' && (_jsxs(Box, { flexWrap: "nowrap", children: [_jsx(Text, { children: "(" }), _jsx(SyntaxText, { text: clipHeaderArgs(displayArgs), sourceText: displayArgs, language: argsLanguage }), _jsx(Text, { children: ")" })] }))] }));
205
206
  }
@@ -210,6 +211,20 @@ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameC
210
211
  if (trimmed === '') {
211
212
  return (_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }));
212
213
  }
214
+ // Clickable path: when the caller resolved a file path that appears in
215
+ // the title (`Edit /path (1 - 100)`), render that segment underlined and
216
+ // clickable. The click stops propagation so the row's fold toggle does
217
+ // not fire. indexOf keeps the split exact even for paths with regex
218
+ // metacharacters.
219
+ if (onOpenFile !== undefined && filePath !== undefined && filePath !== '' && trimmed.includes(filePath)) {
220
+ const at = trimmed.indexOf(filePath);
221
+ const before = trimmed.slice(0, at);
222
+ const after = trimmed.slice(at + filePath.length);
223
+ return (_jsxs(Box, { flexWrap: "nowrap", children: [_jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: before }), _jsx(Box, { onClick: (event) => {
224
+ event.stopImmediatePropagation();
225
+ onOpenFile(filePath);
226
+ }, children: _jsx(Text, { underline: true, wrap: "truncate-end", children: filePath }) }), after !== '' && (_jsx(Text, { bold: false, color: "text", wrap: "truncate-end", children: after }))] }));
227
+ }
213
228
  const space = trimmed.indexOf(' ');
214
229
  const head = space === -1 ? trimmed : trimmed.slice(0, space);
215
230
  const tail = space === -1 ? '' : trimmed.slice(space);
@@ -221,7 +236,7 @@ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameC
221
236
  * output, read content — instead of the raw result dump (mirroring Claude Code's `AssistantToolUseMessage.tsx` + the dsh-tools presentation views the
222
237
  * channel captures per call).
223
238
  */
224
- export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected = false, isExpanded = false, footnote, diffLayout = 'auto', toolBackground = 'none', }) {
239
+ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected = false, isExpanded = false, onClick, footnote, diffLayout = 'auto', toolBackground = 'none', onOpenFile, }) {
225
240
  const isRunning = tool.status === 'running';
226
241
  const isError = tool.status === 'error';
227
242
  const displayArgs = verbose ? tool.argsFull ?? tool.argsText : tool.argsText;
@@ -286,16 +301,31 @@ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected =
286
301
  : ordinaryToolBackground === 'strong'
287
302
  ? 'toolCardBackground'
288
303
  : undefined;
289
- return (_jsx(Box, { ref: viewportRef, flexDirection: "row", justifyContent: "space-between", marginTop: addMargin ? 1 : 0, width: "100%",
304
+ // Hover affordance for the click-to-toggle row: the theme's tool-card blue
305
+ // face marks the call's content area while the pointer dwells (the
306
+ // toolBackground treatment steps up one level to the strong card face), the
307
+ // collapsed `(ctrl+o to expand)` hint steps from dim to text, the elapsed
308
+ // clock stops dimming, and a ▾/▴ discloses the row is a toggle.
309
+ // No layout change: the indicator is a fixed column on the header line, the
310
+ // body never moves.
311
+ const [hovered, setHovered] = React.useState(false);
312
+ const interactive = onClick !== undefined;
313
+ const hoverTint = interactive && hovered && !isSelected;
314
+ return (_jsx(Box, { ref: viewportRef, flexDirection: "row", justifyContent: "space-between", marginTop: addMargin ? 1 : 0, width: "100%", onClick: onClick,
290
315
  // Only selection paints a highlight; the configured treatment applies
291
316
  // to an ordinary card. Diff line tints stay - they are content, not chrome.
292
- backgroundColor: isSelected ? 'messageActionsBackground' : ordinaryBackground, children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "row", flexWrap: "nowrap", minWidth: minWidth, children: [_jsx(ToolUseLoader, { shouldAnimate: isRunning, isUnresolved: isRunning, isError: isError, toolName: tool.name }), _jsx(HeaderTitle, { name: name, title: headerTitle, isTerminal: headerIsTerminal, displayArgs: displayArgs, argsLanguage: argsLanguage, nameColor: toolNameColor(tool.name) }), !isRunning && (_jsx(Box, { flexWrap: "nowrap", children: _jsx(Text, { dimColor: true, children: elapsedText }) }))] }), useSplitDiff && view?.card === 'diff' ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_FIRST }) }), _jsx(SplitDiffView, { diffs: view.diffs, width: columns - 4, maxRows: DIFF_BODY_MAX_LINES, verbose: verbose, toolBackground: ordinaryToolBackground })] })) : (rendered.map((line, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { color: line.tone === 'add'
317
+ backgroundColor: isSelected ? 'messageActionsBackground' : hoverTint ? 'toolCardBackground' : ordinaryBackground, onMouseEnter: interactive ? () => setHovered(true) : undefined, onMouseLeave: interactive ? () => setHovered(false) : undefined, children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "row", flexWrap: "nowrap", minWidth: minWidth, children: [_jsx(ToolUseLoader, { shouldAnimate: isRunning, isUnresolved: isRunning, isError: isError, toolName: tool.name }), _jsx(HeaderTitle, { name: name, title: headerTitle, isTerminal: headerIsTerminal, displayArgs: displayArgs, argsLanguage: argsLanguage, nameColor: toolNameColor(tool.name), filePath: filePath, onOpenFile: onOpenFile }), !isRunning && (_jsx(Box, { flexWrap: "nowrap", children: _jsx(Text, { dimColor: !hovered, children: elapsedText }) })), hovered && (_jsx(Box, { flexShrink: 0, children: _jsx(Text, { dimColor: true, children: isExpanded ? '▴' : '▾' }) }))] }), useSplitDiff && view?.card === 'diff' ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_FIRST }) }), _jsx(SplitDiffView, { diffs: view.diffs, width: columns - 4, maxRows: DIFF_BODY_MAX_LINES, verbose: verbose, toolBackground: ordinaryToolBackground })] })) : (rendered.map((line, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { color: line.tone === 'add'
293
318
  ? 'diffAddedWord'
294
319
  : line.tone === 'del'
295
320
  ? 'diffRemovedWord'
296
321
  : line.tone === 'path'
297
322
  ? 'ide'
298
- : undefined, dimColor: line.tone !== 'add' && line.tone !== 'del' && line.tone !== 'path', children: index === 0 ? GUTTER_FIRST : GUTTER_REST }) }), _jsx(Box, { flexGrow: 1, children: _jsx(Text, { color: line.tone === 'add'
323
+ : undefined, dimColor: line.tone !== 'add' && line.tone !== 'del' && line.tone !== 'path', children: index === 0 ? GUTTER_FIRST : GUTTER_REST }) }), _jsx(Box, { flexGrow: 1, children: line.tone === 'path' && onOpenFile !== undefined ? (_jsx(Box, { onClick: (event) => {
324
+ // Stop propagation so the row's fold toggle does not
325
+ // fire when clicking the path.
326
+ event.stopImmediatePropagation();
327
+ onOpenFile(line.text);
328
+ }, children: _jsx(Text, { color: "ide", underline: true, children: line.text }) })) : (_jsx(Text, { color: line.tone === 'add'
299
329
  ? 'diffAddedWord'
300
330
  : line.tone === 'del'
301
331
  ? 'diffRemovedWord'
@@ -305,5 +335,5 @@ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected =
305
335
  ? 'subtle'
306
336
  : line.tone === 'path'
307
337
  ? 'ide'
308
- : undefined, dimColor: line.tone === 'dim', wrap: "wrap", children: line.tone === 'plain' && syntaxLanguage !== undefined ? (_jsx(SyntaxText, { text: line.text, sourceText: bodySource, lineIndex: index, language: syntaxLanguage })) : (line.text === '' ? ' ' : line.text) }) })] }, index)))), useSplitDiff && footnote !== undefined && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_REST }) }), _jsx(Text, { color: "subtle", children: footnote })] }))] }) }));
338
+ : undefined, dimColor: line.tone === 'dim' && !(line.revealOnHover === true && hovered), wrap: "wrap", children: line.tone === 'plain' && syntaxLanguage !== undefined ? (_jsx(SyntaxText, { text: line.text, sourceText: bodySource, lineIndex: index, language: syntaxLanguage })) : (line.text === '' ? ' ' : line.text) })) })] }, index)))), useSplitDiff && footnote !== undefined && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_REST }) }), _jsx(Text, { color: "subtle", children: footnote })] }))] }) }));
309
339
  }
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
+ import type { ClickEvent } from '../../ink/events/click-event.js';
2
3
  type Props = {
3
4
  text: string;
4
5
  /** Adds the top margin between turns (CC: addMargin). */
5
6
  addMargin: boolean;
6
7
  /** Message-selection mode highlight. */
7
8
  isSelected?: boolean;
8
- onClick?(): void;
9
+ onClick?(event: ClickEvent): void;
9
10
  };
10
11
  /**
11
12
  * User prompt bubble: `❯ text` in bold briefLabelYou gold with no background
@@ -1 +1 @@
1
- {"version":3,"file":"UserPromptMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/UserPromptMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,SAAS,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,SAAS,EACT,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA6BzB"}
1
+ {"version":3,"file":"UserPromptMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/UserPromptMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,SAAS,EAAE,OAAO,CAAA;IAClB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,CAAA;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,SAAS,EACT,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA6BzB"}
@@ -12,7 +12,7 @@
12
12
  * the input row itself and typing gives a pure custom answer.
13
13
  */
14
14
  import React from 'react';
15
- import type { QuestionSelection } from '../../dsh-adapter/questions.js';
15
+ import type { QuestionDraft, QuestionSelection } from '../../dsh-adapter/questions.js';
16
16
  export type AskUserQuestionPanelProps = {
17
17
  /** The question to render (from the QuestionStore snapshot). */
18
18
  readonly question: {
@@ -41,9 +41,13 @@ export type AskUserQuestionPanelProps = {
41
41
  readonly total: number;
42
42
  /** Questions answered before the current one. */
43
43
  readonly answered: number;
44
+ /** Previously saved answer or draft, restored when returning to this item. */
45
+ readonly initialDraft?: QuestionDraft;
44
46
  readonly onAnswer: (selection: QuestionSelection) => void;
45
- /** Esc / Ctrl+C — aborts the whole ask (ASK_ABORTED back to the model). */
47
+ /** Esc on the first question / Ctrl+C — aborts the whole ask. */
46
48
  readonly onCancel: () => void;
49
+ /** Esc on later questions — navigates to the previous question. */
50
+ readonly onBack?: (draft: QuestionDraft) => void;
47
51
  };
48
- export declare function AskUserQuestionPanel({ question, position, total, answered, onAnswer, onCancel, }: AskUserQuestionPanelProps): React.ReactNode;
52
+ export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, }: AskUserQuestionPanelProps): React.ReactNode;
49
53
  //# sourceMappingURL=AskUserQuestionPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AASvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CAwW7C"}
1
+ {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAStF,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACjD,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CAkb7C"}
@@ -24,7 +24,7 @@ import { listWindow } from '../listWindow.js';
24
24
  const CHECKED = '◉';
25
25
  const UNCHECKED = '○';
26
26
  const PENCIL = '✎';
27
- export function AskUserQuestionPanel({ question, position, total, answered, onAnswer, onCancel, }) {
27
+ export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, }) {
28
28
  // Plan-mode's exit_plan_mode ask carries a presentation intent: render
29
29
  // the CC-style decision card instead of the generic questionnaire. The
30
30
  // branch precedes every hook so hook order stays stable per remount key.
@@ -37,13 +37,21 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
37
37
  const { rows: terminalRows } = useTerminalSize();
38
38
  /** Rows: the real options plus the inline input row at the tail. */
39
39
  const rowCount = options.length + (hideCustomInput ? 0 : 1);
40
- const [focusIndex, setFocusIndex] = React.useState(0);
41
- const [checked, setChecked] = React.useState(() => new Set());
42
- const [customText, setCustomText] = React.useState('');
43
- const [customCursor, setCustomCursor] = React.useState(0);
40
+ const initialSelected = initialDraft?.selected ?? [];
41
+ const initialCustom = initialDraft?.custom ?? '';
42
+ const selectedIndices = options
43
+ .map((option, index) => initialSelected.includes(option.label) ? index : -1)
44
+ .filter(index => index >= 0);
45
+ const initialFocus = initialCustom !== '' && selectedIndices.length === 0 && !hideCustomInput
46
+ ? options.length
47
+ : selectedIndices[0] ?? 0;
48
+ const [focusIndex, setFocusIndex] = React.useState(initialFocus);
49
+ const [checked, setChecked] = React.useState(() => new Set(multiSelect ? selectedIndices : []));
50
+ const [customText, setCustomText] = React.useState(initialCustom);
51
+ const [customCursor, setCustomCursor] = React.useState(initialCustom.length);
44
52
  /** Single-select label captured by typing on a focused option — submitted
45
53
  * together with the custom text when the input row itself is Entered. */
46
- const [attached, setAttached] = React.useState(null);
54
+ const [attached, setAttached] = React.useState(() => initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
47
55
  const [error, setError] = React.useState(null);
48
56
  const inputFocused = !hideCustomInput && focusIndex === options.length;
49
57
  // Chat chrome + panel scaffolding consume twelve rows before the option
@@ -139,11 +147,33 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
139
147
  }
140
148
  onAnswer({ selected: attached !== null ? [attached] : [], custom: text });
141
149
  };
150
+ /** Capture the visible answer state before navigating away. */
151
+ const currentDraft = () => {
152
+ const selected = multiSelect
153
+ ? checkedLabels()
154
+ : inputFocused
155
+ ? (attached === null ? [] : [attached])
156
+ : (() => {
157
+ const label = options[focusIndex]?.label;
158
+ return label === undefined ? [] : [label];
159
+ })();
160
+ return {
161
+ selected,
162
+ ...(customText !== '' ? { custom: customText } : {}),
163
+ };
164
+ };
142
165
  useInput((input, key) => {
143
- if (key.escape || (key.ctrl && input === 'c')) {
166
+ if (key.ctrl && input === 'c') {
144
167
  onCancel();
145
168
  return;
146
169
  }
170
+ if (key.escape) {
171
+ if (onBack !== undefined)
172
+ onBack(currentDraft());
173
+ else
174
+ onCancel();
175
+ return;
176
+ }
147
177
  if (inputFocused) {
148
178
  if (key.upArrow) {
149
179
  moveFocus(-1);
@@ -241,7 +271,39 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
241
271
  const remaining = total - answered;
242
272
  const headerTitle = ` ${t('question-header-progress', { position, total, remaining: remaining > 1 ? t('question-remaining-more', { n: remaining }) : '' })} `;
243
273
  const cursorChar = customCursor < customText.length ? customText[customCursor] : ' ';
244
- const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'claude' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('question-direct-input') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: customText.slice(0, customCursor) }), inputFocused
274
+ /** Mouse: click the input row to focus it (same as Tab). */
275
+ const focusInputRow = () => {
276
+ if (hideCustomInput)
277
+ return;
278
+ setFocusIndex(options.length);
279
+ setError(null);
280
+ };
281
+ /**
282
+ * Mouse: click an option row. Multi-select toggles the checkmark (same as
283
+ * Space); single-select answers immediately with that option plus any
284
+ * typed text (same as focusing the row and pressing Enter) — one click =
285
+ * one answer, matching ApprovalPanel's click semantics.
286
+ */
287
+ const clickOption = (index) => {
288
+ if (multiSelect) {
289
+ setChecked(previous => {
290
+ const next = new Set(previous);
291
+ if (next.has(index))
292
+ next.delete(index);
293
+ else
294
+ next.add(index);
295
+ return next;
296
+ });
297
+ return;
298
+ }
299
+ const label = options[index]?.label;
300
+ if (label === undefined)
301
+ return;
302
+ const text = customText.trim();
303
+ onAnswer({ selected: [label], ...(text !== '' ? { custom: text } : {}) });
304
+ };
305
+ const [hoverIndex, setHoverIndex] = React.useState(-1);
306
+ const renderInputRow = () => (_jsxs(Box, { flexDirection: "row", marginTop: inputFocused ? 1 : 0, onClick: focusInputRow, onMouseEnter: () => setHoverIndex(options.length), onMouseLeave: () => setHoverIndex(current => (current === options.length ? -1 : current)), backgroundColor: hoverIndex === options.length && !inputFocused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : undefined, bold: inputFocused, children: inputFocused ? POINTER : ' ' }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: inputFocused ? 'claude' : 'suggestion', children: PENCIL }) }), _jsxs(Box, { flexDirection: "row", marginLeft: 1, children: [_jsx(Text, { bold: inputFocused, color: inputFocused ? 'claude' : 'suggestion', children: t('question-custom-tab') }), attached !== null && (_jsx(Text, { color: "suggestion", children: t('question-attached-label', { label: attached }) })), _jsx(Text, { dimColor: true, children: "\uFF1A" }), customText === '' && !inputFocused ? (_jsx(Text, { ref: caretRef, dimColor: true, children: t('question-direct-input') })) : (_jsxs(_Fragment, { children: [_jsx(Text, { wrap: "wrap", children: customText.slice(0, customCursor) }), inputFocused
245
307
  ? _jsx(Text, { ref: caretRef, inverse: true, children: cursorChar })
246
308
  : _jsx(Text, { ref: caretRef, color: "suggestion", children: "\u258F" }), _jsx(Text, { wrap: "wrap", children: customText.slice(inputFocused ? customCursor + 1 : customCursor) })] }))] })] }));
247
309
  const renderOptions = () => (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [options.slice(optionWindow.start, optionWindow.end).map((option, index) => {
@@ -259,14 +321,15 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
259
321
  const description = windowedOptions
260
322
  ? option.description?.replace(/\s+/gu, ' ').trim()
261
323
  : option.description;
262
- return (_jsxs(Box, { flexDirection: "row", marginTop: !windowedOptions && focused ? 1 : 0, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: pointer }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: selected, children: selected ? (multiSelect ? CHECKED : '●') : UNCHECKED }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsx(Text, { bold: focused || selected, color: focused ? 'claude' : undefined, wrap: windowedOptions ? 'truncate' : 'wrap', children: label }), description !== undefined && (_jsx(Text, { dimColor: true, wrap: windowedOptions ? 'truncate' : 'wrap', children: description }))] })] }, `${absoluteIndex}:${option.label}`));
324
+ return (_jsxs(Box, { flexDirection: "row", marginTop: !windowedOptions && focused ? 1 : 0, onClick: () => clickOption(absoluteIndex), onMouseEnter: () => setHoverIndex(absoluteIndex), onMouseLeave: () => setHoverIndex(current => (current === absoluteIndex ? -1 : current)), backgroundColor: hoverIndex === absoluteIndex && !focused ? 'userMessageBackgroundHover' : undefined, children: [_jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: focused, children: pointer }) }), _jsx(Box, { width: 1, flexShrink: 0, children: _jsx(Text, { color: focused ? 'claude' : undefined, bold: selected, children: selected ? (multiSelect ? CHECKED : '●') : UNCHECKED }) }), _jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsx(Text, { bold: focused || selected, color: focused ? 'claude' : undefined, wrap: windowedOptions ? 'truncate' : 'wrap', children: label }), description !== undefined && (_jsx(Text, { dimColor: true, wrap: windowedOptions ? 'truncate' : 'wrap', children: description }))] })] }, `${absoluteIndex}:${option.label}`));
263
325
  }), hideCustomInput ? null : renderInputRow()] }));
264
326
  const hintParts = inputFocused
265
327
  ? [
266
328
  t('question-hint-type'),
267
329
  t('question-hint-enter'),
268
330
  ...(options.length > 0 ? [t('question-hint-back')] : []),
269
- t('question-hint-esc'),
331
+ onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
332
+ ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
270
333
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
271
334
  ]
272
335
  : [
@@ -274,7 +337,8 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
274
337
  ...(multiSelect ? [t('question-hint-multi')] : []),
275
338
  ...(hideCustomInput ? [] : [t('question-hint-attach')]),
276
339
  t('question-hint-enter'),
277
- t('question-hint-esc'),
340
+ onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
341
+ ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
278
342
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
279
343
  ];
280
344
  return (_jsxs(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 2, paddingRight: 2, width: "100%", children: [_jsx(Divider, { color: "permission", title: headerTitle, padding: 4 }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [question.header !== undefined && (_jsxs(Text, { color: "suggestion", bold: true, children: ["\u25C8 ", question.header] })), _jsx(Text, { bold: true, wrap: "wrap", children: question.question }), question.detail !== undefined && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: question.detail.split('\n').map((line, index) => (_jsx(Text, { dimColor: true, italic: true, wrap: "wrap", children: line }, index))) }))] }), renderOptions(), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: hintParts.join(' · ') }) })] }));
@@ -1 +1 @@
1
- {"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAyOxC"}
1
+ {"version":3,"file":"PlanReviewPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/PlanReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAKvE,MAAM,MAAM,oBAAoB,GAAG;IACjC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,oBAAoB,GAAG,KAAK,CAAC,SAAS,CAmQxC"}