@deepseek-harness-tui/dsh-tui 0.9.0 → 0.9.2

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 (307) hide show
  1. package/README.md +69 -256
  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 +6 -0
  26. package/lib/types/components/AutoRecapRow.d.ts +23 -0
  27. package/lib/types/components/AutoRecapRow.d.ts.map +1 -0
  28. package/lib/types/components/AutoRecapRow.js +23 -0
  29. package/lib/types/components/ColorPicker.d.ts +17 -0
  30. package/lib/types/components/ColorPicker.d.ts.map +1 -0
  31. package/lib/types/components/ColorPicker.js +20 -0
  32. package/lib/types/components/CommandSuggestions.d.ts +3 -1
  33. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  34. package/lib/types/components/ContextBarView.d.ts +33 -0
  35. package/lib/types/components/ContextBarView.d.ts.map +1 -0
  36. package/lib/types/components/ContextBarView.js +46 -0
  37. package/lib/types/components/EffortInputBorder.d.ts +12 -1
  38. package/lib/types/components/EffortInputBorder.d.ts.map +1 -1
  39. package/lib/types/components/EffortInputBorder.js +22 -5
  40. package/lib/types/components/FileActionsPanel.d.ts +22 -0
  41. package/lib/types/components/FileActionsPanel.d.ts.map +1 -0
  42. package/lib/types/components/FileActionsPanel.js +28 -0
  43. package/lib/types/components/FileSuggestions.d.ts +3 -1
  44. package/lib/types/components/FileSuggestions.d.ts.map +1 -1
  45. package/lib/types/components/MessageList.d.ts +3 -1
  46. package/lib/types/components/MessageList.d.ts.map +1 -1
  47. package/lib/types/components/MessageList.js +13 -6
  48. package/lib/types/components/ModelPicker.d.ts +26 -4
  49. package/lib/types/components/ModelPicker.d.ts.map +1 -1
  50. package/lib/types/components/ModelPicker.js +26 -6
  51. package/lib/types/components/PromptInput.d.ts.map +1 -1
  52. package/lib/types/components/PromptInput.js +365 -57
  53. package/lib/types/components/RecapPanel.d.ts +25 -0
  54. package/lib/types/components/RecapPanel.d.ts.map +1 -0
  55. package/lib/types/components/RecapPanel.js +55 -0
  56. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -1
  57. package/lib/types/components/ScrollbarGutter.js +55 -4
  58. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  59. package/lib/types/components/SubagentCard.js +6 -4
  60. package/lib/types/components/SuggestionCard.d.ts +4 -2
  61. package/lib/types/components/SuggestionCard.d.ts.map +1 -1
  62. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  63. package/lib/types/components/TimelineRail.js +9 -2
  64. package/lib/types/components/design-system/ThemeProvider.d.ts +7 -0
  65. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  66. package/lib/types/components/design-system/ThemeProvider.js +2 -1
  67. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +8 -1
  68. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  69. package/lib/types/components/messages/AssistantToolUseMessage.js +36 -8
  70. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +7 -3
  71. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  72. package/lib/types/components/questions/AskUserQuestionPanel.js +41 -9
  73. package/lib/types/dsh-adapter/channel.d.ts +101 -2
  74. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  75. package/lib/types/dsh-adapter/channel.js +969 -93
  76. package/lib/types/dsh-adapter/compat/index.d.ts +8 -6
  77. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  78. package/lib/types/dsh-adapter/compat/index.js +8 -6
  79. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +150 -0
  80. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  81. package/lib/types/dsh-adapter/compat/sessionLog.js +518 -41
  82. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  83. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  84. package/lib/types/dsh-adapter/contract.js +1 -0
  85. package/lib/types/dsh-adapter/extension-events.d.ts +1 -1
  86. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
  87. package/lib/types/dsh-adapter/index.d.ts +10 -0
  88. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  89. package/lib/types/dsh-adapter/index.js +5 -0
  90. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  91. package/lib/types/dsh-adapter/plugin.js +317 -8
  92. package/lib/types/dsh-adapter/presets.d.ts +18 -0
  93. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  94. package/lib/types/dsh-adapter/presets.js +31 -0
  95. package/lib/types/dsh-adapter/providerWizard.d.ts +29 -1
  96. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  97. package/lib/types/dsh-adapter/providerWizard.js +89 -5
  98. package/lib/types/dsh-adapter/questions.d.ts +19 -2
  99. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  100. package/lib/types/dsh-adapter/questions.js +53 -10
  101. package/lib/types/dsh-adapter/recap.d.ts +49 -0
  102. package/lib/types/dsh-adapter/recap.d.ts.map +1 -0
  103. package/lib/types/dsh-adapter/recap.js +121 -0
  104. package/lib/types/dsh-adapter/sessionTree.d.ts +314 -0
  105. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -0
  106. package/lib/types/dsh-adapter/sessionTree.js +954 -0
  107. package/lib/types/dsh-adapter/shortcuts.d.ts +15 -44
  108. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
  109. package/lib/types/dsh-adapter/shortcuts.js +28 -165
  110. package/lib/types/dsh-adapter/types.d.ts +1 -1
  111. package/lib/types/dsh-adapter/types.d.ts.map +1 -1
  112. package/lib/types/herdr.js +1 -1
  113. package/lib/types/i18n.d.ts +604 -176
  114. package/lib/types/i18n.d.ts.map +1 -1
  115. package/lib/types/i18n.js +206 -72
  116. package/lib/types/ink/log-update.d.ts.map +1 -1
  117. package/lib/types/ink/log-update.js +21 -0
  118. package/lib/types/migrationPrefs.d.ts +60 -0
  119. package/lib/types/migrationPrefs.d.ts.map +1 -0
  120. package/lib/types/migrationPrefs.js +97 -0
  121. package/lib/types/modelGroups.d.ts +72 -0
  122. package/lib/types/modelGroups.d.ts.map +1 -0
  123. package/lib/types/modelGroups.js +97 -0
  124. package/lib/types/modelRecents.d.ts +39 -0
  125. package/lib/types/modelRecents.d.ts.map +1 -0
  126. package/lib/types/modelRecents.js +97 -0
  127. package/lib/types/native-ts/yoga-layout/index.d.ts +11 -0
  128. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
  129. package/lib/types/native-ts/yoga-layout/index.js +31 -1
  130. package/lib/types/oauth.d.ts +15 -0
  131. package/lib/types/oauth.d.ts.map +1 -0
  132. package/lib/types/oauth.js +14 -0
  133. package/lib/types/plugin-spec/registry.d.ts +1 -1
  134. package/lib/types/plugin-spec/registry.js +1 -1
  135. package/lib/types/reload.d.ts +109 -0
  136. package/lib/types/reload.d.ts.map +1 -0
  137. package/lib/types/reload.js +118 -0
  138. package/lib/types/screens/Chat.d.ts +3 -1
  139. package/lib/types/screens/Chat.d.ts.map +1 -1
  140. package/lib/types/screens/Chat.js +588 -64
  141. package/lib/types/screens/SessionTree.d.ts +27 -0
  142. package/lib/types/screens/SessionTree.d.ts.map +1 -0
  143. package/lib/types/screens/SessionTree.js +555 -0
  144. package/lib/types/screens/StatusLine.d.ts +0 -9
  145. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  146. package/lib/types/screens/StatusLine.js +215 -52
  147. package/lib/types/screens/StatusMetrics.d.ts +35 -3
  148. package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
  149. package/lib/types/screens/StatusMetrics.js +63 -8
  150. package/lib/types/screens/chatOverlay.d.ts +17 -1
  151. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  152. package/lib/types/screens/chatOverlay.js +3 -1
  153. package/lib/types/tips.d.ts.map +1 -1
  154. package/lib/types/tips.js +22 -4
  155. package/lib/types/update.d.ts +159 -0
  156. package/lib/types/update.d.ts.map +1 -1
  157. package/lib/types/update.js +496 -30
  158. package/lib/types/utils/debug.d.ts +1 -1
  159. package/lib/types/utils/debug.js +3 -3
  160. package/lib/types/utils/fileTarget.d.ts +46 -0
  161. package/lib/types/utils/fileTarget.d.ts.map +1 -0
  162. package/lib/types/utils/fileTarget.js +178 -0
  163. package/lib/types/utils/keymap.d.ts +134 -0
  164. package/lib/types/utils/keymap.d.ts.map +1 -0
  165. package/lib/types/utils/keymap.js +311 -0
  166. package/lib/types/utils/mentions.d.ts +25 -2
  167. package/lib/types/utils/mentions.d.ts.map +1 -1
  168. package/lib/types/utils/mentions.js +69 -10
  169. package/lib/types/utils/openExternal.d.ts +50 -0
  170. package/lib/types/utils/openExternal.d.ts.map +1 -0
  171. package/lib/types/utils/openExternal.js +170 -0
  172. package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +21 -0
  173. package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +140 -0
  174. package/node_modules/@deepseek-harness-tui/dsh-auth/cordis.patch.yml +11 -0
  175. package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +44 -0
  176. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/command.d.ts +14 -0
  177. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/command.js +67 -0
  178. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/credentials.d.ts +64 -0
  179. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/credentials.js +170 -0
  180. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.d.ts +79 -0
  181. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.js +196 -0
  182. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.d.ts +68 -0
  183. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.js +193 -0
  184. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/opener.d.ts +32 -0
  185. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/opener.js +101 -0
  186. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.d.ts +31 -0
  187. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.js +68 -0
  188. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/service.d.ts +69 -0
  189. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/service.js +129 -0
  190. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +70 -0
  191. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
  192. package/node_modules/@dsh-std/command/LICENSE +21 -21
  193. package/node_modules/@dsh-std/command/README.md +26 -26
  194. package/node_modules/@dsh-std/command/README.zh.md +28 -28
  195. package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
  196. package/node_modules/@dsh-std/command/package.json +22 -22
  197. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  198. package/node_modules/@dsh-std/connection/LICENSE +21 -21
  199. package/node_modules/@dsh-std/connection/README.md +42 -42
  200. package/node_modules/@dsh-std/connection/README.zh.md +42 -42
  201. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  202. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  203. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  204. package/node_modules/@dsh-std/connection/package.json +20 -20
  205. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  206. package/node_modules/@dsh-std/core/LICENSE +21 -21
  207. package/node_modules/@dsh-std/core/README.md +13 -13
  208. package/node_modules/@dsh-std/core/README.zh.md +13 -13
  209. package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  210. package/node_modules/@dsh-std/core/package.json +21 -21
  211. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  212. package/node_modules/@dsh-std/manifest/LICENSE +21 -21
  213. package/node_modules/@dsh-std/manifest/README.md +5 -5
  214. package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  215. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  216. package/node_modules/@dsh-std/manifest/package.json +20 -20
  217. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  218. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
  219. package/node_modules/@dsh-std/messages/LICENSE +21 -21
  220. package/node_modules/@dsh-std/messages/README.md +5 -5
  221. package/node_modules/@dsh-std/messages/README.zh.md +7 -7
  222. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
  223. package/node_modules/@dsh-std/messages/package.json +20 -20
  224. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
  225. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  226. package/node_modules/@dsh-std/presentation/LICENSE +21 -21
  227. package/node_modules/@dsh-std/presentation/README.md +27 -27
  228. package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  229. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  230. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  231. package/node_modules/@dsh-std/presentation/package.json +25 -25
  232. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
  233. package/node_modules/@dsh-std/storage/LICENSE +21 -21
  234. package/node_modules/@dsh-std/storage/README.md +5 -5
  235. package/node_modules/@dsh-std/storage/README.zh.md +7 -7
  236. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
  237. package/node_modules/@dsh-std/storage/package.json +20 -20
  238. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
  239. package/package.json +17 -5
  240. package/presets/liangshen/.dsh-tui-managed.json +1 -1
  241. package/presets/liangshen/instruction-hint.mjs +8 -0
  242. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  243. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
  244. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
  245. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
  246. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  247. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  248. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  249. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
  250. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  251. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
  252. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
  253. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
  254. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  255. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
  256. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  257. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
  258. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
  259. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  260. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  261. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
  262. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  263. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  264. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
  265. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
  266. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  267. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  268. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  269. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
  270. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  271. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
  272. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
  273. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
  274. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  275. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
  276. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  277. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
  278. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
  279. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
  280. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  281. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
  282. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  283. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
  284. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
  285. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
  286. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  287. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
  288. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  289. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
  290. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
  291. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
  292. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  293. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  294. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  295. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
  296. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  297. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
  298. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
  299. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
  300. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  301. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
  302. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  303. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
  304. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
  305. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
  306. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  307. 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
