@deepseek-harness-tui/dsh-tui 0.9.3 → 0.10.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/README.md +24 -6
  2. package/cordis.patch.yml +117 -39
  3. package/cordis.yml +13 -10
  4. package/lib/types/api.d.ts +7 -0
  5. package/lib/types/api.d.ts.map +1 -0
  6. package/lib/types/api.js +1 -0
  7. package/lib/types/cc/hyperlink.d.ts.map +1 -1
  8. package/lib/types/cc/hyperlink.js +42 -4
  9. package/lib/types/cc/markdown.d.ts.map +1 -1
  10. package/lib/types/cc/markdown.js +15 -5
  11. package/lib/types/commands.d.ts +6 -0
  12. package/lib/types/commands.d.ts.map +1 -1
  13. package/lib/types/commands.js +12 -8
  14. package/lib/types/components/MessageList.d.ts +4 -4
  15. package/lib/types/components/MessageList.d.ts.map +1 -1
  16. package/lib/types/components/MessageList.js +30 -29
  17. package/lib/types/components/PermissionsPicker.d.ts +6 -7
  18. package/lib/types/components/PermissionsPicker.d.ts.map +1 -1
  19. package/lib/types/components/PermissionsPicker.js +20 -14
  20. package/lib/types/components/PromptEditor.d.ts +46 -0
  21. package/lib/types/components/PromptEditor.d.ts.map +1 -0
  22. package/lib/types/components/PromptEditor.js +60 -0
  23. package/lib/types/components/PromptInput.d.ts +12 -0
  24. package/lib/types/components/PromptInput.d.ts.map +1 -1
  25. package/lib/types/components/PromptInput.js +1240 -205
  26. package/lib/types/components/RewindPicker.js +1 -1
  27. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  28. package/lib/types/components/StreamingMarkdown.js +140 -3
  29. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  30. package/lib/types/components/SubagentDashboard.js +2 -2
  31. package/lib/types/components/SubagentDetailScene.js +1 -1
  32. package/lib/types/components/ThemePicker.d.ts +13 -15
  33. package/lib/types/components/ThemePicker.d.ts.map +1 -1
  34. package/lib/types/components/ThemePicker.js +24 -26
  35. package/lib/types/components/Tooltip.d.ts +67 -0
  36. package/lib/types/components/Tooltip.d.ts.map +1 -0
  37. package/lib/types/components/Tooltip.js +220 -0
  38. package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
  39. package/lib/types/components/approvals/ApprovalPanel.js +1 -1
  40. package/lib/types/components/design-system/Divider.d.ts +9 -1
  41. package/lib/types/components/design-system/Divider.d.ts.map +1 -1
  42. package/lib/types/components/design-system/Divider.js +42 -8
  43. package/lib/types/components/design-system/ThemeProvider.d.ts +5 -2
  44. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  45. package/lib/types/components/design-system/ThemeProvider.js +52 -16
  46. package/lib/types/components/design-system/ThemedBox.d.ts +23 -2
  47. package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -1
  48. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -5
  49. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  50. package/lib/types/components/messages/AssistantThinkingMessage.js +4 -4
  51. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  52. package/lib/types/components/messages/AssistantToolUseMessage.js +15 -4
  53. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  54. package/lib/types/components/messages/UserPromptMessage.js +7 -1
  55. package/lib/types/components/questions/AskUserQuestionPanel.js +1 -1
  56. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  57. package/lib/types/components/questions/PlanReviewPanel.js +29 -3
  58. package/lib/types/components/sessions/SessionListRow.d.ts +8 -1
  59. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
  60. package/lib/types/components/sessions/SessionListRow.js +9 -2
  61. package/lib/types/components/sessions/SessionPreview.d.ts.map +1 -1
  62. package/lib/types/components/sessions/SessionPreview.js +5 -3
  63. package/lib/types/components/sessions/WorkspaceListRow.d.ts +17 -0
  64. package/lib/types/components/sessions/WorkspaceListRow.d.ts.map +1 -0
  65. package/lib/types/components/sessions/WorkspaceListRow.js +27 -0
  66. package/lib/types/customTheme.d.ts +4 -0
  67. package/lib/types/customTheme.d.ts.map +1 -1
  68. package/lib/types/customTheme.js +9 -5
  69. package/lib/types/dsh-adapter/approvals.d.ts +114 -2
  70. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
  71. package/lib/types/dsh-adapter/approvals.js +241 -3
  72. package/lib/types/dsh-adapter/channel.d.ts +42 -2
  73. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  74. package/lib/types/dsh-adapter/channel.js +483 -79
  75. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  76. package/lib/types/dsh-adapter/childStderr.js +9 -0
  77. package/lib/types/dsh-adapter/contract.d.ts +17 -13
  78. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  79. package/lib/types/dsh-adapter/contract.js +36 -27
  80. package/lib/types/dsh-adapter/credentialRefGuard.d.ts +40 -0
  81. package/lib/types/dsh-adapter/credentialRefGuard.d.ts.map +1 -0
  82. package/lib/types/dsh-adapter/credentialRefGuard.js +43 -0
  83. package/lib/types/dsh-adapter/effect-ledger.d.ts +1 -1
  84. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  85. package/lib/types/dsh-adapter/effect-ledger.js +1 -0
  86. package/lib/types/dsh-adapter/extensions.d.ts +4 -1
  87. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -1
  88. package/lib/types/dsh-adapter/extensions.js +8 -1
  89. package/lib/types/dsh-adapter/index.d.ts +6 -1
  90. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  91. package/lib/types/dsh-adapter/index.js +1 -0
  92. package/lib/types/dsh-adapter/plugin-test-utils.d.ts +62 -0
  93. package/lib/types/dsh-adapter/plugin-test-utils.d.ts.map +1 -0
  94. package/lib/types/dsh-adapter/plugin-test-utils.js +61 -0
  95. package/lib/types/dsh-adapter/plugin.d.ts +20 -0
  96. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  97. package/lib/types/dsh-adapter/plugin.js +158 -39
  98. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
  99. package/lib/types/dsh-adapter/plugins-info.js +12 -0
  100. package/lib/types/dsh-adapter/preset-resolution.d.ts +49 -0
  101. package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -0
  102. package/lib/types/dsh-adapter/preset-resolution.js +42 -0
  103. package/lib/types/dsh-adapter/presets.d.ts +0 -26
  104. package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
  105. package/lib/types/dsh-adapter/presets.js +4 -14
  106. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  107. package/lib/types/dsh-adapter/promptDebug.js +4 -1
  108. package/lib/types/dsh-adapter/providerGuard.d.ts +75 -0
  109. package/lib/types/dsh-adapter/providerGuard.d.ts.map +1 -0
  110. package/lib/types/dsh-adapter/providerGuard.js +104 -0
  111. package/lib/types/dsh-adapter/questions-answerer.d.ts +49 -0
  112. package/lib/types/dsh-adapter/questions-answerer.d.ts.map +1 -0
  113. package/lib/types/dsh-adapter/questions-answerer.js +61 -0
  114. package/lib/types/dsh-adapter/recap.d.ts.map +1 -1
  115. package/lib/types/dsh-adapter/recap.js +12 -6
  116. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -1
  117. package/lib/types/dsh-adapter/sanitize.js +6 -1
  118. package/lib/types/dsh-adapter/sessions/digest.d.ts +21 -1
  119. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  120. package/lib/types/dsh-adapter/sessions/digest.js +229 -3
  121. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -0
  122. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  123. package/lib/types/dsh-adapter/sessions/frames.js +34 -19
  124. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  125. package/lib/types/dsh-adapter/sessions/list.js +148 -31
  126. package/lib/types/dsh-adapter/sessions/store.d.ts +8 -0
  127. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  128. package/lib/types/dsh-adapter/sessions/store.js +24 -4
  129. package/lib/types/dsh-adapter/sessions/types.d.ts +3 -0
  130. package/lib/types/dsh-adapter/sessions/types.d.ts.map +1 -1
  131. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/settings-sections.js +13 -1
  133. package/lib/types/dsh-adapter/settingsEditor.d.ts +6 -0
  134. package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -1
  135. package/lib/types/dsh-adapter/settingsEditor.js +15 -3
  136. package/lib/types/dsh-adapter/subagents.d.ts +4 -0
  137. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  138. package/lib/types/dsh-adapter/subagents.js +8 -0
  139. package/lib/types/dsh-adapter/themes.d.ts +51 -0
  140. package/lib/types/dsh-adapter/themes.d.ts.map +1 -0
  141. package/lib/types/dsh-adapter/themes.js +272 -0
  142. package/lib/types/dsh-adapter/toast.d.ts +67 -0
  143. package/lib/types/dsh-adapter/toast.d.ts.map +1 -0
  144. package/lib/types/dsh-adapter/toast.js +141 -0
  145. package/lib/types/dsh-adapter/types.d.ts +1 -1
  146. package/lib/types/extensions.d.ts +4 -0
  147. package/lib/types/extensions.d.ts.map +1 -1
  148. package/lib/types/extensions.js +5 -1
  149. package/lib/types/history.d.ts.map +1 -1
  150. package/lib/types/history.js +7 -2
  151. package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts +10 -0
  152. package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts.map +1 -0
  153. package/lib/types/hooks/useRuntimeThemeSnapshot.js +32 -0
  154. package/lib/types/i18n.d.ts +199 -41
  155. package/lib/types/i18n.d.ts.map +1 -1
  156. package/lib/types/i18n.js +82 -20
  157. package/lib/types/ink/components/App.d.ts +20 -0
  158. package/lib/types/ink/components/App.d.ts.map +1 -1
  159. package/lib/types/ink/components/App.js +142 -13
  160. package/lib/types/ink/components/Box.d.ts +39 -2
  161. package/lib/types/ink/components/Box.d.ts.map +1 -1
  162. package/lib/types/ink/components/Box.js +61 -37
  163. package/lib/types/ink/events/context-menu-event.d.ts +19 -0
  164. package/lib/types/ink/events/context-menu-event.d.ts.map +1 -0
  165. package/lib/types/ink/events/context-menu-event.js +20 -0
  166. package/lib/types/ink/events/drag-event.d.ts +44 -0
  167. package/lib/types/ink/events/drag-event.d.ts.map +1 -0
  168. package/lib/types/ink/events/drag-event.js +39 -0
  169. package/lib/types/ink/events/event-handlers.d.ts +8 -0
  170. package/lib/types/ink/events/event-handlers.d.ts.map +1 -1
  171. package/lib/types/ink/events/event-handlers.js +8 -0
  172. package/lib/types/ink/hit-test.d.ts +69 -0
  173. package/lib/types/ink/hit-test.d.ts.map +1 -1
  174. package/lib/types/ink/hit-test.js +260 -6
  175. package/lib/types/ink/ink.d.ts +25 -0
  176. package/lib/types/ink/ink.d.ts.map +1 -1
  177. package/lib/types/ink/ink.js +74 -10
  178. package/lib/types/ink/parse-keypress.d.ts +2 -0
  179. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  180. package/lib/types/ink/parse-keypress.js +12 -15
  181. package/lib/types/ink/renderer.d.ts.map +1 -1
  182. package/lib/types/ink/renderer.js +7 -0
  183. package/lib/types/ink/screen.d.ts +7 -0
  184. package/lib/types/ink/screen.d.ts.map +1 -1
  185. package/lib/types/ink/screen.js +8 -1
  186. package/lib/types/ink/termio/osc.d.ts +2 -1
  187. package/lib/types/ink/termio/osc.d.ts.map +1 -1
  188. package/lib/types/ink/termio/osc.js +26 -5
  189. package/lib/types/plugin-spec/registry.d.ts +1 -1
  190. package/lib/types/plugin-spec/registry.js +1 -1
  191. package/lib/types/presetPrefs.d.ts +6 -5
  192. package/lib/types/presetPrefs.d.ts.map +1 -1
  193. package/lib/types/presetPrefs.js +10 -5
  194. package/lib/types/screens/Chat.d.ts +4 -1
  195. package/lib/types/screens/Chat.d.ts.map +1 -1
  196. package/lib/types/screens/Chat.js +169 -68
  197. package/lib/types/screens/SessionBrowser.d.ts +9 -4
  198. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  199. package/lib/types/screens/SessionBrowser.js +483 -75
  200. package/lib/types/screens/SessionTree.d.ts.map +1 -1
  201. package/lib/types/screens/SessionTree.js +5 -1
  202. package/lib/types/screens/Settings.d.ts.map +1 -1
  203. package/lib/types/screens/Settings.js +5 -1
  204. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  205. package/lib/types/screens/StatusLine.js +5 -1
  206. package/lib/types/screens/chatOverlay.d.ts +3 -2
  207. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  208. package/lib/types/screens/chatOverlay.js +2 -0
  209. package/lib/types/sessionPins.d.ts +33 -0
  210. package/lib/types/sessionPins.d.ts.map +1 -0
  211. package/lib/types/sessionPins.js +181 -0
  212. package/lib/types/sessions/format.d.ts +2 -0
  213. package/lib/types/sessions/format.d.ts.map +1 -1
  214. package/lib/types/sessions/format.js +9 -0
  215. package/lib/types/sessions/view.d.ts +42 -6
  216. package/lib/types/sessions/view.d.ts.map +1 -1
  217. package/lib/types/sessions/view.js +133 -35
  218. package/lib/types/test-utils.d.ts +2 -0
  219. package/lib/types/test-utils.d.ts.map +1 -0
  220. package/lib/types/test-utils.js +8 -0
  221. package/lib/types/theme.d.ts +22 -5
  222. package/lib/types/theme.d.ts.map +1 -1
  223. package/lib/types/theme.js +57 -7
  224. package/lib/types/themeCatalog.d.ts +36 -0
  225. package/lib/types/themeCatalog.d.ts.map +1 -0
  226. package/lib/types/themeCatalog.js +157 -0
  227. package/lib/types/tips.d.ts.map +1 -1
  228. package/lib/types/tips.js +114 -18
  229. package/lib/types/update.d.ts +159 -3
  230. package/lib/types/update.d.ts.map +1 -1
  231. package/lib/types/update.js +497 -16
  232. package/lib/types/utils/debug.d.ts.map +1 -1
  233. package/lib/types/utils/debug.js +2 -1
  234. package/lib/types/utils/keymap.d.ts +1 -1
  235. package/lib/types/utils/keymap.d.ts.map +1 -1
  236. package/lib/types/utils/keymap.js +19 -2
  237. package/lib/types/utils/urlGuard.d.ts +28 -0
  238. package/lib/types/utils/urlGuard.d.ts.map +1 -0
  239. package/lib/types/utils/urlGuard.js +21 -0
  240. package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +3 -0
  241. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/credentials.d.ts +7 -11
  242. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.d.ts +16 -1
  243. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/index.js +23 -2
  244. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.d.ts +5 -5
  245. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/pi-ai.d.ts +23 -0
  246. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/pi-ai.js +27 -0
  247. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.d.ts +17 -3
  248. package/node_modules/@deepseek-harness-tui/dsh-auth/lib/profiles.js +36 -4
  249. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +11 -12
  250. package/package.json +113 -74
  251. package/lib/types/dsh-adapter/packaged-skills.d.ts +0 -19
  252. package/lib/types/dsh-adapter/packaged-skills.d.ts.map +0 -1
  253. package/lib/types/dsh-adapter/packaged-skills.js +0 -78
  254. package/skills/audit/SKILL.md +0 -24
  255. package/skills/bug/SKILL.md +0 -27
  256. package/skills/pr-comments/SKILL.md +0 -20
  257. package/skills/practice/SKILL.md +0 -22
  258. package/skills/release-notes/SKILL.md +0 -25
  259. package/skills/review/SKILL.md +0 -25
  260. package/skills/vuln-check/SKILL.md +0 -25
