@deepseek-harness-tui/dsh-tui 0.15.0 → 0.16.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 (308) hide show
  1. package/README.md +98 -8
  2. package/guide/dsh-tui-guide/claude-backend.en.md +8 -0
  3. package/guide/dsh-tui-guide/claude-backend.md +5 -0
  4. package/guide/dsh-tui-guide/codex-backend.en.md +13 -3
  5. package/guide/dsh-tui-guide/codex-backend.md +9 -2
  6. package/guide/dsh-tui-guide/configuration.en.md +39 -2
  7. package/guide/dsh-tui-guide/configuration.md +34 -2
  8. package/guide/dsh-tui-guide/getting-started.en.md +32 -9
  9. package/guide/dsh-tui-guide/getting-started.md +27 -8
  10. package/guide/dsh-tui-guide/interaction.en.md +8 -1
  11. package/guide/dsh-tui-guide/interaction.md +8 -1
  12. package/guide/dsh-tui-guide/plugins.en.md +66 -5
  13. package/guide/dsh-tui-guide/plugins.md +37 -3
  14. package/guide/dsh-tui-guide/user-guide.en.md +3 -2
  15. package/guide/dsh-tui-guide/user-guide.md +3 -2
  16. package/lib/settings.json +1 -1
  17. package/lib/types/adapter/channel/projection.d.ts.map +1 -1
  18. package/lib/types/adapter/channel/projection.js +1 -0
  19. package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
  20. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  21. package/lib/types/adapter/channel/ui-policy.js +1 -0
  22. package/lib/types/adapter/ports/channel-catalog.d.ts +5 -1
  23. package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
  24. package/lib/types/adapter/ports/channel-settings.d.ts +5 -3
  25. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  26. package/lib/types/adapter/ports/channel-ui.d.ts +7 -1
  27. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  28. package/lib/types/adapter/ports/channel-view.d.ts +47 -0
  29. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  30. package/lib/types/adapter/ports/channel.d.ts +2 -0
  31. package/lib/types/adapter/ports/channel.d.ts.map +1 -1
  32. package/lib/types/agent/events.d.ts +3 -2
  33. package/lib/types/agent/events.d.ts.map +1 -1
  34. package/lib/types/backends/codex/contract.d.ts +3 -0
  35. package/lib/types/backends/codex/contract.d.ts.map +1 -1
  36. package/lib/types/backends/codex/contract.js +3 -0
  37. package/lib/types/backends/codex/session/async-questions.d.ts +17 -0
  38. package/lib/types/backends/codex/session/async-questions.d.ts.map +1 -0
  39. package/lib/types/backends/codex/session/async-questions.js +89 -0
  40. package/lib/types/backends/codex/session/session.d.ts.map +1 -1
  41. package/lib/types/backends/codex/session/session.js +35 -9
  42. package/lib/types/backends/codex/text.d.ts +3 -3
  43. package/lib/types/backends/codex/text.js +1 -1
  44. package/lib/types/backends/codex/translate/items.d.ts.map +1 -1
  45. package/lib/types/backends/codex/translate/items.js +3 -1
  46. package/lib/types/backends/codex/translate/question-reply.d.ts +11 -0
  47. package/lib/types/backends/codex/translate/question-reply.d.ts.map +1 -0
  48. package/lib/types/backends/codex/translate/question-reply.js +53 -0
  49. package/lib/types/channel/projection.d.ts.map +1 -1
  50. package/lib/types/channel/projection.js +10 -0
  51. package/lib/types/commands.d.ts +10 -0
  52. package/lib/types/commands.d.ts.map +1 -1
  53. package/lib/types/commands.js +11 -2
  54. package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
  55. package/lib/types/components/CommandSuggestions.js +4 -1
  56. package/lib/types/components/LogoV2.d.ts +4 -1
  57. package/lib/types/components/LogoV2.d.ts.map +1 -1
  58. package/lib/types/components/LogoV2.js +5 -3
  59. package/lib/types/components/MessageList.d.ts.map +1 -1
  60. package/lib/types/components/MessageList.js +95 -14
  61. package/lib/types/components/PermissionsPicker.d.ts +10 -1
  62. package/lib/types/components/PermissionsPicker.d.ts.map +1 -1
  63. package/lib/types/components/PermissionsPicker.js +24 -16
  64. package/lib/types/components/PluginInstallPane.d.ts +21 -0
  65. package/lib/types/components/PluginInstallPane.d.ts.map +1 -0
  66. package/lib/types/components/PluginInstallPane.js +84 -0
  67. package/lib/types/components/PluginManagePane.d.ts +21 -0
  68. package/lib/types/components/PluginManagePane.d.ts.map +1 -0
  69. package/lib/types/components/PluginManagePane.js +69 -0
  70. package/lib/types/components/PromptInput.d.ts.map +1 -1
  71. package/lib/types/components/PromptInput.js +7 -3
  72. package/lib/types/components/SubagentCard.d.ts +13 -1
  73. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  74. package/lib/types/components/SubagentCard.js +27 -12
  75. package/lib/types/components/SubagentDashboard.d.ts +8 -1
  76. package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
  77. package/lib/types/components/SubagentDashboard.js +58 -16
  78. package/lib/types/components/launchpadLayout.d.ts +14 -1
  79. package/lib/types/components/launchpadLayout.d.ts.map +1 -1
  80. package/lib/types/components/launchpadLayout.js +36 -17
  81. package/lib/types/components/messages/TeamMessageBubble.d.ts +20 -0
  82. package/lib/types/components/messages/TeamMessageBubble.d.ts.map +1 -0
  83. package/lib/types/components/messages/TeamMessageBubble.js +15 -0
  84. package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -1
  85. package/lib/types/components/sidePanel/PanelHost.js +5 -1
  86. package/lib/types/components/sidePanel/PanelStore.d.ts +8 -0
  87. package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -1
  88. package/lib/types/components/sidePanel/PanelStore.js +11 -0
  89. package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -1
  90. package/lib/types/components/sidePanel/SidePanelColumn.js +13 -1
  91. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +7 -0
  92. package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -1
  93. package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +4 -0
  94. package/lib/types/components/sidePanel/btw/BtwComposer.d.ts +3 -0
  95. package/lib/types/components/sidePanel/btw/BtwComposer.d.ts.map +1 -1
  96. package/lib/types/components/sidePanel/btw/BtwComposer.js +20 -8
  97. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts +2 -1
  98. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts.map +1 -1
  99. package/lib/types/components/sidePanel/btw/BtwPanelAdapter.js +104 -13
  100. package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts +6 -2
  101. package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts.map +1 -1
  102. package/lib/types/components/sidePanel/btw/BtwThreadScene.js +61 -15
  103. package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts +14 -4
  104. package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts.map +1 -1
  105. package/lib/types/components/sidePanel/btw/BtwThreadView.js +90 -5
  106. package/lib/types/components/sidePanel/btw/threads.d.ts +18 -0
  107. package/lib/types/components/sidePanel/btw/threads.d.ts.map +1 -1
  108. package/lib/types/components/sidePanel/btw/threads.js +51 -0
  109. package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -1
  110. package/lib/types/components/sidePanel/builtinPanels.js +5 -1
  111. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +5 -1
  112. package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -1
  113. package/lib/types/components/sidePanel/companion/SplashMascot.js +19 -4
  114. package/lib/types/components/sidePanel/companion/skins.d.ts +8 -0
  115. package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -1
  116. package/lib/types/components/sidePanel/companion/skins.js +57 -12
  117. package/lib/types/components/sidePanel/types.d.ts +6 -0
  118. package/lib/types/components/sidePanel/types.d.ts.map +1 -1
  119. package/lib/types/components/splashArtRows.d.ts +29 -0
  120. package/lib/types/components/splashArtRows.d.ts.map +1 -0
  121. package/lib/types/components/splashArtRows.js +31 -0
  122. package/lib/types/components/teamRoster.d.ts +70 -0
  123. package/lib/types/components/teamRoster.d.ts.map +1 -0
  124. package/lib/types/components/teamRoster.js +78 -0
  125. package/lib/types/dsh-adapter/admission-loader.d.ts +82 -0
  126. package/lib/types/dsh-adapter/admission-loader.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/admission-loader.js +73 -28
  128. package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -1
  129. package/lib/types/dsh-adapter/agent-view.js +3 -1
  130. package/lib/types/dsh-adapter/approvals.d.ts +7 -0
  131. package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/approvals.js +45 -1
  133. package/lib/types/dsh-adapter/backend/translate.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/backend/translate.js +68 -8
  135. package/lib/types/dsh-adapter/backend-assembly.d.ts +31 -0
  136. package/lib/types/dsh-adapter/backend-assembly.d.ts.map +1 -0
  137. package/lib/types/dsh-adapter/backend-assembly.js +225 -0
  138. package/lib/types/dsh-adapter/backend-contribution.d.ts +36 -0
  139. package/lib/types/dsh-adapter/backend-contribution.d.ts.map +1 -1
  140. package/lib/types/dsh-adapter/backend-contribution.js +41 -0
  141. package/lib/types/dsh-adapter/backend-registry.d.ts.map +1 -1
  142. package/lib/types/dsh-adapter/backend-registry.js +22 -3
  143. package/lib/types/dsh-adapter/backends.d.ts.map +1 -1
  144. package/lib/types/dsh-adapter/backends.js +4 -5
  145. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
  146. package/lib/types/dsh-adapter/bundled-presets.js +60 -3
  147. package/lib/types/dsh-adapter/channel/binding-events.d.ts +1 -0
  148. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  149. package/lib/types/dsh-adapter/channel/binding-events.js +1 -0
  150. package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/command-completions.js +64 -7
  152. package/lib/types/dsh-adapter/channel/compaction.d.ts +7 -2
  153. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/compaction.js +100 -26
  155. package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts +3 -0
  156. package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/core/binding-feed.js +2 -1
  158. package/lib/types/dsh-adapter/channel/core/compose.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/core/compose.js +12 -0
  160. package/lib/types/dsh-adapter/channel/extensions.d.ts.map +1 -1
  161. package/lib/types/dsh-adapter/channel/extensions.js +68 -8
  162. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +6 -0
  163. package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
  164. package/lib/types/dsh-adapter/channel/mode-permission-actions.js +104 -12
  165. package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
  166. package/lib/types/dsh-adapter/channel/model-actions.js +8 -1
  167. package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -1
  168. package/lib/types/dsh-adapter/channel/permissions.js +4 -1
  169. package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -1
  170. package/lib/types/dsh-adapter/channel/projection-helpers.js +2 -0
  171. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  172. package/lib/types/dsh-adapter/channel/session-metadata.js +4 -3
  173. package/lib/types/dsh-adapter/channel/session-reset.js +2 -2
  174. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  175. package/lib/types/dsh-adapter/channel/session-resume.js +7 -0
  176. package/lib/types/dsh-adapter/channel/settings-host.d.ts +3 -0
  177. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  178. package/lib/types/dsh-adapter/channel/settings-host.js +135 -5
  179. package/lib/types/dsh-adapter/channel/state.d.ts +6 -0
  180. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  181. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  182. package/lib/types/dsh-adapter/channel/subagent-projection.js +18 -6
  183. package/lib/types/dsh-adapter/channel/transcript.d.ts +7 -0
  184. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
  185. package/lib/types/dsh-adapter/channel/transcript.js +19 -2
  186. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts +55 -0
  187. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts.map +1 -0
  188. package/lib/types/dsh-adapter/compat/agent-team-0.2.0.js +96 -0
  189. package/lib/types/dsh-adapter/contract.d.ts +4 -4
  190. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  191. package/lib/types/dsh-adapter/contract.js +5 -5
  192. package/lib/types/dsh-adapter/effect-ledger.d.ts +7 -0
  193. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  194. package/lib/types/dsh-adapter/effect-ledger.js +8 -1
  195. package/lib/types/dsh-adapter/entry-slot.d.ts +3 -1
  196. package/lib/types/dsh-adapter/entry-slot.d.ts.map +1 -1
  197. package/lib/types/dsh-adapter/entry-slot.js +2 -2
  198. package/lib/types/dsh-adapter/fresh-agent.d.ts.map +1 -1
  199. package/lib/types/dsh-adapter/fresh-agent.js +6 -1
  200. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -1
  201. package/lib/types/dsh-adapter/host-access.js +99 -0
  202. package/lib/types/dsh-adapter/host-contract.d.ts +1 -1
  203. package/lib/types/dsh-adapter/host-contract.d.ts.map +1 -1
  204. package/lib/types/dsh-adapter/host-contract.js +4 -3
  205. package/lib/types/dsh-adapter/host-dsh.d.ts +8 -2
  206. package/lib/types/dsh-adapter/host-dsh.d.ts.map +1 -1
  207. package/lib/types/dsh-adapter/host-dsh.js +45 -30
  208. package/lib/types/dsh-adapter/host-entry.js +40 -13
  209. package/lib/types/dsh-adapter/index.d.ts +9 -10
  210. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  211. package/lib/types/dsh-adapter/index.js +8 -6
  212. package/lib/types/dsh-adapter/install/pnpm-profile-add.d.ts.map +1 -1
  213. package/lib/types/dsh-adapter/install/pnpm-profile-add.js +9 -3
  214. package/lib/types/dsh-adapter/invariant.d.ts +7 -2
  215. package/lib/types/dsh-adapter/invariant.d.ts.map +1 -1
  216. package/lib/types/dsh-adapter/invariant.js +6 -3
  217. package/lib/types/dsh-adapter/migrate/index.js +2 -2
  218. package/lib/types/dsh-adapter/panels.d.ts.map +1 -1
  219. package/lib/types/dsh-adapter/panels.js +6 -0
  220. package/lib/types/dsh-adapter/plugin-declaration.d.ts +99 -1
  221. package/lib/types/dsh-adapter/plugin-declaration.d.ts.map +1 -1
  222. package/lib/types/dsh-adapter/plugin-declaration.js +132 -2
  223. package/lib/types/dsh-adapter/plugin-feed.d.ts +94 -0
  224. package/lib/types/dsh-adapter/plugin-feed.d.ts.map +1 -0
  225. package/lib/types/dsh-adapter/plugin-feed.js +135 -0
  226. package/lib/types/dsh-adapter/plugin-guard.d.ts +115 -0
  227. package/lib/types/dsh-adapter/plugin-guard.d.ts.map +1 -0
  228. package/lib/types/dsh-adapter/plugin-guard.js +108 -0
  229. package/lib/types/dsh-adapter/plugin-install.d.ts +160 -0
  230. package/lib/types/dsh-adapter/plugin-install.d.ts.map +1 -0
  231. package/lib/types/dsh-adapter/plugin-install.js +545 -0
  232. package/lib/types/dsh-adapter/plugin-manage.d.ts +178 -0
  233. package/lib/types/dsh-adapter/plugin-manage.d.ts.map +1 -0
  234. package/lib/types/dsh-adapter/plugin-manage.js +468 -0
  235. package/lib/types/dsh-adapter/plugin-manager.d.ts +78 -2
  236. package/lib/types/dsh-adapter/plugin-manager.d.ts.map +1 -1
  237. package/lib/types/dsh-adapter/plugin-manager.js +32 -0
  238. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  239. package/lib/types/dsh-adapter/plugin.js +49 -2
  240. package/lib/types/dsh-adapter/plugins-info.d.ts +87 -1
  241. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
  242. package/lib/types/dsh-adapter/plugins-info.js +131 -26
  243. package/lib/types/dsh-adapter/process-exit.d.ts +1 -1
  244. package/lib/types/dsh-adapter/process-exit.d.ts.map +1 -1
  245. package/lib/types/dsh-adapter/process-exit.js +1 -1
  246. package/lib/types/dsh-adapter/session-projection-store.d.ts +66 -0
  247. package/lib/types/dsh-adapter/session-projection-store.d.ts.map +1 -0
  248. package/lib/types/dsh-adapter/session-projection-store.js +149 -0
  249. package/lib/types/dsh-adapter/settingsEditor.js +2 -2
  250. package/lib/types/dsh-adapter/sideQuestion.d.ts +21 -0
  251. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  252. package/lib/types/dsh-adapter/sideQuestion.js +53 -0
  253. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  254. package/lib/types/dsh-adapter/subagents.js +2 -1
  255. package/lib/types/dsh-adapter/team-mode.d.ts +74 -0
  256. package/lib/types/dsh-adapter/team-mode.d.ts.map +1 -0
  257. package/lib/types/dsh-adapter/team-mode.js +188 -0
  258. package/lib/types/dsh-adapter/team-roster.d.ts +67 -0
  259. package/lib/types/dsh-adapter/team-roster.d.ts.map +1 -0
  260. package/lib/types/dsh-adapter/team-roster.js +136 -0
  261. package/lib/types/dsh-adapter/team-tools.d.ts +58 -0
  262. package/lib/types/dsh-adapter/team-tools.d.ts.map +1 -0
  263. package/lib/types/dsh-adapter/team-tools.js +208 -0
  264. package/lib/types/dsh-adapter/types.d.ts +1 -1
  265. package/lib/types/dsh-adapter/types.d.ts.map +1 -1
  266. package/lib/types/i18n.d.ts +607 -16
  267. package/lib/types/i18n.d.ts.map +1 -1
  268. package/lib/types/i18n.js +295 -9
  269. package/lib/types/ink/components/ScrollBox.d.ts +9 -0
  270. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  271. package/lib/types/ink/components/ScrollBox.js +23 -0
  272. package/lib/types/ink/dom.d.ts.map +1 -1
  273. package/lib/types/kernelPrefs.d.ts +1 -1
  274. package/lib/types/kernelPrefs.d.ts.map +1 -1
  275. package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
  276. package/lib/types/native-ts/yoga-layout/index.js +8 -1
  277. package/lib/types/permissionPresetLabels.d.ts +25 -0
  278. package/lib/types/permissionPresetLabels.d.ts.map +1 -0
  279. package/lib/types/permissionPresetLabels.js +33 -0
  280. package/lib/types/preset-patch.d.ts +22 -0
  281. package/lib/types/preset-patch.d.ts.map +1 -0
  282. package/lib/types/preset-patch.js +14 -0
  283. package/lib/types/screens/Chat.d.ts +33 -1
  284. package/lib/types/screens/Chat.d.ts.map +1 -1
  285. package/lib/types/screens/Chat.js +301 -9
  286. package/lib/types/screens/Launchpad.d.ts +7 -1
  287. package/lib/types/screens/Launchpad.d.ts.map +1 -1
  288. package/lib/types/screens/Launchpad.js +19 -4
  289. package/lib/types/screens/Settings.d.ts.map +1 -1
  290. package/lib/types/screens/Settings.js +1 -0
  291. package/lib/types/screens/chat/usePluginWriteFlow.d.ts +68 -0
  292. package/lib/types/screens/chat/usePluginWriteFlow.d.ts.map +1 -0
  293. package/lib/types/screens/chat/usePluginWriteFlow.js +92 -0
  294. package/lib/types/screens/chatOverlay.d.ts +19 -1
  295. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  296. package/lib/types/sessionModes.d.ts +5 -3
  297. package/lib/types/sessionModes.d.ts.map +1 -1
  298. package/lib/types/sessionModes.js +9 -3
  299. package/lib/types/tips.js +2 -2
  300. package/lib/types/update.d.ts +31 -22
  301. package/lib/types/update.d.ts.map +1 -1
  302. package/lib/types/update.js +85 -42
  303. package/lib/types/utils/paths.d.ts +11 -0
  304. package/lib/types/utils/paths.d.ts.map +1 -1
  305. package/lib/types/utils/paths.js +13 -0
  306. package/package.json +126 -120
  307. package/tui-profile/feed/README.md +63 -0
  308. package/tui-profile/feed/first-party.json +10 -0
