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

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 (241) hide show
  1. package/README.md +30 -15
  2. package/bin/dsh-tui.js +43 -7
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  4. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  6. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  7. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  8. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  10. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  11. package/dsh-ecosystem-spec/registry/README.md +14 -0
  12. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  13. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  14. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  15. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  16. package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
  17. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  18. package/lib/types/command-trees.d.ts +2 -1
  19. package/lib/types/command-trees.d.ts.map +1 -1
  20. package/lib/types/command-trees.js +1 -1
  21. package/lib/types/components/LoadedContextPanel.d.ts +10 -5
  22. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  23. package/lib/types/components/LoadedContextPanel.js +18 -7
  24. package/lib/types/components/LogoV2.d.ts.map +1 -1
  25. package/lib/types/components/LogoV2.js +16 -7
  26. package/lib/types/components/Markdown.d.ts +13 -1
  27. package/lib/types/components/Markdown.d.ts.map +1 -1
  28. package/lib/types/components/Markdown.js +15 -1
  29. package/lib/types/components/MessageList.d.ts +3 -1
  30. package/lib/types/components/MessageList.d.ts.map +1 -1
  31. package/lib/types/components/MessageList.js +90 -9
  32. package/lib/types/components/PromptInput.d.ts.map +1 -1
  33. package/lib/types/components/PromptInput.js +26 -12
  34. package/lib/types/components/StreamingMarkdown.d.ts +2 -8
  35. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  36. package/lib/types/components/StreamingMarkdown.js +51 -9
  37. package/lib/types/components/activityFrames.d.ts +1 -1
  38. package/lib/types/components/activityFrames.d.ts.map +1 -1
  39. package/lib/types/components/activityFrames.js +4 -1
  40. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
  41. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  42. package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
  43. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  44. package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
  45. package/lib/types/dsh-adapter/channel.d.ts +31 -4
  46. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  47. package/lib/types/dsh-adapter/channel.js +267 -102
  48. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  49. package/lib/types/dsh-adapter/childStderr.js +10 -0
  50. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
  51. package/lib/types/dsh-adapter/command-attribution.js +2 -2
  52. package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
  53. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
  54. package/lib/types/dsh-adapter/command-trees.js +70 -20
  55. package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
  56. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
  57. package/lib/types/dsh-adapter/component-identity.js +14 -14
  58. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
  59. package/lib/types/dsh-adapter/decision-guard.js +10 -16
  60. package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
  61. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
  62. package/lib/types/dsh-adapter/dialogs.js +114 -60
  63. package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
  64. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  65. package/lib/types/dsh-adapter/effect-ledger.js +73 -53
  66. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
  67. package/lib/types/dsh-adapter/extension-events.js +39 -1
  68. package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
  69. package/lib/types/dsh-adapter/grants.js +43 -14
  70. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  71. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  72. package/lib/types/dsh-adapter/host-access.js +652 -0
  73. package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
  74. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
  75. package/lib/types/dsh-adapter/host-descriptor.js +31 -8
  76. package/lib/types/dsh-adapter/index.d.ts +4 -0
  77. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  78. package/lib/types/dsh-adapter/index.js +1 -0
  79. package/lib/types/dsh-adapter/message-observer.d.ts +10 -15
  80. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
  81. package/lib/types/dsh-adapter/message-observer.js +114 -70
  82. package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
  83. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
  84. package/lib/types/dsh-adapter/plugin-host.js +139 -44
  85. package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
  86. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
  87. package/lib/types/dsh-adapter/plugin-storage.js +48 -36
  88. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  89. package/lib/types/dsh-adapter/plugin.js +97 -16
  90. package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
  91. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  92. package/lib/types/dsh-adapter/promptDebug.js +13 -4
  93. package/lib/types/dsh-adapter/renderers.d.ts +6 -14
  94. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
  95. package/lib/types/dsh-adapter/renderers.js +81 -46
  96. package/lib/types/dsh-adapter/scenes.d.ts +8 -4
  97. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  98. package/lib/types/dsh-adapter/scenes.js +136 -37
  99. package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
  100. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  101. package/lib/types/dsh-adapter/settings-sections.js +106 -26
  102. package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
  103. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
  104. package/lib/types/dsh-adapter/shortcuts.js +108 -36
  105. package/lib/types/dsh-adapter/status.d.ts +6 -7
  106. package/lib/types/dsh-adapter/status.d.ts.map +1 -1
  107. package/lib/types/dsh-adapter/status.js +88 -22
  108. package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
  109. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  110. package/lib/types/dsh-adapter/workspaces.js +287 -170
  111. package/lib/types/extensions.d.ts +10 -5
  112. package/lib/types/extensions.d.ts.map +1 -1
  113. package/lib/types/extensions.js +11 -5
  114. package/lib/types/force-production-react.d.ts +1 -0
  115. package/lib/types/force-production-react.d.ts.map +1 -0
  116. package/lib/types/force-production-react.js +12 -0
  117. package/lib/types/i18n.d.ts +22 -6
  118. package/lib/types/i18n.d.ts.map +1 -1
  119. package/lib/types/i18n.js +14 -2
  120. package/lib/types/index.d.ts +1 -0
  121. package/lib/types/index.d.ts.map +1 -1
  122. package/lib/types/index.js +1 -0
  123. package/lib/types/ink/components/App.d.ts +2 -0
  124. package/lib/types/ink/components/App.d.ts.map +1 -1
  125. package/lib/types/ink/components/App.js +4 -0
  126. package/lib/types/ink/ink.d.ts +20 -3
  127. package/lib/types/ink/ink.d.ts.map +1 -1
  128. package/lib/types/ink/ink.js +57 -5
  129. package/lib/types/ink/log-update.d.ts.map +1 -1
  130. package/lib/types/ink/log-update.js +128 -9
  131. package/lib/types/ink/output.d.ts +28 -2
  132. package/lib/types/ink/output.d.ts.map +1 -1
  133. package/lib/types/ink/output.js +158 -12
  134. package/lib/types/ink/screen.d.ts +39 -0
  135. package/lib/types/ink/screen.d.ts.map +1 -1
  136. package/lib/types/ink/screen.js +117 -0
  137. package/lib/types/ink/terminal.d.ts.map +1 -1
  138. package/lib/types/ink/terminal.js +10 -2
  139. package/lib/types/ink/wrapAnsi.d.ts +1 -1
  140. package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
  141. package/lib/types/ink/wrapAnsi.js +29 -2
  142. package/lib/types/plugin-host.d.ts +13 -11
  143. package/lib/types/plugin-host.d.ts.map +1 -1
  144. package/lib/types/plugin-host.js +16 -16
  145. package/lib/types/plugin-spec/registry.d.ts +2 -2
  146. package/lib/types/plugin-spec/registry.d.ts.map +1 -1
  147. package/lib/types/plugin-spec/registry.js +113 -18
  148. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
  149. package/lib/types/plugin-spec/tui-extension.js +2 -0
  150. package/lib/types/plugin-spec/validate.d.ts.map +1 -1
  151. package/lib/types/plugin-spec/validate.js +20 -1
  152. package/lib/types/scenes.d.ts +2 -1
  153. package/lib/types/scenes.d.ts.map +1 -1
  154. package/lib/types/scenes.js +1 -1
  155. package/lib/types/screens/Chat.d.ts +3 -3
  156. package/lib/types/screens/Chat.d.ts.map +1 -1
  157. package/lib/types/screens/Chat.js +38 -17
  158. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  159. package/lib/types/screens/SessionBrowser.js +10 -3
  160. package/lib/types/sessions/view.d.ts +3 -2
  161. package/lib/types/sessions/view.d.ts.map +1 -1
  162. package/lib/types/sessions/view.js +18 -0
  163. package/lib/types/settings-sections.d.ts +2 -1
  164. package/lib/types/settings-sections.d.ts.map +1 -1
  165. package/lib/types/settings-sections.js +1 -1
  166. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  167. package/lib/types/utils/execFileNoThrow.js +3 -0
  168. package/lib/types/workspaces.d.ts +2 -1
  169. package/lib/types/workspaces.d.ts.map +1 -1
  170. package/lib/types/workspaces.js +1 -1
  171. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  172. package/node_modules/@dsh-std/command/package.json +1 -1
  173. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  174. package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  175. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  176. package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  177. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  178. package/node_modules/@dsh-std/connection/package.json +1 -1
  179. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  180. package/node_modules/@dsh-std/core/package.json +1 -1
  181. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  182. package/node_modules/@dsh-std/manifest/package.json +1 -1
  183. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  184. package/node_modules/@dsh-std/messages/package.json +1 -1
  185. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  186. package/node_modules/@dsh-std/presentation/README.md +2 -1
  187. package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  188. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  189. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  190. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  191. package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  192. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  193. package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  194. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  195. package/node_modules/@dsh-std/presentation/package.json +7 -3
  196. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  197. package/node_modules/@dsh-std/storage/package.json +1 -1
  198. package/package.json +10 -5
  199. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  200. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  201. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  202. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  203. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  204. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
  205. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  206. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
  207. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  208. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
  209. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  210. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
  211. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  212. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  213. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  214. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  215. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  216. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  217. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  218. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  219. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
  220. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  221. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
  222. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  223. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
  224. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  225. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
  226. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  227. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  228. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  229. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  230. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  231. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
  232. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  233. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
  234. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  235. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
  236. package/ecosystem-spec/registry/registry-0.15.json +0 -57
  237. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
  238. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
  239. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
  240. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
  241. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/host-descriptor.schema.json +0 -0
