@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
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Box, Text } from '../ui.js';
4
+ import { Divider } from './design-system/Divider.js';
5
+ import { t } from '../i18n.js';
6
+ /**
7
+ * Auto-recap row (`dsh-tui.recapOnOpen` setting): a quiet, dim recap shown
8
+ * at the bottom of the transcript after an automatic summary on session
9
+ * open/resume — a thin divider, then a `回顾:` line showing the session
10
+ * tail in FULL (wraps over lines rather than truncating, like a colleague
11
+ * catching the user up). Hover reveals the affordances on their own row;
12
+ * click expands into the full RecapPanel; the dismiss chip hides the row
13
+ * until the next session switch. It bows out on its own once the user
14
+ * starts a new message (see Chat.tsx). Keyboard users keep `/recap` for
15
+ * the full panel.
16
+ */
17
+ export function AutoRecapRow({ summary, streaming, onExpand, onDismiss, }) {
18
+ const [hovered, setHovered] = React.useState(false);
19
+ const line = t('recap-auto-line', {
20
+ summary: streaming ? t('recap-answering') : summary,
21
+ });
22
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Divider, {}), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 1, onClick: onExpand, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [_jsx(Text, { dimColor: !hovered, children: line }), hovered && (_jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsxs(Text, { dimColor: true, children: [" [", t('recap-auto-hint'), "]"] }), _jsx(Box, { onClick: onDismiss, children: _jsxs(Text, { color: "warning", children: [" [\u00D7 ", t('recap-auto-close'), "]"] }) })] }))] })] }));
23
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"BtwPanel.d.ts","sourceRoot":"","sources":["../../../src/components/BtwPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,OAAO,EACP,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CA4DlB"}
1
+ {"version":3,"file":"BtwPanel.d.ts","sourceRoot":"","sources":["../../../src/components/BtwPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,OAAO,EACP,MAAM,GACP,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CA+DlB"}
@@ -43,5 +43,5 @@ export function BtwPanel({ question, answer, error, streaming, onClose, onCopy,
43
43
  event.stopImmediatePropagation();
44
44
  });
45
45
  const settled = answer !== '' || error !== undefined;
46
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: "warning", bold: true, children: "/btw " }), _jsx(Text, { dimColor: true, children: question })] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(5, rows - 8), children: _jsx(Box, { marginLeft: 2, flexDirection: "column", flexGrow: 1, children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: error !== undefined ? (_jsx(Text, { color: "error", children: error })) : answer !== '' ? (_jsx(Markdown, { cacheTokens: false, children: answer })) : (_jsxs(Box, { children: [_jsx(SpinnerGlyph, { frame: frame, messageColor: "warning" }), _jsxs(Text, { color: "warning", children: [" ", t('btw-answering')] })] })) }) }) }), _jsx(Text, { dimColor: true, children: settled ? t('btw-hint-done') : streaming ? t('btw-hint-loading') : t('btw-hint-done') })] }));
46
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: "warning", bold: true, children: "/btw " }), _jsx(Text, { dimColor: true, children: question })] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(5, rows - 8), children: _jsx(Box, { marginLeft: 2, flexDirection: "column", flexGrow: 1, children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: error !== undefined ? (_jsx(Text, { color: "error", children: error })) : answer !== '' ? (_jsx(Markdown, { cacheTokens: false, children: answer })) : (_jsxs(Box, { children: [_jsx(SpinnerGlyph, { frame: frame, messageColor: "warning" }), _jsxs(Text, { color: "warning", children: [" ", t('btw-answering')] })] })) }) }) }), _jsx(Box, { onClick: settled ? onCopy : undefined, children: _jsx(Text, { dimColor: true, children: settled ? t('btw-hint-done') : streaming ? t('btw-hint-loading') : t('btw-hint-done') }) })] }));
47
47
  }
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { SubagentRow } from '../../dsh-adapter/channel.js';
3
+ import type { ClickEvent } from '../../ink/events/click-event.js';
3
4
  /**
4
5
  * Borderless, fixed-height activity card embedded directly in the transcript
5
6
  * (Kimi Code visual language). Running: header + one-line current tool + a
@@ -14,6 +15,6 @@ export declare function SubagentMessage({ subagent, addMargin, activityFrames, o
14
15
  addMargin: boolean;
15
16
  activityFrames?: string;
16
17
  isExpanded: boolean;
17
- onClick: () => void;
18
+ onClick?(event: ClickEvent): void;
18
19
  }): React.ReactNode;
19
20
  //# sourceMappingURL=SubagentMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/SubagentMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AA+C/D;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE;IAChF,QAAQ,EAAE,WAAW,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CAqElB"}
1
+ {"version":3,"file":"SubagentMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/Chat/SubagentMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAO/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAyCjE;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,EAAE;IAChF,QAAQ,EAAE,WAAW,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAClC,GAAG,KAAK,CAAC,SAAS,CAwFlB"}
@@ -58,10 +58,16 @@ function clipLine(text, maxWidth) {
58
58
  * setting as the main spinner.
59
59
  */