+ }
@@ -1 +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;AAOpE;;;;;;;;;;;;;;;;;;;;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,CA2DlB"}
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"}
@@ -1,10 +1,12 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import React from 'react';
3
3
  import { Box, Text, NoSelect } from '../ui.js';
4
4
  import { RAIL_MIN_TERMINAL_WIDTH, RAIL_WIDTH } from '../ink/timeline-rail.js';
5
5
  /** Thumb glyph across the 2-col gutter: solid, clearly positional —
6
6
  * deliberately distinct from the timeline's ━━ active tick. */
7
7
  const THUMB = '██';
8
+ /** Rest time before the hover position chip pops (anti-flash sweep gate). */
9
+ const CHIP_DWELL_MS = 250;
8
10
  /**
9
11
  * Proportional scrollbar for the fullscreen transcript's gutter — the
10
12
  * `scrollbar` option of the `dsh-tui.scrollGutter` setting (the timeline
@@ -28,6 +30,26 @@ const THUMB = '██';
28
30
  */
29
31
  export function ScrollbarGutter({ handle, terminalWidth, }) {
30
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, []);
31
53
  React.useEffect(() => {
32
54
  if (!handle)
33
55
  return;
@@ -59,10 +81,39 @@ export function ScrollbarGutter({ handle, terminalWidth, }) {
59
81
  const rows = [];
60
82
  for (let y = 0; y < viewport; y++) {
61
83
  const inThumb = y >= thumbTop && y < thumbBottom;
62
- rows.push(_jsx(Box, { height: 1, flexShrink: 0, onClick: () => handle.scrollTo(trackScrollTop(y)), children: _jsx(Text, { color: inThumb ? 'inactive' : undefined, children: inThumb ? THUMB : ' ' }) }, y));
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}` }) }));
63
114
  }
64
- return (_jsx(NoSelect, { fromLeftEdge: true, children: _jsx("ink-box", { onWheel: e => {
115
+ return (_jsx(NoSelect, { children: _jsxs("ink-box", { onWheel: e => {
65
116
  if (e.deltaY !== 0)
66
117
  handle.scrollBy(e.deltaY);
67
- }, style: { flexDirection: 'column', flexShrink: 0, width: RAIL_WIDTH }, children: rows }) }));
118
+ }, style: { flexDirection: 'column', flexShrink: 0, width: RAIL_WIDTH }, children: [rows, hoverChip] }) }));
68
119
  }
@@ -1 +1 @@
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,CAwC/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"}
@@ -11,9 +11,14 @@ export function SubagentCard({ subagent, focused, onClick }) {
11
11
  const running = subagent.status === 'running' || subagent.status === 'starting';
12
12
  const elapsed = subagent.completedAt ? subagent.completedAt - subagent.startedAt : Date.now() - subagent.startedAt;
13
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);
14
17
  // Live preview: the newest streamed line rides under the header while the
15
18
  // subagent runs, then folds away — the dashboard stays one line per settled
16
- // 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.
17
22
  const liveLine = running ? subagent.output[subagent.output.length - 1] : undefined;
18
23
  const minimal = isMinimalMode();
19
24
  const glyph = running ? (minimal ? '·' : '🟡')
@@ -23,9 +28,6 @@ export function SubagentCard({ subagent, focused, onClick }) {
23
28
  : running ? 'warning'
24
29
  : subagent.status === 'failed' || subagent.status === 'cancelled' ? 'error'
25
30
  : 'success';
26
- // Mouse affordance: clickable cards tint on hover; the keyboard-focused
27
- // card keeps its brand-color header (no double highlight).
28
- const [hovered, setHovered] = useState(false);
29
31
  const hoverTint = onClick !== undefined && hovered && !focused;
30
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}` })] });
31
33
  }
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
+ import type { Color } from '../ink/styles.js';
3
+ import type { Theme } from '../theme.js';
2
4
  /**
3
5
  * `/` 命令菜单与 `@` 文件菜单共用的圆角卡片外壳(与输入框 EffortInputBorder
4
6
  * 同款 ╭╮╰╯ 视觉语言):
@@ -23,8 +25,8 @@ export declare function SuggestionCard({ title, columns, accent, footer, rows, o
23
25
  /** 嵌在顶边框里的标题(已本地化、含计数)。 */
