@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,25 @@
1
+ import React from 'react';
2
+ /**
3
+ * `/recap` panel (pi-recap semantics), in the picker/dialog visual
4
+ * language: a permission-colored Pane with a title bar (会话回顾), a
5
+ * scrollable summary body (error / summary / answering spinner), the
6
+ * proposed session title row (apply via `a` or clicking the chip), and a
7
+ * dim italic hint line (click to copy, same as `c`). Owns the keyboard
8
+ * while open, mirroring BtwPanel.
9
+ */
10
+ export declare function RecapPanel({ summary, title, error, streaming, titleApplied, onClose, onCopy, onApplyTitle, }: {
11
+ /** The one-line recap summary (streamed raw, then replaced on settle). */
12
+ summary: string;
13
+ /** Proposed session title from the recap call, when the model offered one. */
14
+ title?: string;
15
+ /** Human-readable failure reason. */
16
+ error?: string;
17
+ /** True while the recap call is in flight. */
18
+ streaming: boolean;
19
+ /** True once the proposed title was applied via renameSession. */
20
+ titleApplied: boolean;
21
+ onClose: () => void;
22
+ onCopy: () => void;
23
+ onApplyTitle: () => void;
24
+ }): React.ReactNode;
25
+ //# sourceMappingURL=RecapPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecapPanel.d.ts","sourceRoot":"","sources":["../../../src/components/RecapPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,KAAK,EACL,SAAS,EACT,YAAY,EACZ,OAAO,EACP,MAAM,EACN,YAAY,GACb,EAAE;IACD,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,kEAAkE;IAClE,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,GAAG,KAAK,CAAC,SAAS,CAuFlB"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Box, Text, useInput, ScrollBox, useTerminalSize } from '../ui.js';
4
+ import { SpinnerGlyph } from './Spinner/SpinnerGlyph.js';
5
+ import { Pane } from './design-system/Pane.js';
6
+ import { t } from '../i18n.js';
7
+ import { isPlainReturnInput } from '../utils/modifiers.js';
8
+ /**
9
+ * `/recap` panel (pi-recap semantics), in the picker/dialog visual
10
+ * language: a permission-colored Pane with a title bar (会话回顾), a
11
+ * scrollable summary body (error / summary / answering spinner), the
12
+ * proposed session title row (apply via `a` or clicking the chip), and a
13
+ * dim italic hint line (click to copy, same as `c`). Owns the keyboard
14
+ * while open, mirroring BtwPanel.
15
+ */
16
+ export function RecapPanel({ summary, title, error, streaming, titleApplied, onClose, onCopy, onApplyTitle, }) {
17
+ const scrollRef = React.useRef(null);
18
+ const { rows } = useTerminalSize();
19
+ // Spinner frame (80ms cadence, only while waiting for the first text).
20
+ const [frame, setFrame] = React.useState(0);
21
+ React.useEffect(() => {
22
+ if (!streaming || summary !== '')
23
+ return;
24
+ const interval = setInterval(() => setFrame(f => f + 1), 80);
25
+ return () => clearInterval(interval);
26
+ }, [streaming, summary]);
27
+ const canApply = title !== undefined && title !== '' && !titleApplied;
28
+ useInput((input, key, event) => {
29
+ if (key.escape || isPlainReturnInput(input, key) || input === ' ') {
30
+ event.stopImmediatePropagation();
31
+ onClose();
32
+ return;
33
+ }
34
+ if (key.upArrow || key.downArrow) {
35
+ scrollRef.current?.scrollBy(key.upArrow ? -3 : 3);
36
+ event.stopImmediatePropagation();
37
+ return;
38
+ }
39
+ if (input === 'c' && !key.ctrl) {
40
+ event.stopImmediatePropagation();
41
+ onCopy();
42
+ return;
43
+ }
44
+ if (input === 'a' && !key.ctrl && canApply) {
45
+ event.stopImmediatePropagation();
46
+ onApplyTitle();
47
+ return;
48
+ }
49
+ // The overlay owns the keyboard while open: swallow everything else so
50
+ // nothing leaks into the prompt input behind it.
51
+ event.stopImmediatePropagation();
52
+ });
53
+ const settled = summary !== '' || error !== undefined;
54
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('recap-panel-title') }), _jsxs(Text, { dimColor: true, children: [" \u00B7 ", t('recap-panel-subtitle')] })] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(5, rows - 11), children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: error !== undefined ? (_jsx(Text, { color: "error", children: error })) : summary !== '' ? (_jsx(Text, { children: summary })) : (_jsxs(Box, { children: [_jsx(SpinnerGlyph, { frame: frame, messageColor: "warning" }), _jsxs(Text, { color: "warning", children: [" ", t('recap-answering')] })] })) }) }), title !== undefined && (_jsxs(Box, { flexDirection: "row", marginTop: 1, children: [_jsxs(Text, { dimColor: true, children: [t('recap-title-label'), ": "] }), _jsx(Text, { color: "suggestion", children: title }), titleApplied ? (_jsxs(Text, { color: "success", children: [" \u2713 ", t('recap-title-applied')] })) : (_jsx(Box, { onClick: canApply ? onApplyTitle : undefined, children: _jsxs(Text, { color: "success", bold: true, children: [' ', "[", t('recap-apply-title'), "]"] }) }))] })), _jsx(Box, { onClick: settled ? onCopy : undefined, children: _jsx(Text, { dimColor: true, italic: true, children: t('recap-hint', { apply: canApply ? ' · a ' + t('recap-apply-title') : '' }) }) })] }) }));
55
+ }
@@ -12,7 +12,7 @@ import type { TuiRewindMode } from '../dsh-adapter/extension-events.js';
12
12
  * a choice list whose option zero is always the built-in conversation-only