60
60
  export function SubagentMessage({ subagent, addMargin, activityFrames, onClick }) {
61
- const [, time] = useAnimationFrame(120);
61
+ const settled = subagent.status === 'completed' || subagent.status === 'failed' || subagent.status === 'cancelled';
62
+ // 动画订阅仅限运行中的卡片:settled 后传 null 退出共享 clock(keepAlive
63
+ // 归零 → interval 清除),否则历史里的每张完成卡片都以 120ms 永久驱动
64
+ // React commit。viewportRef 必须挂到根节点——useTerminalViewport 初始
65
+ // isVisible:true,ref 不挂就永远不修正(虚拟化滚出视口的卡片继续动画)。
66
+ const [viewportRef, time] = useAnimationFrame(settled ? null : 120);
62
67
  const { columns } = useTerminalSize();
63
68
  const info = status(subagent);
64
- const settled = subagent.status === 'completed' || subagent.status === 'failed' || subagent.status === 'cancelled';
69
+ const [hovered, setHovered] = React.useState(false);
70
+ const clickable = onClick !== undefined;
65
71
  const elapsed = subagent.completedAt ? subagent.durationMs : Date.now() - subagent.startedAt;
66
72
  const lastRunning = [...subagent.toolCalls].reverse().find(tool => tool.status === 'running');
67
73
  const previousDone = lastRunning
@@ -71,5 +77,7 @@ export function SubagentMessage({ subagent, addMargin, activityFrames, onClick }
71
77
  const activity = settled ? [] : subagent.outputLines.slice(-WATERFALL_ROWS);
72
78
  const runningGlyph = preset.frames[Math.floor(time / preset.intervalMs) % preset.frames.length] ?? '·';
73
79
  const rowWidth = Math.max(20, (columns ?? 80) - WATERFALL_GUTTER);
74
- return _jsxs(Box, { flexDirection: "column", marginTop: addMargin ? 1 : 0, paddingLeft: 2, onClick: onClick, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, children: settled ? info.glyph : ` ${runningGlyph}` }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), subagent.effort && _jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: subagent.effort })] }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: duration(elapsed) }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: tokens(subagent) }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsxs(Text, { dimColor: true, children: [subagent.toolCalls.length, " tools"] }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label })] }), !settled && (lastRunning ?? previousDone) !== undefined && (_jsx(Text, { wrap: "truncate", children: lastRunning !== undefined ? (_jsxs(_Fragment, { children: [previousDone !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { color: "success", children: "\u2713" }), _jsx(Text, { color: toolNameColor(previousDone.name), children: previousDone.name }), _jsx(Text, { dimColor: true, children: ' · ' })] })), lastRunning.argsPreview === undefined && (_jsx(Text, { color: toolNameColor(lastRunning.name), children: lastRunning.name })), lastRunning.argsPreview !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { color: toolNameColor(lastRunning.name), children: lastRunning.name }), _jsx(Text, { dimColor: true, children: ` (${clipLine(lastRunning.argsPreview.replace(/\s+/g, ' ').trim(), Math.max(10, rowWidth - lastRunning.name.length - 6))})` })] }))] })) : (previousDone !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { color: "success", children: "\u2713" }), _jsx(Text, { color: toolNameColor(previousDone.name), children: previousDone.name }), previousDone.argsPreview !== undefined && (_jsx(Text, { dimColor: true, children: ` (${clipLine(previousDone.argsPreview.replace(/\s+/g, ' ').trim(), Math.max(10, rowWidth - previousDone.name.length - 6))})` }))] }))) })), !settled && Array.from({ length: WATERFALL_ROWS }, (_, index) => (_jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${clipLine(activity[index] ?? '', rowWidth)}` }, `${subagent.agentId}-wf-${index}-${time}`))), settled && subagent.status === 'failed' && subagent.error && (_jsx(Text, { color: "error", wrap: "truncate", children: ` └ ${clipLine(subagent.error, rowWidth)}` }))] });
80
+ // 点击打开详情场景;hover 不刷整行背景(转录视觉保持安静),只把状态
81
+ // glyph 提亮为品牌色作为可点指示。
82
+ return _jsxs(Box, { flexDirection: "column", marginTop: addMargin ? 1 : 0, paddingLeft: 2, ref: viewportRef, onClick: onClick, onMouseEnter: clickable ? () => setHovered(true) : undefined, onMouseLeave: clickable ? () => setHovered(false) : undefined, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: hovered && clickable ? 'claude' : info.color, children: settled ? info.glyph : ` ${runningGlyph}` }), _jsx(Text, { bold: true, color: hovered && clickable ? 'claude' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), subagent.effort && _jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: subagent.effort })] }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: duration(elapsed) }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { dimColor: true, children: tokens(subagent) }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsxs(Text, { dimColor: true, children: [subagent.toolCalls.length, " tools"] }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label })] }), !settled && (lastRunning ?? previousDone) !== undefined && (_jsx(Text, { wrap: "truncate", children: lastRunning !== undefined ? (_jsxs(_Fragment, { children: [previousDone !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { color: "success", children: "\u2713" }), _jsx(Text, { color: toolNameColor(previousDone.name), children: previousDone.name }), _jsx(Text, { dimColor: true, children: ' · ' })] })), lastRunning.argsPreview === undefined && (_jsx(Text, { color: toolNameColor(lastRunning.name), children: lastRunning.name })), lastRunning.argsPreview !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { color: toolNameColor(lastRunning.name), children: lastRunning.name }), _jsx(Text, { dimColor: true, children: ` (${clipLine(lastRunning.argsPreview.replace(/\s+/g, ' ').trim(), Math.max(10, rowWidth - lastRunning.name.length - 6))})` })] }))] })) : (previousDone !== undefined && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { color: "success", children: "\u2713" }), _jsx(Text, { color: toolNameColor(previousDone.name), children: previousDone.name }), previousDone.argsPreview !== undefined && (_jsx(Text, { dimColor: true, children: ` (${clipLine(previousDone.argsPreview.replace(/\s+/g, ' ').trim(), Math.max(10, rowWidth - previousDone.name.length - 6))})` }))] }))) })), !settled && Array.from({ length: WATERFALL_ROWS }, (_, index) => (_jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${clipLine(activity[index] ?? '', rowWidth)}` }, `${subagent.agentId}-wf-${index}`))), settled && subagent.status === 'failed' && subagent.error && (_jsx(Text, { color: "error", wrap: "truncate", children: ` └ ${clipLine(subagent.error, rowWidth)}` }))] });
75
83
  }
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ /**
3
+ * Session accent color picker (bare `/color`): a permission-colored Pane
4
+ * listing the whole palette with a colored swatch per row, `❯` focus
5
+ * pointer and `✓` on the session's current color. Enter applies through
6
+ * `channel.setSessionColor`, Esc cancels. The palette is static, so the
7
+ * picker never needs an async list.
8
+ */
9
+ export declare function ColorPicker({ focusIndex, currentColor, onPick, }: {
10
+ focusIndex: number;
11
+ /** The session's current accent color name ('' = theme default). */
12
+ currentColor: string;
13
+ /** Mouse pick (fullscreen): clicked row's absolute index (Chat applies
14
+ * the same code path as the keyboard Enter). */
15
+ onPick?: (index: number) => void;
16
+ }): React.ReactNode;
17
+ //# sourceMappingURL=ColorPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorPicker.d.ts","sourceRoot":"","sources":["../../../src/components/ColorPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,UAAU,EACV,YAAY,EACZ,MAAM,GACP,EAAE;IACD,UAAU,EAAE,MAAM,CAAA;IAClB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAA;IACpB;qDACiD;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,KAAK,CAAC,SAAS,CA6BlB"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { t } from '../i18n.js';
3
+ import { Box, Text } from '../ui.js';
4
+ import { Pane } from './design-system/Pane.js';
5
+ import { Select } from './Select.js';
6
+ import { HintLine } from './design-system/HintLine.js';
7
+ import { SESSION_COLOR_NAMES, SESSION_COLORS } from '../cc/sessionColors.js';
8
+ /**
9
+ * Session accent color picker (bare `/color`): a permission-colored Pane
10
+ * listing the whole palette with a colored swatch per row, `❯` focus
11
+ * pointer and `✓` on the session's current color. Enter applies through
12
+ * `channel.setSessionColor`, Esc cancels. The palette is static, so the
13
+ * picker never needs an async list.
14
+ */
15
+ export function ColorPicker({ focusIndex, currentColor, onPick, }) {
16
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('picker-title-color') }) }), _jsx(Select, { options: SESSION_COLOR_NAMES.map(name => ({
17
+ value: name,
18
+ label: (_jsxs(Text, { children: [_jsx(Text, { color: SESSION_COLORS[name], children: "\u25CF " }), name] })),
19
+ })), focusIndex: focusIndex, selectedValue: currentColor === '' ? undefined : currentColor, onPick: onPick ? index => onPick(index) : undefined }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-confirm-exit') }) })] }) }));
20
+ }
@@ -1,16 +1,35 @@
1
1
  import React from 'react';