@@ -22,11 +22,16 @@ import { ensureLegacySessionEventTypes } from './compat/index.js';
22
22
  import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
23
23
  import { resolveSessionCwd } from '../utils/workspaceRoot.js';
24
24
  import { checkForTuiUpdate, installedTuiVersion, isBootDeadlockTarget, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
25
- import { isLang, resolveStartupLang, setLang, t } from '../i18n.js';
25
+ import { getLang, isLang, resolveStartupLang, setLang, t, writeLangPref } from '../i18n.js';
26
26
  import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
27
27
  import { Chat } from '../screens/Chat.js';
28
+ import { getHostDialogStore } from './dialogs.js';
29
+ import { getHostStatusStore } from './status.js';
30
+ import { getHostShortcuts } from './shortcuts.js';
28
31
  import { attachSessionToWorkspace } from './workspace.js';
29
- import { createLocalWorkspaceRuntime } from './workspaces.js';
32
+ import { createLocalWorkspaceRuntime, getHostWorkspaceRuntime } from './workspaces.js';
33
+ import { getHostSettingsSections } from './settings-sections.js';
34
+ import { withHostRootCapability } from './host-access.js';
30
35
  import { render, ThemeProvider, AlternateScreen } from '../ui.js';
31
36
  import instances from '../ink/instances.js';
32
37
  import { cursorMove, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE } from '../ink/termio/csi.js';
@@ -66,10 +71,11 @@ export async function apply(ctx, config) {
66
71
  // already touches lang.json). Copy, not move — old launchers keep working
67
72
  // and the user deletes the legacy directory themselves.
68
73
  const migrated = migrateLegacyDataDir();
69
- // UI language resolution: DSH_TUI_LANG env var wins, then cordis.yml
70
- // `lang`, then the persisted `/lang` choice, then `zh`. Must settle
71
- // before the first render so every module resolves strings in the same
72
- // language.
74
+ // UI language resolution: DSH_TUI_LANG env var wins, then the
75
+ // settings.yaml `dsh-tui.lang` user layer (applied once the settings
76
+ // namespace registers below), then cordis.yml `lang`, then the
77
+ // persisted `/lang` choice, then `zh`. Must settle before the first
78
+ // render so every module resolves strings in the same language.
73
79
  const envLang = process.env.DSH_TUI_LANG;
74
80
  setLang(isLang(envLang) ? envLang : isLang(config.lang) ? config.lang : resolveStartupLang());
75
81
  // Rename notices must land before the first render — stderr writes break
@@ -106,6 +112,23 @@ export async function apply(ctx, config) {
106
112
  `可能是镜像 registry 未同步,请稍后重试或检查 registry 配置。\n`);
107
113
  }
108
114
  }