package/README.md CHANGED
@@ -53,9 +53,10 @@
53
53
  ## 核心能力
54
54
 
55
55
  - **终端交互**:低资源占用,长会话稳定可靠;多种主题切换,样式美观,实时显示工作状态、TPS、缓存命中率等
56
- 推理等级、输入/输出 token 与 Git/会话信息;终端卡多行命令可经 `/settings` 折叠为首行 + 计数提示(Ctrl+O 或点击卡片展开)。
57
- - **功能全面**:`/resume`、`/new`、`/compact`、`/export`、`/btw`,模型热切换,原生subagent,会话fork,自动更新;可在vs code中[以vscode插件形式启动](docs/vscode.md),已上架 VS Code Marketplace。
56
+ 推理等级、输入/输出 token 与 Git/会话信息;终端卡多行命令可经 `/settings` 折叠为首行 + 计数提示(Ctrl+O 或点击卡片展开);全屏模式下悬停在截断的工具卡标题、用户消息或会话标题上约 600ms,浮层显示完整内容。
57
+ - **功能全面**:`/resume` 按工作目录分类浏览、搜索与预览历史会话(左键恢复、右键弹出操作菜单;可固定常用会话——「已固定」分组置顶显示,行内 ★ 或 `Ctrl+P` 切换,持久化到 `~/.dsh-tui`),另有 `/new`、`/compact`、`/export`、`/btw`,模型热切换,原生subagent,会话fork,自动更新,输入框 `/vim` vim 编辑模式、鼠标选区编辑(拖选高亮、Shift+click 扩展、双击选词、Ctrl+C 复制选区)与全屏草稿编辑(`Ctrl+Shift+E` 或输入行 `⛶` 按钮:行号 + 当前行高亮、Enter 换行、Ctrl+Enter 发送、滚轮滚动、点击/拖选,长草稿独占整屏;`/settings` 可关);可在vs code中[以vscode插件形式启动](docs/vscode.md),已上架 VS Code Marketplace。
58
58
  - **扩展丰富**:原生浏览器交互,compter use等大量附属功能性扩展