2
+ import type { Color } from '../ink/styles.js';
3
+ import type { Theme } from '../theme.js';
2
4
  import type { LocalCommand } from '../commands.js';
3
5
  /**
4
6
  * The slash-command suggestion overlay, mirroring Claude Code's
5
- * `PromptInputFooterSuggestions.tsx` (command layout only): a name column
6
- * padded to a fixed width, optional `[tag]`, then a truncated description.
7
- * The selected row renders in the theme's `suggestion` color, others dim.
7
+ * `PromptInputFooterSuggestions.tsx` (command layout only) wrapped in the
8
+ * shared rounded `SuggestionCard`:
9
+ *
10
+ * ╭─ 命令 · 共 12 项 ──────────────────────╮
11
+ * │ ❯ compact Compact the conversation … │ ← 选中:❯ + 加粗 + suggestion 色
12
+ * │ compare Compare selected messages … │ ← 名字里命中输入的段提亮
13
+ * │ ↑2 · ↓3 │ ← 仅当列表被窗口裁剪
14
+ * ╰─────────────────────────────────────────╯
15
+ *
16
+ * 未选中行整体 dim,唯独名字里匹配当前查询 token 的前缀以正常亮度提亮
17
+ * (bold 与 dim 在终端互斥,故提亮用非 dim 而非加粗);选中行整行
18
+ * suggestion 色、名字加粗、前置 ❯ 指针。
8
19
  */