115
+ else if (process.stderr.isTTY) {
116
+ // Launcher alignment bridge (0.8.3): /update only replaces the
117
+ // package inside the DSH profile; a globally installed `dsh-tui`
118
+ // launcher is a separate copy that keeps its old version. Launchers
119
+ // >=0.8.3 export DSH_TUI_LAUNCHER_VERSION so we can tell whether
120
+ // the outer launcher lags the freshly installed profile. Launchers
121
+ // <=0.8.2 never set the marker — the generic branch below is
122
+ // intentionally one-shot: DSH_TUI_UPDATED_FROM exists only on the
123
+ // replacement process immediately after /update.
124
+ const launcherVersion = process.env.DSH_TUI_LAUNCHER_VERSION;
125
+ if (launcherVersion === undefined) {
126
+ process.stderr.write(`\n[dsh-tui] ${t('update-launcher-align-unknown', { version: now })}\n`);
127
+ }
128
+ else if (isVersionNewer(now, launcherVersion)) {
129
+ process.stderr.write(`\n[dsh-tui] ${t('update-launcher-outdated', { profile: now, launcher: launcherVersion })}\n`);
130
+ }
131
+ }
109
132
  }
110
133
  }
111
134
  // DSH user-interaction seam: the model's ask_user_question tool parks on