package/README.md CHANGED
@@ -27,7 +27,7 @@
27
27
  ## Highlights
28
28
 
29
29
  - **Pixel whale pet** — three startup intros, click to wake; freezes after the first task.
30
- - **Launchpad and first-run guide** — every ordinary launch lands on a landing page with a **real input box** (big text + whale + quick actions, dropping whole blocks on short/narrow terminals; on by default — /settings `launchpad` off boots straight into chat); command completion matches chat: `Tab` fills the input, `Enter` runs the command and clears it. The first run walks a four-step wizard (API key / language+theme / model+workspace / shortcuts), re-runnable with `/setup`.
30
+ - **Launchpad and first-run guide** — every ordinary launch lands on a landing page with a **real input box** (big text + whale + quick actions, dropping whole blocks on short/narrow terminals; whale-girl images use a compact native-canvas footprint instead of leaving a large gap before the title; on by default — /settings `launchpad` off boots straight into chat); command completion matches chat: `Tab` fills the input, `Enter` runs the command and clears it. The first run walks a four-step wizard (API key / language+theme / model+workspace / shortcuts), re-runnable with `/setup`.
31
31
  - **Terminal-native UI** — streaming Markdown, tool cards, `/` and `@` completion, `#L12-14` ranges, history search, zh/en UI.