24
26
  title: string;
25
27
  columns: number;
26
- /** 边框色(主题 token);缺省 promptBorder。 */
27
- accent?: 'promptBorder' | 'planMode';
28
+ /** 边框色(主题 token 或裸色);缺省 promptBorder。 */
29
+ accent?: keyof Theme | Color;
28
30
  /** 底部 dim 提示行(滚动指示);null/undefined 时不渲染。 */
29
31
  footer?: string | null;
30
32
  /** 已渲染的行内容(每行一个节点),本组件为各行补上左右边框。 */
@@ -1 +1 @@
1
- {"version":3,"file":"SuggestionCard.d.ts","sourceRoot":"","sources":["../../../src/components/SuggestionCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,GACZ,EAAE;IACD,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,cAAc,GAAG,UAAU,CAAA;IACpC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,oCAAoC;IACpC,IAAI,EAAE,SAAS,KAAK,CAAC,SAAS,EAAE,CAAA;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAA;CACrC,GAAG,KAAK,CAAC,SAAS,CAwDlB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBzD"}
1
+ {"version":3,"file":"SuggestionCard.d.ts","sourceRoot":"","sources":["../../../src/components/SuggestionCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAGxC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,OAAO,EACP,MAAM,EACN,MAAM,EACN,IAAI,EACJ,SAAS,EACT,WAAW,GACZ,EAAE;IACD,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,KAAK,GAAG,KAAK,CAAA;IAC5B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,oCAAoC;IACpC,IAAI,EAAE,SAAS,KAAK,CAAC,SAAS,EAAE,CAAA;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAA;CACrC,GAAG,KAAK,CAAC,SAAS,CAwDlB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"TimelineRail.d.ts","sourceRoot":"","sources":["../../../src/components/TimelineRail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAEpE,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAA;AAwBhC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,GACb,EAAE;IACD,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B,qEAAqE;IACrE,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;IAClC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB;sCACkC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB;6DACyD;IACzD,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC,GAAG,KAAK,CAAC,SAAS,CA0MlB"}
1
+ {"version":3,"file":"TimelineRail.d.ts","sourceRoot":"","sources":["../../../src/components/TimelineRail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAEpE,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAA;AAwBhC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,aAAa,EACb,YAAY,EACZ,YAAY,GACb,EAAE;IACD,MAAM,EAAE,eAAe,GAAG,IAAI,CAAA;IAC9B,qEAAqE;IACrE,KAAK,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;IAClC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB;sCACkC;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB;6DACyD;IACzD,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC,GAAG,KAAK,CAAC,SAAS,CAqNlB"}
@@ -177,13 +177,20 @@ export function TimelineRail({ handle, turns, activeId, upId, downId, terminalWi
177
177
  const cardH = lines.length + 2;
178
178
  if (cardH <= viewport) {
179
179
  const top = Math.max(0, Math.min(tickRow - Math.floor(cardH / 2), viewport - cardH));
180
- card = (_jsx(Box, { position: "absolute", top: top, right: RAIL_WIDTH + 1, width: cardW, height: cardH, flexDirection: "column", flexShrink: 0, borderStyle: "round", borderColor: "inactive", backgroundColor: "toolCardBackgroundDim", paddingX: 1, children: lines.map((line, i) => (_jsx(Text, { color: "text", wrap: "truncate-end", children: line }, i))) }));
180
+ card = (_jsx(Box, { position: "absolute", top: top, right: RAIL_WIDTH + 1, width: cardW, height: cardH, flexDirection: "column", flexShrink: 0, borderStyle: "round", borderColor: "inactive", paddingX: 1,
181
+ // The card floats LEFT of the rail over selectable
182
+ // transcript text; fence its own rect so a drag that
183
+ // happens under a dwell-popped preview never copies the
184
+ // card's preview glyphs. On the box itself (not a NoSelect
185
+ // wrapper): absolute children don't contribute to a flow
186
+ // wrapper's layout, so a wrapper's region would be 0×0.
187
+ noSelect: true, children: lines.map((line, i) => (_jsx(Text, { color: "text", wrap: "truncate-end", children: line }, i))) }));
181
188
  }
182
189
  }
183
190
  }
184
191
  }
185
192
  }
186
- return (_jsx(NoSelect, { fromLeftEdge: true, children: _jsxs("ink-box", { onWheel: e => {
193
+ return (_jsx(NoSelect, { children: _jsxs("ink-box", { onWheel: e => {
187
194
  if (e.deltaY !== 0)
188
195
  handle.scrollBy(e.deltaY);
189
196
  }, style: { flexDirection: 'column', flexShrink: 0, width: RAIL_WIDTH }, children: [_jsx(Box, { height: geo.upRow, flexShrink: 0 }), chevron('up'), tickRows, chevron('down'), card] }) }));
@@ -1,4 +1,11 @@
1
1
  import React from 'react';
2
+ /**
3
+ * DSH_TUI_THEME skips terminal detection (tests, debugging). Accepts a
4
+ * built-in name (auto|light|dark|dark-ansi) or a user theme name; invalid
5
+ * values are warned and ignored by the caller, falling back to detection.
6
+ * Exported for /reload, which must respect the env override's precedence.
7
+ */
8
+ export declare function envThemeOverride(): string | undefined;
2
9
  export declare function ThemeProvider({ children, theme, }: {
3
10
  children: React.ReactNode;
4
11
  theme?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAA;AA4F7E,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CAuIlB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAG9D"}
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../../src/components/design-system/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAA;AAsE7E;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAGrD;AAcD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CAuIlB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAG9D"}
@@ -47,8 +47,9 @@ const ThemeContext = createContext({
47
47
  * DSH_TUI_THEME skips terminal detection (tests, debugging). Accepts a
48
48
  * built-in name (auto|light|dark|dark-ansi) or a user theme name; invalid
49
49
  * values are warned and ignored by the caller, falling back to detection.
50
+ * Exported for /reload, which must respect the env override's precedence.
50
51
  */
51
- function envThemeOverride() {
52
+ export function envThemeOverride() {
52
53
  const v = process.env.DSH_TUI_THEME;
53
54
  return v === undefined || v === '' ? undefined : v;
54
55
  }
@@ -32,6 +32,13 @@ type Props = {
32
32
  diffLayout?: 'auto' | 'split' | 'unified';
33
33
  /** Background treatment for the ordinary, unselected tool card surface. */
34
34
  toolBackground?: ToolBackground;
35
+ /**
36
+ * Click-to-act (fullscreen): opens the file-action menu for the tool's
37
+ * file path. When provided, the path in the card header (and diff path
38
+ * rows) renders underlined and clickable; the click stops propagation so
39
+ * the row's own fold-toggle does not fire.
40
+ */
41
+ onOpenFile?: (path: string) => void;
35
42
  };
36
43
  export declare function toolNameColor(raw: string): keyof Theme;
37
44
  /**
@@ -40,6 +47,6 @@ export declare function toolNameColor(raw: string): keyof Theme;
40
47
  * output, read content — instead of the raw result dump (mirroring Claude Code's `AssistantToolUseMessage.tsx` + the dsh-tools presentation views the
41
48
  * channel captures per call).
42
49
  */
43
- export declare function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected, isExpanded, onClick, footnote, diffLayout, toolBackground, }: Props): React.ReactNode;
50
+ export declare function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected, isExpanded, onClick, footnote, diffLayout, toolBackground, onOpenFile, }: Props): React.ReactNode;
44
51
  export {};
45
52
  //# sourceMappingURL=AssistantToolUseMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAKvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC,CAAA;AAgFD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAKtD;AAwKD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,SAAS,EACT,OAAO,EACP,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAmB,EACnB,cAAuB,GACxB,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAsKzB"}
1
+ {"version":3,"file":"AssistantToolUseMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantToolUseMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,OAAO,KAAK,EAA8C,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAKvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEjE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,OAAO,CAAA;IACb,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,2EAA2E;IAC3E,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,CAAA;AAsFD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,CAKtD;AAsMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,SAAS,EACT,OAAO,EACP,UAAkB,EAClB,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAmB,EACnB,cAAuB,EACvB,UAAU,GACX,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAkMzB"}
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import React from 'react';
2
3
  import { extname } from 'node:path';
3
4
  import { Box, Text, useTerminalSize } from '../../ui.js';
4
5
  import { stringWidth } from '../../ink/stringWidth.js';
@@ -180,7 +181,7 @@ function capLines(lines, max, verbose) {
180
181
  return lines;
181
182
  return [
182
183
  ...lines.slice(0, max),
183
- dim(`… +${lines.length - max} lines (ctrl+o to expand)`),
184
+ { ...dim(`… +${lines.length - max} lines (ctrl+o to expand)`), revealOnHover: true },
184
185
  ];
185
186
  }
186
187
  /** Header title from the presentation view: terminal cards keep the
@@ -199,7 +200,7 @@ function clipHeaderArgs(args) {
199
200
  return args;
200
201
  return `${args.slice(0, HEADER_ARGS_BUDGET)}…`;
201
202
  }
202
- function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameColor }) {
203
+ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameColor, filePath, onOpenFile }) {
203
204
  if (title === undefined) {
204
205
  return (_jsxs(_Fragment, { children: [_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }), displayArgs !== '' && (_jsxs(Box, { flexWrap: "nowrap", children: [_jsx(Text, { children: "(" }), _jsx(SyntaxText, { text: clipHeaderArgs(displayArgs), sourceText: displayArgs, language: argsLanguage }), _jsx(Text, { children: ")" })] }))] }));
205
206
  }
@@ -210,6 +211,20 @@ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameC
210
211
  if (trimmed === '') {
211
212
  return (_jsx(Box, { flexShrink: 0, children: _jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: name }) }));
212
213
  }
214
+ // Clickable path: when the caller resolved a file path that appears in
215
+ // the title (`Edit /path (1 - 100)`), render that segment underlined and
216
+ // clickable. The click stops propagation so the row's fold toggle does
217
+ // not fire. indexOf keeps the split exact even for paths with regex
218
+ // metacharacters.
219
+ if (onOpenFile !== undefined && filePath !== undefined && filePath !== '' && trimmed.includes(filePath)) {
220
+ const at = trimmed.indexOf(filePath);
221
+ const before = trimmed.slice(0, at);
222
+ const after = trimmed.slice(at + filePath.length);
223
+ return (_jsxs(Box, { flexWrap: "nowrap", children: [_jsx(Text, { bold: true, color: nameColor, wrap: "truncate-end", children: before }), _jsx(Box, { onClick: (event) => {
224
+ event.stopImmediatePropagation();
225
+ onOpenFile(filePath);
226
+ }, children: _jsx(Text, { underline: true, wrap: "truncate-end", children: filePath }) }), after !== '' && (_jsx(Text, { bold: false, color: "text", wrap: "truncate-end", children: after }))] }));
227
+ }
213
228
  const space = trimmed.indexOf(' ');
214
229
  const head = space === -1 ? trimmed : trimmed.slice(0, space);
215
230
  const tail = space === -1 ? '' : trimmed.slice(space);
@@ -221,7 +236,7 @@ function HeaderTitle({ name, title, isTerminal, displayArgs, argsLanguage, nameC
221
236
  * output, read content — instead of the raw result dump (mirroring Claude Code's `AssistantToolUseMessage.tsx` + the dsh-tools presentation views the
222
237
  * channel captures per call).
223
238
  */
224
- export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected = false, isExpanded = false, onClick, footnote, diffLayout = 'auto', toolBackground = 'none', }) {
239
+ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected = false, isExpanded = false, onClick, footnote, diffLayout = 'auto', toolBackground = 'none', onOpenFile, }) {
225
240
  const isRunning = tool.status === 'running';
226
241
  const isError = tool.status === 'error';
227
242
  const displayArgs = verbose ? tool.argsFull ?? tool.argsText : tool.argsText;
@@ -286,18 +301,31 @@ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected =
286
301
  : ordinaryToolBackground === 'strong'
287
302
  ? 'toolCardBackground'
288
303
  : undefined;
304
+ // Hover affordance for the click-to-toggle row: the theme's tool-card blue
305
+ // face marks the call's content area while the pointer dwells (the
306
+ // toolBackground treatment steps up one level to the strong card face), the
307
+ // collapsed `(ctrl+o to expand)` hint steps from dim to text, the elapsed
308
+ // clock stops dimming, and a ▾/▴ discloses the row is a toggle.
309
+ // No layout change: the indicator is a fixed column on the header line, the
310
+ // body never moves.
311
+ const [hovered, setHovered] = React.useState(false);
312
+ const interactive = onClick !== undefined;
313
+ const hoverTint = interactive && hovered && !isSelected;
289
314
  return (_jsx(Box, { ref: viewportRef, flexDirection: "row", justifyContent: "space-between", marginTop: addMargin ? 1 : 0, width: "100%", onClick: onClick,
290
315
  // Only selection paints a highlight; the configured treatment applies
291
316
  // to an ordinary card. Diff line tints stay - they are content, not chrome.
292
- // No hover tint: the card stays visually quiet until clicked (user
293
- // feedback — row-hover color changes read as noise in the transcript).
294
- backgroundColor: isSelected ? 'messageActionsBackground' : ordinaryBackground, children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "row", flexWrap: "nowrap", minWidth: minWidth, children: [_jsx(ToolUseLoader, { shouldAnimate: isRunning, isUnresolved: isRunning, isError: isError, toolName: tool.name }), _jsx(HeaderTitle, { name: name, title: headerTitle, isTerminal: headerIsTerminal, displayArgs: displayArgs, argsLanguage: argsLanguage, nameColor: toolNameColor(tool.name) }), !isRunning && (_jsx(Box, { flexWrap: "nowrap", children: _jsx(Text, { dimColor: true, children: elapsedText }) }))] }), useSplitDiff && view?.card === 'diff' ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_FIRST }) }), _jsx(SplitDiffView, { diffs: view.diffs, width: columns - 4, maxRows: DIFF_BODY_MAX_LINES, verbose: verbose, toolBackground: ordinaryToolBackground })] })) : (rendered.map((line, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { color: line.tone === 'add'
317
+ backgroundColor: isSelected ? 'messageActionsBackground' : hoverTint ? 'toolCardBackground' : ordinaryBackground, onMouseEnter: interactive ? () => setHovered(true) : undefined, onMouseLeave: interactive ? () => setHovered(false) : undefined, children: _jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "row", flexWrap: "nowrap", minWidth: minWidth, children: [_jsx(ToolUseLoader, { shouldAnimate: isRunning, isUnresolved: isRunning, isError: isError, toolName: tool.name }), _jsx(HeaderTitle, { name: name, title: headerTitle, isTerminal: headerIsTerminal, displayArgs: displayArgs, argsLanguage: argsLanguage, nameColor: toolNameColor(tool.name), filePath: filePath, onOpenFile: onOpenFile }), !isRunning && (_jsx(Box, { flexWrap: "nowrap", children: _jsx(Text, { dimColor: !hovered, children: elapsedText }) })), hovered && (_jsx(Box, { flexShrink: 0, children: _jsx(Text, { dimColor: true, children: isExpanded ? '▴' : '▾' }) }))] }), useSplitDiff && view?.card === 'diff' ? (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_FIRST }) }), _jsx(SplitDiffView, { diffs: view.diffs, width: columns - 4, maxRows: DIFF_BODY_MAX_LINES, verbose: verbose, toolBackground: ordinaryToolBackground })] })) : (rendered.map((line, index) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { color: line.tone === 'add'
295
318
  ? 'diffAddedWord'
296
319
  : line.tone === 'del'
297
320
  ? 'diffRemovedWord'
298
321
  : line.tone === 'path'
299
322
  ? 'ide'
300
- : undefined, dimColor: line.tone !== 'add' && line.tone !== 'del' && line.tone !== 'path', children: index === 0 ? GUTTER_FIRST : GUTTER_REST }) }), _jsx(Box, { flexGrow: 1, children: _jsx(Text, { color: line.tone === 'add'
323
+ : undefined, dimColor: line.tone !== 'add' && line.tone !== 'del' && line.tone !== 'path', children: index === 0 ? GUTTER_FIRST : GUTTER_REST }) }), _jsx(Box, { flexGrow: 1, children: line.tone === 'path' && onOpenFile !== undefined ? (_jsx(Box, { onClick: (event) => {
324
+ // Stop propagation so the row's fold toggle does not
325
+ // fire when clicking the path.
326
+ event.stopImmediatePropagation();
327
+ onOpenFile(line.text);
328
+ }, children: _jsx(Text, { color: "ide", underline: true, children: line.text }) })) : (_jsx(Text, { color: line.tone === 'add'
301
329
  ? 'diffAddedWord'
302
330
  : line.tone === 'del'
303
331
  ? 'diffRemovedWord'
@@ -307,5 +335,5 @@ export function AssistantToolUseMessage({ tool, addMargin, verbose, isSelected =
307
335
  ? 'subtle'
308
336
  : line.tone === 'path'
309
337
  ? 'ide'
310
- : undefined, dimColor: line.tone === 'dim', wrap: "wrap", children: line.tone === 'plain' && syntaxLanguage !== undefined ? (_jsx(SyntaxText, { text: line.text, sourceText: bodySource, lineIndex: index, language: syntaxLanguage })) : (line.text === '' ? ' ' : line.text) }) })] }, index)))), useSplitDiff && footnote !== undefined && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_REST }) }), _jsx(Text, { color: "subtle", children: footnote })] }))] }) }));
338
+ : undefined, dimColor: line.tone === 'dim' && !(line.revealOnHover === true && hovered), wrap: "wrap", children: line.tone === 'plain' && syntaxLanguage !== undefined ? (_jsx(SyntaxText, { text: line.text, sourceText: bodySource, lineIndex: index, language: syntaxLanguage })) : (line.text === '' ? ' ' : line.text) })) })] }, index)))), useSplitDiff && footnote !== undefined && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { dimColor: true, children: GUTTER_REST }) }), _jsx(Text, { color: "subtle", children: footnote })] }))] }) }));
311
339
  }