9
- export declare function CommandSuggestions({ commands, selectedIndex, columns, }: {
20
+ export declare function CommandSuggestions({ commands, selectedIndex, columns, query, accent, onPick, onWheelStep, }: {
10
21
  commands: readonly (LocalCommand & {
11
22
  descriptionKey?: string;
12
23
  })[];
13
24
  selectedIndex: number;
14
25
  columns: number;
26
+ /** 原始 `/…` 输入;其最后一段 token 用于名字前缀高亮。 */
27
+ query?: string;
28
+ accent?: keyof Theme | Color;
29
+ /** 鼠标点击行(fullscreen):上报过滤后列表的绝对索引(与键盘
30
+ * selectedIndex 同一索引空间),接受路径由 PromptInput 复用。 */
31
+ onPick?: (index: number) => void;
32
+ /** 滚轮步进(fullscreen):±1 移动选中行。 */
33
+ onWheelStep?: (step: 1 | -1) => void;
15
34
  }): React.ReactNode;
16
35
  //# sourceMappingURL=CommandSuggestions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandSuggestions.d.ts","sourceRoot":"","sources":["../../../src/components/CommandSuggestions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,aAAa,EACb,OAAO,GACR,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC,YAAY,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;IACjE,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,KAAK,CAAC,SAAS,CAqDlB"}
1
+ {"version":3,"file":"CommandSuggestions.d.ts","sourceRoot":"","sources":["../../../src/components/CommandSuggestions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAMlD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,aAAa,EACb,OAAO,EACP,KAAU,EACV,MAAM,EACN,MAAM,EACN,WAAW,GACZ,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC,YAAY,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;IACjE,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC5B;sDACkD;IAClD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,iCAAiC;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAA;CACrC,GAAG,KAAK,CAAC,SAAS,CAmFlB"}
@@ -1,35 +1,62 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from '../ui.js';
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from '../ui.js';
3
3
  import { stringWidth } from '../ink/stringWidth.js';
4
4
  import { truncateToWidth } from '../ink/truncateToWidth.js';
5
5
  import { localizedDescription } from '../commands.js';
6
+ import { t } from '../i18n.js';
7
+ import { POINTER } from '../cc/figures.js';
8
+ import { SuggestionCard, cardContentWidth, splitQueryMatch } from './SuggestionCard.js';
6
9
  /**
7
10
  * The slash-command suggestion overlay, mirroring Claude Code's
8
- * `PromptInputFooterSuggestions.tsx` (command layout only): a name column
9
- * padded to a fixed width, optional `[tag]`, then a truncated description.
10
- * The selected row renders in the theme's `suggestion` color, others dim.
11
+ * `PromptInputFooterSuggestions.tsx` (command layout only) wrapped in the
12
+ * shared rounded `SuggestionCard`:
13
+ *
14
+ * ╭─ 命令 · 共 12 项 ──────────────────────╮
15
+ * │ ❯ compact Compact the conversation … │ ← 选中:❯ + 加粗 + suggestion 色
16
+ * │ compare Compare selected messages … │ ← 名字里命中输入的段提亮
17
+ * │ ↑2 · ↓3 │ ← 仅当列表被窗口裁剪
18
+ * ╰─────────────────────────────────────────╯
19
+ *
20
+ * 未选中行整体 dim,唯独名字里匹配当前查询 token 的前缀以正常亮度提亮
21
+ * (bold 与 dim 在终端互斥,故提亮用非 dim 而非加粗);选中行整行
22
+ * suggestion 色、名字加粗、前置 ❯ 指针。
11
23
  */
12
- export function CommandSuggestions({ commands, selectedIndex, columns, }) {
24
+ export function CommandSuggestions({ commands, selectedIndex, columns, query = '', accent, onPick, onWheelStep, }) {
13
25
  if (commands.length === 0)
14
26
  return null;
15
- // Cap the command name column at 40% of terminal width to ensure the
16
- // description has space (same as Claude Code).
17
- const maxNameWidth = Math.floor(columns * 0.4);
27
+ // Cap the command name column at 40% of the card's content width to ensure
28
+ // the description has space (same ratio as Claude Code).
29
+ const usable = cardContentWidth(columns);
30
+ const maxNameWidth = Math.floor(usable * 0.4);
18
31
  const nameWidth = Math.min(Math.max(...commands.map(c => stringWidth(c.name))) + 5, maxNameWidth);
19
32
  const maxVisible = 5;
20
33
  const startIndex = Math.max(0, Math.min(selectedIndex - Math.floor(maxVisible / 2), commands.length - maxVisible));
21
34
  const visible = commands.slice(startIndex, startIndex + maxVisible);
22
- return (_jsx(Box, { flexDirection: "column", children: visible.map(command => {
35
+ const above = startIndex;
36
+ const below = commands.length - (startIndex + visible.length);
37
+ // 前缀高亮取查询的最后一段 token(`/plan of` 高亮 `of` 命中的段)。
38
+ const queryToken = query.replace(/^\//, '').match(/[^ \t]*$/)?.[0] ?? '';
39
+ const title = `${t('sugg-commands-title')} · ${t('sugg-count', { n: commands.length })}`;
40
+ const footer = above > 0 || below > 0
41
+ ? [
42
+ above > 0 ? t('sugg-more-above', { n: above }) : null,
43
+ below > 0 ? t('sugg-more-below', { n: below }) : null,
44
+ ]
45
+ .filter((part) => part !== null)
46
+ .join(' · ')
47
+ : null;
48
+ return (_jsx(SuggestionCard, { title: title, columns: columns, accent: accent, footer: footer, onRowPick: onPick ? index => onPick(startIndex + index) : undefined, onWheelStep: onWheelStep, rows: visible.map(command => {
23
49
  const isSelected = command.name === commands[selectedIndex]?.name;
24
- const padded = command.name +
25
- ' '.repeat(Math.max(0, nameWidth - stringWidth(command.name)));
26
50
  const tagText = command.tag ? `[${command.tag}] ` : '';
27
51
  const tagWidth = stringWidth(tagText);
28
- const descriptionWidth = Math.max(0, columns - nameWidth - tagWidth - 4);
52
+ // 行预算:内容宽 − 前导空格 1 − 指针列 2。
53
+ const descriptionWidth = Math.max(0, usable - 3 - nameWidth - tagWidth);
29
54
  const rawDescription = localizedDescription(command);
30
55
  const description = stringWidth(rawDescription) > descriptionWidth
31
56
  ? truncateToWidth(rawDescription, descriptionWidth - 1) + '…'
32
57
  : rawDescription;
33
- return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: isSelected ? 'suggestion' : undefined, dimColor: !isSelected, children: padded }), tagText ? _jsx(Text, { dimColor: true, children: tagText }) : null, _jsx(Text, { color: isSelected ? 'suggestion' : undefined, dimColor: !isSelected, children: description })] }, command.name));
58
+ const parts = splitQueryMatch(command.name, queryToken);
59
+ const padAfter = Math.max(0, nameWidth - stringWidth(command.name));
60
+ return (_jsxs(Text, { wrap: "truncate", children: [' ', isSelected ? (_jsx(Text, { color: "suggestion", bold: true, children: `${POINTER} ${command.name}${' '.repeat(padAfter)}` })) : parts ? (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ` ${parts.before}` }), _jsx(Text, { children: parts.match }), _jsx(Text, { dimColor: true, children: `${parts.after}${' '.repeat(padAfter)}` })] })) : (_jsx(Text, { dimColor: true, children: ` ${command.name}${' '.repeat(padAfter)}` })), tagText ? _jsx(Text, { dimColor: true, children: tagText }) : null, _jsx(Text, { color: isSelected ? 'suggestion' : undefined, dimColor: !isSelected, children: description })] }, command.name));
34
61
  }) }));
