@deepseek-harness-tui/dsh-tui 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/README.md +74 -21
  2. package/bin/dsh-tui.js +115 -25
  3. package/cordis.patch.yml +69 -17
  4. package/cordis.yml +50 -12
  5. package/lib/types/activityPrefs.d.ts +1 -1
  6. package/lib/types/activityPrefs.js +3 -3
  7. package/lib/types/cc/figures.d.ts +27 -20
  8. package/lib/types/cc/figures.d.ts.map +1 -1
  9. package/lib/types/cc/figures.js +43 -34
  10. package/lib/types/cc/format.d.ts +18 -9
  11. package/lib/types/cc/format.d.ts.map +1 -1
  12. package/lib/types/cc/format.js +26 -18
  13. package/lib/types/cc/markdown.d.ts +31 -16
  14. package/lib/types/cc/markdown.d.ts.map +1 -1
  15. package/lib/types/cc/markdown.js +283 -260
  16. package/lib/types/cc/terminal.d.ts +10 -7
  17. package/lib/types/cc/terminal.d.ts.map +1 -1
  18. package/lib/types/cc/terminal.js +62 -50
  19. package/lib/types/command-trees.d.ts +3 -0
  20. package/lib/types/command-trees.d.ts.map +1 -0
  21. package/lib/types/command-trees.js +4 -0
  22. package/lib/types/commands.d.ts +37 -1
  23. package/lib/types/commands.d.ts.map +1 -1
  24. package/lib/types/commands.js +68 -3
  25. package/lib/types/components/ActivityLine.d.ts +1 -1
  26. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  27. package/lib/types/components/ActivityPicker.d.ts.map +1 -1
  28. package/lib/types/components/ActivityPicker.js +3 -4
  29. package/lib/types/components/BtwPanel.d.ts +16 -0
  30. package/lib/types/components/BtwPanel.d.ts.map +1 -0
  31. package/lib/types/components/BtwPanel.js +47 -0
  32. package/lib/types/components/CommandSuggestions.d.ts +4 -2
  33. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  34. package/lib/types/components/CommandSuggestions.js +2 -2
  35. package/lib/types/components/EffortSlider.d.ts +15 -0
  36. package/lib/types/components/EffortSlider.d.ts.map +1 -0
  37. package/lib/types/components/EffortSlider.js +17 -0
  38. package/lib/types/components/GoalTodoPanel.d.ts +1 -1
  39. package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
  40. package/lib/types/components/HelpMenu.d.ts +5 -2
  41. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  42. package/lib/types/components/HelpMenu.js +8 -3
  43. package/lib/types/components/HistorySearchDialog.d.ts +1 -1
  44. package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
  45. package/lib/types/components/HistorySearchDialog.js +21 -10
  46. package/lib/types/components/InterruptedByUser.d.ts +2 -2
  47. package/lib/types/components/InterruptedByUser.d.ts.map +1 -1
  48. package/lib/types/components/InterruptedByUser.js +4 -3
  49. package/lib/types/components/LoadedContextPanel.d.ts +1 -1
  50. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  51. package/lib/types/components/LogoV2.d.ts.map +1 -1
  52. package/lib/types/components/LogoV2.js +2 -1
  53. package/lib/types/components/Markdown.d.ts +11 -11
  54. package/lib/types/components/Markdown.d.ts.map +1 -1
  55. package/lib/types/components/Markdown.js +63 -57
  56. package/lib/types/components/MarkdownTable.d.ts +1 -1
  57. package/lib/types/components/MarkdownTable.js +2 -2
  58. package/lib/types/components/MessageList.d.ts +10 -2
  59. package/lib/types/components/MessageList.d.ts.map +1 -1
  60. package/lib/types/components/MessageList.js +17 -10
  61. package/lib/types/components/ModelPicker.d.ts +4 -1
  62. package/lib/types/components/ModelPicker.d.ts.map +1 -1
  63. package/lib/types/components/ModelPicker.js +16 -4
  64. package/lib/types/components/OverlayAbove.d.ts +20 -0
  65. package/lib/types/components/OverlayAbove.d.ts.map +1 -0
  66. package/lib/types/components/OverlayAbove.js +18 -0
  67. package/lib/types/components/PresetPicker.d.ts +1 -1
  68. package/lib/types/components/PresetPicker.d.ts.map +1 -1
  69. package/lib/types/components/PresetPicker.js +2 -3
  70. package/lib/types/components/PromptInput.d.ts +5 -4
  71. package/lib/types/components/PromptInput.d.ts.map +1 -1
  72. package/lib/types/components/PromptInput.js +186 -39
  73. package/lib/types/components/ResumePicker.d.ts +15 -4
  74. package/lib/types/components/ResumePicker.d.ts.map +1 -1
  75. package/lib/types/components/ResumePicker.js +25 -9
  76. package/lib/types/components/RewindPicker.d.ts +1 -1
  77. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  78. package/lib/types/components/RewindPicker.js +14 -5
  79. package/lib/types/components/SearchBox.d.ts +1 -1
  80. package/lib/types/components/SearchBox.js +1 -1
  81. package/lib/types/components/Spinner/GlimmerMessage.d.ts +1 -2
  82. package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -1
  83. package/lib/types/components/Spinner/GlimmerMessage.js +1 -2
  84. package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +1 -1
  85. package/lib/types/components/Spinner/SpinnerAnimationRow.js +2 -2
  86. package/lib/types/components/Spinner/SpinnerGlyph.d.ts +1 -1
  87. package/lib/types/components/Spinner/SpinnerGlyph.js +1 -1
  88. package/lib/types/components/Spinner/spinnerUtils.d.ts +13 -18
  89. package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -1
  90. package/lib/types/components/Spinner/spinnerUtils.js +67 -71
  91. package/lib/types/components/Spinner/useStalledAnimation.d.ts +1 -2
  92. package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -1
  93. package/lib/types/components/Spinner/useStalledAnimation.js +1 -2
  94. package/lib/types/components/StreamingMarkdown.d.ts +1 -1
  95. package/lib/types/components/StreamingMarkdown.js +1 -1
  96. package/lib/types/components/ThemePicker.d.ts +13 -9
  97. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  98. package/lib/types/components/ThemePicker.js +21 -15
  99. package/lib/types/components/ThinkingToggle.d.ts +1 -1
  100. package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
  101. package/lib/types/components/ThinkingToggle.js +8 -8
  102. package/lib/types/components/ToolUseLoader.d.ts +1 -1
  103. package/lib/types/components/ToolUseLoader.js +1 -1
  104. package/lib/types/components/WorkingSpinner.d.ts +2 -2
  105. package/lib/types/components/WorkingSpinner.js +2 -2
  106. package/lib/types/components/WorkspaceFlowPicker.d.ts +15 -0
  107. package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
  108. package/lib/types/components/WorkspaceFlowPicker.js +19 -0
  109. package/lib/types/components/WorkspacePicker.d.ts +9 -0
  110. package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
  111. package/lib/types/components/WorkspacePicker.js +13 -0
  112. package/lib/types/components/approvals/ApprovalPanel.d.ts +1 -1
  113. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
  114. package/lib/types/components/approvals/ApprovalPanel.js +2 -1
  115. package/lib/types/components/design-system/Byline.d.ts +1 -1
  116. package/lib/types/components/design-system/Byline.js +1 -1
  117. package/lib/types/components/design-system/Divider.d.ts +1 -1
  118. package/lib/types/components/design-system/Divider.js +1 -1
  119. package/lib/types/components/design-system/HintLine.d.ts +12 -0
  120. package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
  121. package/lib/types/components/design-system/HintLine.js +15 -0
  122. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +1 -1
  123. package/lib/types/components/design-system/KeyboardShortcutHint.js +1 -1
  124. package/lib/types/components/design-system/ListItem.d.ts +2 -2
  125. package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
  126. package/lib/types/components/design-system/ListItem.js +35 -3
  127. package/lib/types/components/design-system/LoadingState.d.ts +1 -2
  128. package/lib/types/components/design-system/LoadingState.d.ts.map +1 -1
  129. package/lib/types/components/design-system/LoadingState.js +1 -2
  130. package/lib/types/components/design-system/Pane.d.ts +2 -2
  131. package/lib/types/components/design-system/Pane.js +2 -2
  132. package/lib/types/components/design-system/ProgressBar.d.ts +1 -2
  133. package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -1
  134. package/lib/types/components/design-system/ProgressBar.js +1 -2
  135. package/lib/types/components/design-system/StatusIcon.d.ts +2 -2
  136. package/lib/types/components/design-system/StatusIcon.js +2 -2
  137. package/lib/types/components/design-system/ThemeProvider.d.ts +1 -1
  138. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  139. package/lib/types/components/design-system/ThemeProvider.js +87 -26
  140. package/lib/types/components/design-system/ThemedBox.d.ts +1 -1
  141. package/lib/types/components/design-system/ThemedBox.js +1 -1
  142. package/lib/types/components/design-system/ThemedText.d.ts +2 -2
  143. package/lib/types/components/design-system/ThemedText.js +2 -2
  144. package/lib/types/components/listWindow.d.ts +26 -0
  145. package/lib/types/components/listWindow.d.ts.map +1 -0
  146. package/lib/types/components/listWindow.js +47 -0
  147. package/lib/types/components/messages/AssistantTextMessage.d.ts +1 -2
  148. package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
  149. package/lib/types/components/messages/AssistantTextMessage.js +1 -2
  150. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -2
  151. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  152. package/lib/types/components/messages/AssistantThinkingMessage.js +6 -6
  153. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +12 -4
  154. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  155. package/lib/types/components/messages/AssistantToolUseMessage.js +9 -5
  156. package/lib/types/components/messages/MessageMetadata.d.ts +1 -1
  157. package/lib/types/components/messages/MessageMetadata.js +1 -1
  158. package/lib/types/components/messages/UserPromptMessage.d.ts +1 -1
  159. package/lib/types/components/messages/UserPromptMessage.js +1 -1
  160. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +5 -1
  161. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  162. package/lib/types/components/questions/AskUserQuestionPanel.js +11 -9
  163. package/lib/types/components/questions/PlanReviewPanel.d.ts +1 -1
  164. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  165. package/lib/types/components/questions/PlanReviewPanel.js +3 -2
  166. package/lib/types/components/trajectory/HotspotView.d.ts +14 -0
  167. package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
  168. package/lib/types/components/trajectory/HotspotView.js +83 -0
  169. package/lib/types/components/trajectory/Inspector.d.ts +31 -0
  170. package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
  171. package/lib/types/components/trajectory/Inspector.js +67 -0
  172. package/lib/types/components/trajectory/Ledger.d.ts +20 -0
  173. package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
  174. package/lib/types/components/trajectory/Ledger.js +112 -0
  175. package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
  176. package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
  177. package/lib/types/components/trajectory/MiniWake.js +99 -0
  178. package/lib/types/components/trajectory/WaveBand.d.ts +33 -0
  179. package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
  180. package/lib/types/components/trajectory/WaveBand.js +145 -0
  181. package/lib/types/customTheme.d.ts +6 -6
  182. package/lib/types/customTheme.d.ts.map +1 -1
  183. package/lib/types/customTheme.js +15 -12
  184. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
  185. package/lib/types/{channel.d.ts → dsh-adapter/channel.d.ts} +184 -43
  186. package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
  187. package/lib/types/{channel.js → dsh-adapter/channel.js} +972 -201
  188. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
  189. package/lib/types/{childStderr.js → dsh-adapter/childStderr.js} +1 -1
  190. package/lib/types/dsh-adapter/command-trees.d.ts +27 -0
  191. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
  192. package/lib/types/dsh-adapter/command-trees.js +42 -0
  193. package/lib/types/dsh-adapter/compat/index.d.ts +22 -0
  194. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
  195. package/lib/types/{compat → dsh-adapter/compat}/index.js +7 -4
  196. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +86 -0
  197. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
  198. package/lib/types/dsh-adapter/compat/sessionLog.js +347 -0
  199. package/lib/types/dsh-adapter/contract.d.ts +20 -0
  200. package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
  201. package/lib/types/dsh-adapter/contract.js +109 -0
  202. package/lib/types/dsh-adapter/index.d.ts +80 -0
  203. package/lib/types/dsh-adapter/index.d.ts.map +1 -0
  204. package/lib/types/dsh-adapter/index.js +45 -0
  205. package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
  206. package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -0
  207. package/lib/types/{plugin.d.ts → dsh-adapter/plugin.d.ts} +17 -0
  208. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
  209. package/lib/types/{plugin.js → dsh-adapter/plugin.js} +280 -80
  210. package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
  211. package/lib/types/dsh-adapter/providerWizard.d.ts +91 -0
  212. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
  213. package/lib/types/dsh-adapter/providerWizard.js +332 -0
  214. package/lib/types/{questions.d.ts → dsh-adapter/questions.d.ts} +7 -2
  215. package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
  216. package/lib/types/{questions.js → dsh-adapter/questions.js} +15 -7
  217. package/lib/types/dsh-adapter/sideQuestion.d.ts +38 -0
  218. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
  219. package/lib/types/dsh-adapter/sideQuestion.js +69 -0
  220. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +46 -0
  221. package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
  222. package/lib/types/dsh-adapter/trajectory/aggregate.js +207 -0
  223. package/lib/types/dsh-adapter/trajectory/guards.d.ts +177 -0
  224. package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
  225. package/lib/types/dsh-adapter/trajectory/guards.js +235 -0
  226. package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
  227. package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
  228. package/lib/types/dsh-adapter/trajectory/index.js +15 -0
  229. package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
  230. package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
  231. package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
  232. package/lib/types/dsh-adapter/trajectory/projection.d.ts +128 -0
  233. package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
  234. package/lib/types/dsh-adapter/trajectory/projection.js +653 -0
  235. package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
  236. package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
  237. package/lib/types/dsh-adapter/trajectory/types.js +70 -0
  238. package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
  239. package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
  240. package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
  241. package/lib/types/dsh-adapter/types.d.ts +23 -0
  242. package/lib/types/dsh-adapter/types.d.ts.map +1 -0
  243. package/lib/types/dsh-adapter/types.js +1 -0
  244. package/lib/types/dsh-adapter/workspace.d.ts +22 -0
  245. package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
  246. package/lib/types/dsh-adapter/workspace.js +16 -0
  247. package/lib/types/dsh-adapter/workspaces.d.ts +118 -0
  248. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
  249. package/lib/types/dsh-adapter/workspaces.js +290 -0
  250. package/lib/types/effortPrefs.d.ts +1 -1
  251. package/lib/types/effortPrefs.js +3 -3
  252. package/lib/types/history.js +2 -2
  253. package/lib/types/hooks/useBlink.d.ts +1 -1
  254. package/lib/types/hooks/useBlink.js +1 -1
  255. package/lib/types/i18n.d.ts +977 -36
  256. package/lib/types/i18n.d.ts.map +1 -1
  257. package/lib/types/i18n.js +307 -30
  258. package/lib/types/index.d.ts +1 -69
  259. package/lib/types/index.d.ts.map +1 -1
  260. package/lib/types/index.js +3 -31
  261. package/lib/types/ink/components/App.d.ts.map +1 -1
  262. package/lib/types/ink/components/App.js +33 -19
  263. package/lib/types/ink/dom.d.ts +15 -0
  264. package/lib/types/ink/dom.d.ts.map +1 -1
  265. package/lib/types/ink/dom.js +32 -0
  266. package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
  267. package/lib/types/ink/hooks/use-input.js +8 -0
  268. package/lib/types/ink/hooks/use-terminal-size.d.ts +1 -1
  269. package/lib/types/ink/hooks/use-terminal-size.js +1 -1
  270. package/lib/types/ink/ink.d.ts.map +1 -1
  271. package/lib/types/ink/ink.js +109 -28
  272. package/lib/types/ink/input-suppression.d.ts +20 -0
  273. package/lib/types/ink/input-suppression.d.ts.map +1 -0
  274. package/lib/types/ink/input-suppression.js +26 -0
  275. package/lib/types/ink/log-update.js +21 -6
  276. package/lib/types/ink/parse-keypress.d.ts +31 -0
  277. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  278. package/lib/types/ink/parse-keypress.js +442 -8
  279. package/lib/types/ink/terminal-querier.d.ts +5 -1
  280. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  281. package/lib/types/ink/terminal-querier.js +27 -3
  282. package/lib/types/ink/terminal.d.ts +18 -0
  283. package/lib/types/ink/terminal.d.ts.map +1 -1
  284. package/lib/types/ink/terminal.js +32 -4
  285. package/lib/types/ink/termio/csi.d.ts +10 -0
  286. package/lib/types/ink/termio/csi.d.ts.map +1 -1
  287. package/lib/types/ink/termio/csi.js +20 -0
  288. package/lib/types/ink/termio/tokenize.js +10 -0
  289. package/lib/types/modelPrefs.d.ts +1 -1
  290. package/lib/types/modelPrefs.js +3 -3
  291. package/lib/types/presetPrefs.d.ts +1 -1
  292. package/lib/types/presetPrefs.js +3 -3
  293. package/lib/types/screens/Chat.d.ts +20 -4
  294. package/lib/types/screens/Chat.d.ts.map +1 -1
  295. package/lib/types/screens/Chat.js +655 -55
  296. package/lib/types/screens/StatusLine.d.ts +17 -2
  297. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  298. package/lib/types/screens/StatusLine.js +12 -4
  299. package/lib/types/screens/TrajectoryScene.d.ts +16 -0
  300. package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
  301. package/lib/types/screens/TrajectoryScene.js +305 -0
  302. package/lib/types/sessionHistory.d.ts +9 -1
  303. package/lib/types/sessionHistory.d.ts.map +1 -1
  304. package/lib/types/sessionHistory.js +56 -16
  305. package/lib/types/sessionModes.d.ts +29 -0
  306. package/lib/types/sessionModes.d.ts.map +1 -0
  307. package/lib/types/sessionModes.js +45 -0
  308. package/lib/types/theme.d.ts +27 -3
  309. package/lib/types/theme.d.ts.map +1 -1
  310. package/lib/types/theme.js +48 -4
  311. package/lib/types/themePrefs.d.ts +3 -3
  312. package/lib/types/themePrefs.js +5 -5
  313. package/lib/types/trajectory/format.d.ts +100 -0
  314. package/lib/types/trajectory/format.d.ts.map +1 -0
  315. package/lib/types/trajectory/format.js +213 -0
  316. package/lib/types/trajectory/motion.d.ts +99 -0
  317. package/lib/types/trajectory/motion.d.ts.map +1 -0
  318. package/lib/types/trajectory/motion.js +143 -0
  319. package/lib/types/trajectory/query.d.ts +83 -0
  320. package/lib/types/trajectory/query.d.ts.map +1 -0
  321. package/lib/types/trajectory/query.js +187 -0
  322. package/lib/types/trajectoryPrefs.d.ts +36 -0
  323. package/lib/types/trajectoryPrefs.d.ts.map +1 -0
  324. package/lib/types/trajectoryPrefs.js +65 -0
  325. package/lib/types/update.d.ts +3 -3
  326. package/lib/types/update.d.ts.map +1 -1
  327. package/lib/types/update.js +18 -7
  328. package/lib/types/utils/clipboard.d.ts +101 -29
  329. package/lib/types/utils/clipboard.d.ts.map +1 -1
  330. package/lib/types/utils/clipboard.js +533 -55
  331. package/lib/types/utils/debug.d.ts +1 -1
  332. package/lib/types/utils/debug.js +2 -2
  333. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  334. package/lib/types/utils/execFileNoThrow.js +16 -6
  335. package/lib/types/utils/externalEditor.d.ts +115 -0
  336. package/lib/types/utils/externalEditor.d.ts.map +1 -0
  337. package/lib/types/utils/externalEditor.js +270 -0
  338. package/lib/types/utils/fullscreen.d.ts +2 -2
  339. package/lib/types/utils/fullscreen.js +3 -3
  340. package/lib/types/utils/loaded-context.d.ts +1 -1
  341. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  342. package/lib/types/utils/modifiers.d.ts +24 -0
  343. package/lib/types/utils/modifiers.d.ts.map +1 -1
  344. package/lib/types/utils/modifiers.js +27 -0
  345. package/lib/types/utils/paths.d.ts +45 -0
  346. package/lib/types/utils/paths.d.ts.map +1 -0
  347. package/lib/types/utils/paths.js +69 -0
  348. package/lib/types/utils/shellQuote.d.ts +14 -0
  349. package/lib/types/utils/shellQuote.d.ts.map +1 -0
  350. package/lib/types/utils/shellQuote.js +39 -0
  351. package/lib/types/utils/workspaceRoot.d.ts +21 -0
  352. package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
  353. package/lib/types/utils/workspaceRoot.js +47 -0
  354. package/lib/types/workspaces.d.ts +3 -0
  355. package/lib/types/workspaces.d.ts.map +1 -0
  356. package/lib/types/workspaces.js +4 -0
  357. package/package.json +26 -8
  358. package/lib/types/approvals.d.ts.map +0 -1
  359. package/lib/types/channel.d.ts.map +0 -1
  360. package/lib/types/childStderr.d.ts.map +0 -1
  361. package/lib/types/compat/index.d.ts +0 -20
  362. package/lib/types/compat/index.d.ts.map +0 -1
  363. package/lib/types/compat/sessionLog.d.ts +0 -40
  364. package/lib/types/compat/sessionLog.d.ts.map +0 -1
  365. package/lib/types/compat/sessionLog.js +0 -226
  366. package/lib/types/invariant.d.ts.map +0 -1
  367. package/lib/types/packaged-skills.d.ts.map +0 -1
  368. package/lib/types/plugin.d.ts.map +0 -1
  369. package/lib/types/presets.d.ts.map +0 -1
  370. package/lib/types/questions.d.ts.map +0 -1
  371. /package/lib/types/{approvals.d.ts → dsh-adapter/approvals.d.ts} +0 -0
  372. /package/lib/types/{approvals.js → dsh-adapter/approvals.js} +0 -0
  373. /package/lib/types/{childStderr.d.ts → dsh-adapter/childStderr.d.ts} +0 -0
  374. /package/lib/types/{invariant.d.ts → dsh-adapter/invariant.d.ts} +0 -0
  375. /package/lib/types/{invariant.js → dsh-adapter/invariant.js} +0 -0
  376. /package/lib/types/{packaged-skills.d.ts → dsh-adapter/packaged-skills.d.ts} +0 -0
  377. /package/lib/types/{packaged-skills.js → dsh-adapter/packaged-skills.js} +0 -0
  378. /package/lib/types/{presets.d.ts → dsh-adapter/presets.d.ts} +0 -0
  379. /package/lib/types/{presets.js → dsh-adapter/presets.js} +0 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * `/provider` wizard — interactively adds an LLM provider route at runtime.