@@ -12,7 +12,7 @@
12
12
  * the input row itself and typing gives a pure custom answer.
13
13
  */
14
14
  import React from 'react';
15
- import type { QuestionSelection } from '../../dsh-adapter/questions.js';
15
+ import type { QuestionDraft, QuestionSelection } from '../../dsh-adapter/questions.js';
16
16
  export type AskUserQuestionPanelProps = {
17
17
  /** The question to render (from the QuestionStore snapshot). */
18
18
  readonly question: {
@@ -41,9 +41,13 @@ export type AskUserQuestionPanelProps = {
41
41
  readonly total: number;
42
42
  /** Questions answered before the current one. */
43
43
  readonly answered: number;
44
+ /** Previously saved answer or draft, restored when returning to this item. */
45
+ readonly initialDraft?: QuestionDraft;
44
46
  readonly onAnswer: (selection: QuestionSelection) => void;
45
- /** Esc / Ctrl+C — aborts the whole ask (ASK_ABORTED back to the model). */
47
+ /** Esc on the first question / Ctrl+C — aborts the whole ask. */
46
48
  readonly onCancel: () => void;
49
+ /** Esc on later questions — navigates to the previous question. */
50
+ readonly onBack?: (draft: QuestionDraft) => void;
47
51
  };
48
- export declare function AskUserQuestionPanel({ question, position, total, answered, onAnswer, onCancel, }: AskUserQuestionPanelProps): React.ReactNode;
52
+ export declare function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, }: AskUserQuestionPanelProps): React.ReactNode;
49
53
  //# sourceMappingURL=AskUserQuestionPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AASvE,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;CAC9B,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CA+Y7C"}