35
62
  }
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import type { Color } from '../ink/styles.js';
3
+ import { type ContextSegments } from '../screens/StatusMetrics.js';
4
+ /**
5
+ * The hoverable JSX twin of `renderContextBar`: the same segmented context
6
+ * bar (same largest-remainder column split, same label fallback ladder,
7
+ * same free-segment readout), rendered as one Box per segment so each
8
+ * carries its own mouse handlers. Hovering a segment reports its key (or
9
+ * `free`) upward through `onHover`; the footer turns that into a detail
10
+ * readout on its supplemental row.
11
+ *
12
+ * Pixel parity with the ANSI path is the contract: this exists so the bar
13
+ * can react to the pointer, not to restyle it.
14
+ */
15
+ export declare function ContextBarView({ segments, usedTokens, contextWindow, width, colors, onHover, }: {
16
+ /** Used tokens per content type. */
17
+ segments: ContextSegments;
18
+ /** Total used tokens, driving the usage readout. */
19
+ usedTokens: number;
20
+ /** The context window size in tokens. */
21
+ contextWindow: number;
22
+ /** Total bar width in terminal columns. */
23
+ width: number;
24
+ /** Theme overrides for the free segment (light theme passes its own). */
25
+ colors?: {
26
+ freeFill: Color;
27
+ freeText: Color;
28
+ };
29
+ /** Hover signal: a segment key (`system`…`tools`), `free`, or null on
30
+ * leave. Absent handlers render a static bar (tests, headless embeds). */
31
+ onHover?: (segment: string | null) => void;
32
+ }): React.ReactNode;
33
+ //# sourceMappingURL=ContextBarView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextBarView.d.ts","sourceRoot":"","sources":["../../../src/components/ContextBarView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAA;AAOpC;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,UAAU,EACV,aAAa,EACb,KAAK,EACL,MAAM,EACN,OAAO,GACR,EAAE;IACD,oCAAoC;IACpC,QAAQ,EAAE,eAAe,CAAA;IACzB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAA;IAClB,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAA;KAAE,CAAA;IAC7C;+EAC2E;IAC3E,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAA;CAC3C,GAAG,KAAK,CAAC,SAAS,CAgElB"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from '../ui.js';
3
+ import { USED_SEGMENTS, allocateBarColumns, centeredText, chooseLabel, composeFreeSegmentText, formatTokens, } from '../screens/StatusMetrics.js';
4
+ /** Free-segment colors, mirroring StatusMetrics' dark-theme defaults. */
5
+ const FREE_FILL = '#E8E8E8';
6
+ const FREE_TEXT = '#4A4A4A';
7
+ const USED_TEXT = '#FFFFFF';
8
+ /**
9
+ * The hoverable JSX twin of `renderContextBar`: the same segmented context
10
+ * bar (same largest-remainder column split, same label fallback ladder,
11
+ * same free-segment readout), rendered as one Box per segment so each
12
+ * carries its own mouse handlers. Hovering a segment reports its key (or
13
+ * `free`) upward through `onHover`; the footer turns that into a detail
14
+ * readout on its supplemental row.
15
+ *
16
+ * Pixel parity with the ANSI path is the contract: this exists so the bar
17
+ * can react to the pointer, not to restyle it.
18
+ */
19
+ export function ContextBarView({ segments, usedTokens, contextWindow, width, colors, onHover, }) {
20
+ if (width <= 0 || contextWindow <= 0)
21
+ return null;
22
+ const freeTokens = Math.max(0, contextWindow - usedTokens);
23
+ const values = [...USED_SEGMENTS.map(segment => segments[segment.key]), freeTokens];
24
+ const columns = allocateBarColumns(values, width);
25
+ const percent = `${((usedTokens / contextWindow) * 100).toFixed(1)}%`;
26
+ const total = `${formatTokens(usedTokens)}/${formatTokens(contextWindow)}`;
27
+ const free = formatTokens(contextWindow - usedTokens);
28
+ const nodes = [];
29
+ for (const [index, segment] of USED_SEGMENTS.entries()) {
30
+ const segmentWidth = columns[index] ?? 0;
31
+ if (segmentWidth <= 0)
32
+ continue;
33
+ const label = chooseLabel(segment.labels, segmentWidth);
34
+ nodes.push(_jsx(Box, { width: segmentWidth, height: 1, flexShrink: 0, backgroundColor: segment.color, onMouseEnter: onHover === undefined ? undefined : () => onHover(segment.key), onMouseLeave: onHover === undefined ? undefined : () => onHover(null), children: _jsx(Text, { color: USED_TEXT, children: label.length > 0 ? centeredText(label, segmentWidth) : ' '.repeat(segmentWidth) }) }, segment.key));
35
+ }
36
+ const freeWidth = columns[USED_SEGMENTS.length] ?? 0;
37
+ if (freeWidth > 0) {
38
+ nodes.push(_jsx(Box, { width: freeWidth, height: 1, flexShrink: 0, backgroundColor: colors?.freeFill ?? FREE_FILL, onMouseEnter: onHover === undefined ? undefined : () => onHover('free'), onMouseLeave: onHover === undefined ? undefined : () => onHover(null), children: _jsx(Text, { color: colors?.freeText ?? FREE_TEXT, children: composeFreeSegmentText([
39
+ `ctx ${total} ${percent} ${free}`,
40
+ `${total} ${percent} ${free}`,
41
+ `${total} ${percent}`,
42
+ percent,
43
+ ], freeWidth) }) }, "free"));
44
+ }
45
+ return (_jsx(Box, { flexDirection: "row", flexShrink: 0, width: width, children: nodes }));
46
+ }
@@ -22,7 +22,16 @@
22
22
  import React from 'react';
23
23
  import type { Color } from '../ink/styles.js';
24
24
  import type { Theme } from '../theme.js';