@@ -211,7 +234,7 @@ export async function apply(ctx, config) {
211
234
  // without the service means the patch came from an older dsh-tui copy
212
235
  // than the running code — warn once so the skew is diagnosable. Bare
213
236
  // embedders (no --profile) take the same fallback by design, silently.
214
- const mountedWorkspaceService = ctx.get('tuiWorkspaces');
237
+ const mountedWorkspaceService = getHostWorkspaceRuntime(ctx.get('tuiWorkspaces'));
215
238
  if (mountedWorkspaceService === undefined && resolveDshProfileName() !== undefined) {
216
239
  ctx.logger.warn('dsh-tui: tuiWorkspaces service is not mounted; /workspace runs with the local-only fallback. ' +
217
240
  'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
@@ -302,6 +325,7 @@ export async function apply(ctx, config) {
302
325
  // Edit/Write diff presentation (schema default 'auto'); the /settings
303
326
  // screen edits this key live through the dsh-tui namespace.
304
327
  diffLayout: config.diffLayout,
328
+ thinkingFold: config.thinkingFold,
305
329
  handle,
306
330
  });
307
331
  // Register the dsh-tui settings namespace so the /settings screen can
@@ -311,24 +335,69 @@ export async function apply(ctx, config) {
311
335
  ctx.inject(['settings'], (settingsCtx) => {
312
336
  const scope = settingsCtx.settings.register(settingsNamespace('dsh-tui'), Schema.object({
313
337
  diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
338
+ thinkingFold: Schema.union(['preview', 'full']).default('preview'),
339
+ // No default on purpose: an unset `lang` keeps the field showing
340
+ // the effective language (see the section's format below) and lets
341
+ // cordis.yml / lang.json keep their precedence.
342
+ lang: Schema.union(['zh', 'en']),
314
343
  }));
315
344
  const applyLayout = (value) => {
316
345
  channel.setDiffLayout(value.diffLayout ?? config.diffLayout ?? 'auto');
317
346
  };
318
- applyLayout(scope.get());
319
- scope.watch(next => {
347
+ // The /settings language field writes `lang` through the settings
348
+ // service (user layer): apply it live and mirror it to lang.json so
349
+ // the /lang command and next-boot resolution agree. DSH_TUI_LANG
350
+ // stays the top precedence — a pinned env is never overridden by the
351
+ // document.
352
+ const applyLang = (value) => {
353
+ if (!isLang(process.env.DSH_TUI_LANG) && isLang(value.lang)) {
354
+ setLang(value.lang);
355
+ writeLangPref(value.lang);
356
+ }
357
+ };
358
+ // thinkingFold rides the same namespace: /settings writes it live and
359
+ // the channel picks it up at the next step seal.
360
+ const applyThinkingFold = (value) => {
361
+ channel.setThinkingFold(value.thinkingFold ?? config.thinkingFold ?? 'preview');
362
+ };
363
+ const apply = (next) => {
320
364
  applyLayout(next);
365
+ applyLang(next);
366
+ applyThinkingFold(next);
367
+ };
368
+ apply(scope.get());
369
+ scope.watch(next => {
370
+ apply(next);
321
371
  });
322
372
  });
323
373
  // The /settings screen's own section: the dsh-tui namespace comes from
324
- // this plugin's Config schema, and the declared select writes diffLayout
325
- // back through the settings service's revision-fenced mutate.
326
- const settingsSections = ctx.get('tuiSettingsSections');
374
+ // the settings registration above, and the declared selects write `lang`
375
+ // and `diffLayout` back through the settings service's revision-fenced
376
+ // mutate (the watch applies both live).
377
+ const settingsSections = getHostSettingsSections(ctx.get('tuiSettingsSections'));
327
378
  if (settingsSections !== undefined) {
328
379
  const unregister = settingsSections.register({
329
380
  ns: 'dsh-tui',
330
381
  title: 'dsh-tui',
331
382
  fields: [
383
+ {
384
+ path: ['lang'],
385
+ label: 'Language',
386
+ descriptions: { zh: '界面语言' },
387
+ hint: 'UI language for the whole interface — applies immediately and is saved.',
388
+ hintDescriptions: { zh: '整个界面的显示语言——立即生效并保存。' },
389
+ kind: 'select',
390
+ options: [
391
+ { value: 'zh', label: '中文', descriptions: { zh: '中文' } },
392
+ { value: 'en', label: 'English', descriptions: { zh: '英文' } },
393
+ ],
394
+ format(value) {
395
+ // Unset in settings.yaml: show the effective UI language
396
+ // (env / cordis.yml / lang.json resolution) instead of a
397
+ // blank "unset" that hides the current choice.
398
+ return value === undefined || value === null ? getLang() : String(value);
399
+ },
400
+ },
332
401
  {
333
402
  path: ['diffLayout'],
334
403
  label: 'Diff layout',
@@ -342,6 +411,18 @@ export async function apply(ctx, config) {
342
411
  { value: 'unified', label: 'Unified', descriptions: { zh: '统一式' } },
343
412
  ],
344
413
  },
414
+ {
415
+ path: ['thinkingFold'],
416
+ label: 'Thinking display',
417
+ descriptions: { zh: '思考块展示' },
418
+ hint: 'Streaming thinking shows a 2-3 line live preview and each step folds when it settles; Full keeps thinking expanded until the turn ends.',
419
+ hintDescriptions: { zh: '流式时思考显示 2-3 行动态预览,每步落定后折叠;展开模式保持思考展开直到整轮结束。' },
420
+ kind: 'select',
421
+ options: [
422
+ { value: 'preview', label: 'Preview (2-3 lines)', descriptions: { zh: '预览(2-3 行)' } },
423
+ { value: 'full', label: 'Full until turn end', descriptions: { zh: '展开至轮末' } },
424
+ ],
425
+ },
345
426
  ],
346
427
  });
347
428
  ctx.effect(() => unregister);
@@ -449,9 +530,9 @@ export async function apply(ctx, config) {
449
530
  // The dsh-tui-extensions row's services (managed dialogs, status line,
450
531
  // shortcuts). Soft-consumed: absent the row (stale patch, bare embed),
451
532
  // Chat falls back to inert stores and no shortcut registry.
452
- extensionDialogs: ctx.get('tuiDialogs')?.store,
453
- extensionStatus: ctx.get('tuiStatus')?.store,
454
- extensionShortcuts: ctx.get('tuiShortcuts'),
533
+ extensionDialogs: getHostDialogStore(ctx.get('tuiDialogs')),
534
+ extensionStatus: getHostStatusStore(ctx.get('tuiStatus')),
535
+ extensionShortcuts: getHostShortcuts(ctx.get('tuiShortcuts')),
455
536
  // Full-screen surfaces inside Chat — the trajectory scene and the session
456
537
  // browser — enter the alt screen themselves in inline mode; in fullscreen
457
538
  // the tree is already wrapped below, so they must not nest.
@@ -824,7 +905,7 @@ function resumeCommand(profile, sessionId) {
824
905
  function disposeRootAndThen(ctx, done, fallbackCode = 1) {
825
906
  const timer = setTimeout(() => process.exit(fallbackCode), 5000);
826
907
  timer.unref();
827
- void ctx.root.fiber.dispose().then(() => {
908
+ void withHostRootCapability(() => ctx.root.fiber.dispose()).then(() => {
828
909
  clearTimeout(timer);
829
910
  done();
830
911
  }, () => {
@@ -1,10 +1,4 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  export declare const PROMPT_DEBUG_FILENAME = ".dsh-prompt-debug.json";
3
- /**
4
- * Register `/debug-prompt` and retain every final request observed for each
5
- * live session. The command writes one private, atomic snapshot into the
6
- * receiving session's workspace; it never records credentials, transport
7
- * headers, or AbortSignals.
8
- */
9
3
  export declare function registerPromptDebug(ctx: Context): void;
10
4
  //# sourceMappingURL=promptDebug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"promptDebug.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/promptDebug.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,eAAO,MAAM,qBAAqB,2BAA2B,CAAA;AAmF7D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA4FtD"}
1
+ {"version":3,"file":"promptDebug.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/promptDebug.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,eAAO,MAAM,qBAAqB,2BAA2B,CAAA;AAiG7D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA+FtD"}
@@ -52,11 +52,17 @@ function captureRequest(agent, options, requestIndex, position, attempt) {
52
52
  };
53
53
  }
54
54
  /**
55
- * Register `/debug-prompt` and retain every final request observed for each
56
- * live session. The command writes one private, atomic snapshot into the
57
- * receiving session's workspace; it never records credentials, transport
58
- * headers, or AbortSignals.
55
+ * Register `/debug-prompt` and retain the final requests observed for each
56
+ * live session (most recent {@link DEBUG_PROMPT_MAX_REQUESTS} kept). The
57
+ * command writes one private, atomic snapshot into the receiving session's
58
+ * workspace; it never records credentials, transport headers, or
59
+ * AbortSignals.
59
60
  */
61
+ /** Retention cap per session: every capture holds the fully assembled
62
+ * request context (messages + tools), so an unbounded list grows
63
+ * quadratically with an uncompacted conversation — the dominant long-session
64
+ * memory term. Retries of the current step stay well inside this window. */
65
+ const DEBUG_PROMPT_MAX_REQUESTS = 8;
60
66
  export function registerPromptDebug(ctx) {
61
67
  const commands = ctx.get('commands');
62
68
  const agents = ctx.get('agents');
@@ -80,6 +86,9 @@ export function registerPromptDebug(ctx) {
80
86
  const previous = capture.requests.findLast(request => request.turn === position.turn && request.step === position.step);
81
87
  const attempt = (previous?.attempt ?? 0) + 1;
82
88
  capture.requests.push(captureRequest(agent, options, capture.requests.length + 1, position, attempt));
89
+ if (capture.requests.length > DEBUG_PROMPT_MAX_REQUESTS) {
90
+ capture.requests.splice(0, capture.requests.length - DEBUG_PROMPT_MAX_REQUESTS);
91
+ }
83
92
  return next();
84
93
  });
85
94
  // Replaced agents are no longer addressable by `/debug-prompt`; release
@@ -30,6 +30,11 @@ export interface TuiEntryRenderResult {
30
30
  lines: readonly string[];
31
31
  }
32
32
  export type TuiEntryRenderer = (payload: unknown) => TuiEntryRenderResult | undefined;
33
+ /** Host-only transcript projection path. Plugins can register a renderer but
34
+ * cannot invoke an arbitrary registered renderer on demand. */
35
+ export interface TuiRendererHost {
36
+ render(type: string, payload: unknown): TuiEntryRenderResult | undefined;
37
+ }
33
38
  declare module '@deepseek-ai/cordis' {
34
39
  interface Context {
35
40
  tuiRenderers: TuiRendererRuntime;
@@ -37,8 +42,6 @@ declare module '@deepseek-ai/cordis' {
37
42
  }
38
43
  /** `ctx.tuiRenderers` — custom session-entry text renderers. */
39
44
  export declare class TuiRendererRuntime extends Service {
40
- private readonly renderers;
41
- private readonly failedTypes;
42
45
  constructor(ctx: Context);
43
46
  /**
44
47
  * Map a log-only session event type to transcript rows. Returns the
@@ -48,18 +51,7 @@ export declare class TuiRendererRuntime extends Service {
48
51
  * pluginId — omitting it records `undeclared` (C-060).
49
52
  */
50
53
  register(type: string, renderer: TuiEntryRenderer, identity?: Context): () => void;
51
- /**
52
- * Project one event; undefined when no renderer applies, the renderer has
53
- * no opinion, or it failed (failure is sticky-logged once per type so a
54
- * replayed log does not spam the warn stream per event).
55
- *
56
- * The result is validated and sanitized INSIDE the try boundary: the title
57
- * must be a string (anything else is dropped — a non-string would crash
58
- * the React render path), lines are kept to scalars, control chars are
59
- * stripped, and the count/width caps bound what a replay can synchronously
60
- * lay out.
61
- */
62
- render(type: string, payload: unknown): TuiEntryRenderResult | undefined;
63
54
  }
55
+ export declare function getHostRenderers(runtime: TuiRendererRuntime | undefined): TuiRendererHost | undefined;
64
56
  export default TuiRendererRuntime;
65
57
  //# sourceMappingURL=renderers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/renderers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAItD,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,GAAG,SAAS,CAAA;AAsBrF,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,YAAY,EAAE,kBAAkB,CAAA;KACjC;CACF;AAED,gEAAgE;AAChE,qBAAa,kBAAmB,SAAQ,OAAO;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,GAAG,EAAE,OAAO;IAIxB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI;IA+ClF;;;;;;;;;;OAUG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,GAAG,SAAS;CAwBzE;AAED,eAAe,kBAAkB,CAAA"}
1
+ {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/renderers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKtD,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CACzB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,oBAAoB,GAAG,SAAS,CAAA;AAErF;+DAC+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB,GAAG,SAAS,CAAA;CACzE;AAsBD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,YAAY,EAAE,kBAAkB,CAAA;KACjC;CACF;AAED,gEAAgE;AAChE,qBAAa,kBAAmB,SAAQ,OAAO;gBACjC,GAAG,EAAE,OAAO;IAexB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI;CA8DnF;AA4CD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GAAG,eAAe,GAAG,SAAS,CAOrG;AAED,eAAe,kBAAkB,CAAA"}
@@ -24,6 +24,7 @@
24
24
  import { Service } from '@deepseek-ai/cordis';
25
25
  import { KNOWN_SESSION_EVENT_TYPES } from '@deepseek-ai/dsh-session';
26
26
  import { cleanRenderText } from './sanitize.js';
27
+ import { bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
27
28
  const TYPE_PATTERN = /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/u;
28
29
  /**
29
30
  * The built-in session-event vocabulary, FROZEN at module load. The live
@@ -43,10 +44,19 @@ const TITLE_CELLS = 120;
43
44
  const LINE_CELLS = 400;
44
45
  /** `ctx.tuiRenderers` — custom session-entry text renderers. */
45
46
  export class TuiRendererRuntime extends Service {
46
- renderers = new Map();
47
- failedTypes = new Set();
48
47
  constructor(ctx) {
49
48
  super(ctx, 'tuiRenderers');
49
+ compositionRoot(ctx);
50
+ const runtime = this;
51
+ const state = {
52
+ renderers: new Map(),
53
+ failedTypes: new Set(),
54
+ host: undefined,
55
+ logger: ctx.logger,
56
+ };
57
+ const host = Object.freeze({ render: (type, payload) => renderEntry(runtime, type, payload) });
58
+ state.host = host;
59
+ hostRenderers.set(runtime, state);
50
60
  }
51
61
  /**
52
62
  * Map a log-only session event type to transcript rows. Returns the
@@ -56,9 +66,25 @@ export class TuiRendererRuntime extends Service {
56
66
  * pluginId — omitting it records `undeclared` (C-060).
57
67
  */
58
68
  register(type, renderer, identity) {
59
- const normalized = String(type ?? '').trim().toLowerCase();
69
+ let caller;
70
+ try {
71
+ caller = requirePluginCaller(this.ctx, 'tuiRenderers.register', this);
72
+ }
73
+ catch {
74
+ this.ctx.logger.warn('dsh-tui: tuiRenderers.register requires a live non-root plugin activation');
75
+ return () => { };
76
+ }
77
+ const state = rendererStateFor(this);
78
+ let normalized;
79
+ try {
80
+ normalized = String(type ?? '').trim().toLowerCase();
81
+ }
82
+ catch {
83
+ this.ctx.logger.warn('dsh-tui: tuiRenderers.register rejected an uncoercible event type');
84
+ return () => { };
85
+ }
60
86
  if (!TYPE_PATTERN.test(normalized)) {
61
- this.ctx.logger.warn(`dsh-tui: tuiRenderers.register rejected invalid event type ${JSON.stringify(type)}`);
87
+ this.ctx.logger.warn('dsh-tui: tuiRenderers.register rejected an invalid event type');
62
88
  return () => { };
63
89
  }
64
90
  // The channel's own projection (its renderEvent switch plus special-
@@ -70,7 +96,7 @@ export class TuiRendererRuntime extends Service {
70
96
  this.ctx.logger.warn(`dsh-tui: tuiRenderers.register rejected "${normalized}" — built-in event types keep their own projection`);
71
97
  return () => { };
72
98
  }
73
- if (this.renderers.has(normalized)) {
99
+ if (state.renderers.has(normalized)) {
74
100
  this.ctx.logger.warn(`dsh-tui: tuiRenderers.register rejected "${normalized}" — already registered`);
75
101
  this.ctx.get('tuiEffectLedger')?.record({
76
102
  operation: 'create',
@@ -84,55 +110,64 @@ export class TuiRendererRuntime extends Service {
84
110
  this.ctx.logger.warn(`dsh-tui: tuiRenderers.register rejected "${normalized}" — renderer must be a function`);
85
111
  return () => { };
86
112
  }
87
- this.renderers.set(normalized, renderer);
113
+ state.renderers.set(normalized, renderer);
88
114
  this.ctx.get('tuiEffectLedger')?.record({ operation: 'create', resource: { kind: 'renderer', id: normalized }, result: 'applied' }, identity);
89
- return () => {
90
- if (this.renderers.get(normalized) !== renderer)
115
+ const dispose = () => {
116
+ if (state.renderers.get(normalized) !== renderer)
91
117
  return;
92
- this.renderers.delete(normalized);
118
+ state.renderers.delete(normalized);
93
119
  this.ctx.get('tuiEffectLedger')?.record({ operation: 'release', resource: { kind: 'renderer', id: normalized }, result: 'applied' }, identity);
94
120
  };
121
+ bindCallerEffect(caller, dispose);
122
+ return dispose;
95
123
  }
96
- /**
97
- * Project one event; undefined when no renderer applies, the renderer has
98
- * no opinion, or it failed (failure is sticky-logged once per type so a
99
- * replayed log does not spam the warn stream per event).
100
- *
101
- * The result is validated and sanitized INSIDE the try boundary: the title
102
- * must be a string (anything else is dropped — a non-string would crash
103
- * the React render path), lines are kept to scalars, control chars are
104
- * stripped, and the count/width caps bound what a replay can synchronously
105
- * lay out.
106
- */
107
- render(type, payload) {
108
- const renderer = this.renderers.get(type);
109
- if (renderer === undefined)
124
+ }
125
+ const hostRenderers = new WeakMap();
126
+ function rendererStateFor(runtime) {
127
+ const state = hostRenderers.get(concreteService(runtime));
128
+ if (state === undefined)
129
+ throw new Error('tuiRenderers host state is unavailable');
130
+ return state;
131
+ }
132
+ function renderEntry(runtime, type, payload) {
133
+ const state = rendererStateFor(runtime);
134
+ const renderer = state.renderers.get(type);
135
+ if (renderer === undefined)
136
+ return undefined;
137
+ try {
138
+ const result = renderer(payload);
139
+ if (result === undefined)
110
140
  return undefined;
111
- try {
112
- const result = renderer(payload);
113
- if (result === undefined)
114
- return undefined;
115
- const raw = result;
116
- if (!Array.isArray(raw.lines))
117
- return undefined;
118
- const lines = [];
119
- for (const line of raw.lines) {
120
- if (lines.length >= MAX_RENDER_LINES)
121
- break;
122
- if (typeof line !== 'string' && typeof line !== 'number' && typeof line !== 'boolean')
123
- continue;
124
- lines.push(cleanRenderText(String(line), LINE_CELLS));
125
- }
126
- const title = typeof raw.title === 'string' ? cleanRenderText(raw.title, TITLE_CELLS) : undefined;
127
- return { ...(title === undefined || title === '' ? {} : { title }), lines };
128
- }
129
- catch (error) {
130
- if (!this.failedTypes.has(type)) {
131
- this.failedTypes.add(type);
132
- this.ctx.logger.warn(`dsh-tui: renderer for "${type}" threw; its entries are skipped: %o`, error);
133
- }
141
+ const raw = result;
142
+ if (!Array.isArray(raw.lines))
134
143
  return undefined;
144
+ const lines = [];
145
+ for (const line of raw.lines) {
146
+ if (lines.length >= MAX_RENDER_LINES)
147
+ break;
148
+ if (typeof line !== 'string' && typeof line !== 'number' && typeof line !== 'boolean')
149
+ continue;
150
+ lines.push(cleanRenderText(String(line), LINE_CELLS));
135
151
  }
152
+ const title = typeof raw.title === 'string' ? cleanRenderText(raw.title, TITLE_CELLS) : undefined;
153
+ return { ...(title === undefined || title === '' ? {} : { title }), lines };
154
+ }
155
+ catch (error) {
156
+ if (!state.failedTypes.has(type)) {
157
+ state.failedTypes.add(type);
158
+ state.logger.warn(`dsh-tui: renderer for "${type}" threw; its entries are skipped: %o`, error);
159
+ }
160
+ return undefined;
161
+ }
162
+ }
163
+ export function getHostRenderers(runtime) {
164
+ if (runtime === undefined)
165
+ return undefined;
166
+ try {
167
+ return hostRenderers.get(concreteService(runtime))?.host;
168
+ }
169
+ catch {
170
+ return undefined;
136
171
  }
137
172
  }
138
173
  export default TuiRendererRuntime;
@@ -37,6 +37,13 @@ export interface TuiSceneDescriptor {
37
37
  title?: string;
38
38
  component: React.ComponentType<TuiSceneProps>;
39
39
  }
40
+ /** Host-only scene controls used by the channel; omitted from the plugin export. */
41
+ export interface TuiSceneHost {
42
+ readonly active: TuiSceneDescriptor | undefined;
43
+ open(id: string): boolean;
44
+ close(): void;
45
+ subscribe(listener: () => void): () => void;
46
+ }
40
47
  declare module '@deepseek-ai/cordis' {
41
48
  interface Context {
42
49
  tuiScenes: TuiSceneRuntime;
@@ -53,9 +60,6 @@ export declare const name = "dsh-tui-scenes";
53
60
  * takes the whole terminal the way the trajectory scene does.
54
61
  */
55
62
  export declare class TuiSceneRuntime extends Service {
56
- private readonly scenes;
57
- private readonly listeners;
58
- private current;
59
63
  constructor(ctx: Context);
60
64
  /**
61
65
  * Register a full-screen scene; returns the dispose function (caller
@@ -75,7 +79,7 @@ export declare class TuiSceneRuntime extends Service {
75
79
  get active(): TuiSceneDescriptor | undefined;
76
80
  /** UI-side change feed: fired after every open/close/dispose transition. */
77
81
  subscribe(listener: () => void): () => void;
78
- private notify;
79
82
  }
83
+ export declare function getHostSceneRuntime(runtime: TuiSceneRuntime | undefined): TuiSceneHost | undefined;
80
84
  export default TuiSceneRuntime;
81
85
  //# sourceMappingURL=scenes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/scenes.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,8DAA8D;IAC9D,EAAE,EAAE,cAAc,UAAU,CAAC,CAAA;IAC7B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,mEAAmE;IACnE,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAA;IACV,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAA;CAC9C;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,SAAS,EAAE,eAAe,CAAA;KAC3B;CACF;AAED,eAAO,MAAM,IAAI,mBAAmB,CAAA;AAEpC;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,OAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,OAAO,CAAgC;gBAEnC,GAAG,EAAE,OAAO;IAIxB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI;IAoCxE;;;;OAIG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYzB,KAAK,IAAI,IAAI;IAMb,8DAA8D;IAC9D,IAAI,MAAM,IAAI,kBAAkB,GAAG,SAAS,CAE3C;IAED,4EAA4E;IAC5E,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C,OAAO,CAAC,MAAM;CAGf;AAED,eAAe,eAAe,CAAA"}
1
+ {"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/scenes.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAI3C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,8DAA8D;IAC9D,EAAE,EAAE,cAAc,UAAU,CAAC,CAAA;IAC7B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,mEAAmE;IACnE,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAA;IACV,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAA;CAC9C;AAED,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAA;IAC/C,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAA;IACzB,KAAK,IAAI,IAAI,CAAA;IACb,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,SAAS,EAAE,eAAe,CAAA;KAC3B;CACF;AAED,eAAO,MAAM,IAAI,mBAAmB,CAAA;AAEpC;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,OAAO;gBAC9B,GAAG,EAAE,OAAO;IA6BxB;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,kBAAkB,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,IAAI;IAiDxE;;;;OAIG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMzB,KAAK,IAAI,IAAI;IAMb,8DAA8D;IAC9D,IAAI,MAAM,IAAI,kBAAkB,GAAG,SAAS,CAO3C;IAED,4EAA4E;IAC5E,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;CAS5C;AAkED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAOlG;AAED,eAAe,eAAe,CAAA"}