59
+ - **技能归 DSH 管理**:`/skills` 展示当前 profile、用户与项目发现的技能;dsh-TUI 不预装通用技能。
59
60
 
60
61
 
61
62
 
@@ -129,6 +130,20 @@ sh install.sh
129
130
  - **模板仓库**:[plugin-template](https://github.com/dsh-tui-ecosystem/plugin-template)(从模板起步,5 分钟出一个插件)
130
131
  - **参考实现**:`dsh-working-activity`(实时工作状态行:TUI 槽位 + `activity/status` 会话事件双出口)
131
132
 
133
+ ### 接缝稳定性参考
134
+
135
+ 按当前实现成熟度给出的**非正式**分级,帮助插件作者评估投入;正式状态与兼容性协定以
136
+ [准入与开发指南](https://github.com/T-Auto/dsh-ecosystem-spec/blob/main/docs/plugin-admission-and-development.md)为准:
137
+
138
+ | 分级 | 接缝 |
139
+ | --- | --- |
140
+ | 稳定候选(形态冻结;如有破坏性变更,先在次版本弃用告警再移除) | 六 设置区块 · 八 全屏场景 · 十 托管对话框 · 十一 状态行 · 十二 键盘快捷键 · 十三 条目渲染器 |
141
+ | 实验性(仍可能随 dsh-std / 准入规范演进调整) | 九 决策事件 · toast 通知(`ctx.tuiToast`,新增) |
142
+ | 跟随上游(稳定性由 cordis / dsh 官方机制决定) | 一 会话事件 · 二 官方 prompt 槽位 · 三 技能打包 · 四 主题 · 五 system prompt 段 · 七 profile 组合 |
143
+
144
+ 另:`@deepseek-harness-tui/dsh-tui/test-utils`(headless 准入/挂载测试助手)与
145
+ `@deepseek-harness-tui/dsh-tui/api`(纯类型入口)为实验性公开面。
146
+
132
147
 
133
148
 
134
149
  ## 文档索引
@@ -137,7 +152,7 @@ sh install.sh
137
152
  | --- | --- |
138
153
  | [安装与快速开始](docs/getting-started.md) | 前置条件、安装、启动、profile 生命周期、源码开发 |
139
154
  | [配置参考](docs/configuration.md) | Cordis 覆盖、配置字段、Agent preset、MCP、环境变量 |
140
- | [主题系统](docs/themes.md) | 内置主题、自动检测、自定义 JSON 主题与校验规则 |
155
+ | [主题系统](docs/themes.md) | 内置主题、自动检测、静态 JSON 与 npm 插件主题、校验规则 |
141
156
  | [交互与命令](docs/interaction.md) | 快捷键、鼠标、问卷、slash command 与会话工作流 |
142
157
  | [架构与限制](docs/architecture.md) | 运行链路、渲染与持久化设计、安全边界、已知限制 |
143
158
  | [VS Code 使用指南](docs/vscode.md) | 在 VS Code 集成终端运行 dsh-tui;companion 扩展 `dsh-tui-vscode` 提供与 Claude Code 官方扩展几乎一致的体验(已上架 Marketplace) |
@@ -152,16 +167,19 @@ sh install.sh
152
167
 
153
168
  - **生态组织**:[dsh-tui-ecosystem](https://github.com/dsh-tui-ecosystem) —— 社区插件、模板与收录列表的家。欢迎来发插件、提创意、互相取暖 🐋
154
169
  - **社区交流群**:使用问题、插件创意、功能许愿,都欢迎进来聊。
170
+ - **行为准则**:参与前请读一遍[贡献者行为准则](CODE_OF_CONDUCT.md)。
155
171
 
156
- | 微信群 | QQ 群(群号 572549239) | 微信三群 |
172
+ | 微信群 | QQ 群(群号 572549239) | 微信四群 |
157
173
  | :---: | :---: | :---: |
158
- | <img src="screenshots/wechat-group.jpg" alt="dsh-TUI 社区交流群微信群二维码" width="200"> | <img src="screenshots/qq-group.png" alt="dsh-TUI 社区交流群 QQ 群二维码" width="200"> | <img src="screenshots/wechat-group3.jpg" alt="dsh-TUI 社区交流群微信三群二维码" width="200"> |
174
+ | <img src="screenshots/wechat-group.jpg" alt="dsh-TUI 社区交流群微信群二维码" width="200"> | <img src="screenshots/qq-group.png" alt="dsh-TUI 社区交流群 QQ 群二维码" width="200"> | <img src="screenshots/wechat-group4.jpg" alt="dsh-TUI 社区交流四群微信群二维码" width="200"> |
159
175
 
160
176
  > 微信群二维码约 7 天过期一次,如遇失效请走 QQ 群(572549239),或开个 issue 提醒我们更新。
161
177
 
162
178
  ## 权限与安全边界
163
179
 
164
- `dsh-TUI` 不实现独立沙箱,而是使用当前 DSH profile 的文件、Shell、sandbox 与 approval 策略。仓库提供的 profile 在非 Windows 平台默认采用工作区约束与审批;Windows 当前没有对应的沙箱后端,组合会退回到 `danger-full-access` 且不弹审批。在包含敏感凭证或不可信仓库的环境中启动前,请先检查 profile 配置。
180
+ > **Windows 安全警告:** Windows profile 默认使用 `danger-full-access`,且 approval 默认是 `never`。这会授予工具不受限制的访问权限;在敏感凭证或不可信仓库环境中启动前,务必先检查并收紧 profile 配置。
181
+
182
+ `dsh-TUI` 不实现独立沙箱,而是使用当前 DSH profile 的文件、Shell、sandbox 与 approval 策略。权限预设来自 DSH `permissionPresets` registry:服务缺失时使用 legacy 三项兼容名册;服务已挂载但为空、损坏或不一致时标记为 unavailable,TUI fail closed,不伪造名册。可用 registry 按声明顺序提供第三方预设,只有符合既有 command-token 语法的 ID 才进入补全,`custom` 只显示为当前态,不是可选择目标;切换始终走官方 `/permission <preset>` 命令。若外部 `/permission` 命令本身未注册,输入沿用现有默认命令/model dispatch。在包含敏感凭证或不可信仓库的环境中启动前,请先检查 profile 配置。
165
183
 
166
184
  详见[权限边界与已知限制](docs/architecture.md#权限与安全边界)。
167
185
 
package/cordis.patch.yml CHANGED
@@ -7,7 +7,7 @@
7
7
  # restates every key it owns (see the dsh-base patch for the shared
8
8
  # defaults). The dsh-base core rows that need no dsh-tui value — tools,
9
9
  # sandbox/approval policy, skills, goal, plan mode, workspace context,
10
- # telemetry — are inherited unchanged.
10
+ # telemetry — are inherited unless this surface explicitly restates them.
11
11
 
12
12
  # ── surface-specific values over the dsh-base layer ─────────────────────────
13
13
 
@@ -37,18 +37,39 @@
37
37
  config:
38
38
  agents: []
39
39
 
40
+ # Preserve the TUI's opt-in privacy stance across the alpha base default
41
+ # change to FEEDBACK_ONLY. An explicit DSH_TELEMETRY_MODE still wins. This
42
+ # restates the whole alpha config because include patches replace config
43
+ # objects rather than merging them.
44
+ - id: session-telemetry-otel
45
+ config:
46
+ mode: !!js process.env.DSH_TELEMETRY_MODE || 'DISABLED'
47
+ shutdownTimeoutMillis: 3000
48
+ exporter:
49
+ url: !!js process.env.DSH_TELEMETRY_OTLP_URL ?? 'https://harness-telemetry.deepseeksvc.com/v1/logs'
50
+ compression: gzip
51
+ timeoutMillis: 1000
52
+ processor:
53
+ scheduledDelayMillis: 10000
54
+ maxQueueSize: 2048
55
+ maxExportBatchSize: 2048
56
+ exportTimeoutMillis: 1500
57
+
58
+ # The alpha base sends the active Loader package inventory on official
59
+ # DeepSeek requests by default. TUI keeps that diagnostic metadata opt-in.
60
+ - id: plugin-package-inventory-deepseek
61
+ config:
62
+ enabled: false
63
+
40
64
  # ── agent presets (issue #8) ────────────────────────────────────────────────
41
65
  #
42
66
  # The model-facing plugin set moves INTO the agent-presets roster: every
43
67
  # session composes its tools/prompt sections from one preset directory
44
- # (standard/code/minimal/cordis) instead of the host rows below. The TUI's
45
- # roster row uses the scoped `dsh-tui-agent-presets` id and carries the
46
- # shipped `config/agent-presets/` system root itself (derived from the dsh
47
- # CLI installation through the launcher-maintained `profiles/node_modules`
48
- # fallback link), because the official profile-boot root overlay only targets
49
- # the unscoped `agent-presets` id that surface bundles own. The roster itself
50
- # appends `$DSH_HOME/.agent-presets` (user-authored presets,
51
- # `includeUserRoot` default). Mirroring the official dsh-web-app patch: every
68
+ # (standard/ptc/minimal/cordis) instead of the host rows below. The TUI's
69
+ # roster row uses the scoped `dsh-tui-agent-presets` id. alpha packages prepend
70
+ # their bundled system root; the validated rc line still needs the dsh CLI's
71
+ # `config/agent-presets/` directory supplied explicitly. Both append
72
+ # `$DSH_HOME/.agent-presets`. Mirroring the official dsh-web-app patch: every
52
73
  # dsh-base row a preset now owns is disabled here, so a minimal agent does not
53
74
  # leak host-layer tools (an agent's registry view resolves agent → preset →
54
75
  # global).
@@ -59,7 +80,7 @@
59
80
  - id: command-compact
60
81
  disabled: true
61
82
 
62
- # compaction lives in the preset's own isolate realm (standard/code/cordis
83
+ # compaction lives in the preset's own isolate realm (standard/ptc/cordis
63
84
  # carry `compaction-basic` with package defaults; minimal has none). The
64
85
  # CC_TUI_COMPACT_RATIO/CC_TUI_COMPACT_RETAIN tunables retired with this host
65
86
  # row — preset compositions own their compaction config.
@@ -81,6 +102,27 @@
81
102
  - id: tool-fs-search
82
103
  disabled: true
83
104
 
105
+ - id: command-goal
106
+ # rc.2 presets do not carry this command, so their host row must remain
107
+ # active. alpha disables it only when the shipped standard preset really
108
+ # owns the command; reading the capability avoids guessing from another
109
+ # optional Loader row.
110
+ disabled: !!js >-
111
+ (() => {
112
+ const require = process.getBuiltinModule('node:module').createRequire(ctx.baseUrl)
113
+ const fs = process.getBuiltinModule('node:fs')
114
+ const path = process.getBuiltinModule('node:path')
115
+ try {
116
+ const manifest = require.resolve('@deepseek-ai/dsh-agent-presets/package.json')
117
+ const preset = path.join(path.dirname(manifest), 'presets', 'standard', 'agent.cordis.yml')
118
+ return fs.readFileSync(preset, 'utf8')
119
+ .split(/\r?\n/u)
120
+ .some(line => line.trim() === '- id: command-goal')
121
+ } catch {
122
+ return false
123
+ }
124
+ })()
125
+
84
126
  - id: tool-goal
85
127
  disabled: true
86
128
 
@@ -158,16 +200,17 @@
158
200
  # semantics would create a duplicate row. dsh-tui defensively creates the
159
201
  # service on its own context when no composition provides it (bare
160
202
  # `dsh --config cordis.yml` boots), then mounts the model-facing
161
- # ask_user_question tool and registers the questionnaire provider on
162
- # `ctx.userQuestions`.
203
+ # ask_user_question tool. On legacy hosts it registers the TUI provider on
204
+ # `ctx.userQuestions`; on Alpha it answers the scoped
205
+ # `user-questions/request` waterfall.
163
206
 
164
207
  - insert:
165
208
  # Workspace grouping is a separate durable ledger, not a cwd-derived
166
209
  # projection. Mount the same domain stack and storage root as dsh-web-app
167
210
  # so TUI-created sessions can attach to the exact registry Web reads.
168
211
  #
169
- # The six rows below own host-plane services that the official web-app
170
- # bundle may already mount. Loader entry ids are process-global, so these
212
+ # These rows own host-plane services that the official web-app bundle may
213
+ # already mount. Loader entry ids are process-global, so these
171
214
  # rows use dsh-tui-* scoped ids and self-disable when an enabled row with
172
215
  # the official id/name is already present in the tree. The disabled check
173
216
  # is evaluated during the same include update that inserts every row, so
@@ -188,10 +231,38 @@
188
231
  config:
189
232
  backend: json
190
233
 
234
+ # Alpha moved the durable storage stack into dsh-base, so these three
235
+ # scoped copies self-disable there. Keep them for the validated rc lines,
236
+ # whose base layer does not provide the stack to a TUI-only profile.
237
+
191
238
  - id: dsh-tui-workspace
192
239
  name: '@deepseek-ai/dsh-workspace'
193
240
  disabled: !!js "[...ctx.loader.entries()].some(entry => entry.options.id === 'workspace' && entry.options.name === '@deepseek-ai/dsh-workspace' && !entry.disabled)"
194
241
 
242
+ # PTC presentation waits on this Host service. The scoped row supports a
243
+ # TUI-only profile and yields to the official web-app row in mixed profiles.
244
+ - id: dsh-tui-code-runtime
245
+ name: '@deepseek-ai/dsh-code-runtime-worker-thread'
246
+ disabled: !!js "[...ctx.loader.entries()].some(entry => entry.options.id === 'code-runtime' && entry.options.name === '@deepseek-ai/dsh-code-runtime-worker-thread' && !entry.disabled)"
247
+
248
+ # Alpha presets opt their delegation tool into Host-owned model-selection
249
+ # settings. Without this service standard/ptc/cordis preset mounting fails.
250
+ # The package subpath does not exist on rc.2, so resolve that capability
251
+ # directly before Loader attempts the import. An enabled official row still
252
+ # owns the seat in mixed profiles.
253
+ - id: dsh-tui-subagent-model-selection-settings
254
+ name: '@deepseek-ai/dsh-tool-subagent/model-selection-settings'
255
+ disabled: !!js >-
256
+ (() => {
257
+ const require = process.getBuiltinModule('node:module').createRequire(ctx.baseUrl)
258
+ try {
259
+ require.resolve('@deepseek-ai/dsh-tool-subagent/model-selection-settings')
260
+ } catch {
261
+ return true
262
+ }
263
+ return [...ctx.loader.entries()].some(entry => entry.options.id === 'subagent-model-selection-settings' && entry.options.name === '@deepseek-ai/dsh-tool-subagent/model-selection-settings' && !entry.disabled)
264
+ })()
265
+
195
266
  # Generic terminal workspace registry. Optional plugins add providers;
196
267
  # the TUI itself always supplies LOCAL and has no provider-specific code.
197
268
  - id: dsh-tui-workspaces
@@ -231,27 +302,35 @@
231
302
  name: '@deepseek-harness-tui/dsh-tui/extensions'
232
303
 
233
304
  # The agent-preset roster (issue #8): `ctx.agentPresets`, the service the
234
- # TUI composes every session's model-facing world from. The scoped row
235
- # carries the official CLI's shipped `config/agent-presets/` directory
236
- # (standard/code/minimal/cordis, system trust) through the
237
- # launcher-maintained profiles/node_modules fallback link; the roster
238
- # itself appends `$DSH_HOME/.agent-presets` (user-authored presets,
239
- # `includeUserRoot` default). A boot that never reached profile-boot
240
- # leaves the system root empty and the roster finds only user presets.
305
+ # TUI composes every session's model-facing world from. alpha packages
306
+ # prepend their bundled presets as the read-only system root; rc.2 packages
307
+ # have no bundled root and still scan the dsh CLI directory. Both append
308
+ # `$DSH_HOME/.agent-presets` as the user root. Deployment-added roots may
309
+ # still be supplied by a later patch.
241
310
  - id: dsh-tui-agent-presets
242
311
  name: '@deepseek-ai/dsh-agent-presets'
243
312
  disabled: !!js "[...ctx.loader.entries()].some(entry => entry.options.id === 'agent-presets' && entry.options.name === '@deepseek-ai/dsh-agent-presets' && !entry.disabled)"
244
- config:
245
- default: standard
246
- roots: !!js >-
247
- (() => {
248
- const base = ctx.baseUrl
249
- if (!base) return undefined
250
- const root = new URL('../node_modules/@deepseek-ai/dsh/config/agent-presets/', base)
251
- let path = decodeURIComponent(root.pathname)
252
- if (/^\/[A-Za-z]:/.test(path)) path = path.slice(1)
253
- return [{ path, trust: 'system' }]
254
- })()
313
+ config: !!js >-
314
+ (() => {
315
+ const require = process.getBuiltinModule('node:module').createRequire(ctx.baseUrl)
316
+ const fs = process.getBuiltinModule('node:fs')
317
+ const path = process.getBuiltinModule('node:path')
318
+ try {
319
+ const manifest = require.resolve('@deepseek-ai/dsh-agent-presets/package.json')
320
+ if (fs.existsSync(path.join(path.dirname(manifest), 'presets'))) {
321
+ return { default: 'standard' }
322
+ }
323
+ } catch {
324
+ // Let the roster import report a missing package; preserve the rc
325
+ // root fallback below for every package generation without one.
326
+ }
327
+ const base = ctx.baseUrl
328
+ if (!base) return { default: 'standard' }
329
+ const root = new URL('../node_modules/@deepseek-ai/dsh/config/agent-presets/', base)
330
+ let rootPath = decodeURIComponent(root.pathname)
331
+ if (/^\/[A-Za-z]:/.test(rootPath)) rootPath = rootPath.slice(1)
332
+ return { default: 'standard', roots: [{ path: rootPath, trust: 'system' }] }
333
+ })()
255
334
 
256
335
  # Host-plane services the `cordis` preset's plugin-experimentation tool
257
336
  # waits on (dynamicCordisRunner/cordisInspect); dsh-base carries no such
@@ -281,10 +360,11 @@
281
360
  name: '@deepseek-harness-tui/dsh-tui'
282
361
  # The entry-level dependency augments the plugin's `agents` inject and
283
362
  # prevents startup Session creation from racing WorkspaceRegistry init.
284
- inject: [workspaceRegistry, agents, tuiWorkspaces, tuiScenes, tuiDialogs, tuiStatus, tuiShortcuts, tuiRenderers]
285
- # `tuiWorkspaces`/`tuiScenes` (and the dsh-tui-extensions services)
286
- # live in the entry-level inject ONLY as an
287
- # ordering (and reload-rebind) guarantee alongside their service rows
363
+ inject: [workspaceRegistry, agents, tuiWorkspaces, tuiScenes, tuiDialogs, tuiStatus, tuiShortcuts, tuiRenderers, tuiThemes]
364
+ # `tuiWorkspaces`/`tuiScenes` (and the dsh-tui-extensions services,
365
+ # including `tuiThemes`)
366
+ # live in the entry-level inject ONLY as an ordering (and reload-rebind)
367
+ # guarantee alongside their service rows
288
368
  # above — they are deliberately absent from the plugin's code-level
289
369
  # inject (issue #183): the dsh CLI may read this patch from an older
290
370
  # copy of the package than the plugin module it loads, and a hard
@@ -306,9 +386,7 @@
306
386
  # split(强制双栏)/ unified(强制统一式)。/settings 屏可实时改。
307
387
  # diffLayout: auto
308
388
  # 每个请求实际生效的推理强度,按当前路由的 adapter 档位校验
309
- # (deepseek: off/high/max)——不在档位表里的值被忽略,回落 adapter
310
- # 默认值。优先于持久化的 Shift+Tab 选择(~/.dsh-tui/effort.json);
311
- # 同时作为顶栏/状态栏的启动显示,首个请求头回来后以实际值为准。
389
+ #(deepseek: off/low/high/max);非法值回落 adapter 默认。
312
390
  effort: max
313
391
  # Shift+Tab session-mode cycle (array order IS the cycle order;
314
392
  # absent → the built-in default/plan/full trio below). Each entry
package/cordis.yml CHANGED
@@ -3,9 +3,10 @@
3
3
  # Requires DEEPSEEK_API_KEY; a terminal TTY is mandatory.
4
4
 
5
5
  # The user-interaction service: hosts `ctx.userQuestions`, the seam behind
6
- # the model-facing ask_user_question tool. dsh-tui registers its questionnaire
7
- # provider on it; the service must live at the root so the agent loop's tool
8
- # execution can reach it.
6
+ # the model-facing ask_user_question tool. dsh-tui uses the legacy provider
7
+ # API when present, otherwise the scoped user-questions/request waterfall;
8
+ # the service must live at the root so the agent loop's tool execution can
9
+ # reach it.
9
10
  - id: user-questions
10
11
  name: '@deepseek-ai/dsh-user-questions'
11
12
 
@@ -43,14 +44,17 @@
43
44
  name: '@deepseek-harness-tui/dsh-tui/plugin-host'
44
45
 
45
46
  # Plugin-facing UI seams: managed dialogs, status-line contributions,
46
- # keyboard shortcuts, custom session-entry renderers (decision events are
47
- # fired by the channel and need no row).
47
+ # keyboard shortcuts, custom session-entry renderers, and runtime themes
48
+ # (decision events are fired by the channel and need no row).
48
49
  - id: dsh-tui-extensions
49
50
  name: '@deepseek-harness-tui/dsh-tui/extensions'
50
51
 
51
52
  - id: dsh-tui
52
53
  name: '@deepseek-harness-tui/dsh-tui'
53
- inject: [agents, tuiWorkspaces, tuiScenes, tuiDialogs, tuiStatus, tuiShortcuts, tuiRenderers]
54
+ # Entry-level only: orders/rebinds optional extension services on reload;
55
+ # dsh-tui does not hard-inject them at code level, so stale profiles degrade
56
+ # to static themes and inert extension surfaces instead of deadlocking boot.
57
+ inject: [agents, tuiWorkspaces, tuiScenes, tuiDialogs, tuiStatus, tuiShortcuts, tuiRenderers, tuiThemes]
54
58
  config:
55
59
  provider: deepseek-official
56
60
  # Alt-screen fullscreen (CC 同款): 应用内鼠标选区(选择即复制, OSC 52 +
@@ -58,10 +62,9 @@
58
62
  # inline 渲染, 鼠标交给终端模拟器原生选择。
59
63
  fullscreen: true
60
64
  # Reasoning effort applied to every request, validated against the live
61
- # route's adapter levels (deepseek: off/high/max) — an unlisted level is
62
- # ignored and the adapter default applies. Wins over the persisted
63
- # Shift+Tab choice (~/.dsh-tui/effort.json); also seeds the startup
64
- # header/statusline until the first request header reports the live value.
65
+ # route's adapter levels. An unlisted level falls back to the adapter
66
+ # default; this wins over the persisted /effort choice and seeds the
67
+ # startup header/statusline.
65
68
  effort: max
66
69
  # Shift+Tab 会话模式循环(数组顺序即循环顺序;缺省为下面三档)。
67
70
  # 每档可声明 plan(计划模式开/关)、sandbox(read-only/
@@ -0,0 +1,7 @@
1
+ export type { TuiDecisionContext, TuiInputEvent, TuiInputDecision, TuiRewindPromptEvent, TuiRewindMode, TuiRewindPromptDecision, TuiRewindDoneEvent, TuiSessionSwitchEvent, TuiSessionSwitchDecision, TuiSessionSwitchedEvent, TuiCompactEvent, TuiCompactDecision, TuiDialogAnswer, TuiDialogBase, TuiDialogConfirmRequest, TuiDialogInputRequest, TuiDialogSelectOption, TuiDialogSelectRequest, TuiDialogSnapshot, TuiStatusEntry, TuiShortcutKey, TuiShortcutOptions, TuiEntryRenderer, TuiEntryRenderResult, TuiToastDelivery, TuiToastOptions, TuiToastSink, } from './extensions.js';
2
+ export type { GrantPrincipal, GrantStore, HostContract, HostDescriptor, ContractCoordinate, ContractRef, NegotiationDecision, PermissionEntry, PermissionRegistry, TuiPluginStorage, PluginStorageErrorCode, TuiPluginStorageRuntime, MessagesObserveContentBlock, MessagesObserveEnvelope, MessagesObserveListener, MessagesObservePayload, TuiMessageObserverRuntime, LedgerEntry, LedgerOperation, LedgerResult, TuiEffectLedgerRuntime, CommandErrorCode, CodedCommandError, } from './plugin-host.js';
3
+ export type { TuiSceneProps, TuiSceneDescriptor } from './scenes.js';
4
+ export type { TuiSettingsFieldKind, TuiSettingsFieldOption, TuiSettingsGroup, TuiSettingsFieldWrite, TuiSettingsField, TuiSettingsSection, } from './settings-sections.js';
5
+ export type { TuiCommandTreeProvider } from './command-trees.js';
6
+ export type { TuiWorkspaceKind, TuiWorkspaceTarget, TuiWorkspaceChoice, TuiWorkspaceCommandResult, TuiWorkspaceCommand, TuiCommandShell, TuiWorkspaceProvider, } from './workspaces.js';
7
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAQA,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,YAAY,GACb,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,WAAW,EACX,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AACpE,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAChE,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACrB,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1 @@
1
- {"version":3,"file":"hyperlink.d.ts","sourceRoot":"","sources":["../../../src/cc/hyperlink.ts"],"names":[],"mappings":"AAMA,0EAA0E;AAC1E,eAAO,MAAM,UAAU,eAAa,CAAA;AACpC,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,WAAS,CAAA;AAE9B,KAAK,gBAAgB,GAAG;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACjC,CAAA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAYR"}
1
+ {"version":3,"file":"hyperlink.d.ts","sourceRoot":"","sources":["../../../src/cc/hyperlink.ts"],"names":[],"mappings":"AAMA,0EAA0E;AAC1E,eAAO,MAAM,UAAU,eAAa,CAAA;AACpC,2FAA2F;AAC3F,eAAO,MAAM,QAAQ,WAAS,CAAA;AAE9B,KAAK,gBAAgB,GAAG;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CACjC,CAAA;AAkCD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACzB,MAAM,CAqBR"}
@@ -7,6 +7,35 @@ import { supportsHyperlinks } from '../ink/supports-hyperlinks.js';
7
7
  export const OSC8_START = '\x1b]8;;';
8
8
  /** OSC 8 hyperlink terminator: BEL (`\x07`), more widely supported than the ST variant. */
9
9
  export const OSC8_END = '\x07';
10
+ /** Schemes a rendered hyperlink may point at. Anything else degrades to
11
+ * plain display text: link targets come from model output and file
12
+ * contents, and an arbitrary scheme would reach the OS handler on click. */
13
+ const HYPERLINK_SCHEMES = new Set(['http:', 'https:', 'dsh-file:', 'file:', 'mailto:']);
14
+ // Control characters never legitimately appear in a URL; stripping them
15
+ // before the scheme check keeps `java\x00script:` from passing as a
16
+ // relative reference and keeps the embedded URL 7-bit clean (the osc()
17
+ // exit strips again — this is the entry side of the same defense). Spaces
18
+ // are stripped for the scheme check but preserved as %20 in the embedded
19
+ // URL — deleting them would retarget `file:///C:/My Project/x`.
20
+ const URL_CONTROL_CHARS = /[\x00-\x1f\x7f-\x9f]/g;
21
+ function sanitizeHyperlinkUrl(raw) {
22
+ const stripped = raw.replace(URL_CONTROL_CHARS, '');
23
+ const scheme = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(stripped);
24
+ if (scheme === null)
25
+ return null;
26
+ if (!HYPERLINK_SCHEMES.has(`${scheme[1].toLowerCase()}:`))
27
+ return null;
28
+ return stripped.replaceAll(' ', '%20');
29
+ }
30
+ // Display text keeps spaces (legitimate in link labels) but drops every
31
+ // escape sequence and leftover control character: an OSC 8 sequence
32
+ // smuggled into `content` would survive the plain-text wrap verbatim,
33
+ // hijack cell.hyperlink after tokenize, and repaint a phish link over the
34
+ // legitimate URL. Stripping COMPLETE ANSI sequences (not just the ESC byte)
35
+ // also keeps the display clean when a caller passes an already-painted
36
+ // string — the SGR parameter text would otherwise appear on screen as
37
+ // literal `[38;2;…m` garbage.
38
+ const DISPLAY_TEXT_CONTROL_CHARS = /[\u001b\u009b][[\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><~]|\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)|[\x00-\x1f\x7f-\x9f]/g;
10
39
  /**
11
40
  * Create a clickable hyperlink using OSC 8 escape sequences.
12
41
  * Falls back to plain text if the terminal doesn't support hyperlinks.
@@ -20,13 +49,22 @@ export const OSC8_END = '\x07';
20
49
  */
21
50
  export function createHyperlink(url, content, options) {
22
51
  const hasSupport = options?.supportsHyperlinks ?? supportsHyperlinks();
23
- if (!hasSupport) {
24
- return url;
52
+ const safeUrl = sanitizeHyperlinkUrl(url);
53
+ // Sanitized up front so BOTH degrade paths emit clean text too: non-TTY
54
+ // and log destinations bypass the cell-layer escape stripping, so a raw
55
+ // url/content with control characters would escape there.
56
+ const safeContent = content?.replace(DISPLAY_TEXT_CONTROL_CHARS, '');
57
+ if (!hasSupport || safeUrl === null) {
58
+ // Degrade to the plain display text — for a rejected scheme that is
59
+ // the content alone (never the raw url: `javascript:...` must not
60
+ // reach the screen either), for a supported terminal it is the
61
+ // control-stripped url (safeUrl).
62
+ return safeUrl === null ? (safeContent ?? '') : safeUrl;
25
63
  }
26
64
  // Apply basic ANSI blue color - wrap-ansi preserves this across line breaks
27
65
  // RGB colors (like theme colors) are NOT preserved by wrap-ansi with OSC 8
28
- const displayText = content ?? url;
66
+ const displayText = safeContent ?? safeUrl;
29
67
  const style = options?.style ?? ((text) => chalk.blue(text));
30
68
  const coloredText = style(displayText);
31
- return `${OSC8_START}${url}${OSC8_END}${coloredText}${OSC8_START}${OSC8_END}`;
69
+ return `${OSC8_START}${safeUrl}${OSC8_END}${coloredText}${OSC8_START}${OSC8_END}`;
32
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../src/cc/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAA4B,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;AAO1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA6BrD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAWtC;AAsED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,EACZ,SAAS,SAAI,EACb,iBAAiB,GAAE,MAAM,GAAG,IAAW,EACvC,MAAM,GAAE,KAAK,GAAG,IAAW,EAC3B,SAAS,GAAE,YAAY,GAAG,IAAW,GACpC,MAAM,CAER;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,YAAY,GAAG,IAAW,GACpC,MAAM,CAgBR;AA2SD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GACpD,MAAM,CAUR"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../src/cc/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAA4B,KAAK,KAAK,EAAe,MAAM,QAAQ,CAAA;AAO1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AA6BrD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO1D;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAWtC;AA0ED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,KAAK,EACZ,SAAS,SAAI,EACb,iBAAiB,GAAE,MAAM,GAAG,IAAW,EACvC,MAAM,GAAE,KAAK,GAAG,IAAW,EAC3B,SAAS,GAAE,YAAY,GAAG,IAAW,GACpC,MAAM,CAER;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,YAAY,GAAG,IAAW,GACpC,MAAM,CAgBR;AA2SD;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GACpD,MAAM,CAUR"}
@@ -47,6 +47,12 @@ const ISSUE_REFERENCE_PATTERN = /(^|[^\w./-])([A-Za-z0-9][\w-]*\/[A-Za-z0-9][\w.
47
47
  * @returns The content with those blocks removed and whitespace trimmed.
48
48
  */
49
49
  export function stripPromptXMLTags(content) {
50
+ // Every alternative in the pattern is anchored on a literal '<', so content
51
+ // without one cannot match. Skip the regex entirely in that case: the
52
+ // backreference defeats most of the engine's fast paths, and streaming
53
+ // re-runs this over the whole accumulated message on every frame.
54
+ if (!content.includes('<'))
55
+ return content.trim();
50
56
  return content.replace(TOOL_ANALYSIS_TAG_BLOCKS, '').trim();
51
57
  }
52
58
  let markedInitialized = false;
@@ -79,13 +85,17 @@ function paintInlineCode(text) {
79
85
  * without OSC 8 support keep the plain painted code span.
80
86
  */
81
87
  function renderCodeSpan(token) {
82
- const painted = paintInlineCode(token.text);
88
+ // Paint via the style callback so the permission color is applied AFTER
89
+ // createHyperlink's anti-smuggle content scrub: passing the painted
90
+ // string as content would have its ESC bytes stripped, leaving
91
+ // `[38;2;…m` parameter text on screen.
92
+ const paint = (text) => paintInlineCode(text);
83
93
  if (!looksLikeFilePath(token.text))
84
- return painted;
94
+ return paint(token.text);
85
95
  if (!supportsHyperlinks())
86
- return painted;
87
- return createHyperlink(fileLinkUrl(token.text), painted, {
88
- style: (text) => text,
96
+ return paint(token.text);
97
+ return createHyperlink(fileLinkUrl(token.text), token.text, {
98
+ style: paint,
89
99
  });
90
100
  }
91
101
  /**
@@ -48,6 +48,12 @@ export interface CommandCompletion extends LocalCommand {
48
48
  descriptionKey?: string;
49
49
  }
50
50
  export type CommandChildren = (canonicalPath: readonly string[]) => readonly CommandCompletionNode[];
51
+ /**
52
+ * Whether a value can occupy one command-completion token. Keep this aligned
53
+ * with the grammar accepted by {@link completeCommands}; callers that need an
54
+ * empty prefix handle that case separately.
55
+ */
56
+ export declare function isCommandCompletionToken(value: string): boolean;
51
57
  /**
52
58
  * The built-in slash commands (name + description pairs). Plugin-registered
53
59
  * commands merge in at runtime; locals win on name collisions.
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EA+DxC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAElD,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAEpD,CAAA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,YAAY,EAAE,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,SAAS,YAAY,EAAmB,EAC/C,QAAQ,GAAE,eAA0B,GACnC,iBAAiB,EAAE,CAuCrB"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/commands.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAElF,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,+EAA+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,KAAK,SAAS,qBAAqB,EAAE,CAAA;AAEpG;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EA2DxC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAElD,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAEpD,CAAA;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAIhG;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,OAAO,CAKT;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,YAAY,EAAmB,GAC7C,YAAY,EAAE,CAKhB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,SAAS,YAAY,EAAmB,EAC/C,QAAQ,GAAE,eAA0B,GACnC,iBAAiB,EAAE,CAuCrB"}
@@ -7,6 +7,14 @@
7
7
  * handler winning for names both sides declare.
8
8
  */
9
9
  import { getLang, tOr } from './i18n.js';
10
+ /**
11
+ * Whether a value can occupy one command-completion token. Keep this aligned
12
+ * with the grammar accepted by {@link completeCommands}; callers that need an
13
+ * empty prefix handle that case separately.
14
+ */
15
+ export function isCommandCompletionToken(value) {
16
+ return /^[a-z0-9_.:\/-]+$/iu.test(value);
17
+ }
10
18
  /**
11
19
  * The built-in slash commands (name + description pairs). Plugin-registered
12
20
  * commands merge in at runtime; locals win on name collisions.
@@ -56,12 +64,8 @@ export const LOCAL_COMMANDS = [
56
64
  { name: 'skills', description: 'List available skills' },
57
65
  { name: 'plugins', description: 'Show plugin contract, grant, and ledger diagnostics' },
58
66
  { name: 'update', description: 'Update dsh-tui and restart' },
59
- // Built-in skills (audit/review/pr-comments/…) are NOT listed here: their
60
- // packaged SKILL.md files register through the DSH skill registry, and
61
- // refreshSkillCommands publishes each as a real command whose handler
62
- // injects the body host-side (#86/#496). A local entry of the same name
63
- // would win the collision filter and lock the skill onto the legacy
64
- // "activation prompt" path forever.
67
+ // Skills are discovered through the DSH registry and added at runtime.
68
+ // A local entry of the same name would win the collision filter.
65
69
  // Misc / not applicable on this leaf
66
70
  { name: 'vim', description: 'Toggle vim mode' },
67
71
  { name: 'terminal-setup', description: 'Show terminal setup instructions' },
@@ -161,7 +165,7 @@ export function completeCommands(input, roots = LOCAL_COMMANDS, children = () =>
161
165
  // Token charset includes `. : /` so provider/model specs (e.g.
162
166
  // `deepseek/deepseek-v4-flash`, `openai/gpt-4.1`) survive as ONE token —
163
167
  // the /model completion matches its candidates against the whole spec.
164
- if (!/^[a-z0-9_.:\/-]*(?:[\t ]+[a-z0-9_.:\/-]*)*$/iu.test(body))
168
+ if (!body.split(/[\t ]+/u).every(token => token === '' || isCommandCompletionToken(token)))
165
169
  return [];
166
170
  const trailingSeparator = /[\t ]$/u.test(body);
167
171
  const tokens = body.split(/[\t ]+/u);
@@ -180,7 +184,7 @@ export function completeCommands(input, roots = LOCAL_COMMANDS, children = () =>
180
184
  const normalizedPrefix = prefix.toLowerCase();
181
185
  return candidates.flatMap(candidate => {
182
186
  const completionToken = matchingCompletionToken(candidate, normalizedPrefix);
183
- if (completionToken === undefined)
187
+ if (completionToken === undefined || !isCommandCompletionToken(completionToken))
184
188
  return [];
185
189
  const path = [...tokens, completionToken];
186
190
  const commandLine = `/${path.join(' ')}`;
@@ -4,15 +4,15 @@ import type { ChatRow } from '../dsh-adapter/channel.js';
4
4
  import type { DOMElement } from '../ink/dom.js';
5
5
  import { type TimelineSnapshot } from '../ink/timeline-rail.js';
6
6
  import type { ToolBackground } from '../tuiDisplayPrefs.js';
7
- export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, streamFoldedRows, onToggleStreamFold, model, diffLayout, thinkingFold, toolBackground, foldTerminalCommand, activityFrames, showAll, onToggleAll, onLoadOlder, thinkingVisible, historyPaintEnabled, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, onTimeline, failureHintRowId, failureHint, onOpenSubagent, onOpenFile, }: {
7
+ export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, streamViewToggledRows, onToggleStreamView, model, diffLayout, thinkingFold, toolBackground, foldTerminalCommand, activityFrames, showAll, onToggleAll, onLoadOlder, thinkingVisible, historyPaintEnabled, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, onTimeline, failureHintRowId, failureHint, onOpenSubagent, onOpenFile, }: {
8
8
  rows: readonly ChatRow[];
9
9
  expanded: boolean;
10
10
  expandedRows: ReadonlySet<number>;
11
11
  selectedId: number | null;
12
12
  onToggleRow: (rowId: number) => void;
13
- /** 流式 reasoning 行被用户折叠(点击展开/折叠对流式行同样有效)。 */
14
- streamFoldedRows?: ReadonlySet<number>;
15
- onToggleStreamFold?: (rowId: number) => void;
13
+ /** 流式 reasoning 行相对 thinkingFold 默认视图的逐行切换。 */
14
+ streamViewToggledRows?: ReadonlySet<number>;
15
+ onToggleStreamView?: (rowId: number) => void;
16
16
  model: string;
17
17
  /** Edit/Write diff presentation preference (forwarded to tool cards). */
18
18
  diffLayout?: 'auto' | 'split' | 'unified';
@@ -1 +1 @@
1
- {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"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"}