25
- export declare function EffortInputBorder({ effort, levels, columns, onLight, idleColor, children, }: {
25
+ /** A static chip on the top border row (the session label, CC-style). */
26
+ export interface InputBorderLabel {
27
+ /** Visible text (already width-truncated by the caller). */
28
+ text: string;
29
+ /** Chip background (theme token or raw color). */
30
+ color: keyof Theme | Color;
31
+ /** Chip foreground (theme token or raw color). */
32
+ ink: keyof Theme | Color;
33
+ }
34
+ export declare function EffortInputBorder({ effort, levels, columns, onLight, idleColor, topRightLabel, children, }: {
26
35
  /** 当前思考强度档 id;`undefined` 表示路线未声明。 */
27
36
  effort: string | undefined;
28
37
  /** 当前路线的档位表(低→高,末位为最高档);未知时传 `undefined`。 */
@@ -31,6 +40,8 @@ export declare function EffortInputBorder({ effort, levels, columns, onLight, id
31
40
  onLight: boolean;
32
41
  /** 静止边框色(主题 token 名,如 'promptBorder' / 'planMode')。 */
33
42
  idleColor: keyof Theme | Color;
43
+ /** 顶边框右侧的静态标签 chip(会话名标签);undefined = 不显示。 */
44
+ topRightLabel?: InputBorderLabel;
34
45
  children: React.ReactNode;
35
46
  }): React.ReactNode;
36
47
  //# sourceMappingURL=EffortInputBorder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EffortInputBorder.d.ts","sourceRoot":"","sources":["../../../src/components/EffortInputBorder.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAA8D,MAAM,OAAO,CAAA;AAGlF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAgCxC,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,QAAQ,GACT,EAAE;IACD,sCAAsC;IACtC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC9B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,GAAG,KAAK,CAAC,SAAS,CA0DlB"}
1
+ {"version":3,"file":"EffortInputBorder.d.ts","sourceRoot":"","sources":["../../../src/components/EffortInputBorder.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAA8D,MAAM,OAAO,CAAA;AAGlF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAKxC,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAA;IACZ,kDAAkD;IAClD,KAAK,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC1B,kDAAkD;IAClD,GAAG,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;CACzB;AAiDD,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,MAAM,EACN,OAAO,EACP,OAAO,EACP,SAAS,EACT,aAAa,EACb,QAAQ,GACT,EAAE;IACD,sCAAsC;IACtC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,uDAAuD;IACvD,SAAS,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC9B,8CAA8C;IAC9C,aAAa,CAAC,EAAE,gBAAgB,CAAA;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,GAAG,KAAK,CAAC,SAAS,CA0DlB"}
@@ -23,12 +23,29 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
23
  import { useContext, useEffect, useReducer, useState } from 'react';
24
24
  import { Box, Text } from '../ui.js';
25
25
  import { ClockContext } from '../ink/components/ClockContext.js';
26
+ import { stringWidth } from '../ink/stringWidth.js';
26
27
  import { IGNITION_TIMELINE, ignitionLineColors } from '../trajectory/effortIgnition.js';
27
- /** 边框行(顶/底共用同一色段序列——同步变色)。 */
28
- function BorderRow({ left, right, runs, idleColor, }) {
29
- return (_jsx(Box, { width: "100%", height: 1, flexShrink: 0, overflow: "hidden", children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: idleColor, children: left }), runs.map((run, i) => (_jsx(Text, { color: run.color, children: run.glyph }, i))), _jsx(Text, { color: idleColor, children: right })] }) }));
28
+ /** 边框行(顶/底共用同一色段序列——同步变色)。顶行可在右圆角前插入
29
+ * 一个静态标签 chip(会话名),占用的列数从色段序列里扣掉,行宽不变。 */
30
+ function BorderRow({ left, right, runs, idleColor, label, }) {
31
+ const labelWidth = label === undefined ? 0 : stringWidth(` ${label.text} `);
32
+ // chip 与右圆角之间的留白(边框线格数):视觉上不让标签贴死 ╮。
33
+ const labelGap = label === undefined ? 0 : 2;
34
+ // 裁剪色段序列到剩余列数(label 行与底行的列数一致,总宽不变)。
35
+ // 色段保留左侧部分,右侧让位给 chip + 留白(右上角布局)。
36
+ let budget = Math.max(0, runs.reduce((sum, run) => sum + run.glyph.length, 0) - labelWidth - labelGap);
37
+ const clipped = [];
38
+ for (const run of runs) {
39
+ if (budget <= 0)
40
+ break;
41
+ const take = Math.min(run.glyph.length, budget);
42
+ if (take > 0)
43
+ clipped.push({ glyph: run.glyph.slice(0, take), color: run.color });
44
+ budget -= take;
45
+ }
46
+ return (_jsx(Box, { width: "100%", height: 1, flexShrink: 0, overflow: "hidden", children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: idleColor, children: left }), clipped.map((run, i) => (_jsx(Text, { color: run.color, children: run.glyph }, i))), label !== undefined && (_jsx(Text, { backgroundColor: label.color, color: label.ink, children: ` ${label.text} ` })), label !== undefined && _jsx(Text, { color: idleColor, children: '─'.repeat(labelGap) }), _jsx(Text, { color: idleColor, children: right })] }) }));
30
47
  }