13
13
  * rewind, followed by the plugin's modes (e.g. "also restore files").
14
14
  */
15
- export declare function RewindPicker({ rows, focusIndex, confirmRow, modes, modeIndex, busy, }: {
15
+ export declare function RewindPicker({ rows, focusIndex, confirmRow, modes, modeIndex, busy, onPickRow, onConfirm, onPickMode, }: {
16
16
  rows: readonly ChatRow[];
17
17
  focusIndex: number;
18
18
  confirmRow: ChatRow | null;
@@ -22,5 +22,16 @@ export declare function RewindPicker({ rows, focusIndex, confirmRow, modes, mode
22
22
  modeIndex?: number;
23
23
  /** True while the plugin decision is in flight. */
24
24
  busy?: boolean;
25
+ /**
26
+ * Mouse pick on a list row (fullscreen): sets focus only — rewind is a
27
+ * high-risk invisible-confirm operation, so stepping into the confirm
28
+ * state stays an explicit keyboard Enter.
29
+ */
30
+ onPickRow?: (index: number) => void;
31
+ /** Mouse click on the plain confirm row: executes the rewind directly —
32
+ * the confirm pane itself is the explicit confirmation layer. */
33
+ onConfirm?: () => void;
34
+ /** Mouse pick on a modes-list option: executes that mode directly. */
35
+ onPickMode?: (index: number) => void;
25
36
  }): React.ReactNode;
26
37
  //# sourceMappingURL=RewindPicker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RewindPicker.d.ts","sourceRoot":"","sources":["../../../src/components/RewindPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AAMvE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,UAAU,EACV,UAAU,EACV,KAAY,EACZ,SAAa,EACb,IAAY,GACb,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAA;IACvC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CA4GlB"}
1
+ {"version":3,"file":"RewindPicker.d.ts","sourceRoot":"","sources":["../../../src/components/RewindPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AAMvE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,UAAU,EACV,UAAU,EACV,KAAY,EACZ,SAAa,EACb,IAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,GACX,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAA;IACvC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC;sEACkE;IAClE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC,GAAG,KAAK,CAAC,SAAS,CAkHlB"}
@@ -16,7 +16,7 @@ import { listWindow } from './listWindow.js';
16
16
  * a choice list whose option zero is always the built-in conversation-only
17
17
  * rewind, followed by the plugin's modes (e.g. "also restore files").
18
18
  */
19
- export function RewindPicker({ rows, focusIndex, confirmRow, modes = null, modeIndex = 0, busy = false, }) {
19
+ export function RewindPicker({ rows, focusIndex, confirmRow, modes = null, modeIndex = 0, busy = false, onPickRow, onConfirm, onPickMode, }) {
20
20
  if (confirmRow !== null) {
21
21
  if (modes !== null) {
22
22
  // Plugin modes: a described choice list (one extra row per
@@ -34,10 +34,10 @@ export function RewindPicker({ rows, focusIndex, confirmRow, modes = null, modeI
34
34
  ];
35
35
  return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('rewind-confirm-title') }), _jsx(Text, { dimColor: true, children: preview(confirmRow.text) })] }), options.slice(start, end).map((option, index) => {
36
36
  const absoluteIndex = start + index;
37
- return (_jsx(ListItem, { isFocused: absoluteIndex === modeIndex, description: option.description, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < options.length, children: option.label }, option.key));
37
+ return (_jsx(ListItem, { isFocused: absoluteIndex === modeIndex, description: option.description, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < options.length, onClick: onPickMode === undefined ? undefined : () => onPickMode(absoluteIndex), children: option.label }, option.key));
38
38
  })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
39
39
  }
40
- return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('rewind-confirm-title') }) }), _jsx(ListItem, { isFocused: false, description: t('rewind-confirm-desc'), children: preview(confirmRow.text) }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-rewind-back') }) })] }) }));
40
+ return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('rewind-confirm-title') }) }), _jsx(ListItem, { isFocused: false, description: t('rewind-confirm-desc'), onClick: onConfirm, children: preview(confirmRow.text) }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-rewind-back') }) })] }) }));
41
41
  }
42
42
  const { rows: terminalRows } = useTerminalSize();
43
43
  // 焦点窗口化按行预算:首项带 'last message' 描述占 2 行、其余 1 行
@@ -46,7 +46,9 @@ export function RewindPicker({ rows, focusIndex, confirmRow, modes = null, modeI
46
46
  const { start, end } = listWindow(rows.map((_, i) => (i === 0 ? 2 : 1)), focusIndex, Math.max(terminalRows - 14, 2));
47
47
  return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('rewind-title') }), _jsx(Text, { dimColor: true, children: t('rewind-subtitle') })] }), rows.length === 0 ? (_jsx(ListItem, { isFocused: false, children: t('rewind-empty') })) : (rows.slice(start, end).map((row, index) => {
48
48
  const absoluteIndex = start + index;
49
- return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: absoluteIndex === 0 ? t('rewind-last-message') : undefined, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < rows.length, children: preview(row.text) }, row.id));
49
+ return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: absoluteIndex === 0 ? t('rewind-last-message') : undefined, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < rows.length, onClick: onPickRow !== undefined && !busy
50
+ ? () => onPickRow(absoluteIndex)
51
+ : undefined, children: preview(row.text) }, row.id));
50
52
  })), busy && _jsx(Text, { dimColor: true, children: t('rewind-waiting-plugins') })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
51
53
  }