3
+ *
4
+ * The wizard is a sequence of `QuestionStore` asks (the same panel the
5
+ * model-facing `ask_user_question` tool uses), so it needs no UI state of
6
+ * its own. All side effects go through {@link ProviderSetupHost}, which the
7
+ * channel implements over the dsh settings/credentials/llm seams:
8
+ *
9
+ * profile → settings `llm-pi-ai.providers.<route>` (dsh-llm-pi-ai watches
10
+ * the section and registers the route without a restart)
11
+ * key → credentials store (`~/.dsh/.credentials.yaml`, 0600), named by
12
+ * the derived `<ROUTE>_API_KEY` env-style ref the profile's
13
+ * `apiKeyEnv` points at
14
+ *
15
+ * The module is React-free so `scripts/verify-provider-wizard.mjs` can drive
16
+ * it headless with a stubbed host and scripted answers.
17
+ */
18
+ import { t } from '../i18n.js';
19
+ import { UserQuestionError, } from '@deepseek-ai/dsh-user-questions';
20
+ /** Route id rule shared with the dsh configuration surface (web Models page). */
21
+ export const PROVIDER_ROUTE_ID = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
22
+ /** Wire protocols dsh-llm-pi-ai can serve on a manually declared route. */
23
+ export const PROVIDER_PROTOCOLS = [
24
+ 'openai-completions',
25
+ 'openai-responses',
26
+ 'anthropic-messages',
27
+ ];
28
+ /**
29
+ * Derive the credential ref for a route, matching the official web UI
30
+ * convention so TUI- and web-added providers resolve the same key.
31
+ */
32
+ export function deriveKeyRef(route) {
33
+ return `${route.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`;
34
+ }
35
+ /** Max attempts for validated free-text prompts before giving up. */
36
+ const MAX_RETRY = 3;
37
+ function answerText(answer, id) {
38
+ return answer.answers.find(item => item.id === id)?.custom?.trim() ?? '';
39
+ }
40
+ function answerSelected(answer, id) {
41
+ return answer.answers.find(item => item.id === id)?.selected ?? [];
42
+ }
43
+ function optionQuestion(id, question, options, extra) {
44
+ const item = {
45
+ id,
46
+ question,
47
+ header: '/provider',
48
+ options: options.map(option => ({ ...option })),
49
+ ...(extra?.detail !== undefined ? { detail: extra.detail } : {}),
50
+ ...(extra?.multiSelect ? { multiSelect: true } : {}),
51
+ ...(extra?.hideCustomInput ? { hideCustomInput: true } : {}),
52
+ };
53
+ return item;
54
+ }
55
+ function textQuestion(id, question, detail) {
56
+ return {
57
+ id,
58
+ question,
59
+ header: '/provider',
60
+ ...(detail !== undefined ? { detail } : {}),
61
+ };
62
+ }
63
+ /**
64
+ * Run the add-provider wizard. Resolves 'cancelled' when the user dismisses
65
+ * any question (Esc) — nothing has been written at that point by design:
66
+ * all asks complete before the first side effect.
67
+ */
68
+ export async function runProviderWizard(deps) {
69
+ const { host, ask, notify, pushLocal } = deps;
70
+ try {
71
+ // ── 1. mode ────────────────────────────────────────────────────────
72
+ const modeAnswer = await ask({
73
+ questions: [optionQuestion('mode', t('provider-q-mode'), [
74
+ { label: t('provider-opt-catalog'), description: t('provider-opt-catalog-desc') },
75
+ { label: t('provider-opt-custom'), description: t('provider-opt-custom-desc') },
76
+ ], { hideCustomInput: true })],
77
+ });
78
+ const isCatalog = answerSelected(modeAnswer, 'mode')[0] === t('provider-opt-catalog');
79
+ // ── 2. route ───────────────────────────────────────────────────────
80
+ let route = '';
81
+ if (isCatalog) {
82
+ const candidates = host.listCatalogProviders();
83
+ if (candidates.length > 0) {
84
+ const otherLabel = t('provider-opt-other-route');
85
+ const catalogAnswer = await ask({
86
+ questions: [optionQuestion('catalog', t('provider-q-catalog'), [
87
+ ...candidates.map(candidate => ({
88
+ label: candidate.provider,
89
+ description: candidate.displayName,
90
+ })),
91
+ { label: otherLabel, description: t('provider-opt-other-route-desc') },
92
+ ], { hideCustomInput: true })],
93
+ });
94
+ const pick = answerSelected(catalogAnswer, 'catalog')[0];
95
+ if (pick !== undefined && pick !== otherLabel)
96
+ route = pick;
97
+ }
98
+ }
99
+ if (route === '') {
100
+ route = await promptRouteId(ask, notify);
101
+ if (route === '')
102
+ return 'cancelled';
103
+ }
104
+ // ── 3. API key (own batch so redact covers exactly the secret) ─────
105
+ const keyAnswer = await ask({
106
+ questions: [textQuestion('apikey', t('provider-q-apikey'), t('provider-q-apikey-detail'))],
107
+ }, { redact: true });
108
+ const apiKey = answerText(keyAnswer, 'apikey');
109
+ // ── 4. endpoint / protocol ─────────────────────────────────────────
110
+ let baseURL;
111
+ let api;
112
+ if (isCatalog) {
113
+ const choiceAnswer = await ask({
114
+ questions: [optionQuestion('baseurl-choice', t('provider-q-baseurl-choice'), [
115
+ { label: t('provider-opt-baseurl-skip') },
116
+ { label: t('provider-opt-baseurl-input') },
117
+ ], { hideCustomInput: true })],
118
+ });
119
+ if (answerSelected(choiceAnswer, 'baseurl-choice')[0] === t('provider-opt-baseurl-input')) {
120
+ const urlAnswer = await ask({
121
+ questions: [textQuestion('baseurl', t('provider-q-baseurl'))],
122
+ });
123
+ baseURL = answerText(urlAnswer, 'baseurl');
124
+ }
125
+ }
126
+ else {
127
+ const endpointAnswer = await ask({
128
+ questions: [
129
+ textQuestion('baseurl', t('provider-q-baseurl')),
130
+ optionQuestion('protocol', t('provider-q-protocol'), [
131
+ { label: 'openai-completions', description: t('provider-protocol-completions-desc') },
132
+ { label: 'openai-responses', description: t('provider-protocol-responses-desc') },
133
+ { label: 'anthropic-messages', description: t('provider-protocol-anthropic-desc') },
134
+ ], { hideCustomInput: true }),
135
+ ],
136
+ });
137
+ baseURL = answerText(endpointAnswer, 'baseurl');
138
+ api = answerSelected(endpointAnswer, 'protocol')[0];
139
+ }
140
+ // ── 5. model discovery (draft credential, nothing persisted) ───────
141
+ notify(t('provider-discovery-running'));
142
+ const discovered = await host.discoverModels({
143
+ ...(isCatalog ? { provider: route } : {}),
144
+ ...(baseURL !== undefined && baseURL !== '' ? { baseURL } : {}),
145
+ ...(api !== undefined ? { api } : {}),
146
+ apiKey,
147
+ }).catch(() => []);
148
+ // ── 6. model selection ─────────────────────────────────────────────
149
+ let models = [];
150
+ let discoveredById = new Map();
151
+ if (discovered.length > 0) {
152
+ discoveredById = new Map(discovered.map(model => [model.id, model]));
153
+ const modelsAnswer = await ask({
154
+ questions: [optionQuestion('models', t('provider-q-models'), discovered.map(model => ({
155
+ label: model.id,
156
+ description: [
157
+ model.name ?? '',
158
+ model.contextWindow !== undefined ? `${model.contextWindow}` : '',
159
+ ].filter(part => part !== '').join(' · ') || undefined,
160
+ })), { multiSelect: true })],
161
+ });
162
+ models = mergeModelIds(answerSelected(modelsAnswer, 'models'), answerText(modelsAnswer, 'models'));
163
+ }
164
+ else {
165
+ notify(t('provider-discovery-failed'), { color: 'warning' });
166
+ for (let attempt = 0; attempt < MAX_RETRY && models.length === 0; attempt += 1) {
167
+ const fallbackAnswer = await ask({
168
+ questions: [textQuestion('models-fallback', t('provider-q-models-fallback'))],
169
+ });
170
+ models = mergeModelIds([], answerText(fallbackAnswer, 'models-fallback'));
171
+ if (models.length === 0)
172
+ notify(t('provider-models-required'), { color: 'warning' });
173
+ }
174
+ if (models.length === 0)
175
+ return 'cancelled';
176
+ }
177
+ if (!isCatalog && models.length === 0) {
178
+ // A manual route without models fails the adapter validation; the
179
+ // loops above should prevent this, but guard before writing.
180
+ notify(t('provider-models-required'), { color: 'error' });
181
+ return 'cancelled';
182
+ }
183
+ // ── 7. confirm ─────────────────────────────────────────────────────
184
+ const ref = deriveKeyRef(route);
185
+ const shadowed = host.envShadows(ref);
186
+ const summaryLines = buildSummaryLines({
187
+ route, ref, shadowed, baseURL, api, models, isCatalog,
188
+ });
189
+ const detail = host.routeExists(route)
190
+ ? `${summaryLines.join('\n')}\n${t('provider-route-exists-warning')}`
191
+ : summaryLines.join('\n');
192
+ const confirmAnswer = await ask({
193
+ questions: [optionQuestion('confirm', t('provider-q-confirm'), [
194
+ { label: t('provider-opt-confirm-write') },
195
+ { label: t('provider-opt-confirm-cancel') },
196
+ ], { detail, hideCustomInput: true })],
197
+ });
198
+ if (answerSelected(confirmAnswer, 'confirm')[0] !== t('provider-opt-confirm-write')) {
199
+ notify(t('provider-cancelled'));
200
+ return 'cancelled';
201
+ }
202
+ // ── 8. persist: credential first (rollbackable), then the profile ──
203
+ let wroteCredential = false;
204
+ let previousCredential;
205
+ if (!shadowed) {
206
+ // Capture any pre-existing value BEFORE overwriting: when the profile
207
+ // write below fails, rollback must restore it — an unconditional unset
208
+ // would destroy the old key of the route being overwritten.
209
+ previousCredential = await host.readCredential(ref);
210
+ await host.writeCredential(ref, apiKey);
211
+ wroteCredential = true;
212
+ }
213
+ const profile = buildProfile({ isCatalog, ref, baseURL, api, models, discoveredById });
214
+ try {
215
+ await host.writeProfile(route, profile);
216
+ }
217
+ catch (error) {
218
+ if (wroteCredential) {
219
+ try {
220
+ if (previousCredential !== undefined) {
221
+ await host.writeCredential(ref, previousCredential);
222
+ }
223
+ else {
224
+ await host.removeCredential(ref);
225
+ }
226
+ notify(t('provider-rollback-ok'));
227
+ }
228
+ catch {
229
+ notify(t('provider-rollback-failed'), { color: 'warning' });
230
+ }
231
+ }
232
+ const err = error instanceof Error ? error.message : String(error);
233
+ notify(t('provider-write-failed', { err }), { color: 'error', timeoutMs: 8000 });
234
+ return 'failed';
235
+ }
236
+ // ── 9. success: transcript summary + optional live switch ──────────
237
+ pushLocal('/provider', [
238
+ ...summaryLines,
239
+ ...(deps.working() || models.length === 0
240
+ ? [t('provider-switch-hint')]
241
+ : []),
242
+ ]);
243
+ notify(t('provider-success', { route }), { color: 'success' });
244
+ if (!deps.working() && models.length > 0) {
245
+ const target = models[0];
246
+ const switchAnswer = await ask({
247
+ questions: [optionQuestion('switch', t('provider-q-switch'), [
248
+ { label: t('provider-opt-switch-now', { model: target }) },
249
+ { label: t('provider-opt-switch-keep') },
250
+ ], { hideCustomInput: true })],
251
+ });
252
+ if (answerSelected(switchAnswer, 'switch')[0] === t('provider-opt-switch-now', { model: target })) {
253
+ await deps.switchModel(route, target);
254
+ }
255
+ }
256
+ return 'added';
257
+ }
258
+ catch (error) {
259
+ if (error instanceof UserQuestionError) {
260
+ notify(t('provider-cancelled'));
261
+ return 'cancelled';
262
+ }
263
+ const err = error instanceof Error ? error.message : String(error);
264
+ notify(t('provider-write-failed', { err }), { color: 'error', timeoutMs: 8000 });
265
+ return 'failed';
266
+ }
267
+ }
268
+ /** Prompt for a route id until it validates or the retry budget runs out. */
269
+ async function promptRouteId(ask, notify) {
270
+ for (let attempt = 0; attempt < MAX_RETRY; attempt += 1) {
271
+ const answer = await ask({
272
+ questions: [textQuestion('route-id', t('provider-q-route-id'), t('provider-q-route-id-detail'))],
273
+ });
274
+ const route = answerText(answer, 'route-id');
275
+ if (PROVIDER_ROUTE_ID.test(route))
276
+ return route;
277
+ notify(t('provider-route-id-invalid'), { color: 'warning' });
278
+ }
279
+ return '';
280
+ }
281
+ /** Merge multi-select picks with comma/space-separated custom input, deduped. */
282
+ function mergeModelIds(selected, custom) {
283
+ const ids = [...selected];
284
+ for (const piece of custom.split(/[,,\s]+/)) {
285
+ const id = piece.trim();
286
+ if (id !== '' && !ids.includes(id))
287
+ ids.push(id);
288
+ }
289
+ return ids;
290
+ }
291
+ function buildSummaryLines(input) {
292
+ const lines = [t('provider-line-route', { route: input.route })];
293
+ lines.push(input.shadowed
294
+ ? t('provider-line-keyref-env', { ref: input.ref })
295
+ : t('provider-line-keyref', { ref: input.ref }));
296
+ if (input.baseURL !== undefined && input.baseURL !== '') {
297
+ lines.push(t('provider-line-baseurl', { url: input.baseURL }));
298
+ }
299
+ if (input.api !== undefined)
300
+ lines.push(t('provider-line-protocol', { api: input.api }));
301
+ lines.push(input.models.length > 0
302
+ ? t('provider-line-models', { models: input.models.join(', ') })
303
+ : t('provider-line-models-catalog'));
304
+ return lines;
305
+ }
306
+ function buildProfile(input) {
307
+ const profile = { apiKeyEnv: input.ref };
308
+ if (input.baseURL !== undefined && input.baseURL !== '')
309
+ profile['baseURL'] = input.baseURL;
310
+ if (input.isCatalog) {
311
+ // `models` replaces the catalog when present; omit it to keep the whole
312
+ // catalog served.
313
+ if (input.models.length > 0) {
314
+ profile['models'] = input.models.map(id => ({ id }));
315
+ }
316
+ return profile;
317
+ }
318
+ profile['api'] = input.api;
319
+ profile['models'] = input.models.map(id => {
320
+ const discovered = input.discoveredById.get(id);
321
+ return {
322
+ id,
323
+ ...(discovered?.contextWindow !== undefined
324
+ ? { contextWindow: discovered.contextWindow }
325
+ : {}),
326
+ ...(discovered?.maxTokens !== undefined
327
+ ? { maxTokens: discovered.maxTokens }
328
+ : {}),
329
+ };
330
+ });
331
+ return profile;
332
+ }
@@ -74,12 +74,17 @@ export declare class QuestionStore {
74
74
  private rebuildSnapshot;
75
75
  /**
76
76
  * Provider entry point — called by `ctx.userQuestions.ask()` when the
77
- * model runs the `ask_user_question` tool.
77
+ * model runs the `ask_user_question` tool, and by local wizards (e.g.
78
+ * `/provider`) driving the same panel.
78
79
  * @param request - The ask request: questions plus optional abort signal.
80
+ * @param options - `redact` hides answer text from the transcript summary
81
+ * (use for batches that collect secrets such as API keys).
79
82
  * @returns A promise settling with the collected answers when the user
80
83
  * submits the batch, or rejecting when the ask is interrupted.
81
84
  */
82
- ask(request: AskUserQuestionRequest): Promise<AskUserQuestionAnswer>;
85
+ ask(request: AskUserQuestionRequest, options?: {
86
+ redact?: boolean;
87
+ }): Promise<AskUserQuestionAnswer>;
83
88
  /** Advance to the next queued ask, if any. */
84
89
  private startNext;
85
90
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/questions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AAExC;mEACmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAsBD,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAClC;AAqCD;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwB;IAC9C,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAI;IACpB,yEAAyE;IACzE,OAAO,CAAC,SAAS,CAAwB;IACzC;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAgC;IAErD;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C;;;OAGG;IACH,WAAW,IAAI,gBAAgB,GAAG,IAAI;IAItC;;;OAGG;IACH,aAAa,IAAI,eAAe,EAAE;IAMlC,OAAO,CAAC,IAAI;IAIZ,sEAAsE;IACtE,OAAO,CAAC,eAAe;IAgBvB;;;;;;;;;OASG;IACH,GAAG,CAAC,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA8BnE,8CAA8C;IAC9C,OAAO,CAAC,SAAS;IAOjB;;;;OAIG;IACH,aAAa,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAwBjD,6DAA6D;IAC7D,aAAa,IAAI,IAAI;IAUrB,+DAA+D;IAC/D,SAAS,IAAI,IAAI;IASjB,wEAAwE;IACxE,OAAO,CAAC,MAAM;IAOd,yEAAyE;IACzE,OAAO,CAAC,IAAI;CAMb"}
@@ -11,7 +11,7 @@
11
11
  * arrive one at a time in practice (the tool blocks until answered), but
12
12
  * concurrent asks from subagents are drained FIFO.
13
13
  */
14
- import { t } from './i18n.js';
14
+ import { t } from '../i18n.js';
15
15
  import { UserQuestionError, } from '@deepseek-ai/dsh-user-questions';
16
16
  const ASK_ABORTED = 'ASK_ABORTED';
17
17
  /**
@@ -30,10 +30,14 @@ function clip(text, max = 140) {
30
30
  function buildSummary(pending) {
31
31
  const lines = pending.answers.map(answer => {
32
32
  const question = pending.request.questions.find(q => q.id === answer.id);
33
- const labels = answer.selected.join('、');
34
- const text = answer.custom !== undefined && answer.custom !== ''
35
- ? labels === '' ? answer.custom : `${labels}:${answer.custom}`
36
- : labels;
33
+ const text = pending.redact
34
+ ? '••••••'
35
+ : (() => {
36
+ const labels = answer.selected.join('、');
37
+ return answer.custom !== undefined && answer.custom !== ''
38
+ ? labels === '' ? answer.custom : `${labels}:${answer.custom}`
39
+ : labels;
40
+ })();
37
41
  return `· ${question?.question ?? answer.id} → ${clip(text)}`;
38
42
  });
39
43
  const total = pending.request.questions.length;
@@ -109,18 +113,22 @@ export class QuestionStore {
109
113
  }
110
114
  /**
111
115
  * Provider entry point — called by `ctx.userQuestions.ask()` when the
112
- * model runs the `ask_user_question` tool.
116
+ * model runs the `ask_user_question` tool, and by local wizards (e.g.
117
+ * `/provider`) driving the same panel.
113
118
  * @param request - The ask request: questions plus optional abort signal.
119
+ * @param options - `redact` hides answer text from the transcript summary
120
+ * (use for batches that collect secrets such as API keys).
114
121
  * @returns A promise settling with the collected answers when the user
115
122
  * submits the batch, or rejecting when the ask is interrupted.
116
123
  */
117
- ask(request) {
124
+ ask(request, options) {
118
125
  return new Promise((resolve, reject) => {
119
126
  const pending = {
120
127
  request,
121
128
  batchId: ++this.batchSeq,
122
129
  index: 0,
123
130
  answers: [],
131
+ ...(options?.redact ? { redact: true } : {}),
124
132
  resolve,
125
133
  reject,
126
134
  onAbort: () => {
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Side Question (`/btw`) — CC's btw.tsx/sideQuestion.ts semantics on the
3
+ * dsh call primitives: a single-turn, TOOL-LESS LLM call replaying the
4
+ * live session's derived history (prompt-cache reuse, compaction-style
5
+ * auxiliary call) plus one wrapped user message. The answer never enters
6
+ * the session log — it is pure UI state in the Chat screen.
7
+ *
8
+ * @module
9
+ */
10
+ import { type StreamChunk } from '@deepseek-ai/dsh-llm';
11
+ /**
12
+ * Wrap a side question with the single-response, no-tools contract (CC's
13
+ * wording): a lightweight instance sharing the conversation context, the
14
+ * main agent uninterrupted, no promises of action, no looking things up.
15
+ */
16
+ export declare function wrapSideQuestion(question: string): string;
17
+ /** Outcome of one side question: the visible text answer, or an error. */
18
+ export interface SideQuestionOutcome {
19
+ answer: string | null;
20
+ error?: string;
21
+ }
22
+ /**
23
+ * Run one side-question call: stream the assembled options, fold chunks
24
+ * through the shared BlockAssembler, and surface the assembled text
25
+ * blocks as the answer. `onText` receives visible text deltas only
26
+ * (reasoning deltas are ignored — a side question wants the quick answer).
27
+ */
28
+ export declare function runSideQuestion(params: {
29
+ /** `ctx.llm.stream` (bound); the options below pass through verbatim. */
30
+ stream: (options: object) => AsyncIterable<StreamChunk>;
31
+ /** Assembled GenerateOptions — no `tools` field, ever. */
32
+ options: object;
33
+ /** Streaming display hook (text deltas only). */
34
+ onText?: (delta: string) => void;
35
+ /** Cancellation: aborting yields `{answer: null}` with no error text. */
36
+ signal?: AbortSignal;
37
+ }): Promise<SideQuestionOutcome>;
38
+ //# sourceMappingURL=sideQuestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sideQuestion.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/sideQuestion.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEvE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBzD;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,yEAAyE;IACzE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,aAAa,CAAC,WAAW,CAAC,CAAA;IACvD,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,yEAAyE;IACzE,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB/B"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Side Question (`/btw`) — CC's btw.tsx/sideQuestion.ts semantics on the
3
+ * dsh call primitives: a single-turn, TOOL-LESS LLM call replaying the
4
+ * live session's derived history (prompt-cache reuse, compaction-style
5
+ * auxiliary call) plus one wrapped user message. The answer never enters
6
+ * the session log — it is pure UI state in the Chat screen.
7
+ *
8
+ * @module
9
+ */
10
+ import { BlockAssembler } from '@deepseek-ai/dsh-llm';
11
+ /**
12
+ * Wrap a side question with the single-response, no-tools contract (CC's
13
+ * wording): a lightweight instance sharing the conversation context, the
14
+ * main agent uninterrupted, no promises of action, no looking things up.
15
+ */
16
+ export function wrapSideQuestion(question) {
17
+ return `<system-reminder>This is a side question from the user. You must answer this question directly in a single response.
18
+
19
+ IMPORTANT CONTEXT:
20
+ - You are a separate, lightweight agent spawned to answer this one question
21
+ - The main agent is NOT interrupted - it continues working independently in the background
22
+ - You share the conversation context but are a completely separate instance
23
+ - Do NOT reference being interrupted or what you were "previously doing" - that framing is incorrect
24
+
25
+ CRITICAL CONSTRAINTS:
26
+ - You have NO tools available - you cannot read files, run commands, search, or take any actions
27
+ - This is a one-off response - there will be no follow-up turns
28
+ - You can ONLY provide information based on what you already know from the conversation context
29
+ - NEVER say things like "Let me try...", "I'll now...", "Let me check...", or promise to take any action
30
+ - If you don't know the answer, say so - do not offer to look it up or investigate
31
+
32
+ Simply answer the question with the information you have.</system-reminder>
33
+
34
+ ${question}`;
35
+ }
36
+ /**
37
+ * Run one side-question call: stream the assembled options, fold chunks
38
+ * through the shared BlockAssembler, and surface the assembled text
39
+ * blocks as the answer. `onText` receives visible text deltas only
40
+ * (reasoning deltas are ignored — a side question wants the quick answer).
41
+ */
42
+ export async function runSideQuestion(params) {
43
+ const { stream, options, onText, signal } = params;
44
+ const assembler = new BlockAssembler();
45
+ try {
46
+ for await (const chunk of stream(options)) {
47
+ assembler.push(chunk);
48
+ if (chunk.type === 'text-delta' && chunk.text)
49
+ onText?.(chunk.text);
50
+ }
51
+ }
52
+ catch (error) {
53
+ if (signal?.aborted)
54
+ return { answer: null };
55
+ return { answer: null, error: error instanceof Error ? error.message : String(error) };
56
+ }
57
+ const finish = assembler.finish;
58
+ if (finish.kind === 'error' || finish.kind === 'aborted') {
59
+ return { answer: null, error: finish.failure.message };
60
+ }
61
+ const answer = assembler.blocks()
62
+ .filter((block) => block.type === 'text')
63
+ .map(block => block.text)
64
+ .join('')
65
+ .trim();
66
+ if (answer === '')
67
+ return { answer: null, error: 'No response received' };
68
+ return { answer };
69
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Trajectory aggregate — the hotspot view's data and the session totals.
3
+ *
4
+ * The ledger answers "what happened, in order". This module answers the other
5
+ * question a long session raises: **where did the time go**. Chronological
6
+ * order is the worst order for that, so everything here is grouped and ranked
7
+ * instead: cost per tool, cost per model phase (decode vs. waiting for the
8
+ * first token vs. retry backoff), cost per turn.
9
+ *
10
+ * Three details make the numbers trustworthy rather than merely plausible:
11
+ *
12
+ * - **Own duration only.** A turn's cost is its own bracket, never the sum of
13
+ * its children — summing both would double-count every tool inside it.
14
+ * - **No fabricated spans.** A step that produced no `assistant/chunk` (the
15
+ * request failed, or the log predates chunk capture) contributes no TTFT and
16
+ * no decode sample rather than a zero that would drag the average down.
17
+ * - **Bursts expand.** A folded run is one ledger row but N calls; the counts
18
+ * and totals here are over calls, so `count` matches what actually ran.
19
+ */
20
+ import type { HotspotRow, HotspotSort, TrajAggregate, TrajNode } from './types.js';
21
+ import type { TrajBuild } from './projection.js';
22
+ /**
23
+ * Visit every logical call in ledger order, expanding burst rows.
24
+ *
25
+ * @param nodes - The folded ledger.
26
+ * @param visit - Receives each call node plus the ledger index of the row it
27
+ * is displayed under (the burst row's index, for folded members).
28
+ */
29
+ export declare function forEachCall(nodes: readonly TrajNode[], visit: (node: TrajNode, ledgerIndex: number) => void): void;
30
+ /**
31
+ * Rank hotspot rows by the active sort key.
32
+ *
33
+ * Ties break on label so the order is total — an unstable order would make
34
+ * rows jump between frames while the session streams.
35
+ */
36
+ export declare function sortRows(rows: readonly HotspotRow[], sort: HotspotSort): HotspotRow[];
37
+ /**
38
+ * Derive the hotspot groups and session totals from a projection.
39
+ *
40
+ * @param build - The current projection.
41
+ * @param sort - Ranking key for the tool and turn groups.
42
+ * @returns Ranked groups plus the counters the scene header and status badge
43
+ * read. Pure: nothing here mutates the build.
44
+ */
45
+ export declare function aggregate(build: TrajBuild, sort?: HotspotSort): TrajAggregate;
46
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/trajectory/aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAA0B,MAAM,YAAY,CAAA;AAC1G,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAK5D;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GACnD,IAAI,CASN;AAqCD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,EAAE,CAIrF;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,GAAE,WAAwB,GAAG,aAAa,CAuGzF"}