31
- export function EffortInputBorder({ effort, levels, columns, onLight, idleColor, children, }) {
48
+ export function EffortInputBorder({ effort, levels, columns, onLight, idleColor, topRightLabel, children, }) {
32
49
  const clock = useContext(ClockContext);
33
50
  const [overlay, setOverlay] = useState(null);
34
51
  const [prevEffort, setPrevEffort] = useState(effort);
@@ -69,5 +86,5 @@ export function EffortInputBorder({ effort, levels, columns, onLight, idleColor,
69
86
  else
70
87
  runs.push({ glyph: '─', color });
71
88
  }
72
- return (_jsxs(Box, { flexDirection: "column", alignItems: "flex-start", justifyContent: "flex-start", width: "100%", flexShrink: 0, children: [_jsx(BorderRow, { left: "\u256D", right: "\u256E", runs: runs, idleColor: idleColor }), _jsx(Box, { flexShrink: 0, children: children }), _jsx(BorderRow, { left: "\u2570", right: "\u256F", runs: runs, idleColor: idleColor })] }));
89
+ return (_jsxs(Box, { flexDirection: "column", alignItems: "flex-start", justifyContent: "flex-start", width: "100%", flexShrink: 0, children: [_jsx(BorderRow, { left: "\u256D", right: "\u256E", runs: runs, idleColor: idleColor, label: topRightLabel }), _jsx(Box, { flexShrink: 0, children: children }), _jsx(BorderRow, { left: "\u2570", right: "\u256F", runs: runs, idleColor: idleColor })] }));
73
90
  }
@@ -7,9 +7,12 @@ import type { EffortOption } from '../dsh-adapter/channel.js';
7
7
  * or Esc just closes it). The current level carries `✓`; the focused level's
8
8
  * description renders below the row.
9
9
  */
10
- export declare function EffortSlider({ options, focusIndex, currentId, }: {
10
+ export declare function EffortSlider({ options, focusIndex, currentId, onPick, }: {
11
11
  options: readonly EffortOption[];
12
12
  focusIndex: number;
13
13
  currentId: string | undefined;
14
+ /** Mouse pick (fullscreen): click a tier = move there and live-apply —
15
+ * the same semantics as the ←/→ keys (the slider IS the control). */
16
+ onPick?: (index: number) => void;
14
17
  }): React.ReactNode;
15
18
  //# sourceMappingURL=EffortSlider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EffortSlider.d.ts","sourceRoot":"","sources":["../../../src/components/EffortSlider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,UAAU,EACV,SAAS,GACV,EAAE;IACD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B,GAAG,KAAK,CAAC,SAAS,CAmClB"}
1
+ {"version":3,"file":"EffortSlider.d.ts","sourceRoot":"","sources":["../../../src/components/EffortSlider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,UAAU,EACV,SAAS,EACT,MAAM,GACP,EAAE;IACD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B;0EACsE;IACtE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,KAAK,CAAC,SAAS,CA4ClB"}
@@ -11,7 +11,9 @@ import { HintLine } from './design-system/HintLine.js';
11
11
  * or Esc just closes it). The current level carries `✓`; the focused level's
12
12
  * description renders below the row.
13
13
  */
14
- export function EffortSlider({ options, focusIndex, currentId, }) {
14
+ export function EffortSlider({ options, focusIndex, currentId, onPick, }) {
15
15
  const focused = options[focusIndex];
16
- return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('picker-title-effort') }) }), _jsx(Box, { flexDirection: "row", children: options.map((option, index) => (_jsxs(React.Fragment, { children: [index > 0 ? (_jsx(Text, { dimColor: true, children: " \u2500\u2500 " })) : null, _jsx(Text, { inverse: index === focusIndex, bold: index === focusIndex, children: option.name }), option.id === currentId ? _jsx(Text, { color: "remember", children: "\u2713" }) : null] }, option.id))) }), focused?.description !== undefined ? (_jsx(Text, { dimColor: true, children: focused.description })) : null, _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-adjust-done') }) })] }) }));
16
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('picker-title-effort') }) }), _jsx(Box, { flexDirection: "row", children: options.map((option, index) => (_jsxs(React.Fragment, { children: [index > 0 ? (_jsx(Text, { dimColor: true, children: " \u2500\u2500 " })) : null, _jsx(Box, { onClick: onPick ? () => onPick(index) : undefined, backgroundColor: onPick !== undefined && index !== focusIndex
17
+ ? 'userMessageBackgroundHover'
18
+ : undefined, children: _jsx(Text, { inverse: index === focusIndex, bold: index === focusIndex, children: option.name }) }), option.id === currentId ? _jsx(Text, { color: "remember", children: "\u2713" }) : null] }, option.id))) }), focused?.description !== undefined ? (_jsx(Text, { dimColor: true, children: focused.description })) : null, _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-adjust-done') }) })] }) }));
17
19
  }
@@ -87,7 +87,9 @@ function SelectDialog({ dialog, onDecide, onCancel, }) {
87
87
  const { start, end } = listWindow(dialog.options.map(option => (option.description === undefined ? 1 : 2)), focusIndex, Math.max(terminalRows - 10, 2));
88
88
  return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: dialog.title }) }), dialog.options.slice(start, end).map((option, index) => {
89
89
  const absoluteIndex = start + index;
90
- return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: option.description, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < dialog.options.length, children: option.label }, option.id));
90
+ return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: option.description, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < dialog.options.length,
91
+ // Click = decide this option (same as Enter on it).
92
+ onClick: () => onDecide(option.id), children: option.label }, option.id));
91
93
  })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
92
94
  }
93
95
  function ConfirmDialog({ dialog, onDecide, onCancel, }) {
@@ -123,7 +125,9 @@ function ConfirmDialog({ dialog, onDecide, onCancel, }) {
123
125
  onDecide(focusRef.current === 0);
124
126
  }
125
127
  }, { isActive: true });
126
- return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: dialog.title }), dialog.message !== undefined && _jsx(Text, { dimColor: true, children: dialog.message })] }), labels.map((label, index) => (_jsx(ListItem, { isFocused: index === focusIndex, children: label }, label)))] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
128
+ return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: dialog.title }), dialog.message !== undefined && _jsx(Text, { dimColor: true, children: dialog.message })] }), labels.map((label, index) => (_jsx(ListItem, { isFocused: index === focusIndex,
129
+ // Click = decide this row (same as Enter on it).
130
+ onClick: () => onDecide(index === 0), children: label }, label)))] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
127
131
  }