52
54
  /** One-line preview of a message (newlines flattened, capped). */
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { type ScrollBoxHandle } from '../ui.js';
3
+ /**
4
+ * Proportional scrollbar for the fullscreen transcript's gutter — the
5
+ * `scrollbar` option of the `dsh-tui.scrollGutter` setting (the timeline
6
+ * rail's sibling; same 2-column slot, same chrome rules):
7
+ *
8
+ * - the thumb (██) shows the visible window's position AND size over the
9
+ * whole content (viewport²/content tall, positioned by scrollTop);
10
+ * - clicking the track scrolls the clicked position to the viewport top
11
+ * (classic scrollbar semantics — the thumb centers under the click
12
+ * through the follow-up renders);
13
+ * - the gutter is permanent while scrollable (Qwen's rule: an
14
+ * auto-hiding gutter that changes content width rewraps everything);
15
+ * hidden below 60 terminal columns or when the content fits (inline
16
+ * mode keeps the terminal's native scrollback);
17
+ * - NoSelect fences the glyphs out of click-drag text selection; the
18
+ * wheel over the gutter scrolls the transcript.
19
+ *
20
+ * Thumb dragging is intentionally NOT implemented (Grok's MVP rule): a
21
+ * proportional thumb encodes position, and the tick rail remains the
22
+ * semantic navigator. Click-to-position covers the same need.
23
+ */
24
+ export declare function ScrollbarGutter({ handle, terminalWidth, }: {
25
+ handle: ScrollBoxHandle | null;
26
+ terminalWidth: number;
27
+ }): React.ReactNode;
28
+ //# sourceMappingURL=ScrollbarGutter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScrollbarGutter.d.ts","sourceRoot":"","sources":["../../../src/components/ScrollbarGutter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAUpE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,MAAM,EACN,aAAa,GACd,EAAE;IACD,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;CACtB,GAAG,KAAK,CAAC,SAAS,CAoIlB"}
@@ -0,0 +1,119 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { Box, Text, NoSelect } from '../ui.js';
4
+ import { RAIL_MIN_TERMINAL_WIDTH, RAIL_WIDTH } from '../ink/timeline-rail.js';
5
+ /** Thumb glyph across the 2-col gutter: solid, clearly positional —
6
+ * deliberately distinct from the timeline's ━━ active tick. */
7
+ const THUMB = '██';
8
+ /** Rest time before the hover position chip pops (anti-flash sweep gate). */
9
+ const CHIP_DWELL_MS = 250;
10
+ /**
11
+ * Proportional scrollbar for the fullscreen transcript's gutter — the
12
+ * `scrollbar` option of the `dsh-tui.scrollGutter` setting (the timeline
13
+ * rail's sibling; same 2-column slot, same chrome rules):
14
+ *
15
+ * - the thumb (██) shows the visible window's position AND size over the
16
+ * whole content (viewport²/content tall, positioned by scrollTop);
17
+ * - clicking the track scrolls the clicked position to the viewport top
18
+ * (classic scrollbar semantics — the thumb centers under the click
19
+ * through the follow-up renders);
20
+ * - the gutter is permanent while scrollable (Qwen's rule: an
21
+ * auto-hiding gutter that changes content width rewraps everything);
22
+ * hidden below 60 terminal columns or when the content fits (inline
23
+ * mode keeps the terminal's native scrollback);
24
+ * - NoSelect fences the glyphs out of click-drag text selection; the
25
+ * wheel over the gutter scrolls the transcript.
26
+ *
27
+ * Thumb dragging is intentionally NOT implemented (Grok's MVP rule): a
28
+ * proportional thumb encodes position, and the tick rail remains the
29
+ * semantic navigator. Click-to-position covers the same need.
30
+ */
31
+ export function ScrollbarGutter({ handle, terminalWidth, }) {
32
+ const [, setTick] = React.useState(0);
33
+ // Hover readout: the row under the pointer brightens the thumb when it is
34
+ // the hovered one, and floats a `62% · 340/540` chip left of the gutter
35
+ // naming the position a click there would jump to. The chip is
36
+ // dwell-gated (TimelineRail's preview-card rule): a sweep across the
37
+ // track brightens rows but never pops chips — only ~250ms of rest does.
38
+ // Once shown it follows row changes immediately; leaving hides it.
39
+ const [hoverRow, setHoverRow] = React.useState(null);
40
+ const [chipRow, setChipRow] = React.useState(null);
41
+ const dwellTimer = React.useRef(null);
42
+ const clearDwell = () => {
43
+ if (dwellTimer.current !== null) {
44
+ clearTimeout(dwellTimer.current);
45
+ dwellTimer.current = null;
46
+ }
47
+ };
48
+ const clearChip = () => {
49
+ clearDwell();
50
+ setChipRow(null);
51
+ };
52
+ React.useEffect(() => clearDwell, []);
53
+ React.useEffect(() => {
54
+ if (!handle)
55
+ return;
56
+ return handle.subscribe(() => setTick(t => t + 1));
57
+ }, [handle]);
58
+ if (!handle)
59
+ return null;
60
+ const viewport = handle.getViewportHeight();
61
+ const content = handle.getScrollHeight();
62
+ const maxScroll = Math.max(0, content - viewport);
63
+ if (viewport < 2 || content <= viewport || terminalWidth < RAIL_MIN_TERMINAL_WIDTH)
64
+ return null;
65
+ // Thumb: the visible window mapped onto the gutter. Height proportional
66
+ // to the visible fraction (≥2 rows so it is always grabbable-looking);
67
+ // top follows scrollTop over the scroll range.
68
+ const thumbH = Math.max(2, Math.round((viewport * viewport) / content));
69
+ const trackH = Math.max(1, viewport - thumbH);
70
+ const thumbTop = Math.round((handle.getScrollTop() / Math.max(1, maxScroll)) * trackH);
71
+ const thumbBottom = Math.min(viewport, thumbTop + thumbH);
72
+ // Clicking the track maps the clicked row's position on the track back
73
+ // to a scrollTop and scrolls that content position to the viewport top.
74
+ const trackScrollTop = (y) => {
75
+ if (y <= 0)
76
+ return 0;
77
+ if (y >= trackH)
78
+ return maxScroll;
79
+ return Math.round((y / trackH) * maxScroll);
80
+ };
81
+ const rows = [];
82
+ for (let y = 0; y < viewport; y++) {
83
+ const inThumb = y >= thumbTop && y < thumbBottom;
84
+ rows.push(_jsx(Box, { height: 1, flexShrink: 0, onClick: () => handle.scrollTo(trackScrollTop(y)), onMouseEnter: () => {
85
+ setHoverRow(y);
86
+ // Resting pointer: chip follows immediately once dwell has
87
+ // opened it; a sweep re-arms the dwell instead of flashing.
88
+ clearDwell();
89
+ if (chipRow !== null) {
90
+ setChipRow(y);
91
+ }
92
+ else {
93
+ dwellTimer.current = setTimeout(() => setChipRow(y), CHIP_DWELL_MS);
94
+ }
95
+ }, onMouseLeave: () => {
96
+ setHoverRow(current => (current === y ? null : current));
97
+ clearChip();
98
+ }, children: _jsx(Text, { color: inThumb
99
+ ? hoverRow !== null && hoverRow >= thumbTop && hoverRow < thumbBottom
100
+ ? 'professionalBlue'
101
+ : 'inactive'
102
+ : undefined, children: inThumb ? THUMB : ' ' }) }, y));
103
+ }
104
+ // The floating position chip, anchored left of the gutter on the
105
+ // dwell-armed row (TimelineRail's preview-card geometry, one line tall).
106
+ // Absolute + zero layout contribution: popping it never moves anything.
107
+ // Fenced with noSelect: it floats over selectable transcript text.
108
+ let hoverChip = null;
109
+ if (chipRow !== null && maxScroll > 0) {
110
+ const jumpTop = trackScrollTop(chipRow);
111
+ const pct = Math.round((jumpTop / maxScroll) * 100);
112
+ const line = Math.min(content, jumpTop + 1);
113
+ hoverChip = (_jsx(Box, { position: "absolute", top: chipRow, right: RAIL_WIDTH + 1, flexShrink: 0, backgroundColor: "toolCardBackgroundDim", paddingX: 1, noSelect: true, children: _jsx(Text, { color: "text", children: `${pct}% · ${line}/${content}` }) }));
114
+ }
115
+ return (_jsx(NoSelect, { children: _jsxs("ink-box", { onWheel: e => {
116
+ if (e.deltaY !== 0)
117
+ handle.scrollBy(e.deltaY);
118
+ }, style: { flexDirection: 'column', flexShrink: 0, width: RAIL_WIDTH }, children: [rows, hoverChip] }) }));
119
+ }
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import type { ClickEvent } from '../ink/events/click-event.js';
2
3
  export type SelectOption = {
3
4
  value: string;
4
5
  /** Row content; plain strings render inline, richer rows may carry color swatches. */
@@ -11,12 +12,18 @@ export type SelectOption = {
11
12
  * scroll arrows). Keyboard navigation is owned by the parent dialog, which
12
13
  * passes focus/selection indices back in.
13
14
  */
14
- export declare function Select({ options, focusIndex, selectedValue, visibleOptionCount, }: {
15
+ export declare function Select({ options, focusIndex, selectedValue, visibleOptionCount, onPick, }: {
15
16
  options: readonly SelectOption[];
16
17
  /** Index of the keyboard-focused row (shows the ❯ pointer). */
17
18
  focusIndex: number;
18
19
  /** Value of the chosen row (shows the ✓ checkmark). */
19
20
  selectedValue: string | undefined;
20
21
  visibleOptionCount?: number;
22
+ /**
23
+ * Mouse pick handler (fullscreen). Clicking a row reports the row's
24
+ * absolute index — the parent typically applies it with the same code
25
+ * path as the keyboard Enter. Absent → rows are not clickable.
26
+ */
27
+ onPick?: (index: number, value: string, event: ClickEvent) => void;
21
28
  }): React.ReactNode;
22
29
  //# sourceMappingURL=Select.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,UAAU,EACV,aAAa,EACb,kBAAsB,GACvB,EAAE;IACD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IAChC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,GAAG,KAAK,CAAC,SAAS,CAiClB"}
1
+ {"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAG9D,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,UAAU,EACV,aAAa,EACb,kBAAsB,EACtB,MAAM,GACP,EAAE;IACD,OAAO,EAAE,SAAS,YAAY,EAAE,CAAA;IAChC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACnE,GAAG,KAAK,CAAC,SAAS,CAsClB"}
@@ -7,13 +7,15 @@ import { ListItem } from './design-system/ListItem.js';
7
7
  * scroll arrows). Keyboard navigation is owned by the parent dialog, which
8
8
  * passes focus/selection indices back in.
9
9
  */
10
- export function Select({ options, focusIndex, selectedValue, visibleOptionCount = 5, }) {
10
+ export function Select({ options, focusIndex, selectedValue, visibleOptionCount = 5, onPick, }) {
11
11
  // Window around the focus row, with scroll hints at the edges (CC style).
12
12
  const startIndex = Math.max(0, Math.min(focusIndex - Math.floor(visibleOptionCount / 2), options.length - visibleOptionCount));
13
13
  const endIndex = Math.min(startIndex + visibleOptionCount, options.length);
14
14
  const visible = options.slice(startIndex, endIndex);
15
15
  return (_jsx(Box, { flexDirection: "column", children: visible.map((option, index) => {
16
16
  const absoluteIndex = startIndex + index;
17
- return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, isSelected: option.value === selectedValue, description: option.description, showScrollUp: absoluteIndex === startIndex && startIndex > 0, showScrollDown: absoluteIndex === endIndex - 1 && endIndex < options.length, children: option.label }, option.value));
17
+ return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, isSelected: option.value === selectedValue, description: option.description, showScrollUp: absoluteIndex === startIndex && startIndex > 0, showScrollDown: absoluteIndex === endIndex - 1 && endIndex < options.length, onClick: onPick
18
+ ? (event) => onPick(absoluteIndex, option.value, event)
19
+ : undefined, children: option.label }, option.value));
18
20
  }) }));