32
32
  - **Task completion notifications** — DSH, Claude and Codex notify after successful live work settles, with no queued follow-up or active goal. The title is “dsh-TUI · Task complete”; the body shows the latest settled reply as a single-line plain-text preview (Markdown formatting removed, up to 200 characters). OSC 777/9 apply an additional 2048-byte sequence budget, including title and protocol bytes, preserving whole graphemes. No reply shows only the title; BEL only rings. `/settings` → Conversation: `taskNotifications` = `unfocused` (default), `always`, or `off`; `notificationMethod` = `auto` (default), `osc9`, or `bel`. Auto uses separate title/body fields on Ghostty/WezTerm (OSC 777) and Kitty (OSC 99); iTerm2/Warp and explicit `osc9` use a title prefix; other terminals ring the bell; delivery follows your terminal's notification/bell settings. tmux requires `set -g allow-passthrough on` for OSC notifications and `set -g focus-events on` for focus reporting. Terminals without focus reporting need `always`. Replay, cancellation and failures do not notify. Works in inline and fullscreen modes.
33
33
  - **Native cursor** — focused text inputs inherit your terminal's cursor shape, color, blinking, and enabled animation or trail effects in both inline and fullscreen modes. The `/model` picker shows the same cursor during movement between provider tabs, model rows, and effort levels, then hides it after **0.5 seconds at rest**; clipped regions fall back to the model row. The session manager also moves this cursor between the workspace rail, session rows, and search box; typing claims the search caret, and navigation returns it to the focused row. Configure animation and trail effects in your terminal.
@@ -98,10 +98,15 @@ The `deepseek-official` API-key route needs `DEEPSEEK_API_KEY`. On DSH
98
98
  and select the separate account route through `/model`. Other supported
99
99
  accounts can sign in through `/provider` or `/auth` after startup.
100
100
 
101
- The primary compatibility target is DSH `0.2.0-rc.2`. This adapter supports its
101
+ The primary compatibility target is DSH `0.2.1-rc.2`. This adapter supports its
102
102
  Shell API, V4 session messages, declarative presets, and profile-backed settings;
103
103
  older supported hosts retain their compatibility paths. See [configuration](docs/configuration.en.md).
104
104
 
105
+ On DSH rc.2, `/settings` also selects DeepSeek Search / Fetch APIs and edits their
106
+ endpoint and result limits, supporting custom Loader entry IDs and a masked API
107
+ key input saved through DSH's credential store. Official Flash model labels show the `1017` release
108
+ marker while retaining the `deepseek-flash` model ID.
109
+
105
110
  On DSH 0.1.7, `/settings` uses the TUI's actual Loader entry ID, including custom
106
111
  IDs. It requires matching profile dependencies with `@deepseek-ai/schemastery`
107
112
  3.18.3 or newer; an incompatible schema stops TUI startup with repair guidance
@@ -127,9 +132,12 @@ Afterwards `dsh-tui` and `dsh --profile dsh-tui` are equivalent.
127
132
 
128
133
  > **New-user note**: pnpm ≥11 blocks dependencies with install scripts by
129
134
  > default and reports `ERR_PNPM_IGNORED_BUILDS`. Updates skip foreign-platform