1
+ {"version":3,"file":"AskUserQuestionPanel.d.ts","sourceRoot":"","sources":["../../../../src/components/questions/AskUserQuestionPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAStF,MAAM,MAAM,yBAAyB,GAAG;IACtC,gEAAgE;IAChE,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;YAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC3F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;QAC9B;;oEAE4D;QAC5D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;QAClC;0EACkE;QAClE,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;YAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7E,CAAA;IACD,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACzD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;CACjD,CAAA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,GACP,EAAE,yBAAyB,GAAG,KAAK,CAAC,SAAS,CAkb7C"}
@@ -24,7 +24,7 @@ import { listWindow } from '../listWindow.js';
24
24
  const CHECKED = '◉';
25
25
  const UNCHECKED = '○';
26
26
  const PENCIL = '✎';
27
- export function AskUserQuestionPanel({ question, position, total, answered, onAnswer, onCancel, }) {
27
+ export function AskUserQuestionPanel({ question, position, total, answered, initialDraft, onAnswer, onCancel, onBack, }) {
28
28
  // Plan-mode's exit_plan_mode ask carries a presentation intent: render
29
29
  // the CC-style decision card instead of the generic questionnaire. The
30
30
  // branch precedes every hook so hook order stays stable per remount key.
@@ -37,13 +37,21 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
37
37
  const { rows: terminalRows } = useTerminalSize();
38
38
  /** Rows: the real options plus the inline input row at the tail. */
39
39
  const rowCount = options.length + (hideCustomInput ? 0 : 1);
40
- const [focusIndex, setFocusIndex] = React.useState(0);
41
- const [checked, setChecked] = React.useState(() => new Set());
42
- const [customText, setCustomText] = React.useState('');
43
- const [customCursor, setCustomCursor] = React.useState(0);
40
+ const initialSelected = initialDraft?.selected ?? [];
41
+ const initialCustom = initialDraft?.custom ?? '';
42
+ const selectedIndices = options
43
+ .map((option, index) => initialSelected.includes(option.label) ? index : -1)
44
+ .filter(index => index >= 0);
45
+ const initialFocus = initialCustom !== '' && selectedIndices.length === 0 && !hideCustomInput
46
+ ? options.length
47
+ : selectedIndices[0] ?? 0;
48
+ const [focusIndex, setFocusIndex] = React.useState(initialFocus);
49
+ const [checked, setChecked] = React.useState(() => new Set(multiSelect ? selectedIndices : []));
50
+ const [customText, setCustomText] = React.useState(initialCustom);
51
+ const [customCursor, setCustomCursor] = React.useState(initialCustom.length);
44
52
  /** Single-select label captured by typing on a focused option — submitted
45
53
  * together with the custom text when the input row itself is Entered. */
46
- const [attached, setAttached] = React.useState(null);
54
+ const [attached, setAttached] = React.useState(() => initialCustom !== '' && !multiSelect ? (initialSelected[0] ?? null) : null);
47
55
  const [error, setError] = React.useState(null);
48
56
  const inputFocused = !hideCustomInput && focusIndex === options.length;
49
57
  // Chat chrome + panel scaffolding consume twelve rows before the option
@@ -139,11 +147,33 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
139
147
  }
140
148
  onAnswer({ selected: attached !== null ? [attached] : [], custom: text });
141
149
  };
150
+ /** Capture the visible answer state before navigating away. */
151
+ const currentDraft = () => {
152
+ const selected = multiSelect
153
+ ? checkedLabels()
154
+ : inputFocused
155
+ ? (attached === null ? [] : [attached])
156
+ : (() => {
157
+ const label = options[focusIndex]?.label;
158
+ return label === undefined ? [] : [label];
159
+ })();
160
+ return {
161
+ selected,
162
+ ...(customText !== '' ? { custom: customText } : {}),
163
+ };
164
+ };
142
165
  useInput((input, key) => {
143
- if (key.escape || (key.ctrl && input === 'c')) {
166
+ if (key.ctrl && input === 'c') {
144
167
  onCancel();
145
168
  return;
146
169
  }
170
+ if (key.escape) {
171
+ if (onBack !== undefined)
172
+ onBack(currentDraft());
173
+ else
174
+ onCancel();
175
+ return;
176
+ }
147
177
  if (inputFocused) {
148
178
  if (key.upArrow) {
149
179
  moveFocus(-1);
@@ -298,7 +328,8 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
298
328
  t('question-hint-type'),
299
329
  t('question-hint-enter'),
300
330
  ...(options.length > 0 ? [t('question-hint-back')] : []),
301
- t('question-hint-esc'),
331
+ onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
332
+ ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
302
333
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
303
334
  ]
304
335
  : [
@@ -306,7 +337,8 @@ export function AskUserQuestionPanel({ question, position, total, answered, onAn
306
337
  ...(multiSelect ? [t('question-hint-multi')] : []),
307
338
  ...(hideCustomInput ? [] : [t('question-hint-attach')]),
308
339
  t('question-hint-enter'),
309
- t('question-hint-esc'),
340
+ onBack === undefined ? t('question-hint-esc') : t('question-hint-previous'),
341
+ ...(onBack === undefined ? [] : [t('question-hint-cancel')]),
310
342
  ...(multiSelect && checked.size > 0 ? [t('question-hint-selected', { n: checked.size })] : []),
311
343
  ];
312
344
  return (_jsxs(Box, { flexDirection: "column", marginTop: 1, paddingLeft: 2, paddingRight: 2, width: "100%", children: [_jsx(Divider, { color: "permission", title: headerTitle, padding: 4 }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [question.header !== undefined && (_jsxs(Text, { color: "suggestion", bold: true, children: ["\u25C8 ", question.header] })), _jsx(Text, { bold: true, wrap: "wrap", children: question.question }), question.detail !== undefined && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: question.detail.split('\n').map((line, index) => (_jsx(Text, { dimColor: true, italic: true, wrap: "wrap", children: line }, index))) }))] }), renderOptions(), error !== null && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "error", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: hintParts.join(' · ') }) })] }));