19
21
  }
@@ -9,9 +9,12 @@ import type { SkillInfo } from '../dsh-adapter/channel.js';
9
9
  * 长列表按焦点窗口化(ModelPicker 同款):picker 经 OverlayAbove 浮层挂载后
10
10
  * 有 maxHeight 裁剪,全量渲染会让焦点行被裁掉(看不到焦点按 Enter)。
11
11
  */
12
- export declare function SkillsPicker({ skills, focusIndex, }: {
12
+ export declare function SkillsPicker({ skills, focusIndex, onPick, }: {
13
13
  skills: readonly SkillInfo[];
14
14
  focusIndex: number;
15
+ /** Mouse pick (fullscreen): clicked row's absolute index (Chat applies
16
+ * the same code path as the keyboard Enter). */
17
+ onPick?: (index: number) => void;
15
18
  }): React.ReactNode;
16
19
  /** `/skills` while the registry snapshot is still in flight (ModelPickerLoading 同款). */
17
20
  export declare function SkillsPickerLoading(): React.ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"SkillsPicker.d.ts","sourceRoot":"","sources":["../../../src/components/SkillsPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AA2B1D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,UAAU,GACX,EAAE;IACD,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CAyClB;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,IAAI,KAAK,CAAC,SAAS,CAerD"}
1
+ {"version":3,"file":"SkillsPicker.d.ts","sourceRoot":"","sources":["../../../src/components/SkillsPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AA2B1D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE;IACD,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAClB;qDACiD;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACjC,GAAG,KAAK,CAAC,SAAS,CA0ClB;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,IAAI,KAAK,CAAC,SAAS,CAerD"}
@@ -34,14 +34,14 @@ function sourceLabel(source) {
34
34
  * 长列表按焦点窗口化(ModelPicker 同款):picker 经 OverlayAbove 浮层挂载后
35
35
  * 有 maxHeight 裁剪,全量渲染会让焦点行被裁掉(看不到焦点按 Enter)。
36
36
  */
37
- export function SkillsPicker({ skills, focusIndex, }) {
37
+ export function SkillsPicker({ skills, focusIndex, onPick, }) {
38
38
  const { rows: terminalRows } = useTerminalSize();
39
39
  // 每项恒占 2 行(正文 + 来源/简述描述行,均 truncate 成单行)。
40
40
  // 框架行:浮层预留 8 + Pane 2 + 标题 2 + 页脚 1 + 挂载包裹 marginTop 1 = 14(ModelPicker 同款)。
41
41
  const { start, end } = listWindow(skills.map(() => 2), focusIndex, Math.max(terminalRows - 14, 2));
42
42
  return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('picker-title-skills') }) }), skills.length === 0 ? (_jsx(Text, { dimColor: true, children: t('skills-empty') })) : (skills.slice(start, end).map((skill, index) => {
43
43
  const absoluteIndex = start + index;
44
- return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: `${sourceLabel(skill.source)}${skill.description === '' ? '' : ` · ${skill.description}`}`, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < skills.length, children: skill.userInvocable ? `/${skill.name}` : skill.name }, skill.name));
44
+ return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: `${sourceLabel(skill.source)}${skill.description === '' ? '' : ` · ${skill.description}`}`, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < skills.length, onClick: onPick ? () => onPick(absoluteIndex) : undefined, children: skill.userInvocable ? `/${skill.name}` : skill.name }, skill.name));
45
45
  }))] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-fill-exit') }) })] }));