128
132
  function InputDialog({ dialog, onDecide, onCancel, }) {
129
133
  const [value, setValue] = React.useState(dialog.initial);
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ /**
3
+ * Click-to-act file menu (fullscreen): opened by clicking a file path in
4
+ * the transcript (tool cards, markdown code spans / plain text, file://
5
+ * links). Rows: open the target, reveal it in the file manager, copy its
6
+ * absolute path. The path shown is already resolved to an absolute path by
7
+ * the caller (Chat.tsx resolves against the channel cwd at click time).
8
+ * When the target is a directory, the first row reads "open folder" — the
9
+ * same action (default handler), just honest about what it opens.
10
+ */
11
+ export declare const FILE_ACTION_COUNT = 3;
12
+ export declare function FileActionsPanel({ path, isDir, focusIndex, onPick, }: {
13
+ /** Absolute path the actions operate on (caller-resolved). */
14
+ path: string;
15
+ /** Whether the target exists on disk and is a directory. */
16
+ isDir: boolean;
17
+ /** Index of the keyboard-focused row. */
18
+ focusIndex: number;
19
+ /** Mouse pick (fullscreen): clicked row's absolute index. */
20
+ onPick?: (index: number) => void;
21
+ }): React.ReactNode;
22
+ //# sourceMappingURL=FileActionsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileActionsPanel.d.ts","sourceRoot":"","sources":["../../../src/components/FileActionsPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAQzB;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAKlC,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,UAAU,EACV,MAAM,GACP,EAAE;IACD,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,4DAA4D;IAC5D,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,KAAK,CAAC,SAAS,CAiClB"}
@@ -0,0 +1,28 @@
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 } from '../ui.js';
5
+ import { Pane } from './design-system/Pane.js';
6
+ import { Select } from './Select.js';
7
+ import { HintLine } from './design-system/HintLine.js';
8
+ import { truncateToWidth } from '../ink/truncateToWidth.js';
9
+ /**
10
+ * Click-to-act file menu (fullscreen): opened by clicking a file path in
11
+ * the transcript (tool cards, markdown code spans / plain text, file://
12
+ * links). Rows: open the target, reveal it in the file manager, copy its
13
+ * absolute path. The path shown is already resolved to an absolute path by
14
+ * the caller (Chat.tsx resolves against the channel cwd at click time).
15
+ * When the target is a directory, the first row reads "open folder" — the
16
+ * same action (default handler), just honest about what it opens.
17
+ */
18
+ export const FILE_ACTION_COUNT = 3;
19
+ /** How many terminal cells of the path fit next to the title. */
20
+ const PATH_DISPLAY_BUDGET = 48;
21
+ export function FileActionsPanel({ path, isDir, focusIndex, onPick, }) {
22
+ const options = React.useMemo(() => [
23
+ { value: 'open', label: t(isDir ? 'file-actions-open-dir' : 'file-actions-open') },
24
+ { value: 'reveal', label: t('file-actions-reveal') },
25
+ { value: 'copy', label: t('file-actions-copy') },
26
+ ], [isDir]);
27
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('file-actions-title') }), _jsxs(Text, { dimColor: true, wrap: "truncate-end", children: [' ', truncateToWidth(path, PATH_DISPLAY_BUDGET)] })] }), _jsx(Select, { options: options, focusIndex: focusIndex, selectedValue: undefined, visibleOptionCount: FILE_ACTION_COUNT, onPick: onPick ? index => onPick(index) : undefined }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-confirm-exit') }) })] }) }));
28
+ }
@@ -1,16 +1,35 @@
1
1
  import React from 'react';
2
+ import type { Color } from '../ink/styles.js';
3
+ import type { Theme } from '../theme.js';
2
4
  import type { FileCandidate } from '../utils/fileSuggestions.js';
3
5
  /**
4
- * The `@` file-completion overlay in CC's suggestion style: full relative
5
- * path (directory suffix stripped) + a `file`/`directory` description. The
6
- * selected row renders in the theme's `suggestion` color, others dim. The
7
- * name column is padded to a fixed display width so the description column
8
- * keeps its contract at narrow terminals (pinned by verify-cjk-truncate.tsx);
9
- * every pad/truncate uses display width, so CJK names never split a glyph.
6
+ * The `@` file-completion overlay in CC's suggestion style, wrapped in the
7
+ * shared rounded `SuggestionCard` (与 `/` 命令菜单同一视觉语言):
8
+ *
9
+ * ╭─ 文件 · 共 12 项 ──────────────────────╮
10
+ * │ ❯ ▸ src/components/ directory │
11
+ * │ + README.md file │
12
+ * ╰─────────────────────────────────────────╯
13
+ *
14
+ * Full relative path (directory suffix stripped) + a `file`/`directory`
15
+ * description; the selected row renders `❯` + bold in the theme's
16
+ * `suggestion` color, others dim with the query-matched prefix of the name
17
+ * highlighted (non-dim). The name column is padded to a fixed display width
18
+ * so the description column keeps its contract at narrow terminals (pinned
19
+ * by verify-cjk-truncate.tsx); every pad/truncate uses display width, so CJK
20
+ * names never split a glyph.
10
21
  */
11
- export declare function FileSuggestions({ files, selectedIndex, columns, }: {
22
+ export declare function FileSuggestions({ files, selectedIndex, columns, query, accent, onPick, onWheelStep, }: {
12
23
  files: readonly FileCandidate[];
13
24
  selectedIndex: number;
14
25
  columns: number;
26
+ /** `@` 触发 token 里已输入的查询(`mention.query`),用于名字前缀高亮。 */
27
+ query?: string;
28
+ accent?: keyof Theme | Color;
29
+ /** 鼠标点击行(fullscreen):上报过滤后列表的绝对索引(与键盘
30
+ * selectedIndex 同一索引空间),接受路径由 PromptInput 复用。 */
31
+ onPick?: (index: number) => void;
32
+ /** 滚轮步进(fullscreen):±1 移动选中行。 */
33
+ onWheelStep?: (step: 1 | -1) => void;
15
34
  }): React.ReactNode;
16
35
  //# sourceMappingURL=FileSuggestions.d.ts.map