130
- > `@img/sharp-*` native packages, saving about 200MB of downloads. `/update`
131
- > and `dsh-tui update` write both settings automatically. No manual step
132
- > needed. Details:
135
+ > natives — the `@img/sharp-*` packages and the Claude SDK's per-platform
136
+ > bundles — so only this machine's binaries are fetched. `/update` and
137
+ > `dsh-tui update` write both settings automatically. An update never installs
138
+ > the Claude SDK on its own: it enters a profile only when you pick that
139
+ > backend in the kernel picker, which then installs the pinned SDK for the
140
+ > running platform. No manual step needed. Details:
133
141
  > [Getting started](docs/getting-started.en.md#pnpm-install-script-blocks-and-foreign-platform-natives).
134
142
 
135
143
  After startup the TUI checks for newer versions in the background. It never
@@ -253,7 +261,9 @@ subscription credentials and `/channel` connections use private app-server proce
253
261
 
254
262
  Streaming/tool cards, approvals, questions, steer/queue/interrupt, model and
255
263
  effort controls, Plan, `/review`, `/diff`, `/usage`, `/init`, skills and MCP
256
- share the existing UI. **Shift+Tab only toggles Plan**, keeping its underlying
264
+ share the existing UI. Async questions open the questionnaire while Codex
265
+ continues working; answers steer the turn (or queue if unavailable), and
266
+ dismissing the question leaves work running. **Shift+Tab only toggles Plan**, keeping its underlying
257
267
  permission preset; Full Access requires an explicit choice. Existing Codex
258
268
  settings are respected, not overwritten with defaults. `/login` offers
259
269
  ChatGPT OAuth, a device code or an API key (the last writes to Codex’s own
@@ -270,7 +280,8 @@ start notice: Codex itself rejects every turn of that provider.
270
280
  TPS includes hidden reasoning time and excludes tool execution time. Live
271
281
  text estimates are corrected when Codex reports output token usage.
272
282
 
273
- Native browsing/archive, fork/conversation rewind, paged history, images,
283
+ Native browsing/archive, fork/conversation rewind (the first message requires
284
+ Codex app-server 0.160.1+), paged history, images,
274
285
  subagents, polled background terminals, goals and `/btw`/`/recap` use the
275
286
  existing surfaces. `/logout` removes only the matching dsh-auth credential;
276
287
  already-loaded managed tokens require a normal restart, not native logout.
@@ -282,6 +293,58 @@ Using ChatGPT subscription tokens in third-party clients is subject to
282
293
  OpenAI’s terms. Full instructions and current boundaries:
283
294
  [Codex backend](docs/codex-backend.en.md).
284
295
 
296
+ ### Experimental: DSH Agent Teams
297
+
298
+ DSH's experimental Agent Teams lets the session's agent (the Lead) create
299
+ named teammates that share the working directory, message each other and
300
+ coordinate on a shared task board. It is off by default. Install the
301
+ upstream bundle into the TUI profile once:
302
+
303
+ ```sh
304
+ dsh plugin --profile dsh-tui add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.2
305
+ ```
306
+
307
+ Then switch it with `/team on` / `/team off` (`/team` alone reports the
308
+ bundle, the service and this session's teammates). The switch enables or
309
+ disables the bundle in the profile, so it persists across restarts, and on a
310
+ `dsh --profile` launch it applies at once — running sessions included: the
311
+ model is told which tools came and went. Turning it off while teammates run
312
+ asks first, and switching off stops them: the team service releases the
313
+ teammates still running as it unloads. Inside a teammate session the other
314
+ teammates' runs are not visible, so the question counts them as possibly
315
+ running. The team record stays in the session for the next `/team on`.
316
+ `/plugin enable|disable` on the bundle does the same.
317
+
318
+ Pin the version to exactly your installed DSH version (the command above
319
+ uses the primary line `0.2.1-rc.2`; on DSH `0.2.1-alpha.5`, `0.2.0-rc.1` or
320
+ `0.2.0-rc.2` install `…-profile@` that same version). The team packages ship in lockstep with DSH and pin
321
+ their DSH peers exactly, so neither the untagged install nor `next` works.
322
+ When the package is missing, `/team on` prints the command with your
323
+ DSH version filled in on those lines (`0.2.1-rc.2` when the version cannot
324
+ be read); on any other DSH version it asks you to switch DSH to one of those lines first, since
325
+ no team bundle installs there.
326
+
327
+ While a request carries `spawn_teammate`, dsh-TUI drops `subagent` /
328
+ `subagent_fork` from it, and the team's `send_message` / `list_agents` /
329
+ `interrupt_agent` / `wait_agent` take the place of the legacy controls of the
330
+ same names, so `spawn_teammate` is the delegation tool; with the team off
331
+ the legacy tools are back. Subagents that are not team members (workflow,
332
+ ralph) keep `subagent`. A teammate shows up as a subagent row, a message between
333
+ members as a `✉ <sender>` bubble in the receiving session (a teammate's
334
+ received messages show on its subagent detail as agent messages), and the
335
+ other team tools as one-line cards (`send_message` with its target and
336
+ `sent`). The agents dashboard (Ctrl+A) and the agents side
337
+ panel switch to a team view: each teammate under its member name with
338
+ `running` / `idle` / `provisioning` / `failed` (a teammate whose turn ended
339
+ is idle — a message wakes it — not done), the Lead line, the remaining
340
+ subagents, a read-only task board (status, owner, `blocked`, write-scope
341
+ warnings) and a banner when the team record was rejected.
342
+
343
+ Limits: the switch covers the whole profile, not one session (a launch
344
+ without the profile plugin service, or without hot reload, needs `dsh plugin`
345
+ and a restart); there is no "enter teammate session" yet, and `/export` leaves team messages out. Upstream limits apply: teammates share one working directory, a
346
+ team lives in one process, and a task owner is never released automatically.
347
+
285
348
  ## Keybindings & Mouse
286
349
 
287
350
  `Enter` send · `Tab` complete · `Ctrl+Enter` interrupt and send · `Alt+Up` recall the last message · `Esc` dismiss, double-`Esc` rewinds · `Ctrl+B` side panel · `Ctrl+O` details · `Ctrl+R` history (`↑`/`↓` and `Ctrl+R` are scoped to the current project) · `Ctrl+V` paste · `Ctrl+Shift+E` fullscreen draft editor · `?` shortcuts · `←` open the session manager (DSH backgrounds the current session first).
@@ -400,8 +463,33 @@ questionnaire, or tool-card changes also need the matching regression scripts.
400
463
 
401
464
  Plugin development: [admission & development guide](tui-profile/docs/plugin-admission-and-development.md) · [plugin-template](https://github.com/dsh-tui-ecosystem/plugin-template) · [dsh-tui-ecosystem](https://github.com/dsh-tui-ecosystem). Reference implementation: `dsh-working-activity`.
402
465
 
466
+ Exported plugin subcomponents are admitted using the nearest package manifest of their ESM entry, including import-only and conditional exports; they do not inherit an outer package's identity.
467
+
468
+ A backend plugin (the `tui.dsh/v1alpha1` `Backend` contribution family) is in the kernel picker after a restart: the boot scans the bundles the profile declares, admits and registers each package-root `dsh-plugin.json` declaration, and reads the implementation from the package's `backend` export — importing that module only when the backend is actually selected.
469
+ Each bundle may declare one backend, and its handler id must match the declaration. Entries awaiting authorization are neither probed nor loaded, including when explicitly requested at startup.
470
+
403
471
  Seam grading and API notes: [Plugin development](docs/plugins.en.md). The organization maintains the listing only; it does not endorse community plugins.
404
472
 
473
+ Installing a plugin from inside the TUI: `/plugin install <package | path | git url>`. It goes through the host's profile plugin manager — a pre-install notice, a trust confirmation, cancellable progress, build-script approval and exact-version exemptions. Packages on the first-party feed this package ships (`tui-profile/feed/first-party.json`, pinned per release and decided offline) skip the trust confirmation, and only a spec that names that exact version qualifies: a bare name, a tag or a range is resolved again at install time, so it is confirmed with the person instead. What was confirmed is what gets installed — the run pins the exact `name@version` the inspection read — and a turn that is still running refuses the install (finish it, or `/new`, first). The same actions remain available from the CLI (`dsh plugin --profile dsh-tui …`).
474
+
475
+ A spec names one of three things:
476
+
477
+ ```sh
478
+ /plugin install /path/to/repo
479
+ /plugin install https://github.com/exam/ple.git
480
+ /plugin install @scope/package@1.2.3
481
+ ```
482
+
483
+ Typing `/plugin install ` lists these three shapes in the completion popup, and the same shapes follow the installed names on `/plugin info `. They are examples, never candidates: `Tab` leaves the draft exactly as it is, and `Enter` runs the line you typed — the subcommand's usage line while the spec is still empty, your own spec once it is not. No example can therefore be inserted or installed by accident, and a real path that merely starts like one is never swallowed.
484
+
485
+ During installation, `esc` attempts cancellation and keeps the pane open until the write settles; if cancellation is too late, it waits for the installation to finish. During exemption registration, it waits for the current write and stops subsequent grants and the retry. Exemptions already written remain.
486
+
487
+ Failed installs show up to six redacted log lines; lines larger than 16 KiB are omitted with a notice.
488
+
489
+ Managing what is installed: `/plugin remove <bundle>`, `/plugin enable <name | row id>` and `/plugin disable <name | row id>`. A bundle is a composition layer and a row is one patch entry, so the two are separate actions, and a bundle name is matched before any row identity. A module name shared by multiple rows requires a specific row ID. **Gate 2 refuses the three ways this app could switch itself off** — removing or disabling the bundle that provides it, the host layer `dsh-base`, or one of its own rows — and says which rule it broke, without calling the service at all; that holds whether or not hot reload is live, which is the path the host's own guard misses. `enable` is never refused by gate 2 (it is the repair action). Every enable and removal asks first; `disable` asks only about a host-layer row. The host does not attest installed package sources, so even an exact feed match requires confirmation before enabling.
490
+
491
+ These three actions have no cancellation — the service offers none — so `esc` only closes the pane while the write finishes and reports itself into the transcript. Enable and disable have no CLI verb either (the service writes them into the profile's own files), and a removal never deletes your own data: anything left under `~/.dsh-tui` is reported once and left for you to delete.
492
+
405
493
  ## Documentation
406
494
 
407
495
  - **Start** — [Getting started](docs/getting-started.en.md) · [VS Code](docs/vscode.en.md)
@@ -437,7 +525,9 @@ Everything, bilingual: [docs/README.md](docs/README.md).
437
525
 
438
526
  No sandbox of its own: dsh-TUI uses the active DSH profile's filesystem, shell, sandbox and approval policies. Permission presets come from the DSH `permissionPresets` registry.
439
527
 
440
- **Permission persistence** (all three backends): the Claude and Codex backends keep their `/permission` picks in `~/.dsh-tui/backends/<id>/prefs.json`; the DSH pick is kept at `~/.dsh-tui/permission.json`. Every durable preset switch teaches it (picker, typed `/permission`, Shift+Tab static modes, or a switch the official command performed on its own), and a session that never customized its permission planes starts on the remembered preset — applied through the same official switch path. "Never customized" is about the user: the composition writes its own default preset into every fresh session at creation, and those events do not count. Plan-mode transients are excluded, a `DSH_PERMISSION_MODE` launch pin (this run's initial permission plane) outranks the file, and an identity the mounted roster no longer offers is skipped.
528
+ **Permission persistence** (all three backends): the Claude and Codex backends keep their `/permission` picks in `~/.dsh-tui/backends/<id>/prefs.json`; the DSH pick is kept at `~/.dsh-tui/permission.json`. Every durable preset switch teaches it (picker, typed `/permission`, Shift+Tab static modes, or a switch the official command performed on its own), and a session that never customized its permission planes starts on the remembered preset — applied through the same official switch path. "Never customized" is about the user: the composition writes its own default preset into every fresh session at creation, and those events do not count. Plan-mode transients and the experimental Auto review preset (see below) are excluded, a `DSH_PERMISSION_MODE` launch pin (this run's initial permission plane) outranks the file, and an identity the mounted roster no longer offers is skipped.
529
+
530
+ **Auto review** (DSH, experimental): when the `dsh-experimental-auto-review` plugin is enabled, the `auto` preset (shown as "Auto review", tagged `EXP`) appears in `/permission` and its completions live, and disappears when the plugin is removed. It is session-only: the model reviews every tool call before it runs, there is no file sandbox, and each call costs one extra model request; its approval prompts show the localized reason, and a subagent denial reads "Auto review denied; not executed". Picking it in the picker first shows a risk confirmation (`Enter` enables, `Esc` goes back; in fullscreen its Enable / Go back rows are clickable); a typed `/permission auto` switches directly. Once the current session has selected it, the picker skips the confirmation and Shift+Tab stops skipping it.
441
531
 
442
532
  **Upstream auto-retry** (DSH): whenever a session binds (boot, `/model` switch, resume), the TUI seeds a retry policy — 5 attempts, transport-drop-aware failure codes including `STREAM_CLOSED` (a dropped upstream stream) — on **the provider route that session actually uses**, through the official `llm-pi-ai` settings section (the policy the kernel's `llm-retry` plugin executes). Only routes without an explicit `retryPolicy` are seeded — dormant channels are never written — and `upstreamRetry: false` in cordis.yml opts out.
443
533
 
@@ -32,6 +32,14 @@ You need:
32
32
  cd ~/.dsh/profiles/dsh-tui && pnpm add @anthropic-ai/claude-agent-sdk@0.3.287
33
33
  ```
34
34
 
35
+ The SDK ships as all-platform optional dependencies (one native bundle per
36
+ platform, about 230MB unpacked). The profile's
37
+ `ignoredOptionalDependencies` keeps only the running platform's bundle, and
38
+ the installer recomputes that list for the current machine, so a reinstall
39
+ after moving platforms still fetches exactly one. `/update` and
40
+ `dsh-tui update` never install the SDK on their own: when the profile does
41
+ not depend on it, they do not bring it in.
42
+
35
43
  - A Claude credential; see "Signing in" below.
36
44
  - The `claude` command is optional: dsh-TUI probes an **explicitly specified
37
45
  executable path** (an environment variable, used as set, with no version check;
@@ -25,6 +25,11 @@ dsh-TUI 可以把会话跑在 Claude Agent 后端上,而不是 DeepSeek Harnes
25
25
  cd ~/.dsh/profiles/dsh-tui && pnpm add @anthropic-ai/claude-agent-sdk@0.3.287
26
26
  ```
27
27
 
28
+ SDK 以全平台可选依赖分发(每个平台一个原生包,解包约 230MB)。profile 的
29
+ `ignoredOptionalDependencies` 只放行本机平台的包,安装器每次按当前机器重算
30
+ 这份名单,换平台后重装也只取对应那个。`/update` 与 `dsh-tui update` **不会**
31
+ 主动安装 SDK:profile 里没有这个依赖时,它们不会把它带进来。
32
+
28
33
  - 一份 Claude 凭据,见下面的「登录」。
29
34
  - `claude` 命令不是必需的:按**显式指定的可执行路径**(环境变量,设置后原样采用,不做版本校验;
30
35
  变量名见[多后端架构](agent-backend-design.md))→ `PATH` 上的 `claude` → 用户主目录下的
@@ -184,13 +184,20 @@ changes during a turn apply to the next one, not to reasoning already in progres
184
184
  - Command, file, network and permission approvals use server-provided choices. Allow-once,
185
185
  session allowance or remembered rules appear only when supported. Questions and MCP forms
186
186
  share the existing panel, with secret answers masked.
187
+ - Codex's `request_user_input_async` opens the questionnaire while the agent continues
188
+ working. The first suggestion is selected by default; free text is also available.
189
+ Answers use the native question-reply envelope to steer, falling back to a queued
190
+ follow-up when steering is unavailable. Dismissal closes that question without
191
+ interrupting. Turn completion, connection loss and exit withdraw unanswered questions;
192
+ historical resume never reopens old questionnaires. Codex's persisted echo renders
193
+ as a quoted question and answer, including when rebuilding history.
187
194
 
188
195
  ## Daily commands and input
189
196
 
190
197
  | Entry | Behavior |
191
198
  | --- | --- |
192
199
  | `Enter` / `Tab` / `Ctrl+Enter` while working | Steer / queue a follow-up / interrupt and send now; non-steerable turns fall back to follow-up |
193
- | `Esc` / `Ctrl+C` | Dismiss the focused panel or interrupt. Cancelling a model question also interrupts its turn rather than leaving it hung |
200
+ | `Esc` / `Ctrl+C` | Dismiss the focused panel or interrupt. Cancelling a blocking question interrupts its turn; dismissing an async question only closes that question |
194
201
  | `/review` | Review uncommitted changes inline; requires idle state and consumes model usage |
195
202
  | `/review base <branch>` / `/review commit <sha>` | Review against a branch or commit; other arguments are custom review instructions |
196
203
  | `/diff` | Latest turn’s aggregated diff; otherwise try Git diff against the remote, then show an empty-state notice |
@@ -238,8 +245,11 @@ past tokens/cost. Fresh usage notifications update the readings.
238
245
  - `/rename` changes the official thread title; `/color` stores a session accent, not a global theme.
239
246
  - `/fork` creates a resumable copy without switching. Double `Esc` or `/rewind` conversation
240
247
  rewind creates a copy before the selected question, returns the question to the composer
241
- and preserves the original. Rewinding the first question creates an empty thread. **File-only
242
- and conversation+files rewind are unsupported**; the Git working tree does not revert.
248
+ and preserves the original. Rewinding the first question creates an empty, resumable fork.
249
+ First-question rewind, or rewind without a loaded predecessor, requires Codex app-server
250
+ **0.160.1+**, checked from the connection handshake. Older or unknown server versions
251
+ receive an explicit upgrade notice; rewind with a loaded predecessor keeps its existing path.
252
+ **File-only and conversation+files rewind are unsupported**; the Git working tree does not revert.
243
253
  - Resume replays the newest 20 full turns before live continuation. Load older messages uses
244
254
  prefetched full-item pages, not tool-omitting summaries. Retry when prefetch is still pending;
245
255
  repeated failure reports a notice. Active resume deduplicates redelivered approvals and
@@ -149,13 +149,17 @@ Chat Completions 端点当作 Responses 使用。通过 `/channel` 选择/新建
149
149
  的路径以新 thread 继续,原 thread 保留;批准计划不会暗中打开 Full Access。
150
150
  - 命令、文件改动、网络/权限请求由 Codex 给出的选项驱动;允许本次、会话内允许、
151
151
  记住规则等选项只在服务端支持时出现。问卷与 MCP 表单共用现有面板,保密答案掩码。
152
+ - Codex 的 `request_user_input_async` 在运行中打开问卷,智能体继续执行。建议答案默认
153
+ 聚焦第一项,也可自由输入;提交通过原生问题回复信封插话,不可插话时排队到下一回合。
154
+ 取消只关闭该题,不中断回合。回合结束、连接断开或退出时撤回未答问题;历史恢复不会
155
+ 重新打开旧问卷。答案由 Codex 持久化回显投影成「问题 + 答案」,恢复历史时同样显示。
152
156
 
153
157
  ## 日常命令与输入
154
158
 
155
159
  | 入口 | 行为 |
156
160
  | --- | --- |
157
161
  | 工作时 `Enter` / `Tab` / `Ctrl+Enter` | 插话(steer)/ 排队下一回合 / 打断并立即发送;不可 steer 时退为排队 |
158
- | `Esc` / `Ctrl+C` | 按当前焦点关闭面板或中断;取消提问也会中断相应回合,避免挂起 |
162
+ | `Esc` / `Ctrl+C` | 按当前焦点关闭面板或中断;取消阻塞提问会中断相应回合,取消异步提问只关闭该题 |
159
163
  | `/review` | 审查未提交改动,结果 inline 展示;需要空闲,消耗模型用量 |
160
164
  | `/review base <branch>` / `/review commit <sha>` | 按分支基线或提交审查;其他参数作为自定义审查说明 |
161
165
  | `/diff` | 最近回合的聚合 diff;没有时尝试相对远端的 Git diff,再无内容则提示 |
@@ -199,7 +203,10 @@ used = max(0, T - 12000)
199
203
  - `/rename` 改官方 thread 标题;`/color` 只保存会话强调色,不改全局主题。
200
204
  - `/fork` 创建可恢复副本,不自动切换;双击 `Esc` 或 `/rewind` 的对话回退在
201
205
  所选提问之前创建副本并继续,提问回到输入框、原 thread 保留。首条提问回退会
202
- 得到空 thread。**不支持文件回退或对话+文件回退**,Git 工作树不会随对话恢复。
206
+ 得到可恢复的空分支。首条消息及上一回合未加载时的回退需要 Codex app-server
207
+ **0.160.1+**;按连接握手中的服务端版本判断,版本未知或更旧时明确拒绝并提示升级。
208
+ 上一回合已加载时沿用原有回退方式。
209
+ **不支持文件回退或对话+文件回退**,Git 工作树不会随对话恢复。
203
210
  - 恢复先回放最近 20 个完整回合,再接 live;加载更早消息使用预取的完整分页,
204
211
  不拿省略工具项的 summary 当全转录。预取尚未就绪时可再试一次,连续失败会提示。
205
212
  运行中的恢复会去重重发审批;历史没有的完整用量不伪造。
@@ -26,6 +26,43 @@ only for a genuinely new service.
26
26
  > When a row is overridden, its `config` block is replaced as a whole. It is
27
27
  > not deep-merged, so repeat every key that must remain active.
28
28
 
29
+ ## Web search and fetch (DSH 0.2.1-rc.2)
30
+
31
+ The standard DSH profile loads the new DeepSeek Search / Fetch API providers,
32
+ while Messages search and local HTTP fetch remain the defaults. In `/settings`,
33
+ use the arrow keys in **Web search** to select **Search API** and **Fetch API**.
34
+ Each selection saves immediately and applies to the next operation. Choose
35
+ **Messages** / **HTTP** to restore the original providers. Enter accepts a custom
36
+ provider ID. Sections use the plugin's actual Loader entry ID, including custom IDs.
37
+
38
+ **Web search** has one **API key** input. Paste the key for the selected search API;
39
+ typing is masked and confirmation saves it in DSH's credential store, outside
40
+ profile configuration. Reopening shows only whether a key is configured. Blank
41
+ input preserves the saved key, and switching APIs selects that API's credential.
42
+
43
+ The **DeepSeek Search / Fetch API** section edits the API base URL,
44
+ result count (1–50), and **Send original question**. The base URL
45
+ includes the path prefix without `/search` or `/fetch`; its default is
46
+ `https://api.deepseek.com/v1/tools`. DSH supplies an authorized account token for the account route.
47
+ Search sends the first 128 characters of the latest user prompt by default;
48
+ the section can disable this. Messages search has its own endpoint and maximum
49
+ search count section.
50
+
51
+ The user profile patch can also select both providers:
52
+
53
+ ```yaml
54
+ - id: web
55
+ config:
56
+ searchProvider: deepseek-search-api
57
+ fetchProvider: deepseek-fetch-api
58
+ ```
59
+
60
+ The TUI uses DSH's tools, authentication, cancellation and persisted results;
61
+ it does not make an additional model request. Older hosts and compositions
62
+ without the API plugin omit these new settings. The official `deepseek-official`
63
+ and `deepseek-account` routes show a `1017` marker for `DeepSeek-V4.1-Flash` in
64
+ the model list, retaining the original route IDs.
65
+
29
66
  ## Official request metadata and feedback reporting
30
67
 
31
68
  The TUI bundle inherits reporting configuration from the installed official DSH
@@ -438,8 +475,8 @@ The `/provider` add branch signs in to ChatGPT/Codex (`openai-codex`), Claude
438
475
  (`anthropic`), or Grok (`xai`) subscriptions. When the installed host's pi-ai
439
476
  catalog ships the corresponding flows, it also offers OpenAI direct ChatGPT sign-in
440
477
  (`openai`, using the OpenAI API rather than the legacy Codex backend) and Meta
441
- Muse (`meta`). The primary validated DSH `0.2.0-rc.2` fixture carries pi-ai
442
- `0.87.1`, which includes Meta Muse but not OpenAI direct sign-in.
478
+ Muse (`meta`). The primary validated DSH `0.2.1-rc.2` development fixture resolves pi-ai
479
+ `1.2.0`, which includes Meta Muse and OpenAI direct sign-in.
443
480
  `/auth status`, `/auth login [provider]`, and `/auth logout <provider>` use
444
481
  that credential store for these pi-ai routes. Browser authorization tries to open the page
445
482
  automatically and offers the authorization link and manual callback URL/code
@@ -25,6 +25,38 @@ Profile 启动按顺序叠加:
25
25
  > 覆盖某一行时,`config` 是整块替换,不是逐字段深合并。需要继续生效的字段必须
26
26
  > 在用户补丁中全部重写。
27
27
 
28
+ ## 网页搜索与抓取(DSH 0.2.1-rc.2)
29
+
30
+ 标准 DSH profile 会加载新的 DeepSeek Search / Fetch API 提供者,默认仍使用
31
+ Messages 搜索和本地 HTTP 抓取。在 `/settings` 的「网页搜索」分区,用左右键将
32
+ 「搜索」选为「搜索 API」、「抓取」选为「抓取 API」;选择立即保存,从下一次操作
33
+ 生效,不需要重启。切回 `Messages` / `HTTP` 可恢复原提供者。Enter 可输入第三方
34
+ 提供者 ID。分区使用插件实际的 Loader 行 ID,也支持自定义 ID。
35
+
36
+ 「网页搜索」分区只有一个 API key 输入框,可直接粘贴当前搜索 API 的密钥。
37
+ 输入时显示掩码,确认后保存到 DSH 凭据库,不写入 profile 配置;重新打开只显示
38
+ 是否已设置,不回显原值。留空保留已有密钥,切换搜索 API 后使用该 API 的凭据。
39
+
40
+ 「DeepSeek 搜索 / 抓取 API」分区可修改 API 基础地址、搜索结果数
41
+ (1–50)和「发送原始问题」。基础地址包含路径前缀,不含 `/search` 或 `/fetch`,
42
+ 默认 `https://api.deepseek.com/v1/tools`。账号路由由 DSH 使用已授权的账号令牌。
43
+ 默认会将最近一条
44
+ 用户提示的前 128 个字符随搜索请求发送,可在该分区关闭。Messages 搜索的端点与
45
+ 最大搜索次数在独立分区设置。
46
+
47
+ 也可通过用户 profile 补丁选择两个提供者:
48
+
49
+ ```yaml
50
+ - id: web
51
+ config:
52
+ searchProvider: deepseek-search-api
53
+ fetchProvider: deepseek-fetch-api
54
+ ```
55
+
56
+ TUI 沿用 DSH 的工具、鉴权、取消和结果持久化,不额外发起模型请求;旧宿主或未加载
57
+ API 插件的组合不显示这些新增设置。官方 `deepseek-official` / `deepseek-account`
58
+ 路由的 `DeepSeek-V4.1-Flash` 在模型列表中显示 `1017` 标记,路由 ID 不变。
59
+
28
60
  ## 官方请求元数据与反馈上报
29
61
 
30
62
  TUI bundle 继承已安装 DSH 官方组合的上报配置;上游未提供的服务不会由 TUI
@@ -382,8 +414,8 @@ Profile 模式不再使用旧的 `DSH_TUI_COMPACT_RATIO`、`DSH_TUI_COMPACT_RETA
382
414
  `dsh-auth` 插件包**。`/provider` 的添加分支提供 ChatGPT/Codex(`openai-codex`)、
383
415
  Claude(`anthropic`)、Grok(`xai`)订阅账号登录。宿主 pi-ai catalog 提供相应流程
384
416
  时还可使用 OpenAI 直连 ChatGPT 登录(`openai`,使用 OpenAI API 而非旧版 Codex
385
- 后端)和 Meta Muse(`meta`)。当前主验证线 DSH `0.2.0-rc.2` 携带 pi-ai
386
- `0.87.1`,包含 Meta Muse,但不提供 OpenAI 直连登录。`/auth status`、`/auth login [provider]`、
417
+ 后端)和 Meta Muse(`meta`)。当前主验证线 DSH `0.2.1-rc.2` 的开发依赖解析到 pi-ai
418
+ `1.2.0`,包含 Meta Muse 与 OpenAI 直连登录。`/auth status`、`/auth login [provider]`、
387
419
  `/auth logout <provider>` 对这些 pi-ai 路由操作同一套凭据。浏览器授权会尝试自动打开页面,并在同一
388
420
  问卷中提供授权链接与手动粘贴回调 URL/代码的输入;设备码流程在轮询期间显示可复制的
389
421
  短码。无交互问卷服务的宿主会明确拒绝登录。
@@ -234,15 +234,23 @@ allowBuilds:
234
234
  manual step needed.
235
235
 
236
236
  Updates also maintain `ignoredOptionalDependencies` covering foreign-platform
237
- `@img/sharp-*` natives:
238
-
239
- - sharp ships as all-platform optional dependencies, and an untouched
240
- `pnpm update` downloads every platform's binaries (about 200MB measured).
241
- - The list is recomputed for the running platform on every update. Foreign
242
- natives are skipped while this platform's own and the platform-agnostic wasm
243
- fallbacks stay.
244
- - Move the profile to another platform or musl container and the next update
245
- there refreshes it.
237
+ natives — `@img/sharp-*` and the Claude SDK's
238
+ `@anthropic-ai/claude-agent-sdk-*` bundles:
239
+
240
+ - Both ship as all-platform optional dependencies, and an untouched pnpm update
241
+ resolves and downloads every platform's binaries (about 200MB measured for
242
+ sharp; each SDK bundle unpacks to about 230MB, and one 0.15 → 0.16 update
243
+ pulled seven foreign bundles, roughly 1.6GB).
244
+ - The list is recomputed for the running platform on every update. This
245
+ platform's own natives and the platform-agnostic wasm fallbacks stay; foreign
246
+ ones are skipped at resolution, so they no longer appear in the lockfile
247
+ either.
248
+ - The SDK is never installed by an update: it only enters a profile when you
249
+ pick that backend in the kernel picker, and the installer recomputes the list
250
+ for the current machine first, so exactly one platform's bundle lands. An
251
+ unused backend keeps taking no space.
252
+ - Move the profile to another platform or musl container and the next update or
253
+ kernel install there refreshes it.
246
254
  - An existing profile's lockfile still lists every platform, so its first
247
255
  update downloads them once more before the filter takes effect.
248
256
  - Entries outside those two platform tables (a user's `fsevents`, a
@@ -387,6 +395,21 @@ that starts `dsh`. Check `DEEPSEEK_BASE_URL` too for a custom endpoint. For
387
395
  `deepseek-account` or a subscription model, inspect `/auth status` and sign in again with
388
396
  `/auth login <provider>` if needed.
389
397
 
398
+ ### The browser connects but dsh-tui cannot reach a self-hosted HTTPS endpoint (self-signed cert / private CA)
399
+
400
+ Self-hosted LLM token servers on a private network are often fronted with HTTPS certificates issued by Caddy, mkcert, Step CA, or similar, whose root certificate is not in Node.js's built-in Mozilla CA bundle. The browser and system `curl` then work fine, but after switching dsh-tui to that provider the TLS handshake fails with `self-signed certificate in certificate chain` or `UNABLE_TO_VERIFY_LEAF_SIGNATURE`.
401
+
402
+ The reason is that dsh-tui's HTTP requests run on Node.js's TLS layer, and Node.js trusts only two things: the Mozilla CA bundle compiled into it, plus the PEM file named by the `NODE_EXTRA_CA_CERTS` environment variable (merged with the built-in list). macOS Keychain "trust" settings have no effect on a Node.js process — Node does not call the system Security.framework, so the trust chain the browser and `curl` use is irrelevant here.
403
+
404
+ Export the root certificate as PEM and set the variable before launching dsh-tui:
405
+
406
+ ```sh
407
+ export NODE_EXTRA_CA_CERTS=/path/to/your-ca-root.pem
408
+ dsh-tui
409
+ ```
410
+
411
+ Note that `NODE_EXTRA_CA_CERTS` is a bootstrap-protected variable for the DSH launcher: no `.env` file may set it (neither the project directory's `.env` nor `~/.dsh/.env`), and putting it there makes startup fail with an error telling you to `export` it instead — it can only come from the shell environment that launches dsh. The same protected group covers other certificate / TLS variables such as `SSL_CERT_FILE`, `SSL_CERT_DIR`, and `NODE_TLS_REJECT_UNAUTHORIZED`.
412
+
390
413
  ### The activity row appears twice
391
414
 
392
415
  Check whether `dsh-working-activity` was added separately to the profile. Keep
@@ -230,14 +230,18 @@ allowBuilds:
230
230
 
231
231
  `/update` 与 `dsh-tui update` 会自动写入这份配置,无需手工处理。
232
232
 
233
- 更新时还会维护 `ignoredOptionalDependencies`(忽略异平台的 `@img/sharp-*`
234
- 原生包):
235
-
236
- - sharp 以全平台可选依赖分发,不处理时 `pnpm update` 会把各平台二进制一起
237
- 下载(实测约 200MB)。
238
- - 名单每次更新按当前平台重算,异平台原生包不再下载(当前平台原生包与无平台
239
- 归属的 wasm 回退包保留)。
240
- - 把 profile 搬到别的平台或 musl 容器后,在那台机器上跑一次更新即可刷新。
233
+ 更新时还会维护 `ignoredOptionalDependencies`(忽略异平台原生包:`@img/sharp-*`
234
+ 与 Claude SDK 的 `@anthropic-ai/claude-agent-sdk-*`):
235
+
236
+ - sharp 与 Claude SDK 都以全平台可选依赖分发,不处理时 pnpm 的 update 路径会
237
+ 把各平台二进制一起解析/下载(实测 sharp 约 200MB;Claude SDK 单个包解包约
238
+ 230MB,0.15 → 0.16 的一次更新多下 7 个异平台包,约 1.6GB)。
239
+ - 名单每次更新按当前平台重算:当前平台的原生包与无平台归属的 wasm 回退包
240
+ 保留,异平台的整段跳过(pnpm 在解析阶段就不取它们,lockfile 里也不再出现)。
241
+ - SDK 本身不会被更新装进 profile:只有在内核选择器里选中该后端才安装,安装前
242
+ 也按当前机器重算名单,只装本平台对应的那个包。不用的后端一直不占空间。
243
+ - 把 profile 搬到别的平台或 musl 容器后,在那台机器上跑一次更新或内核安装
244
+ 即可刷新。
241
245
  - 老 profile 的 lockfile 里仍写着全平台条目,第一次更新会照旧下载一遍,之后
242
246
  才被忽略。
243
247
  - 块内不属于这两张平台表的条目(`fsevents`、自己写的 `@img/sharp-wasm32`
@@ -387,6 +391,21 @@ dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@latest
387
391
  自定义端点同时检查 `DEEPSEEK_BASE_URL`。若使用 `deepseek-account` 或订阅模型,
388
392
  用 `/auth status` 检查登录状态,必要时重新运行 `/auth login <provider>`。
389
393
 
394
+ ### 浏览器能访问、dsh-tui 连不上自建 HTTPS 端点(自签证书 / 私有 CA)
395
+
396
+ 内网自建的 LLM token 服务器常用 Caddy、mkcert、Step CA 等签发 HTTPS 证书,这类根证书不在 Node.js 内置的 Mozilla CA 列表里。于是浏览器和系统级 `curl` 都能正常访问,dsh-tui 切到该 provider 后却在 TLS 握手阶段失败,报 `self-signed certificate in certificate chain` 或 `UNABLE_TO_VERIFY_LEAF_SIGNATURE`。
397
+
398
+ 原因是 dsh-tui 的 HTTP 请求跑在 Node.js 的 TLS 层上,而 Node.js 只信任两样东西:编译时打包的 Mozilla CA bundle,以及环境变量 `NODE_EXTRA_CA_CERTS` 指向的 PEM 文件(与内置列表合并)。macOS Keychain 里的「信任」设置对 Node.js 进程无效——Node 不调用系统的 Security.framework,浏览器和 `curl` 用的信任链跟它无关。
399
+
400
+ 解决办法是把根证书导出成 PEM,在启动 dsh-tui 之前设置该变量:
401
+
402
+ ```sh
403
+ export NODE_EXTRA_CA_CERTS=/path/to/your-ca-root.pem
404
+ dsh-tui
405
+ ```
406
+
407
+ 注意 `NODE_EXTRA_CA_CERTS` 属于 DSH 启动器的 bootstrap 保护变量:任何 `.env` 文件(项目目录的 `.env` 与 `~/.dsh/.env` 都算)都不允许设置它,写进去会在启动时直接报错退出并提示改用 `export`,只能由启动 dsh 的那个 Shell 环境继承。同组受保护的证书 / TLS 变量还有 `SSL_CERT_FILE`、`SSL_CERT_DIR`、`NODE_TLS_REJECT_UNAUTHORIZED` 等。
408
+
390
409
  ### 工作状态行重复
391
410
 
392
411
  检查 profile 是否曾单独添加 `dsh-working-activity`。保留本包 patch 自动插入的
@@ -473,6 +473,13 @@ Notes:
473
473
  and never reaches the main context or token counts (closing the panel discards it).
474
474
  - **Never interrupts the running turn**: it can be triggered while the model is streaming; the main task keeps going.
475
475
  - Inside the panel: `↑`/`↓` scroll, `Space`/`Enter`/`Esc` dismiss, `c` copies the answer; `Esc` cancels while the answer is still pending.
476
+ - The sidebar panel (when the panel column is open) has two layers: the default **reading layer** — `←`/`→` switch panels, `↑`/`↓` move the **selection** between turns, `PgUp`/`PgDn` page, `n` starts a new topic, `s` sends the **selected** turn's answer to the main composer (press `s` again to take it back), `c` copies the selected turn's answer; `Enter`/`Tab` (or a click on the input) enters the **editing layer** (`Esc` leaves one layer at a time: editing first, draft kept), where `←`/`→` move the caret first and, once the caret sits at the start/end, the same key falls through and switches panels again, while `↑` goes straight back up to the titles.
477
+ - The sidebar's bottom hint line **follows the layer** (the panel advertises it, the host only stitches it): with the cursor in the **list** it says `↑/↓ select · s to chat · c copy` (or `s unsend` for the attached turn); with the cursor in the **input** it drops s/c (there `s` is just a letter) and says `↑ select` instead. An empty thread advertises nothing there. The input box keeps only an `Enter to ask` placeholder.
478
+ - The selection shows itself in exactly two ways: the title's **text** is inverted (not the whole row) and the terminal cursor parks on that row — so `↑`/`↓` visibly walks the native caret between titles. Both are hidden while the cursor sits in the main input or the side composer: they mean "the list owns the keyboard". **Clicking a title row** moves the selection there too.
479
+ - Scrolling only happens when it must: a target title already inside the viewport scrolls nothing at all; one outside it scrolls just far enough to **exactly reveal** that row (flush to the top edge when walking up, flush to the bottom edge when walking down).
480
+ - **Focus returns to the main composer after sending**: the chip is right there, you can keep typing, and `Esc` removes it immediately (inside the panel `Esc` leaves the panel instead of dropping the chip).
481
+ - Clicking the **message area** (question or answer text) only hands the column focus to the panel, exactly like clicking anywhere else in it — it never injects anything; `s` is the only way in.
482
+ - The `⤢` full-screen scene shares the sidebar's keys and selection state (both read the same thread store); the only difference is that after sending it steps aside and returns you to the main composer.
476
483
  - Triggering `/btw` again aborts the previous side question.
477
484
 
478
485
  ### Trajectory scene (/trace / Ctrl+T)
@@ -802,7 +809,7 @@ The command menu merges local commands with the DSH command registry. Type `/` t
802
809
 
803
810
  **Account and policy**
804
811
 
805
- - `/provider`, `/login`, `/logout`, `/permission`, `/add-dir`, `/hooks`, `/mcp`, `/plugin` — `list` shows the plugins you added (the installation-supplied bundles stay out); `check <path>` validates a plugin manifest, `info <id>` describes an installed entry or an install spec, `registries` lists where installations ask; bare `/plugin` gives the full diagnostics (reserved for the plugin management panel).
812
+ - `/provider`, `/login`, `/logout`, `/permission`, `/add-dir`, `/hooks`, `/mcp`, `/plugin` — `list` shows the plugins you added (the installation-supplied bundles stay out); `install <spec>` installs a plugin into this profile (a pre-install notice and a trust confirmation; first-party packages on the packaged feed skip the confirmation; `esc` closes the pane, and during an install it attempts cancellation and waits for writes to settle, or for completion if too late; exemptions already written remain; blocked build scripts are approved in the pane, and an incompatible version can be exempted for that exact version); `remove <bundle>` / `enable <name|id>` / `disable <name|id>` are the lifecycle actions (a bundle name wins over a row identity; a module name matching multiple rows requires a specific row ID; gate 2 refuses the bundle providing this app, the host layer `dsh-base` and this package's own rows, with a reason and no service call, while every enable and removal asks first because installed sources cannot be verified; **no cancellation** — `esc` only closes the pane and the write goes on, and a removal does not delete your own data); `check <path>` validates a plugin manifest, `info <id>` describes an installed entry or an install spec, `registries` lists where installations ask; bare `/plugin` gives the full diagnostics.
806
813
  - After `/auth login deepseek-account` or `/provider` signs in, a Platform-confirmed, unshown login bonus appears with its amount and expiry as a “Whale coupon” in the whale-maid dialog; Enter/Esc closes it.
807
814
 
808
815
  **Skills**
@@ -461,6 +461,13 @@ Windows `dsh-tui.cmd --resume` 使用 `~/.dsh-tui/resume.txt` 中最后选择的
461
461
  - **不进会话历史**:问答不写入 session log,也不会出现在主上下文与 token 计数里(关闭面板即消失)。
462
462
  - **不打断主回合**:模型正在流式输出时也可以触发,主任务继续运行。
463
463
  - 面板内 `↑`/`↓` 滚动,`Space`/`Enter`/`Esc` 关闭,`c` 复制答案;等待答案时 `Esc` 取消。
464
+ - 侧栏面板形态(面板列展开时)分两层:默认**阅读层**——`←`/`→` 切面板、`↑`/`↓` 在轮之间移动**选中**、`PgUp`/`PgDn` 翻页、`n` 新话题、`s` 把**选中轮**的答案送进主输入框(再按一次 `s` = 撤回)、`c` 复制选中轮的答案;`Enter`/`Tab`(或点击输入框)进**编辑层**(`Esc` 逐层退出:先退编辑、草稿保留),编辑层里 `←`/`→` 先移光标,光标贴到行首/行尾后再按同一个键就交回宿主切面板,`↑` 则直接回到标题(列表)。
465
+ - 侧栏那行底栏提示**按层换**(面板自己广告、宿主只拼):光标在**列表**里说 `↑/↓ 选择 · s 送聊天 · c 复制`(已附加的那一轮说 `s 撤回`),光标在**输入框**里则不说 s/c(那里 `s` 只是打字),改说 `↑ 选择`;空线程没有可选的轮,这一段不画。输入框里只留一句 `Enter 提问` 占位。
466
+ - 选中的标记只有两点:标题**文字**反色(不铺满整行),以及终端光标停在那一行(所以按 `↑`/`↓` 时原生光标的拖尾是在标题之间上下走)。光标在主输入框或侧栏输入框里时两者都不显示——它表示的是「列表正拿着键盘」。**点标题行**也能把选中挪到那一轮。
467
+ - 滚动只在必要时发生:目标标题已经在视口里就一行都不滚;走出视口才滚,而且只滚到**恰好露出**这一行(往上走贴视口顶、往下走贴视口底)。
468
+ - **送聊天之后焦点自动回主输入框**:chip 就在眼前、可以直接接着打字,`Esc` 也立刻能把它撤掉(在面板里按 `Esc` 是退出面板,不是撤 chip)。
469
+ - 点**消息区**(问题/答案正文)跟点面板其它地方一样,只把列焦点交给面板,不会注入任何东西——注入只有 `s` 一个入口。
470
+ - `⤢` 全屏场景与侧栏面板同一套键位与选中态(线程 store 共享),区别只是送完聊天后整屏场景让位、回到主输入框。
464
471
  - 再次触发 `/btw` 会中止上一个侧问。
465
472
 
466
473
  ### 轨迹场景(/trace / Ctrl+T)
@@ -804,7 +811,7 @@ Claude 后端的审批来自 CLI:CLI 给出建议时多一个「始终允许
804
811
 
805
812
  - `/provider`、`/login`、`/logout`、`/permission`、`/add-dir`、`/hooks`、`/mcp`。
806
813
  - `/auth login deepseek-account` 或 `/provider` 完成 DeepSeek 登录后,若 Platform 返回尚未展示的登录赠金,鲸鱼女仆娘弹窗会显示“鲸鱼券”的金额与到期时间;按 Enter/Esc 关闭。
807
- - `/plugin`:`list` 简洁列出你装的额外插件(不含安装自带);`check <路径>` 校验插件清单、`info <id>` 查已装条目或待装 spec、`registries` 列安装源;无参 `/plugin` 给完整诊断(预留为插件管理面板)。
814
+ - `/plugin`:`list` 简洁列出你装的额外插件(不含安装自带);`install <spec>` 把插件装进当前 profile(装前提醒 + 信任确认,嫡系包按随包清单免确认;`esc` 收起面板,安装中尝试取消并等待写操作结束,来不及时等待安装完成,已登记的版本豁免保留;构建脚本被拦时在面板里批准,版本不兼容可登记精确版本豁免);`remove <bundle>` / `enable <名称|id>` / `disable <名称|id>` 是生命周期动作(bundle 名优先于行身份,模块名匹配多行时须改用具体行 ID;门禁 2 对提供本应用的 bundle、宿主层 `dsh-base` 与本包自己的行硬拒并给原因,任何启用与卸载都要确认(已装包来源无法验证);**没有取消**——`esc` 只关面板,写入继续,卸载不删你自己的数据);`check <路径>` 校验插件清单、`info <id>` 查已装条目或待装 spec、`registries` 列安装源;无参 `/plugin` 给完整诊断。
808
815
 
809
816
  **Skills**
810
817