46
46
  }
47
47
  /** `/skills` while the registry snapshot is still in flight (ModelPickerLoading 同款). */
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import type { SubagentState } from '../dsh-adapter/subagents.js';
3
+ import type { ClickEvent } from '../ink/events/click-event.js';
3
4
  export interface SubagentCardProps {
4
5
  subagent: SubagentState;
5
6
  focused?: boolean;
6
- onClick?: () => void;
7
+ onClick?(event: ClickEvent): void;
7
8
  }
8
9
  export declare function SubagentCard({ subagent, focused, onClick }: SubagentCardProps): React.ReactNode;
9
10
  //# sourceMappingURL=SubagentCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAShE,MAAM,WAAW,iBAAiB;IAAG,QAAQ,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE;AAEvG,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CA4B/F"}
1
+ {"version":3,"file":"SubagentCard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAEvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAGhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAA;AAO9D,MAAM,WAAW,iBAAiB;IAAG,QAAQ,EAAE,aAAa,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;CAAE;AAEpH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,SAAS,CA0C/F"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
2
3
  import { Box, Text } from '../ui.js';
3
4
  import { t } from '../i18n.js';
4
5
  import { isMinimalMode } from '../minimalMode.js';
@@ -10,9 +11,14 @@ export function SubagentCard({ subagent, focused, onClick }) {
10
11
  const running = subagent.status === 'running' || subagent.status === 'starting';
11
12
  const elapsed = subagent.completedAt ? subagent.completedAt - subagent.startedAt : Date.now() - subagent.startedAt;
12
13
  const total = subagent.tokens?.total ?? ((subagent.tokens?.input ?? 0) + (subagent.tokens?.output ?? 0) || 0);
14
+ // Mouse affordance: clickable cards tint on hover; the keyboard-focused
15
+ // card keeps its brand-color header (no double highlight).
16
+ const [hovered, setHovered] = useState(false);
13
17
  // Live preview: the newest streamed line rides under the header while the
14
18
  // subagent runs, then folds away — the dashboard stays one line per settled
15
- // subagent.
19
+ // subagent. Deliberately NOT revived on hover: an extra line would grow
20
+ // the card mid-gesture and reshuffle the whole dashboard list (user
21
+ // feedback: hover must never change layout). The hover tint stays.
16
22
  const liveLine = running ? subagent.output[subagent.output.length - 1] : undefined;
17
23
  const minimal = isMinimalMode();
18
24
  const glyph = running ? (minimal ? '·' : '🟡')
@@ -22,5 +28,6 @@ export function SubagentCard({ subagent, focused, onClick }) {
22
28
  : running ? 'warning'
23
29
  : subagent.status === 'failed' || subagent.status === 'cancelled' ? 'error'
24
30
  : 'success';
25
- return _jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, onClick: onClick, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsx(Text, { bold: true, color: focused ? 'claude' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${total || '—'} tok · ${subagent.toolCalls.length} tools` })] })] }), liveLine && _jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${liveLine}` })] });
31
+ const hoverTint = onClick !== undefined && hovered && !focused;
32
+ return _jsxs(Box, { flexDirection: "column", paddingLeft: 1, marginBottom: 1, onClick: onClick, onMouseEnter: onClick !== undefined ? () => setHovered(true) : undefined, onMouseLeave: onClick !== undefined ? () => setHovered(false) : undefined, backgroundColor: hoverTint ? 'userMessageBackgroundHover' : undefined, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: glyphColor, children: glyph }), _jsx(Text, { bold: true, color: focused ? 'claude' : undefined, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${total || '—'} tok · ${subagent.toolCalls.length} tools` })] })] }), liveLine && _jsx(Text, { dimColor: true, wrap: "truncate", children: ` │ ${liveLine}` })] });
26
33
  }
@@ -5,6 +5,10 @@ export interface SubagentDashboardProps {
5
5
  onClose: () => void;
6
6
  onSelect?: (agentId: string) => void;
7
7
  }
8
+ /** 可点击 ✕ 退出按钮:整屏/浮层场景的鼠标退出通道(Esc 等价)。 */
9
+ export declare function ExitButton({ onClick }: {
10
+ onClick: () => void;
11
+ }): React.ReactNode;
8
12
  /**
9
13
  * SubagentDashboard — overlay panel showing all active/recent subagents.
10
14
  * Keyboard: up/down to navigate, Enter to view detail, Esc to close.
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAMhE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,QAAQ,EACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,SAAS,CAoG1C"}
1
+ {"version":3,"file":"SubagentDashboard.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDashboard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAMhE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACrC;AAED,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,KAAK,CAAC,SAAS,CAWhF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,SAAS,EACT,OAAO,EACP,QAAQ,EACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,SAAS,CA2G1C"}
@@ -5,6 +5,11 @@ import { SubagentCard } from './SubagentCard.js';
5
5
  import { t } from '../i18n.js';
6
6
  import { Divider } from './design-system/Divider.js';
7
7
  import { isPlainReturnInput } from '../utils/modifiers.js';
8
+ /** 可点击 ✕ 退出按钮:整屏/浮层场景的鼠标退出通道(Esc 等价)。 */
9
+ export function ExitButton({ onClick }) {
10
+ const [hovered, setHovered] = React.useState(false);
11
+ return (_jsx(Box, { onClick: onClick, onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: _jsx(Text, { color: hovered ? 'text' : 'subtle', children: ' ✕' }) }));
12
+ }
8
13
  /**
9
14
  * SubagentDashboard — overlay panel showing all active/recent subagents.
10
15
  * Keyboard: up/down to navigate, Enter to view detail, Esc to close.
@@ -44,7 +49,10 @@ export function SubagentDashboard({ subagents, onClose, onSelect }) {
44
49
  const running = subagents.filter(s => s.status === 'running').length;
45
50
  const completed = subagents.filter(s => s.status === 'completed').length;
46
51
  const failed = subagents.filter(s => s.status === 'failed').length;
47
- return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsx(Divider, { color: "claude", title: t('subagent-dashboard-title'), padding: 4 }), _jsxs(Box, { flexDirection: "row", gap: 3, marginTop: 1, marginBottom: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "claude", children: running }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-running')] })] }), _jsxs(Text, { children: [_jsx(Text, { color: "success", children: completed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-completed')] })] }), failed > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "error", children: failed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-failed')] })] }))] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(10, rows - 10), marginTop: 1, children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: subagents.length === 0 ? (_jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: Math.max(2, Math.floor((rows - 16) / 3)), children: [_jsx(Text, { dimColor: true, children: '○' }), _jsx(Text, { dimColor: true, children: t('subagent-none') }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-empty-hint') }) })] })) : (subagents.map((subagent, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(SubagentCard, { subagent: subagent, focused: index === focusIndex }), index < subagents.length - 1 && (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }))] }, subagent.agentId)))) }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsx(Box, { marginTop: 0, children: _jsx(Text, { dimColor: true, children: onSelect
52
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsx(Divider, { color: "claude", title: t('subagent-dashboard-title'), padding: 4 }), _jsxs(Box, { flexDirection: "row", gap: 3, marginTop: 1, marginBottom: 1, children: [_jsxs(Text, { children: [_jsx(Text, { color: "claude", children: running }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-running')] })] }), _jsxs(Text, { children: [_jsx(Text, { color: "success", children: completed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-completed')] })] }), failed > 0 && (_jsxs(Text, { children: [_jsx(Text, { color: "error", children: failed }), _jsxs(Text, { dimColor: true, children: [" ", t('subagent-count-failed')] })] })), _jsx(Box, { flexGrow: 1 }), _jsx(ExitButton, { onClick: onClose })] }), _jsx(Box, { flexDirection: "column", maxHeight: Math.max(10, rows - 10), marginTop: 1, children: _jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: subagents.length === 0 ? (_jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: Math.max(2, Math.floor((rows - 16) / 3)), children: [_jsx(Text, { dimColor: true, children: '○' }), _jsx(Text, { dimColor: true, children: t('subagent-none') }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: t('subagent-empty-hint') }) })] })) : (subagents.map((subagent, index) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(SubagentCard, { subagent: subagent, focused: index === focusIndex, onClick: onSelect !== undefined
53
+ // Click = view detail, same as Enter on the focused card.
54
+ ? () => onSelect(subagent.agentId)
55
+ : undefined }), index < subagents.length - 1 && (_jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }))] }, subagent.agentId)))) }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsx(Box, { marginTop: 0, children: _jsx(Text, { dimColor: true, children: onSelect
48
56
  ? t('subagent-dashboard-hint-detail')
49
57
  : t('subagent-dashboard-hint-basic') }) })] }));
50
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SubagentDetailScene.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDetailScene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAsGhE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,aAAa,CAAA;IACvB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,EAAE,wBAAwB,GAAG,KAAK,CAAC,SAAS,CA+L5C"}
1
+ {"version":3,"file":"SubagentDetailScene.d.ts","sourceRoot":"","sources":["../../../src/components/SubagentDetailScene.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAuGhE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,aAAa,CAAA;IACvB,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,EAAE,wBAAwB,GAAG,KAAK,CAAC,SAAS,CA8M5C"}
@@ -1,8 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Box, Text, useInput, ScrollBox, useTerminalSize } from '../ui.js';
4
4
  import { t } from '../i18n.js';
5
5
  import { Divider } from './design-system/Divider.js';
6
+ import { ExitButton } from './SubagentDashboard.js';
6
7
  import { isPlainReturnInput } from '../utils/modifiers.js';
7
8
  import { toolNameColor } from './messages/AssistantToolUseMessage.js';
8
9
  import { getCliHighlightPromise } from '../cc/cliHighlight.js';
@@ -134,8 +135,8 @@ export function SubagentDetailScene({ subagent, onBack, onInterrupt, }) {
134
135
  });
135
136
  const tab = (name, label) => {
136
137
  const active = page === name;
137
- return (_jsxs(React.Fragment, { children: [_jsx(Text, { color: active ? 'claude' : undefined, bold: active, inverse: active, children: ` ${label} ` }), _jsx(Text, { dimColor: true, children: name === PAGES[PAGES.length - 1] ? '' : '│' })] }, name));
138
+ return (_jsxs(React.Fragment, { children: [_jsx(Box, { onClick: () => setPage(name), backgroundColor: !active ? 'userMessageBackgroundHover' : undefined, children: _jsx(Text, { color: active ? 'claude' : undefined, bold: active, inverse: active, children: ` ${label} ` }) }), _jsx(Text, { dimColor: true, children: name === PAGES[PAGES.length - 1] ? '' : '│' })] }, name));
138
139
  };
139
- return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, bold: true, children: info.glyph }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label })] }), _jsxs(Text, { children: [_jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${totalTokens || '—'} tok · ${subagent.toolCalls.length} tools` })] }), _jsxs(Text, { dimColor: true, children: [`${t('subagent-started')} ${formatTimestamp(subagent.startedAt)}`
140
- + (subagent.completedAt ? ` · ${t('subagent-completed')} ${formatTimestamp(subagent.completedAt)}` : ''), ` · id ${subagent.agentId}`] }), subagent.error && (_jsx(Box, { marginTop: 0, children: _jsx(Text, { color: "error", wrap: "wrap", children: `${t('subagent-error-label')}: ${subagent.error}` }) })), _jsxs(Box, { flexDirection: "row", gap: 0, marginTop: 1, children: [tab('summary', t('subagent-tab-summary')), tab('output', t('subagent-output-label')), tab('tools', t('subagent-tools')), _jsx(Text, { dimColor: true, children: ` ${pageIndex + 1}/${PAGES.length}` })] }), _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }), _jsx(Box, { flexDirection: "column", paddingX: 1, maxHeight: Math.max(10, rows - 14), children: _jsxs(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: [page === 'summary' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatGrid, { subagent: subagent, totalTokens: totalTokens, elapsed: elapsed, statusLabel: info.label, statusColor: info.color }), subagent.summary && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: '─ summary ' }), _jsx(Text, { wrap: "wrap", children: subagent.summary })] })), !subagent.summary && (_jsx(Text, { dimColor: true, children: isRunning ? t('subagent-no-output') : t('subagent-no-summary') }))] })), page === 'output' && (subagent.outputEvents.length === 0 && subagent.output.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-output') })) : (subagent.outputEvents.map((line, index) => (_jsxs(Text, { wrap: "wrap", dimColor: line.kind === 'thinking' || line.kind === 'system', color: line.kind === 'error' ? 'error' : undefined, children: [line.kind === 'thinking' ? ' ⌁ ' : ' ', line.text, !line.settled && isRunning ? ' ▍' : ''] }, index))))), page === 'tools' && (subagent.toolCalls.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-tools') })) : (subagent.toolCalls.map((tool, index) => (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: tool.status === 'failed' ? 'error' : tool.status === 'running' ? 'warning' : 'success', children: tool.status === 'running' ? '·' : tool.status === 'failed' ? '×' : '✓' }), _jsx(Text, { color: toolNameColor(tool.name), children: tool.name }), tool.endedAt && _jsx(Text, { dimColor: true, children: formatDuration(tool.endedAt - tool.startedAt) })] }), tool.argsPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(JsonArgsText, { raw: tool.argsPreview }) })), tool.resultPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: `⎿ ${tool.resultPreview}` }) })), tool.error && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { color: "error", wrap: "wrap", children: tool.error }) }))] }, tool.id ?? index)))))] }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsx(Box, { marginTop: 0, children: _jsxs(Text, { dimColor: true, children: [`←/→ ${t('subagent-hint-page')} · ↑/↓ ${t('subagent-hint-scroll')}`, isRunning && onInterrupt ? ' · X interrupt' : '', ` · Esc ${t('subagent-hint-back')}`] }) })] }));
140
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: info.color, bold: true, children: info.glyph }), _jsx(Text, { bold: true, children: `${t('subagent-card-prefix')}${subagent.description}` }), _jsx(Text, { dimColor: true, children: "\u00B7" }), _jsx(Text, { color: info.color, children: info.label }), _jsx(Box, { flexGrow: 1 }), _jsx(ExitButton, { onClick: onBack })] }), _jsxs(Text, { children: [_jsx(Text, { children: subagent.model ?? subagent.provider ?? 'default' }), _jsx(Text, { dimColor: true, children: ` · ${formatDuration(elapsed)} · ${totalTokens || '—'} tok · ${subagent.toolCalls.length} tools` })] }), _jsxs(Text, { dimColor: true, children: [`${t('subagent-started')} ${formatTimestamp(subagent.startedAt)}`
141
+ + (subagent.completedAt ? ` · ${t('subagent-completed')} ${formatTimestamp(subagent.completedAt)}` : ''), ` · id ${subagent.agentId}`] }), subagent.error && (_jsx(Box, { marginTop: 0, children: _jsx(Text, { color: "error", wrap: "wrap", children: `${t('subagent-error-label')}: ${subagent.error}` }) })), _jsxs(Box, { flexDirection: "row", gap: 0, marginTop: 1, children: [tab('summary', t('subagent-tab-summary')), tab('output', t('subagent-output-label')), tab('tools', t('subagent-tools')), _jsx(Text, { dimColor: true, children: ` ${pageIndex + 1}/${PAGES.length}` })] }), _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(20, Math.min(72, columns - 6))) }), _jsx(Box, { flexDirection: "column", paddingX: 1, maxHeight: Math.max(10, rows - 14), children: _jsxs(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, children: [page === 'summary' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(StatGrid, { subagent: subagent, totalTokens: totalTokens, elapsed: elapsed, statusLabel: info.label, statusColor: info.color }), subagent.summary && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { dimColor: true, bold: true, children: '─ summary ' }), _jsx(Text, { wrap: "wrap", children: subagent.summary })] })), !subagent.summary && (_jsx(Text, { dimColor: true, children: isRunning ? t('subagent-no-output') : t('subagent-no-summary') }))] })), page === 'output' && (subagent.outputEvents.length === 0 && subagent.output.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-output') })) : (subagent.outputEvents.map((line, index) => (_jsxs(Text, { wrap: "wrap", dimColor: line.kind === 'thinking' || line.kind === 'system', color: line.kind === 'error' ? 'error' : undefined, children: [line.kind === 'thinking' ? ' ⌁ ' : ' ', line.text, !line.settled && isRunning ? ' ▍' : ''] }, index))))), page === 'tools' && (subagent.toolCalls.length === 0 ? (_jsx(Text, { dimColor: true, children: t('subagent-no-tools') })) : (subagent.toolCalls.map((tool, index) => (_jsxs(Box, { flexDirection: "column", marginTop: index === 0 ? 0 : 1, children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: tool.status === 'failed' ? 'error' : tool.status === 'running' ? 'warning' : 'success', children: tool.status === 'running' ? '·' : tool.status === 'failed' ? '×' : '✓' }), _jsx(Text, { color: toolNameColor(tool.name), children: tool.name }), tool.endedAt && _jsx(Text, { dimColor: true, children: formatDuration(tool.endedAt - tool.startedAt) })] }), tool.argsPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(JsonArgsText, { raw: tool.argsPreview }) })), tool.resultPreview && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { dimColor: true, wrap: "wrap", children: `⎿ ${tool.resultPreview}` }) })), tool.error && (_jsx(Box, { flexDirection: "row", paddingLeft: 2, children: _jsx(Text, { color: "error", wrap: "wrap", children: tool.error }) }))] }, tool.id ?? index)))))] }) }), _jsx(Divider, { color: "subtle", title: "", padding: 4 }), _jsxs(Box, { marginTop: 0, flexDirection: "row", children: [_jsx(Text, { dimColor: true, children: `←/→ ${t('subagent-hint-page')} · ↑/↓ ${t('subagent-hint-scroll')}` }), isRunning && onInterrupt && (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: ' · ' }), _jsx(Box, { onClick: () => onInterrupt(subagent.agentId), children: _jsx(Text, { dimColor: true, bold: true, color: "warning", children: "X interrupt" }) })] })), _jsx(Text, { dimColor: true, children: ` · Esc ${t('subagent-hint-back')}` })] })] }));
141
142
  }