@deepseek-harness-tui/dsh-tui 0.8.3 → 0.8.5

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 (198) hide show
  1. package/README.md +29 -10
  2. package/bin/dsh-tui.js +50 -11
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
  4. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
  6. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
  7. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
  8. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
  10. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
  11. package/dsh-ecosystem-spec/registry/README.md +14 -14
  12. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
  13. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
  14. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
  15. package/lib/types/activityPrefs.d.ts +10 -0
  16. package/lib/types/activityPrefs.d.ts.map +1 -1
  17. package/lib/types/activityPrefs.js +17 -0
  18. package/lib/types/commands.d.ts.map +1 -1
  19. package/lib/types/commands.js +1 -0
  20. package/lib/types/components/LogoV2.d.ts +4 -1
  21. package/lib/types/components/LogoV2.d.ts.map +1 -1
  22. package/lib/types/components/LogoV2.js +8 -3
  23. package/lib/types/components/MessageList.d.ts +4 -1
  24. package/lib/types/components/MessageList.d.ts.map +1 -1
  25. package/lib/types/components/MessageList.js +4 -4
  26. package/lib/types/components/PromptInput.d.ts.map +1 -1
  27. package/lib/types/components/PromptInput.js +1 -3
  28. package/lib/types/components/SplitDiffView.d.ts +3 -1
  29. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  30. package/lib/types/components/SplitDiffView.js +12 -5
  31. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  32. package/lib/types/components/StreamingMarkdown.js +10 -2
  33. package/lib/types/components/TipsPanel.d.ts +14 -0
  34. package/lib/types/components/TipsPanel.d.ts.map +1 -0
  35. package/lib/types/components/TipsPanel.js +37 -0
  36. package/lib/types/components/activityFrames.d.ts +7 -28
  37. package/lib/types/components/activityFrames.d.ts.map +1 -1
  38. package/lib/types/components/activityFrames.js +7 -84
  39. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  40. package/lib/types/components/messages/AssistantThinkingMessage.js +1 -1
  41. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +4 -1
  42. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  43. package/lib/types/components/messages/AssistantToolUseMessage.js +14 -3
  44. package/lib/types/dsh-adapter/channel.d.ts +17 -0
  45. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  46. package/lib/types/dsh-adapter/channel.js +169 -33
  47. package/lib/types/dsh-adapter/index.d.ts +5 -0
  48. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  49. package/lib/types/dsh-adapter/index.js +19 -0
  50. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  51. package/lib/types/dsh-adapter/plugin.js +176 -4
  52. package/lib/types/dsh-adapter/settings-sections.d.ts +13 -0
  53. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  54. package/lib/types/dsh-adapter/settings-sections.js +31 -6
  55. package/lib/types/effortPrefs.d.ts +7 -6
  56. package/lib/types/effortPrefs.d.ts.map +1 -1
  57. package/lib/types/effortPrefs.js +7 -6
  58. package/lib/types/i18n.d.ts +42 -14
  59. package/lib/types/i18n.d.ts.map +1 -1
  60. package/lib/types/i18n.js +11 -4
  61. package/lib/types/ink/ink.d.ts +10 -0
  62. package/lib/types/ink/ink.d.ts.map +1 -1
  63. package/lib/types/ink/ink.js +35 -1
  64. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  65. package/lib/types/ink/parse-keypress.js +15 -0
  66. package/lib/types/screens/Chat.d.ts.map +1 -1
  67. package/lib/types/screens/Chat.js +44 -7
  68. package/lib/types/screens/Settings.d.ts.map +1 -1
  69. package/lib/types/screens/Settings.js +109 -50
  70. package/lib/types/screens/StatusLine.d.ts +8 -0
  71. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  72. package/lib/types/screens/StatusLine.js +65 -42
  73. package/lib/types/settings-sections.d.ts +1 -1
  74. package/lib/types/settings-sections.d.ts.map +1 -1
  75. package/lib/types/tips.d.ts +30 -0
  76. package/lib/types/tips.d.ts.map +1 -0
  77. package/lib/types/tips.js +575 -0
  78. package/lib/types/tuiDisplayPrefs.d.ts +47 -0
  79. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
  80. package/lib/types/tuiDisplayPrefs.js +60 -0
  81. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
  82. package/node_modules/@dsh-std/command/LICENSE +21 -21
  83. package/node_modules/@dsh-std/command/README.md +26 -26
  84. package/node_modules/@dsh-std/command/README.zh.md +28 -28
  85. package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
  86. package/node_modules/@dsh-std/command/package.json +22 -22
  87. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  88. package/node_modules/@dsh-std/connection/LICENSE +21 -21
  89. package/node_modules/@dsh-std/connection/README.md +42 -42
  90. package/node_modules/@dsh-std/connection/README.zh.md +42 -42
  91. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  92. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  93. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  94. package/node_modules/@dsh-std/connection/package.json +20 -20
  95. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  96. package/node_modules/@dsh-std/core/LICENSE +21 -21
  97. package/node_modules/@dsh-std/core/README.md +13 -13
  98. package/node_modules/@dsh-std/core/README.zh.md +13 -13
  99. package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  100. package/node_modules/@dsh-std/core/package.json +21 -21
  101. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  102. package/node_modules/@dsh-std/manifest/LICENSE +21 -21
  103. package/node_modules/@dsh-std/manifest/README.md +5 -5
  104. package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  105. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  106. package/node_modules/@dsh-std/manifest/package.json +20 -20
  107. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  108. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
  109. package/node_modules/@dsh-std/messages/LICENSE +21 -21
  110. package/node_modules/@dsh-std/messages/README.md +5 -5
  111. package/node_modules/@dsh-std/messages/README.zh.md +7 -7
  112. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
  113. package/node_modules/@dsh-std/messages/package.json +20 -20
  114. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
  115. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  116. package/node_modules/@dsh-std/presentation/LICENSE +21 -21
  117. package/node_modules/@dsh-std/presentation/README.md +27 -27
  118. package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  119. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  120. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  121. package/node_modules/@dsh-std/presentation/package.json +25 -25
  122. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
  123. package/node_modules/@dsh-std/storage/LICENSE +21 -21
  124. package/node_modules/@dsh-std/storage/README.md +5 -5
  125. package/node_modules/@dsh-std/storage/README.zh.md +7 -7
  126. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
  127. package/node_modules/@dsh-std/storage/package.json +20 -20
  128. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
  129. package/package.json +8 -3
  130. package/presets/liangshen/.dsh-tui-managed.json +1 -1
  131. package/presets/liangshen/agent.cordis.yml +7 -5
  132. package/presets/liangshen/custom-bash.mjs +184 -9
  133. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  134. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
  135. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
  136. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
  137. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  138. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  139. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  140. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
  141. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  142. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
  143. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
  144. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
  145. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  146. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
  147. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
  148. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
  149. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
  150. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
  151. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
  152. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
  153. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
  154. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
  155. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
  156. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
  157. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
  158. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
  159. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  160. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -25
  161. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  162. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
  163. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
  164. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
  165. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  166. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
  167. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  168. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
  169. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
  170. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
  171. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  172. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
  173. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  174. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
  175. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
  176. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
  177. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  178. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
  179. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
  180. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
  181. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
  182. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
  183. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
  184. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  185. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
  186. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
  187. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  188. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
  189. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
  190. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
  191. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  192. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
  193. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
  194. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
  195. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
  196. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
  197. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
  198. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
package/README.md CHANGED
@@ -112,17 +112,26 @@ npm install -g @deepseek-harness-tui/dsh-tui@<profile-version>
112
112
 
113
113
  | 键 | 功能 |
114
114
  |---|---|
115
- | `Enter` | 发送(`Shift+Enter` 换行,无法上报修饰键时可用 `Ctrl+J`);命令菜单打开时执行选中项 |
115
+ | `Enter` | 空闲=发送(`Shift+Enter` 换行,无法上报修饰键时可用 `Ctrl+J`,mac Terminal.app 可用 `Option+Enter` 兜底,issue #110);**模型工作时=steer**(注入下一步边界,不中断);命令菜单打开时执行选中项 |
116
+ | `Ctrl+Enter`(⌘Enter) | **打断当前回合并立即发送**(interrupt) |
117
+ | `Alt+Up` | 把最后一条未处理消息取回输入框编辑(不中断回合) |
118
+ | `Tab` | 补全 `/` 命令或 `@` 文件(目录可继续深入);**模型工作时=follow-up**(排入当前回合之后) |
116
119
  | `Ctrl+C` | 中断当前回合;空闲时连按两次退出 |
117
120
  | `Esc` | 关闭命令/文件菜单;空闲双击清空输入;**空输入双击 = 时间回溯** |
118
121
  | `Ctrl+O` | 展开/收起详情(思考全文、工具参数与输出) |
119
122
  | `Ctrl+R` | 历史消息搜索 |
120
123
  | `/` | 会话内全文搜索(`n`/`N` 跳转) |
121
- | `Tab` / `Enter` | 命令 / `@` 文件补全(目录可继续深入) |
122
124
  | `Ctrl+V` | 粘贴文本或文件管理器中的文件;图片显示为 `[Image #N]` 并作为持久附件发送 |
123
125
  | `Ctrl+X` | 用 `$VISUAL`/`$EDITOR`(如 nvim)打开当前输入编辑,保存退出后回填 |
124
- | `?` | 快捷键菜单 |
126
+ | `?` | 快捷键菜单(仅输入框为空时响应) |
125
127
  | `Shift+↑` | 消息选择模式(Enter 展开单条) |
128
+ | `Ctrl+P` | 切换启动时 loaded-context 面板(面板在屏时有效) |
129
+ | `Home` / `End`、`Ctrl+A` / `Ctrl+E` | 逻辑行首 / 行尾;`Ctrl+E` 双义:输入框=行尾,转录中=展开/折叠隐藏的旧消息 |
130
+ | `Ctrl+←` / `Ctrl+→`(⌘←/→) | 按词跳转 |
131
+ | `Ctrl+U` / `Ctrl+K` | 删除光标前(至行首)/ 光标后(至行尾) |
132
+ | `Ctrl+W` | 删除前一个单词 |
133
+
134
+ **模型工作中的三态投递**:`Enter`=steer(注入下一步边界,不中断)· `Tab`=follow-up(排入当前回合之后)· `Ctrl+Enter`=interrupt(打断并立即发送)。
126
135
 
127
136
  **macOS 修饰键**:上表中 Windows/Linux 的 `Ctrl+<键>` 在 macOS 上同时可用 `⌘<键>`
128
137
  (如 `⌘V` 粘贴、`⌘O` 展开详情、`⌘Enter` 立即发送);仅 `Ctrl+C` / `Ctrl+D`
@@ -136,8 +145,13 @@ macOS 自带 Terminal.app 会自行消费 `⌘` 快捷键,请继续使用 `Ctr
136
145
  |---|---|
137
146
  | 拖拽选择 | 应用内文本选区,**松开即复制**(OSC 52 + `wl-copy`/`xclip`/`xsel` 原生兜底;tmux 内走 `load-buffer -w`),复制后自动取消选区并弹出「已复制 N 个字符」提示 |
138
147
  | 双击 / 三击 | 选词 / 选行,同样即选即复制 |
139
- | 滚轮 | 滚动消息列表 |
148
+ | 滚轮 | 滚动消息列表(±3 行/格) |
140
149
  | `Esc` | 拖拽进行中取消选区(不复制) |
150
+ | 单击消息行 | 展开/收起该行 |
151
+ | 单击「加载更早消息」/「ctrl+e 显示前 N 条」 | 加载更早消息 / 展开全部 |
152
+ | 单击 StickyHeader / 「↓ N new messages」 | 跳回固定消息处 / 滚动到底部 |
153
+ | 单击超链接 | 打开浏览器 |
154
+ | 键盘扩展选区 | 有选区时 `Shift+←/→/↑/↓/Home/End` 扩展/收缩(跨行环绕) |
141
155
 
142
156
  **问卷(模型发起 `ask_user_question` 时)**
143
157
 
@@ -147,19 +161,21 @@ macOS 自带 Terminal.app 会自行消费 `⌘` 快捷键,请继续使用 `Ctr
147
161
  | `Space` | 多选题勾选/取消 |
148
162
  | `Tab` | 切到自定义回答(不选选项直接打字) |
149
163
  | `Enter` | 提交当前选择 |
150
- | `Esc` | 中断提问(模型收到 ASK_ABORTED,可继续对话) |
164
+ | `Esc` / `Ctrl+C` | 取消整批提问(模型收到 ASK_CANCELLED,可继续对话) |
151
165
 
152
166
  **本地命令(CC 指令全集复刻,均走 DSH 官方链路)**
153
167
 
154
168
  | 分组 | 命令 |
155
169
  |---|---|
156
- | 会话 | `/new` 新会话 · `/resume` 会话浏览器(搜索、预览、跨项目、折叠子 agent 运行) · `/rename` 重命名会话 · `/workspace resume|rename|open` 管理工作区 · `/clear` 清屏 · `/compact` 压缩 · `/export` 导出 Markdown · `/trace` 轨迹场景(亦可 `Ctrl+T`) |
157
- | 状态 | `/context` 已加载上下文明细 · `/status` 会话信息 · `/cost` token 用量 · `/doctor` 环境自检 · `/config` 配置来源 · `/init` 创建 AGENTS.md |
158
- | 模型 | `/model` 选择器 · `/thinking` 思考显示 · `/tokens` token 明细 · `/theme` 主题选择器 · `/lang` 中英界面切换(`/settings` 中亦可选择) |
170
+ | 会话 | `/new` 新会话 · `/resume` 会话浏览器(搜索、预览、跨项目、折叠子 agent 运行) · `/rename` 重命名会话 · `/workspace resume|rename|open` 管理工作区 · `/clear` 清屏 · `/compact` 压缩 · `/export` 导出 Markdown · `/trace` 轨迹场景(亦可 `Ctrl+T`) · `/rewind` 回退选择器(同空输入双击 Esc 的时间回溯) · `/btw <问题>` 侧问(不打断主回合、不写历史) |
171
+ | 状态 | `/context` 已加载上下文明细 · `/status` 会话信息 · `/cost` token 用量 · `/doctor` 环境自检 · `/config` 配置来源 · `/init` 创建 AGENTS.md · `/settings` 设置面板(命名空间读取/编辑) |
172
+ | 模型 | `/model` 选择器(**切换 = fork 会话续聊,历史保留**) · `/effort` 推理强度(滑杆 / `status` / `<id>`) · `/preset` Agent 预设(**已开始会话不可切换**,blank-only) · `/thinking` 思考显示 · `/tokens` token 明细 · `/activity` 工作状态行动画(`frames <名>` / `status`) · `/theme` 主题选择器 · `/lang` 中英界面切换(`/settings` 中亦可选择) |
159
173
  | 账号/策略 | `/provider` 添加模型提供方 · `/login` 凭证状态 · `/logout` 登出说明 · `/permissions` 权限说明 · `/add-dir` 文件策略范围 · `/hooks` · `/mcp` |
160
174
  | 技能 | `/audit` 代码审计 · `/bug` bug 报告 · `/review` 代码评审 · `/practice` 编程练习 · `/pr_comments` PR 评论 · `/release-notes` 发布说明 · `/vuln-check` 漏洞检查 |
161
- | 其它 | `/agents` 子代理列表 · `/update` 自动更新并重启 · `/vim` · `/terminal-setup` · `/connect` · `/help` · `/exit` |
162
- | 注册表 | `/plan` `/goal`(DSH 命令注册表插件,随插件自动并入 `/` 菜单) |
175
+ | 其它 | `/agents` 子代理列表 · `/skills` 技能目录 · `/plugins check <路径>` 插件诊断 · `/update` 自动更新并重启 · `/vim` · `/terminal-setup` · `/connect` · `/help` · `/exit`(别名 `/quit` `/q`) |
176
+ | 注册表 | `/plan` `/goal` `/feedback` `/permission`(DSH 命令注册表插件,随插件自动并入 `/` 菜单) |
177
+
178
+ > 未知命令会作为普通消息发给模型(如 `/permission` 未挂载的组合里)。
163
179
 
164
180
  ## 插件生态
165
181
 
@@ -265,6 +281,9 @@ compaction 和持久化继续由 DSH 服务拥有。更详细的模块边界与
265
281
  未挂载该插件(无 `/permission` 命令)。
266
282
  - `/vim` `/connect` `/hooks` 为 CC 同名占位:对应能力在 DSH 侧无等价
267
283
  机制,命令会给出明确说明而非静默。
284
+ - `/thinking` 思考显示开关**不持久化**,重启或新会话回到默认。
285
+ - minimal preset 下 `/compact` 不可用(minimal 不组合 compaction)。
286
+ - `/update` 仅 `dsh --profile` 启动方式可用,回合运行中会拒绝。
268
287
 
269
288
  完整已知限制与安全边界见[架构与限制](docs/architecture.md)。
270
289
 
package/bin/dsh-tui.js CHANGED
@@ -64,6 +64,24 @@ const MSG = {
64
64
  en: `[dsh-tui] Plugin install failed. Retry manually later:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${ownVersion}`,
65
65
  zh: `[dsh-tui] 插件安装失败。可稍后手工重试:\n dsh plugin --profile ${PROFILE} add -w ${PACKAGE}@${ownVersion}`,
66
66
  },
67
+ // no-op 假成功(自举后复查发现判定文件依旧缺失):pnpm 把包文件残缺的
68
+ // profile 视为 already up to date,重装什么都不做却报告成功;继续启动
69
+ // 只会以 cannot resolve profile bundle 崩溃,而崩溃提示的 `plugin
70
+ // install` 同样 no-op——用户会陷入「每步都成功、每次都崩」的循环。
71
+ bootstrapUnreadable: {
72
+ en: dir =>
73
+ `[dsh-tui] install reported success but the plugin package is still unreadable under:\n` +
74
+ ` ${dir}\n` +
75
+ ` pnpm treats this half-installed profile as already up to date, so every retry\n` +
76
+ ` reports success while boot keeps failing. Recovery:\n` +
77
+ ` rm -rf ${dir} && dsh-tui`,
78
+ zh: dir =>
79
+ `[dsh-tui] 安装报告成功,但插件包仍不可读:\n` +
80
+ ` ${dir}\n` +
81
+ ` pnpm 把半残的 profile 视为已装好,重试永远「成功」而启动照旧崩溃。\n` +
82
+ ` 恢复方法:\n` +
83
+ ` rm -rf ${dir} 后重新运行 dsh-tui`,
84
+ },
67
85
  // Non-fatal skew comes in two directions and each needs its own repair:
68
86
  // a profile NEWER than the launcher (typical after /update) must point at
69
87
  // the global install, while a profile older only in patch must point back
@@ -158,11 +176,12 @@ const dshHome = process.env.DSH_HOME || join(homedir(), '.dsh')
158
176
  const profileDir = join(dshHome, 'profiles', PROFILE)
159
177
  // 以已装包的 package.json 可读为准(而非目录存在):安装中途失败留下的
160
178
  // 残骸目录会触发重新安装,而不是以坏 profile 直接启动。
179
+ // 包可读判定文件:installedVersion 读取与自举后的复查共用(残缺 profile
180
+ // 的 no-op 假成功靠它识别——见 bootstrapUnreadable)。
181
+ const installedPkgPath = join(profileDir, 'node_modules', '@deepseek-harness-tui', 'dsh-tui', 'package.json')
161
182
  let installedVersion
162
183
  try {
163
- installedVersion = JSON.parse(
164
- readFileSync(join(profileDir, 'node_modules', '@deepseek-harness-tui', 'dsh-tui', 'package.json'), 'utf8'),
165
- ).version
184
+ installedVersion = JSON.parse(readFileSync(installedPkgPath, 'utf8')).version
166
185
  } catch {
167
186
  installedVersion = undefined
168
187
  }
@@ -175,21 +194,41 @@ if (installedVersion === undefined) {
175
194
  console.log(msg('bootstrapStart'))
176
195
  // pnpm ≥11 在带 pnpm-workspace.yaml 的 profile 目录里可能拒绝向
177
196
  // workspace root 写依赖(ERR_PNPM_ADDING_TO_ROOT,issue #239):识别该
178
- // 错误时带 -w 重试一次。stderr 走 pipe 捕获供识别,stdout 保持
179
- // inherit 让用户实时看到安装进度;手工重试提示同步带 -w。
180
- const runAdd = extraArgs => spawnSync(
197
+ // 错误时带 -w 重试一次。签名在 stdout——pnpm 的错误报告写 stdout(经
198
+ // dsh 原样转发),stderr 上只有 dsh 自己的失败说明,识别 stderr 永远
199
+ // 匹配不到(PR #241 的回归)。因此首次 add 的 stdout/stderr 都走 pipe
200
+ // 捕获,结束后回放(失败回 stderr 保诊断,成功回 stdout 保进度,代价
201
+ // 是不再实时);-w 重试大概率成功,恢复 inherit 让进度实时可见。手工
202
+ // 重试提示同步带 -w。
203
+ const runAdd = (extraArgs, capture) => spawnSync(
181
204
  ...cmd('dsh', ['plugin', '--profile', PROFILE, 'add', ...extraArgs, `${PACKAGE}@${ownVersion}`]),
182
- { stdio: ['inherit', 'inherit', 'pipe'], ...shellOpt },
205
+ { stdio: capture ? ['inherit', 'pipe', 'pipe'] : 'inherit', ...shellOpt },
183
206
  )
184
- let add = runAdd([])
185
- if (add.status !== 0 && String(add.stderr).includes('ERR_PNPM_ADDING_TO_ROOT')) {
186
- console.log(msg('bootstrapRetryW'))
187
- add = runAdd(['-w'])
207
+ let add = runAdd([], true)
208
+ if (add.status !== 0) {
209
+ const captured = `${add.stdout ?? ''}${add.stderr ?? ''}`
210
+ process.stderr.write(captured)
211
+ if (captured.includes('ERR_PNPM_ADDING_TO_ROOT')) {
212
+ console.log(msg('bootstrapRetryW'))
213
+ add = runAdd(['-w'], false)
214
+ }
215
+ } else {
216
+ process.stdout.write(`${add.stdout ?? ''}${add.stderr ?? ''}`)
188
217
  }
189
218
  if (add.status !== 0) {
190
219
  console.error(msg('installFailed'))
191
220
  process.exit(add.status ?? 1)
192
221
  }
222
+ // 自举后复查:pnpm 对包文件残缺的 profile 视为 already up to date,
223
+ // add 报告成功却什么都没装(no-op 假成功)。此时继续启动只会以 cannot
224
+ // resolve profile bundle 崩溃,提示的 `plugin install` 又同样 no-op——
225
+ // fail loud 给出唯一可靠的恢复路径(删 profile 目录重建)。
226
+ try {
227
+ readFileSync(installedPkgPath, 'utf8')
228
+ } catch {
229
+ console.error(MSG.bootstrapUnreadable[lang](profileDir))
230
+ process.exit(1)
231
+ }
193
232
  } else if (installedVersion !== ownVersion) {
194
233
  // Reverse skew is fatal (see MSG.profileOlderThanLauncher): compare
195
234
  // major/minor only — patch-level differences never move the patch surface.
@@ -1,13 +1,13 @@
1
- import type { ApiReference, ProtocolCatalog, ProtocolDefinition } from '@dsh-std/core'
2
- export { registerTuiContributionExtensions } from './tui-contributions.js'
3
- export * from './tui-channel.js'
4
-
5
- export const DECISION_EVENTS: Readonly<ApiReference & {
6
- apiVersion: 'tui.dsh/v1alpha1'
7
- kind: 'DecisionEvents'
8
- }>
9
-
10
- export const decisionEventsDefinition: ProtocolDefinition
11
- export const profileDefinitions: readonly ProtocolDefinition[]
12
-
13
- export function registerProfileProtocols(catalog: ProtocolCatalog): () => void
1
+ import type { ApiReference, ProtocolCatalog, ProtocolDefinition } from '@dsh-std/core'
2
+ export { registerTuiContributionExtensions } from './tui-contributions.js'
3
+ export * from './tui-channel.js'
4
+
5
+ export const DECISION_EVENTS: Readonly<ApiReference & {
6
+ apiVersion: 'tui.dsh/v1alpha1'
7
+ kind: 'DecisionEvents'
8
+ }>
9
+
10
+ export const decisionEventsDefinition: ProtocolDefinition
11
+ export const profileDefinitions: readonly ProtocolDefinition[]
12
+
13
+ export function registerProfileProtocols(catalog: ProtocolCatalog): () => void
@@ -1,59 +1,59 @@
1
- /** dsh-TUI private protocol definitions evaluated by @dsh-std/core. */
2
-
3
- export { registerTuiContributionExtensions } from './tui-contributions.js'
4
- export * from './tui-channel.js'
5
- import { tuiChannelDefinition } from './tui-channel.js'
6
-
7
- export const DECISION_EVENTS = Object.freeze({
8
- apiVersion: 'tui.dsh/v1alpha1',
9
- kind: 'DecisionEvents',
10
- })
11
-
12
- function featureSupport(value, label) {
13
- if (value === undefined) return Object.freeze({ features: Object.freeze([]) })
14
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
15
- throw new TypeError(`${label} support spec must be an object`)
16
- }
17
- const unknown = Object.keys(value).filter(key => key !== 'features' && !key.startsWith('x-'))
18
- if (unknown.length > 0) throw new TypeError(`${label} support spec contains unknown field ${JSON.stringify(unknown[0])}`)
19
- if (value.features !== undefined && (!Array.isArray(value.features)
20
- || value.features.some(feature => typeof feature !== 'string' || feature.trim() === ''))) {
21
- throw new TypeError(`${label} support spec.features must be an array of non-empty strings`)
22
- }
23
- return Object.freeze({ features: Object.freeze([...(value.features ?? [])].sort()) })
24
- }
25
-
26
- function providerDefinition(reference, label) {
27
- return Object.freeze({
28
- ...reference,
29
- validateRequirement(value) {
30
- if (value !== undefined) throw new TypeError(`${label} requirement does not accept spec in manifest v0.15`)
31
- return undefined
32
- },
33
- validateSupport(value) { return featureSupport(value, label) },
34
- negotiate(input) {
35
- const providers = [...new Set(input.supports.map(row => row.participant))].sort()
36
- const issues = input.requirements.flatMap(row => providers.length === 0
37
- ? [{
38
- code: row.requirement.optional === true ? 'optional-support-missing' : 'required-support-missing',
39
- severity: row.requirement.optional === true ? 'warning' : 'error',
40
- participant: row.participant,
41
- message: `${label} has no provider in this negotiation scope`,
42
- }]
43
- : [])
44
- return { agreement: Object.freeze({ providers: Object.freeze(providers) }), issues: Object.freeze(issues) }
45
- },
46
- })
47
- }
48
-
49
- export const decisionEventsDefinition = providerDefinition(DECISION_EVENTS, 'DecisionEvents')
50
-
51
- export const profileDefinitions = Object.freeze([
52
- decisionEventsDefinition,
53
- tuiChannelDefinition,
54
- ])
55
-
56
- export function registerProfileProtocols(catalog) {
57
- const disposers = profileDefinitions.map(definition => catalog.register(definition))
58
- return () => { for (const dispose of disposers.reverse()) dispose() }
59
- }
1
+ /** dsh-TUI private protocol definitions evaluated by @dsh-std/core. */
2
+
3
+ export { registerTuiContributionExtensions } from './tui-contributions.js'
4
+ export * from './tui-channel.js'
5
+ import { tuiChannelDefinition } from './tui-channel.js'
6
+
7
+ export const DECISION_EVENTS = Object.freeze({
8
+ apiVersion: 'tui.dsh/v1alpha1',
9
+ kind: 'DecisionEvents',
10
+ })
11
+
12
+ function featureSupport(value, label) {
13
+ if (value === undefined) return Object.freeze({ features: Object.freeze([]) })
14
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) {
15
+ throw new TypeError(`${label} support spec must be an object`)
16
+ }
17
+ const unknown = Object.keys(value).filter(key => key !== 'features' && !key.startsWith('x-'))
18
+ if (unknown.length > 0) throw new TypeError(`${label} support spec contains unknown field ${JSON.stringify(unknown[0])}`)
19
+ if (value.features !== undefined && (!Array.isArray(value.features)
20
+ || value.features.some(feature => typeof feature !== 'string' || feature.trim() === ''))) {
21
+ throw new TypeError(`${label} support spec.features must be an array of non-empty strings`)
22
+ }
23
+ return Object.freeze({ features: Object.freeze([...(value.features ?? [])].sort()) })
24
+ }
25
+
26
+ function providerDefinition(reference, label) {
27
+ return Object.freeze({
28
+ ...reference,
29
+ validateRequirement(value) {
30
+ if (value !== undefined) throw new TypeError(`${label} requirement does not accept spec in manifest v0.15`)
31
+ return undefined
32
+ },
33
+ validateSupport(value) { return featureSupport(value, label) },
34
+ negotiate(input) {
35
+ const providers = [...new Set(input.supports.map(row => row.participant))].sort()
36
+ const issues = input.requirements.flatMap(row => providers.length === 0
37
+ ? [{
38
+ code: row.requirement.optional === true ? 'optional-support-missing' : 'required-support-missing',
39
+ severity: row.requirement.optional === true ? 'warning' : 'error',
40
+ participant: row.participant,
41
+ message: `${label} has no provider in this negotiation scope`,
42
+ }]
43
+ : [])
44
+ return { agreement: Object.freeze({ providers: Object.freeze(providers) }), issues: Object.freeze(issues) }
45
+ },
46
+ })
47
+ }
48
+
49
+ export const decisionEventsDefinition = providerDefinition(DECISION_EVENTS, 'DecisionEvents')
50
+
51
+ export const profileDefinitions = Object.freeze([
52
+ decisionEventsDefinition,
53
+ tuiChannelDefinition,
54
+ ])
55
+
56
+ export function registerProfileProtocols(catalog) {
57
+ const disposers = profileDefinitions.map(definition => catalog.register(definition))
58
+ return () => { for (const dispose of disposers.reverse()) dispose() }
59
+ }
@@ -1,15 +1,15 @@
1
- export const TUI_CHANNEL_HTTP_API_VERSION: 'tui.dsh/v1alpha1'
2
- export const TUI_CHANNEL_HTTP_KIND: 'ChannelEndpoint'
3
- export const TUI_CHANNEL_HTTP_HEALTH_PATH: '/dsh-tui/v1/health'
4
- export const TUI_CHANNEL_HTTP_DESCRIPTOR_PATH: '/dsh-tui/v1/endpoint'
5
- export const TUI_CHANNEL_HTTP_WEBSOCKET_PATH: '/dsh-tui/v1/connection'
6
-
7
- export interface TuiChannelEndpointDescriptor {
8
- readonly apiVersion: typeof TUI_CHANNEL_HTTP_API_VERSION
9
- readonly kind: typeof TUI_CHANNEL_HTTP_KIND
10
- readonly origin: string
11
- readonly connection: typeof TUI_CHANNEL_HTTP_WEBSOCKET_PATH
12
- }
13
-
14
- export function createTuiChannelEndpointDescriptor(origin: string): TuiChannelEndpointDescriptor
15
- export function validateTuiChannelEndpointDescriptor(value: unknown): TuiChannelEndpointDescriptor
1
+ export const TUI_CHANNEL_HTTP_API_VERSION: 'tui.dsh/v1alpha1'
2
+ export const TUI_CHANNEL_HTTP_KIND: 'ChannelEndpoint'
3
+ export const TUI_CHANNEL_HTTP_HEALTH_PATH: '/dsh-tui/v1/health'
4
+ export const TUI_CHANNEL_HTTP_DESCRIPTOR_PATH: '/dsh-tui/v1/endpoint'
5
+ export const TUI_CHANNEL_HTTP_WEBSOCKET_PATH: '/dsh-tui/v1/connection'
6
+
7
+ export interface TuiChannelEndpointDescriptor {
8
+ readonly apiVersion: typeof TUI_CHANNEL_HTTP_API_VERSION
9
+ readonly kind: typeof TUI_CHANNEL_HTTP_KIND
10
+ readonly origin: string
11
+ readonly connection: typeof TUI_CHANNEL_HTTP_WEBSOCKET_PATH
12
+ }
13
+
14
+ export function createTuiChannelEndpointDescriptor(origin: string): TuiChannelEndpointDescriptor
15
+ export function validateTuiChannelEndpointDescriptor(value: unknown): TuiChannelEndpointDescriptor
@@ -1,32 +1,32 @@
1
- export const TUI_CHANNEL_HTTP_API_VERSION = 'tui.dsh/v1alpha1'
2
- export const TUI_CHANNEL_HTTP_KIND = 'ChannelEndpoint'
3
- export const TUI_CHANNEL_HTTP_HEALTH_PATH = '/dsh-tui/v1/health'
4
- export const TUI_CHANNEL_HTTP_DESCRIPTOR_PATH = '/dsh-tui/v1/endpoint'
5
- export const TUI_CHANNEL_HTTP_WEBSOCKET_PATH = '/dsh-tui/v1/connection'
6
-
7
- export function createTuiChannelEndpointDescriptor(origin) {
8
- const normalized = new URL(origin)
9
- if (normalized.protocol !== 'http:' && normalized.protocol !== 'https:') {
10
- throw new TypeError('TUI Channel endpoint origin must use http or https')
11
- }
12
- normalized.pathname = '/'
13
- normalized.search = ''
14
- normalized.hash = ''
15
- return Object.freeze({
16
- apiVersion: TUI_CHANNEL_HTTP_API_VERSION,
17
- kind: TUI_CHANNEL_HTTP_KIND,
18
- origin: normalized.toString().replace(/\/$/u, ''),
19
- connection: TUI_CHANNEL_HTTP_WEBSOCKET_PATH,
20
- })
21
- }
22
-
23
- export function validateTuiChannelEndpointDescriptor(value) {
24
- if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new TypeError('TUI Channel endpoint descriptor must be an object')
25
- if (value.apiVersion !== TUI_CHANNEL_HTTP_API_VERSION || value.kind !== TUI_CHANNEL_HTTP_KIND) {
26
- throw new TypeError('TUI Channel endpoint descriptor version or kind is unsupported')
27
- }
28
- if (typeof value.origin !== 'string') throw new TypeError('TUI Channel endpoint origin must be a string')
29
- createTuiChannelEndpointDescriptor(value.origin)
30
- if (value.connection !== TUI_CHANNEL_HTTP_WEBSOCKET_PATH) throw new TypeError('TUI Channel endpoint connection path is unsupported')
31
- return value
32
- }
1
+ export const TUI_CHANNEL_HTTP_API_VERSION = 'tui.dsh/v1alpha1'
2
+ export const TUI_CHANNEL_HTTP_KIND = 'ChannelEndpoint'
3
+ export const TUI_CHANNEL_HTTP_HEALTH_PATH = '/dsh-tui/v1/health'
4
+ export const TUI_CHANNEL_HTTP_DESCRIPTOR_PATH = '/dsh-tui/v1/endpoint'
5
+ export const TUI_CHANNEL_HTTP_WEBSOCKET_PATH = '/dsh-tui/v1/connection'
6
+
7
+ export function createTuiChannelEndpointDescriptor(origin) {
8
+ const normalized = new URL(origin)
9
+ if (normalized.protocol !== 'http:' && normalized.protocol !== 'https:') {
10
+ throw new TypeError('TUI Channel endpoint origin must use http or https')
11
+ }
12
+ normalized.pathname = '/'
13
+ normalized.search = ''
14
+ normalized.hash = ''
15
+ return Object.freeze({
16
+ apiVersion: TUI_CHANNEL_HTTP_API_VERSION,
17
+ kind: TUI_CHANNEL_HTTP_KIND,
18
+ origin: normalized.toString().replace(/\/$/u, ''),
19
+ connection: TUI_CHANNEL_HTTP_WEBSOCKET_PATH,
20
+ })
21
+ }
22
+
23
+ export function validateTuiChannelEndpointDescriptor(value) {
24
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new TypeError('TUI Channel endpoint descriptor must be an object')
25
+ if (value.apiVersion !== TUI_CHANNEL_HTTP_API_VERSION || value.kind !== TUI_CHANNEL_HTTP_KIND) {
26
+ throw new TypeError('TUI Channel endpoint descriptor version or kind is unsupported')
27
+ }
28
+ if (typeof value.origin !== 'string') throw new TypeError('TUI Channel endpoint origin must be a string')
29
+ createTuiChannelEndpointDescriptor(value.origin)
30
+ if (value.connection !== TUI_CHANNEL_HTTP_WEBSOCKET_PATH) throw new TypeError('TUI Channel endpoint connection path is unsupported')
31
+ return value
32
+ }
@@ -1,59 +1,59 @@
1
- import type { ApiReference, ProtocolDefinition } from '@dsh-std/core'
2
-
3
- export type JsonValue = null | boolean | number | string | readonly JsonValue[] | { readonly [key: string]: JsonValue }
4
-
5
- export const TUI_CHANNEL: Readonly<ApiReference & {
6
- apiVersion: 'tui.dsh/v1alpha1'
7
- kind: 'Channel'
8
- }>
9
- export const TUI_CHANNEL_WIRE_REVISION: 6
10
- export const TUI_CHANNEL_FEATURES: readonly string[]
11
-
12
- export interface TuiChannelRequirementSpec {
13
- readonly wireRevision: number
14
- readonly features: readonly string[]
15
- }
16
- export interface TuiChannelSupportSpec extends TuiChannelRequirementSpec {}
17
-
18
- export interface TuiChannelSnapshot {
19
- readonly wireRevision: number
20
- readonly channelId: string
21
- readonly version: number
22
- readonly state: Readonly<Record<string, JsonValue>>
23
- }
24
-
25
- export interface TuiChannelWorkspaceFlowChoice {
26
- readonly id: string
27
- readonly label: string
28
- readonly description?: string
29
- readonly badge?: string
30
- readonly action: string
31
- readonly input?: {
32
- readonly action: string
33
- readonly initialValue?: string
34
- readonly placeholder?: string
35
- }
36
- }
37
-
38
- export type TuiChannelWorkspaceFlowResult =
39
- | { readonly kind: 'target'; readonly target: import('./tui-contributions.js').WorkspaceTarget }
40
- | { readonly kind: 'choices'; readonly title: string; readonly choices: readonly TuiChannelWorkspaceFlowChoice[] }
41
-
42
- export type TuiChannelInput =
43
- | { readonly operation: 'open'; readonly value: { readonly workspace?: string; readonly sessionId?: string; readonly options?: JsonValue } }
44
- | { readonly operation: 'subscribe'; readonly value: { readonly channelId: string; readonly afterVersion: number } }
45
- | { readonly operation: 'invoke'; readonly value: { readonly channelId: string; readonly method: string; readonly arguments: readonly JsonValue[] } }
46
- | { readonly operation: 'close'; readonly value: { readonly channelId: string } }
47
-
48
- export interface TuiChannelInvokeOutput {
49
- readonly value: JsonValue
50
- readonly valueDefined?: boolean
51
- readonly snapshot?: TuiChannelSnapshot
52
- }
53
-
54
- export const tuiChannelDefinition: ProtocolDefinition
55
- export function validateTuiChannelRequirement(value: unknown): TuiChannelRequirementSpec
56
- export function validateTuiChannelSupport(value: unknown): TuiChannelSupportSpec
57
- export function validateTuiChannelInput(operation: string, value: unknown): object
58
- export function validateTuiChannelSnapshot(value: unknown): TuiChannelSnapshot
59
- export function validateTuiChannelOutput(operation: string, value: unknown): object
1
+ import type { ApiReference, ProtocolDefinition } from '@dsh-std/core'
2
+
3
+ export type JsonValue = null | boolean | number | string | readonly JsonValue[] | { readonly [key: string]: JsonValue }
4
+
5
+ export const TUI_CHANNEL: Readonly<ApiReference & {
6
+ apiVersion: 'tui.dsh/v1alpha1'
7
+ kind: 'Channel'
8
+ }>
9
+ export const TUI_CHANNEL_WIRE_REVISION: 6
10
+ export const TUI_CHANNEL_FEATURES: readonly string[]
11
+
12
+ export interface TuiChannelRequirementSpec {
13
+ readonly wireRevision: number
14
+ readonly features: readonly string[]
15
+ }
16
+ export interface TuiChannelSupportSpec extends TuiChannelRequirementSpec {}
17
+
18
+ export interface TuiChannelSnapshot {
19
+ readonly wireRevision: number
20
+ readonly channelId: string
21
+ readonly version: number
22
+ readonly state: Readonly<Record<string, JsonValue>>
23
+ }
24
+
25
+ export interface TuiChannelWorkspaceFlowChoice {
26
+ readonly id: string
27
+ readonly label: string
28
+ readonly description?: string
29
+ readonly badge?: string
30
+ readonly action: string
31
+ readonly input?: {
32
+ readonly action: string
33
+ readonly initialValue?: string
34
+ readonly placeholder?: string
35
+ }
36
+ }
37
+
38
+ export type TuiChannelWorkspaceFlowResult =
39
+ | { readonly kind: 'target'; readonly target: import('./tui-contributions.js').WorkspaceTarget }
40
+ | { readonly kind: 'choices'; readonly title: string; readonly choices: readonly TuiChannelWorkspaceFlowChoice[] }
41
+
42
+ export type TuiChannelInput =
43
+ | { readonly operation: 'open'; readonly value: { readonly workspace?: string; readonly sessionId?: string; readonly options?: JsonValue } }
44
+ | { readonly operation: 'subscribe'; readonly value: { readonly channelId: string; readonly afterVersion: number } }
45
+ | { readonly operation: 'invoke'; readonly value: { readonly channelId: string; readonly method: string; readonly arguments: readonly JsonValue[] } }
46
+ | { readonly operation: 'close'; readonly value: { readonly channelId: string } }
47
+
48
+ export interface TuiChannelInvokeOutput {
49
+ readonly value: JsonValue
50
+ readonly valueDefined?: boolean
51
+ readonly snapshot?: TuiChannelSnapshot
52
+ }
53
+
54
+ export const tuiChannelDefinition: ProtocolDefinition
55
+ export function validateTuiChannelRequirement(value: unknown): TuiChannelRequirementSpec
56
+ export function validateTuiChannelSupport(value: unknown): TuiChannelSupportSpec
57
+ export function validateTuiChannelInput(operation: string, value: unknown): object
58
+ export function validateTuiChannelSnapshot(value: unknown): TuiChannelSnapshot
59
+ export function validateTuiChannelOutput(operation: string, value: unknown): object