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

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 (240) hide show
  1. package/README.md +22 -13
  2. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  4. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  6. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  7. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  8. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  10. package/dsh-ecosystem-spec/registry/README.md +14 -0
  11. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  12. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  13. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  14. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  15. package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
  16. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  17. package/lib/types/command-trees.d.ts +2 -1
  18. package/lib/types/command-trees.d.ts.map +1 -1
  19. package/lib/types/command-trees.js +1 -1
  20. package/lib/types/components/LoadedContextPanel.d.ts +10 -5
  21. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  22. package/lib/types/components/LoadedContextPanel.js +18 -7
  23. package/lib/types/components/LogoV2.d.ts.map +1 -1
  24. package/lib/types/components/LogoV2.js +16 -7
  25. package/lib/types/components/Markdown.d.ts +13 -1
  26. package/lib/types/components/Markdown.d.ts.map +1 -1
  27. package/lib/types/components/Markdown.js +15 -1
  28. package/lib/types/components/MessageList.d.ts +3 -1
  29. package/lib/types/components/MessageList.d.ts.map +1 -1
  30. package/lib/types/components/MessageList.js +90 -9
  31. package/lib/types/components/PromptInput.d.ts.map +1 -1
  32. package/lib/types/components/PromptInput.js +26 -12
  33. package/lib/types/components/StreamingMarkdown.d.ts +2 -8
  34. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  35. package/lib/types/components/StreamingMarkdown.js +51 -9
  36. package/lib/types/components/activityFrames.d.ts +1 -1
  37. package/lib/types/components/activityFrames.d.ts.map +1 -1
  38. package/lib/types/components/activityFrames.js +4 -1
  39. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
  40. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  41. package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
  42. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  43. package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
  44. package/lib/types/dsh-adapter/channel.d.ts +31 -4
  45. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  46. package/lib/types/dsh-adapter/channel.js +267 -102
  47. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  48. package/lib/types/dsh-adapter/childStderr.js +10 -0
  49. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
  50. package/lib/types/dsh-adapter/command-attribution.js +2 -2
  51. package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
  52. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
  53. package/lib/types/dsh-adapter/command-trees.js +70 -20
  54. package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
  55. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
  56. package/lib/types/dsh-adapter/component-identity.js +14 -14
  57. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
  58. package/lib/types/dsh-adapter/decision-guard.js +10 -16
  59. package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
  60. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
  61. package/lib/types/dsh-adapter/dialogs.js +114 -60
  62. package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
  63. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  64. package/lib/types/dsh-adapter/effect-ledger.js +73 -53
  65. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
  66. package/lib/types/dsh-adapter/extension-events.js +39 -1
  67. package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
  68. package/lib/types/dsh-adapter/grants.js +43 -14
  69. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  70. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  71. package/lib/types/dsh-adapter/host-access.js +652 -0
  72. package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
  73. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
  74. package/lib/types/dsh-adapter/host-descriptor.js +31 -8
  75. package/lib/types/dsh-adapter/index.d.ts +4 -0
  76. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  77. package/lib/types/dsh-adapter/index.js +1 -0
  78. package/lib/types/dsh-adapter/message-observer.d.ts +10 -15
  79. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
  80. package/lib/types/dsh-adapter/message-observer.js +114 -70
  81. package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
  82. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
  83. package/lib/types/dsh-adapter/plugin-host.js +139 -44
  84. package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
  85. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
  86. package/lib/types/dsh-adapter/plugin-storage.js +48 -36
  87. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  88. package/lib/types/dsh-adapter/plugin.js +80 -16
  89. package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
  90. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  91. package/lib/types/dsh-adapter/promptDebug.js +13 -4
  92. package/lib/types/dsh-adapter/renderers.d.ts +6 -14
  93. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
  94. package/lib/types/dsh-adapter/renderers.js +81 -46
  95. package/lib/types/dsh-adapter/scenes.d.ts +8 -4
  96. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  97. package/lib/types/dsh-adapter/scenes.js +136 -37
  98. package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
  99. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  100. package/lib/types/dsh-adapter/settings-sections.js +106 -26
  101. package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
  102. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
  103. package/lib/types/dsh-adapter/shortcuts.js +108 -36
  104. package/lib/types/dsh-adapter/status.d.ts +6 -7
  105. package/lib/types/dsh-adapter/status.d.ts.map +1 -1
  106. package/lib/types/dsh-adapter/status.js +88 -22
  107. package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
  108. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  109. package/lib/types/dsh-adapter/workspaces.js +287 -170
  110. package/lib/types/extensions.d.ts +10 -5
  111. package/lib/types/extensions.d.ts.map +1 -1
  112. package/lib/types/extensions.js +11 -5
  113. package/lib/types/force-production-react.d.ts +1 -0
  114. package/lib/types/force-production-react.d.ts.map +1 -0
  115. package/lib/types/force-production-react.js +12 -0
  116. package/lib/types/i18n.d.ts +14 -6
  117. package/lib/types/i18n.d.ts.map +1 -1
  118. package/lib/types/i18n.js +4 -2
  119. package/lib/types/index.d.ts +1 -0
  120. package/lib/types/index.d.ts.map +1 -1
  121. package/lib/types/index.js +1 -0
  122. package/lib/types/ink/components/App.d.ts +2 -0
  123. package/lib/types/ink/components/App.d.ts.map +1 -1
  124. package/lib/types/ink/components/App.js +4 -0
  125. package/lib/types/ink/ink.d.ts +20 -3
  126. package/lib/types/ink/ink.d.ts.map +1 -1
  127. package/lib/types/ink/ink.js +57 -5
  128. package/lib/types/ink/log-update.d.ts.map +1 -1
  129. package/lib/types/ink/log-update.js +128 -9
  130. package/lib/types/ink/output.d.ts +28 -2
  131. package/lib/types/ink/output.d.ts.map +1 -1
  132. package/lib/types/ink/output.js +158 -12
  133. package/lib/types/ink/screen.d.ts +39 -0
  134. package/lib/types/ink/screen.d.ts.map +1 -1
  135. package/lib/types/ink/screen.js +117 -0
  136. package/lib/types/ink/terminal.d.ts.map +1 -1
  137. package/lib/types/ink/terminal.js +10 -2
  138. package/lib/types/ink/wrapAnsi.d.ts +1 -1
  139. package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
  140. package/lib/types/ink/wrapAnsi.js +29 -2
  141. package/lib/types/plugin-host.d.ts +13 -11
  142. package/lib/types/plugin-host.d.ts.map +1 -1
  143. package/lib/types/plugin-host.js +16 -16
  144. package/lib/types/plugin-spec/registry.d.ts +2 -2
  145. package/lib/types/plugin-spec/registry.d.ts.map +1 -1
  146. package/lib/types/plugin-spec/registry.js +113 -18
  147. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
  148. package/lib/types/plugin-spec/tui-extension.js +2 -0
  149. package/lib/types/plugin-spec/validate.d.ts.map +1 -1
  150. package/lib/types/plugin-spec/validate.js +20 -1
  151. package/lib/types/scenes.d.ts +2 -1
  152. package/lib/types/scenes.d.ts.map +1 -1
  153. package/lib/types/scenes.js +1 -1
  154. package/lib/types/screens/Chat.d.ts +3 -3
  155. package/lib/types/screens/Chat.d.ts.map +1 -1
  156. package/lib/types/screens/Chat.js +38 -17
  157. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  158. package/lib/types/screens/SessionBrowser.js +10 -3
  159. package/lib/types/sessions/view.d.ts +3 -2
  160. package/lib/types/sessions/view.d.ts.map +1 -1
  161. package/lib/types/sessions/view.js +18 -0
  162. package/lib/types/settings-sections.d.ts +2 -1
  163. package/lib/types/settings-sections.d.ts.map +1 -1
  164. package/lib/types/settings-sections.js +1 -1
  165. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  166. package/lib/types/utils/execFileNoThrow.js +3 -0
  167. package/lib/types/workspaces.d.ts +2 -1
  168. package/lib/types/workspaces.d.ts.map +1 -1
  169. package/lib/types/workspaces.js +1 -1
  170. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  171. package/node_modules/@dsh-std/command/package.json +1 -1
  172. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  173. package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  174. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  175. package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  176. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  177. package/node_modules/@dsh-std/connection/package.json +1 -1
  178. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  179. package/node_modules/@dsh-std/core/package.json +1 -1
  180. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  181. package/node_modules/@dsh-std/manifest/package.json +1 -1
  182. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  183. package/node_modules/@dsh-std/messages/package.json +1 -1
  184. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  185. package/node_modules/@dsh-std/presentation/README.md +2 -1
  186. package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  187. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  188. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  189. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  190. package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  191. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  192. package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  193. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  194. package/node_modules/@dsh-std/presentation/package.json +7 -3
  195. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  196. package/node_modules/@dsh-std/storage/package.json +1 -1
  197. package/package.json +10 -5
  198. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  199. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  200. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  201. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  202. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  203. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
  204. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  205. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
  206. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  207. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
  208. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  209. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
  210. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  211. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  212. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  213. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  214. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  215. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  216. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  217. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  218. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
  219. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  220. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
  221. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  222. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
  223. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  224. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
  225. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  226. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  227. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  228. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  229. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  230. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
  231. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  232. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
  233. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  234. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
  235. package/ecosystem-spec/registry/registry-0.15.json +0 -57
  236. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
  237. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
  238. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
  239. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
  240. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/host-descriptor.schema.json +0 -0
@@ -2,7 +2,7 @@
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
- import { digestFile, loadSpecData } from '../plugin-spec/registry.js';
5
+ import { digestFile, loadSpecData, verifyContractProfiles } from '../plugin-spec/registry.js';
6
6
  import { TUI_DECISION_EVENT_NAMES } from '../plugin-spec/tui-extension.js';
7
7
  import { createContractIndex, validateHost } from '../plugin-spec/validate.js';
8
8
  import { check } from '../plugin-spec/schema-check.js';
@@ -17,6 +17,14 @@ export const HOST_SUPPORTED_CONTRACTS = Object.freeze([
17
17
  * optional vendored registry is unavailable; the contract list is still
18
18
  * empty in that degraded state. */
19
19
  export const HOST_FACET_API_VERSIONS = Object.freeze(['v1alpha1']);
20
+ function freezeDeep(value, seen = new WeakSet()) {
21
+ if (value === null || typeof value !== 'object' || seen.has(value))
22
+ return value;
23
+ seen.add(value);
24
+ for (const child of Object.values(value))
25
+ freezeDeep(child, seen);
26
+ return Object.freeze(value);
27
+ }
20
28
  export function readOwnPackageVersion() {
21
29
  const candidates = [];
22
30
  try {
@@ -58,13 +66,15 @@ export function buildHostDescriptor(options) {
58
66
  const dropped = [];
59
67
  const contracts = [];
60
68
  const data = loadSpecData(options.specDir);
61
- const advertisedFacets = data?.registry.facetApiVersions
62
- ?.filter(version => /^v[0-9]+(?:alpha[0-9]+|beta[0-9]+)$/u.test(version));
63
- const facetApiVersions = advertisedFacets !== undefined && advertisedFacets.length > 0
64
- ? advertisedFacets
65
- : [...HOST_FACET_API_VERSIONS];
69
+ // `loadSpecData` rejects malformed/empty facet declarations. Preserve the
70
+ // pinned values exactly when data is valid; use the schema-valid fallback
71
+ // only for the completely unavailable/degraded path.
72
+ const facetApiVersions = data === undefined
73
+ ? [...HOST_FACET_API_VERSIONS]
74
+ : [...data.registry.facetApiVersions];
75
+ const profileFailures = data === undefined ? [] : verifyContractProfiles(data);
66
76
  if (data === undefined) {
67
- warnings.push('admission profile unavailable (ecosystem-spec/); advertising an empty protocol surface');
77
+ warnings.push('admission profile unavailable (dsh-ecosystem-spec/); advertising an empty protocol surface');
68
78
  }
69
79
  else {
70
80
  const index = createContractIndex(data.registry, data.permissions);
@@ -78,6 +88,11 @@ export function buildHostDescriptor(options) {
78
88
  continue;
79
89
  }
80
90
  if ('profile' in entry) {
91
+ if (profileFailures.length > 0) {
92
+ dropped.push(key);
93
+ warnings.push(`${key}: TUI contract profile self-check failed (${profileFailures.join(' | ')})`);
94
+ continue;
95
+ }
81
96
  let actual;
82
97
  try {
83
98
  actual = digestFile(data.dir, entry.profile);
@@ -142,5 +157,13 @@ export function buildHostDescriptor(options) {
142
157
  descriptor.contracts.length = 0;
143
158
  }
144
159
  }
145
- return { descriptor, dropped, warnings };
160
+ // The descriptor is handed to untrusted admission/diagnostic callers. A
161
+ // cached mutable object would let one caller delete contracts or forge the
162
+ // runtime generation for every later negotiation, so freeze the complete
163
+ // graph and return immutable diagnostic arrays as well.
164
+ return Object.freeze({
165
+ descriptor: freezeDeep(descriptor),
166
+ dropped: Object.freeze(dropped),
167
+ warnings: Object.freeze(warnings),
168
+ });
146
169
  }
@@ -66,6 +66,10 @@ export interface Config {
66
66
  * terminals (≥110 cols) and unified below; `split`/`unified` force one
67
67
  * layout. Editable live from the `/settings` screen. */
68
68
  diffLayout?: 'auto' | 'split' | 'unified';
69
+ /** Thinking-block display: `preview` (default) streams a 2-3 line live
70
+ * preview and folds each step when it settles; `full` keeps thinking
71
+ * expanded until the whole turn ends. Editable live from `/settings`. */
72
+ thinkingFold?: 'preview' | 'full';
69
73
  /** Shift+Tab session-mode cycle (array order IS the cycle order; index 0
70
74
  * is the unmarked base mode). Each entry bundles any subset of the
71
75
  * `plan`/`sandbox`/`approval` atoms; absent → the built-in
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,eAAO,MAAM,IAAI,YAAY,CAAA;AAU7B,eAAO,MAAM,MAAM,UAAa,CAAA;AAEhC;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;yEAKqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;gDAC4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;gFAE4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;oCACgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;sBAIkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;4BAGwB;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;wDAEoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;gCAG4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;6DAEyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC;;;yDAGqD;IACrD,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,CA2BhC,CAAA;AAEF;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAEzD,eAAO,MAAM,IAAI,YAAY,CAAA;AAU7B,eAAO,MAAM,MAAM,UAAa,CAAA;AAEhC;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;yEAKqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;gDAC4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;gFAE4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;oCACgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;sBAIkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;4BAGwB;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;wDAEoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;gCAG4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;6DAEyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC;;8EAE0E;IAC1E,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC;;;yDAGqD;IACrD,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,CA4BhC,CAAA;AAEF;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvE"}
@@ -28,6 +28,7 @@ export const Config = Schema.object({
28
28
  lang: Schema.string().required(false),
29
29
  preset: Schema.string().required(false),
30
30
  diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
31
+ thinkingFold: Schema.union(['preview', 'full']).default('preview'),
31
32
  modes: Schema.array(Schema.object({
32
33
  id: Schema.string(),
33
34
  label: Schema.string().required(false),
@@ -82,6 +82,11 @@ export interface MessagesObserveEnvelope {
82
82
  payload: MessagesObservePayload;
83
83
  }
84
84
  export type MessagesObserveListener = (envelope: MessagesObserveEnvelope) => void | Promise<void>;
85
+ /** Host-only session-event ingress. Plugins receive only `subscribe`; the
86
+ * channel uses this capability to publish events after its own identity check. */
87
+ export interface TuiMessageObserverHost {
88
+ publish(session: unknown, event: unknown): void;
89
+ }
85
90
  /** Summary bound (cells; schema maxLength 1024 chars — 200 cells ≤ 1024). */
86
91
  export declare const OBSERVE_SUMMARY_CELLS = 200;
87
92
  /** Content text bound (chars; schema maxLength 262144). */
@@ -99,6 +104,9 @@ export declare const OBSERVE_CALLBACK_TIMEOUT_MS = 1500;
99
104
  /** Bound queued callbacks per subscription so a stalled listener cannot grow
100
105
  * an unbounded Promise chain before its timeout closes the subscription. */
101
106
  export declare const OBSERVE_CALLBACK_QUEUE_LIMIT = 32;
107
+ /** Attachment reads are part of the broker build chain and therefore need an
108
+ * independent bound; a wedged reader must not stall every later envelope. */
109
+ export declare const OBSERVE_IMAGE_READ_TIMEOUT_MS = 1500;
102
110
  declare module '@deepseek-ai/cordis' {
103
111
  interface Context {
104
112
  tuiMessageObserver: TuiMessageObserverRuntime;
@@ -112,14 +120,7 @@ declare module '@deepseek-ai/cordis' {
112
120
  * is ever delivered (a host that cannot self-check must not emit).
113
121
  */
114
122
  export declare class TuiMessageObserverRuntime extends Service {
115
- private readonly grantsOption;
116
- private readonly fallbackGrants;
117
- private readonly ledgerOption;
118
- private readonly subscriptions;
119
- private readonly validateEnvelope;
120
- private readonly validatorUnavailable;
121
- private validatorWarned;
122
- private buildChain;
123
+ #private;
123
124
  constructor(ctx: Context, options?: {
124
125
  grants?: GrantStore;
125
126
  ledger?: TuiEffectLedgerRuntime;
@@ -147,13 +148,6 @@ export declare class TuiMessageObserverRuntime extends Service {
147
148
  subscribe(pluginCtx: Context, listener: MessagesObserveListener, options: {
148
149
  scope: string;
149
150
  }): () => void;
150
- /**
151
- * Publish a session event (channel `session/event` arm). Non-mapped
152
- * event types return immediately; everything else never throws into the
153
- * caller — problems are warned, not raised.
154
- */
155
- publish(session: unknown, event: unknown): void;
156
- private publishGuarded;
157
151
  private buildAndDeliver;
158
152
  /** Release a subscription exactly once (disposer, ctx unload, revoke). */
159
153
  private drop;
@@ -175,4 +169,5 @@ export declare class TuiMessageObserverRuntime extends Service {
175
169
  * drop (unreadable, oversize, bad media type, no attachment store). */
176
170
  private imageBlockOf;
177
171
  }
172
+ export declare function getHostMessageObserver(runtime: TuiMessageObserverRuntime | undefined): TuiMessageObserverHost | undefined;
178
173
  //# sourceMappingURL=message-observer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-observer.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/message-observer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"message-observer.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/message-observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKtD,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAchE,mEAAmE;AACnE,MAAM,MAAM,2BAA2B,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAErD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,cAAc,CAAA;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,2BAA2B,EAAE,CAAA;IACtC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,gEAAgE;AAChE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,kBAAkB,CAAA;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAA;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,sBAAsB,CAAA;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,CAAC,QAAQ,EAAE,uBAAuB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAEjG;kFACkF;AAClF,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;CAChD;AAED,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,MAAM,CAAA;AACxC,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB,SAAS,CAAA;AAC/C,0CAA0C;AAC1C,eAAO,MAAM,uBAAuB,MAA0B,CAAA;AAC9D,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,MAAM,CAAA;AACvC,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,QAAa,CAAA;AACjD,8DAA8D;AAC9D,eAAO,MAAM,8BAA8B,SAAS,CAAA;AACpD,8EAA8E;AAC9E,eAAO,MAAM,2BAA2B,OAAO,CAAA;AAC/C;4EAC4E;AAC5E,eAAO,MAAM,4BAA4B,KAAK,CAAA;AAC9C;6EAC6E;AAC7E,eAAO,MAAM,6BAA6B,OAAO,CAAA;AA6FjD,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,kBAAkB,EAAE,yBAAyB,CAAA;KAC9C;CACF;AAED;;;;;;GAMG;AACH,qBAAa,yBAA0B,SAAQ,OAAO;;gBAElD,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,UAAU,CAAA;QACnB,MAAM,CAAC,EAAE,sBAAsB,CAAA;QAC/B,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;QAC3C,gEAAgE;QAChE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC;IAwCR;;;gDAG4C;IAC5C,OAAO,CAAC,MAAM;IAKd,2EAA2E;IAC3E,OAAO,CAAC,MAAM;IAKd;;;;;;;;;OASG;IACH,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,IAAI;YAqH1F,eAAe;IA2H7B,0EAA0E;IAC1E,OAAO,CAAC,IAAI;IAYZ,4EAA4E;IAC5E,OAAO,CAAC,MAAM;IAWd;;;;;;;;;OASG;YACW,SAAS;IAuDvB;;4EAEwE;YAC1D,YAAY;CAiC3B;AAKD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,yBAAyB,GAAG,SAAS,GAAG,sBAAsB,GAAG,SAAS,CAOzH"}
@@ -55,8 +55,9 @@ import { Service } from '@deepseek-ai/cordis';
55
55
  import { validateMessageEvent } from '@dsh-std/messages';
56
56
  import { check } from '../plugin-spec/schema-check.js';
57
57
  import { cleanScalarText } from './sanitize.js';
58
+ import { activationContext, assertCallerContext, bindCallerEffect, compositionRoot, concreteService } from './host-access.js';
58
59
  import { readGrantStore } from './grants.js';
59
- import { declaresObserverScope, declaresPermission, requireComponentIdentity, } from './component-identity.js';
60
+ import { declaresObserverScope, declaresPermission, requireComponentIdentity, requiresContract, } from './component-identity.js';
60
61
  import { normalizePermissionScope, scopeCovers, SESSION_SCOPE_MAX_CHARS, } from '../plugin-spec/permission-scope.js';
61
62
  /** Summary bound (cells; schema maxLength 1024 chars — 200 cells ≤ 1024). */
62
63
  export const OBSERVE_SUMMARY_CELLS = 200;
@@ -75,6 +76,9 @@ export const OBSERVE_CALLBACK_TIMEOUT_MS = 1500;
75
76
  /** Bound queued callbacks per subscription so a stalled listener cannot grow
76
77
  * an unbounded Promise chain before its timeout closes the subscription. */
77
78
  export const OBSERVE_CALLBACK_QUEUE_LIMIT = 32;
79
+ /** Attachment reads are part of the broker build chain and therefore need an
80
+ * independent bound; a wedged reader must not stall every later envelope. */
81
+ export const OBSERVE_IMAGE_READ_TIMEOUT_MS = 1500;
78
82
  /** The envelope schema's mimeType pattern (image blocks). */
79
83
  const OBSERVE_MIME_PATTERN = /^[A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+$/;
80
84
  function deepFreeze(value) {
@@ -145,45 +149,56 @@ function observerScopeCovers(subscriptionScope, envelopeScope) {
145
149
  * is ever delivered (a host that cannot self-check must not emit).
146
150
  */
147
151
  export class TuiMessageObserverRuntime extends Service {
148
- grantsOption;
149
- fallbackGrants;
150
- ledgerOption;
151
- subscriptions = new Set();
152
- validateEnvelope;
153
- validatorUnavailable;
154
- validatorWarned = false;
155
- buildChain = Promise.resolve();
156
152
  constructor(ctx, options = {}) {
157
153
  super(ctx, 'tuiMessageObserver');
158
- this.grantsOption = options.grants;
159
- this.fallbackGrants = readGrantStore();
160
- this.ledgerOption = options.ledger;
154
+ const state = {
155
+ hostContext: compositionRoot(ctx),
156
+ grantsOption: options.grants,
157
+ fallbackGrants: readGrantStore(),
158
+ ledgerOption: options.ledger,
159
+ subscriptions: new Set(),
160
+ validateEnvelope: validateMessageEvent,
161
+ validatorUnavailable: false,
162
+ validatorWarned: false,
163
+ buildChain: Promise.resolve(),
164
+ };
165
+ const runtime = this;
166
+ const host = Object.freeze({
167
+ publish: (session, event) => {
168
+ try {
169
+ runtime.#publishGuarded(session, event);
170
+ }
171
+ catch (error) {
172
+ runtime.ctx.logger.warn('dsh-tui: messages.observe publish failed (event dropped)');
173
+ }
174
+ },
175
+ });
176
+ hostMessageObservers.set(runtime, host);
161
177
  if (Object.hasOwn(options, 'validateEnvelope')) {
162
- this.validatorUnavailable = options.validateEnvelope === undefined;
163
- this.validateEnvelope = options.validateEnvelope ?? (() => { throw new Error('standard envelope validator unavailable'); });
178
+ state.validatorUnavailable = options.validateEnvelope === undefined;
179
+ state.validateEnvelope = options.validateEnvelope ?? (() => { throw new Error('standard envelope validator unavailable'); });
164
180
  }
165
181
  else if (Object.hasOwn(options, 'envelopeSchema')) {
166
182
  const schema = options.envelopeSchema;
167
- this.validatorUnavailable = schema === undefined;
168
- this.validateEnvelope = schema === undefined
183
+ state.validatorUnavailable = schema === undefined;
184
+ state.validateEnvelope = schema === undefined
169
185
  ? (() => { throw new Error('vendored envelope schema unavailable'); })
170
186
  : (value) => check(value, schema, schema);
171
187
  }
172
- else {
173
- this.validatorUnavailable = false;
174
- this.validateEnvelope = (value) => { validateMessageEvent(value); };
175
- }
188
+ observerStates.set(this, state);
176
189
  }
177
190
  /** Grants: the plugin-host row's store when mounted, else a private read.
178
191
  * Resolved PER CALL — sibling services mounted later by the same apply()
179
192
  * are not visible to constructors (cordis), so a constructor-time probe
180
193
  * would silently stick to the fallback. */
181
194
  grants() {
182
- return this.grantsOption ?? this.ctx.get('tuiPluginHost')?.grants ?? this.fallbackGrants;
195
+ const state = observerStateFor(this);
196
+ return state.grantsOption ?? state.hostContext.get('tuiPluginHost')?.grants ?? state.fallbackGrants;
183
197
  }
184
198
  /** Optional observability; a bare mount (tests) simply records nothing. */
185
199
  ledger() {
186
- return this.ledgerOption ?? this.ctx.get('tuiEffectLedger');
200
+ const state = observerStateFor(this);
201
+ return state.ledgerOption ?? state.hostContext.get('tuiEffectLedger');
187
202
  }
188
203
  /**
189
204
  * Subscribe to observation envelopes for ONE scope. Identity = the verified
@@ -196,11 +211,20 @@ export class TuiMessageObserverRuntime extends Service {
196
211
  * unloads.
197
212
  */
198
213
  subscribe(pluginCtx, listener, options) {
199
- const identity = requireComponentIdentity(pluginCtx);
214
+ const caller = activationContext(pluginCtx);
215
+ if (caller === undefined)
216
+ throw new Error('dsh-tui: messages.observe.subscribe requires a live activation context');
217
+ assertCallerContext(this.ctx, caller, 'messages.observe.subscribe', this);
218
+ const identity = requireComponentIdentity(caller);
200
219
  const plugin = identity.componentId;
220
+ if (!requiresContract(identity, 'messages.dsh/v1alpha1', 'MessageObserver')) {
221
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe subscription from Component "${plugin}" denied — ` +
222
+ 'the messages.dsh/v1alpha1#MessageObserver contract was not required');
223
+ return () => false;
224
+ }
201
225
  const scope = typeof options?.scope === 'string' ? options.scope : '';
202
226
  if (scope === '' || scope.length > OBSERVE_SCOPE_MAX_CHARS) {
203
- this.ctx.logger.warn(`dsh-tui: messages.observe subscription from plugin "${plugin}" refused — options.scope must be a ` +
227
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe subscription from plugin "${plugin}" refused — options.scope must be a ` +
204
228
  `non-empty string of at most ${OBSERVE_SCOPE_MAX_CHARS} characters (e.g. "session:<id>")`);
205
229
  return () => false;
206
230
  }
@@ -208,28 +232,28 @@ export class TuiMessageObserverRuntime extends Service {
208
232
  || !declaresObserverScope(identity, scope)
209
233
  || !declaresPermission(identity, 'messages.observe.read', scope)
210
234
  || !this.grants().allows({ componentId: identity.componentId, activationId: identity.activationId }, 'messages.observe.read', scope)) {
211
- this.ctx.logger.warn(`dsh-tui: messages.observe subscription from Component "${plugin}" denied — ` +
235
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe subscription from Component "${plugin}" denied — ` +
212
236
  'the scope is not statically declared or the current grant does not cover it; the listener was NOT registered');
213
237
  this.ledger()?.record({
214
238
  operation: 'bind',
215
239
  resource: { kind: 'permission', id: 'messages.observe.read' },
216
240
  result: 'failed',
217
241
  errorCode: 'PERMISSION_NOT_GRANTED',
218
- }, pluginCtx);
242
+ }, caller);
219
243
  return () => false;
220
244
  }
221
245
  const subscription = {
222
246
  plugin,
223
247
  identity,
224
- ownerContext: pluginCtx,
248
+ ownerContext: caller,
225
249
  scope,
226
250
  listener,
227
251
  chain: Promise.resolve(),
228
252
  pendingCallbacks: 0,
229
253
  closed: false,
230
254
  };
231
- this.subscriptions.add(subscription);
232
- this.ledger()?.record({ operation: 'bind', resource: { kind: 'subscription', id: plugin }, result: 'applied' }, pluginCtx);
255
+ observerStateFor(this).subscriptions.add(subscription);
256
+ this.ledger()?.record({ operation: 'bind', resource: { kind: 'subscription', id: plugin }, result: 'applied' }, caller);
233
257
  const release = () => {
234
258
  if (subscription.closed)
235
259
  return false;
@@ -240,29 +264,12 @@ export class TuiMessageObserverRuntime extends Service {
240
264
  if (!this.grants().allows({ componentId: identity.componentId, activationId: identity.activationId }, 'messages.observe.read', scope))
241
265
  release();
242
266
  });
243
- try {
244
- pluginCtx.effect(() => release);
245
- }
246
- catch {
247
- // Degraded context: the subscription lives until process end.
248
- }
267
+ bindCallerEffect(caller, release);
249
268
  return release;
250
269
  }
251
- /**
252
- * Publish a session event (channel `session/event` arm). Non-mapped
253
- * event types return immediately; everything else never throws into the
254
- * caller — problems are warned, not raised.
255
- */
256
- publish(session, event) {
257
- try {
258
- this.publishGuarded(session, event);
259
- }
260
- catch (error) {
261
- this.ctx.logger.warn(`dsh-tui: messages.observe publish failed (event dropped): ${error instanceof Error ? error.message : String(error)}`);
262
- }
263
- }
264
- publishGuarded(session, event) {
265
- if (this.subscriptions.size === 0)
270
+ #publishGuarded(session, event) {
271
+ const state = observerStateFor(this);
272
+ if (state.subscriptions.size === 0)
266
273
  return;
267
274
  const record = event;
268
275
  const kind = record.type === 'user/message'
@@ -276,7 +283,7 @@ export class TuiMessageObserverRuntime extends Service {
276
283
  return;
277
284
  const sessionId = session?.id;
278
285
  if (typeof sessionId !== 'string' || sessionId === '') {
279
- this.ctx.logger.warn('dsh-tui: messages.observe publish skipped — the session carries no string id');
286
+ observerStateFor(this).hostContext.logger.warn('dsh-tui: messages.observe publish skipped — the session carries no string id');
280
287
  return;
281
288
  }
282
289
  const data = (record.data ?? {});
@@ -285,19 +292,20 @@ export class TuiMessageObserverRuntime extends Service {
285
292
  // Never truncate a session identity into the schema's scope bound: two
286
293
  // distinct long ids can otherwise collapse into one subscription scope.
287
294
  if (scope.length > OBSERVE_SCOPE_MAX_CHARS) {
288
- this.ctx.logger.warn(`dsh-tui: messages.observe publish skipped — the session scope exceeds ${OBSERVE_SCOPE_MAX_CHARS} characters`);
295
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe publish skipped — the session scope exceeds ${OBSERVE_SCOPE_MAX_CHARS} characters`);
289
296
  return;
290
297
  }
291
298
  // C-042 isolation: match subscriptions BEFORE building anything — a
292
299
  // subscription for another scope must never see this scope's content.
293
- const matched = [...this.subscriptions].filter(subscription => !subscription.closed && observerScopeCovers(subscription.scope, scope));
300
+ const matched = [...state.subscriptions].filter(subscription => !subscription.closed && observerScopeCovers(subscription.scope, scope));
294
301
  if (matched.length === 0)
295
302
  return;
296
303
  // Builds serialize broker-wide so delivery order stays the publish
297
304
  // order even though image reads are async (sequence stays monotonic).
298
- this.buildChain = this.buildChain.then(() => this.buildAndDeliver(kind, sessionId, scope, record.seq, message, matched));
305
+ state.buildChain = state.buildChain.then(() => this.buildAndDeliver(kind, sessionId, scope, record.seq, message, matched));
299
306
  }
300
307
  async buildAndDeliver(kind, sessionId, scope, sequence, message, matched) {
308
+ const state = observerStateFor(this);
301
309
  try {
302
310
  const text = this.textOf(message?.content);
303
311
  const { blocks, truncated: contentTruncated } = await this.contentOf(message?.content);
@@ -326,18 +334,18 @@ export class TuiMessageObserverRuntime extends Service {
326
334
  },
327
335
  };
328
336
  // Self-check EVERY envelope with the pinned @dsh-std/messages validator.
329
- if (this.validatorUnavailable) {
330
- if (!this.validatorWarned) {
331
- this.validatorWarned = true;
332
- this.ctx.logger.warn('dsh-tui: standard message envelope validator unavailable — delivery is fail-closed');
337
+ if (state.validatorUnavailable) {
338
+ if (!state.validatorWarned) {
339
+ state.validatorWarned = true;
340
+ observerStateFor(this).hostContext.logger.warn('dsh-tui: standard message envelope validator unavailable — delivery is fail-closed');
333
341
  }
334
342
  return;
335
343
  }
336
344
  try {
337
- this.validateEnvelope(envelope);
345
+ state.validateEnvelope(envelope);
338
346
  }
339
347
  catch (error) {
340
- this.ctx.logger.warn(`dsh-tui: messages.observe envelope failed the standard validator and was dropped: ${error instanceof Error ? error.message : String(error)}`);
348
+ observerStateFor(this).hostContext.logger.warn('dsh-tui: messages.observe envelope failed the standard validator and was dropped');
341
349
  return;
342
350
  }
343
351
  for (const subscription of matched) {
@@ -346,12 +354,12 @@ export class TuiMessageObserverRuntime extends Service {
346
354
  // Deliver-time grant re-check: a revoked grant RELEASES the
347
355
  // subscription (contract cleanup rule), with one warning.
348
356
  if (!this.grants().allows({ componentId: subscription.identity.componentId, activationId: subscription.identity.activationId }, 'messages.observe.read', scope)) {
349
- this.ctx.logger.warn(`dsh-tui: messages.observe subscription of plugin "${subscription.plugin}" released — the grant was revoked`);
357
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe subscription of plugin "${subscription.plugin}" released — the grant was revoked`);
350
358
  this.drop(subscription);
351
359
  continue;
352
360
  }
353
361
  if (subscription.pendingCallbacks >= OBSERVE_CALLBACK_QUEUE_LIMIT) {
354
- this.ctx.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" reached its ` +
362
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" reached its ` +
355
363
  `${OBSERVE_CALLBACK_QUEUE_LIMIT}-callback queue limit; this envelope was skipped`);
356
364
  continue;
357
365
  }
@@ -359,25 +367,33 @@ export class TuiMessageObserverRuntime extends Service {
359
367
  const run = subscription.chain.then(async () => {
360
368
  if (subscription.closed)
361
369
  return;
370
+ // Re-check at the actual callback boundary as well as at enqueue
371
+ // time. A grant may be revoked while an earlier callback is still
372
+ // running; queued envelopes must then be skipped rather than
373
+ // delivered from the stale pre-revocation snapshot.
374
+ if (!this.grants().allows({ componentId: subscription.identity.componentId, activationId: subscription.identity.activationId }, 'messages.observe.read', scope)) {
375
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe subscription of plugin "${subscription.plugin}" released — the grant was revoked`);
376
+ this.drop(subscription);
377
+ return;
378
+ }
362
379
  const isolated = freezeEnvelope(envelope);
363
380
  const result = await runWithBudget(() => subscription.listener(isolated), OBSERVE_CALLBACK_TIMEOUT_MS);
364
381
  if (result.kind === 'timeout') {
365
- this.ctx.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" exceeded ` +
382
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" exceeded ` +
366
383
  `${OBSERVE_CALLBACK_TIMEOUT_MS}ms and the subscription was closed`);
367
384
  this.drop(subscription);
368
385
  }
369
386
  else if (result.kind === 'rejected') {
370
- this.ctx.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" failed; delivery continues: ` +
371
- `${result.error instanceof Error ? result.error.message : String(result.error)}`);
387
+ observerStateFor(this).hostContext.logger.warn(`dsh-tui: messages.observe listener of Component "${subscription.plugin}" failed; delivery continues`);
372
388
  }
373
389
  });
374
390
  subscription.chain = run.catch(error => {
375
- this.ctx.logger.warn(`dsh-tui: messages.observe delivery failed: ${error instanceof Error ? error.message : String(error)}`);
391
+ observerStateFor(this).hostContext.logger.warn('dsh-tui: messages.observe delivery failed');
376
392
  }).finally(() => { subscription.pendingCallbacks -= 1; });
377
393
  }
378
394
  }
379
395
  catch (error) {
380
- this.ctx.logger.warn(`dsh-tui: messages.observe publish failed (event dropped): ${error instanceof Error ? error.message : String(error)}`);
396
+ observerStateFor(this).hostContext.logger.warn('dsh-tui: messages.observe publish failed (event dropped)');
381
397
  }
382
398
  }
383
399
  /** Release a subscription exactly once (disposer, ctx unload, revoke). */
@@ -387,7 +403,7 @@ export class TuiMessageObserverRuntime extends Service {
387
403
  subscription.closed = true;
388
404
  subscription.stopGrantWatch?.();
389
405
  subscription.stopGrantWatch = undefined;
390
- this.subscriptions.delete(subscription);
406
+ observerStateFor(this).subscriptions.delete(subscription);
391
407
  this.ledger()?.record({ operation: 'release', resource: { kind: 'subscription', id: subscription.plugin }, result: 'applied' }, subscription.ownerContext);
392
408
  }
393
409
  /** Join the text blocks of a session message's content (text-only view). */
@@ -486,12 +502,21 @@ export class TuiMessageObserverRuntime extends Service {
486
502
  const bytes = attachment.bytes;
487
503
  if (typeof bytes !== 'number' || !Number.isFinite(bytes) || bytes < 0 || bytes > OBSERVE_IMAGE_MAX_BYTES)
488
504
  return undefined;
489
- const reader = this.ctx.get('attachments');
505
+ const reader = observerStateFor(this).hostContext.get('attachments');
490
506
  if (typeof reader?.readImage !== 'function')
491
507
  return undefined;
492
508
  // A failing read drops ONLY this image (the envelope survives with the
493
509
  // truncation mark) — one corrupt attachment must not nuke the message.
494
- const stored = await reader.readImage(attachment);
510
+ let timer;
511
+ const read = Promise.resolve().then(() => reader.readImage(attachment));
512
+ const timeout = new Promise(resolve => {
513
+ timer = setTimeout(() => resolve(undefined), OBSERVE_IMAGE_READ_TIMEOUT_MS);
514
+ });
515
+ const stored = await Promise.race([read, timeout]);
516
+ if (timer !== undefined)
517
+ clearTimeout(timer);
518
+ // `read` has an attached rejection handler through the race's promise
519
+ // chain; late completion after a timeout is deliberately ignored.
495
520
  const data = stored?.data;
496
521
  if (!(data instanceof Uint8Array) || data.byteLength > OBSERVE_IMAGE_MAX_BYTES)
497
522
  return undefined;
@@ -507,3 +532,22 @@ export class TuiMessageObserverRuntime extends Service {
507
532
  }
508
533
  }
509
534
  }
535
+ /** Host-only ingress accessor; deliberately omitted from `./plugin-host`. */
536
+ const hostMessageObservers = new WeakMap();
537
+ export function getHostMessageObserver(runtime) {
538
+ if (runtime === undefined)
539
+ return undefined;
540
+ try {
541
+ return hostMessageObservers.get(concreteService(runtime));
542
+ }
543
+ catch {
544
+ return undefined;
545
+ }
546
+ }
547
+ const observerStates = new WeakMap();
548
+ function observerStateFor(runtime) {
549
+ const state = observerStates.get(concreteService(runtime));
550
+ if (state === undefined)
551
+ throw new Error('tuiMessageObserver host state is unavailable');
552
+ return state;
553
+ }
@@ -39,19 +39,33 @@ import { type GrantStore } from './grants.js';
39
39
  import { type HostDescriptorBuild } from './host-descriptor.js';
40
40
  import { type DecisionRegistrationOptions } from './decision-guard.js';
41
41
  import { type VerifiedComponentIdentity } from './component-identity.js';
42
+ /** Public, mediated plugin-host capability. Loader-only admission remains
43
+ * behind getHostAdmission(), which is deliberately omitted from the package
44
+ * export surface. */
45
+ export interface TuiPluginHost {
46
+ readonly generationId: string;
47
+ readonly grants: GrantStore;
48
+ hostDescriptor(): HostDescriptor;
49
+ describe(): HostDescriptorBuild;
50
+ subscribeDecision(pluginCtx: Context, event: string, listener: (payload: Record<string, unknown>) => unknown, options?: {
51
+ scope?: string;
52
+ order?: string;
53
+ }): () => boolean;
54
+ registerCommand(pluginCtx: Context, definition: CommandDefinition): () => void;
55
+ registerCommand(pluginCtx: Context, contributionId: string, definition: CommandDefinition): () => void;
56
+ selfCheck(): string[];
57
+ }
42
58
  declare module '@deepseek-ai/cordis' {
43
59
  interface Context {
44
- tuiPluginHost: TuiPluginHostRuntime;
60
+ tuiPluginHost: TuiPluginHost;
45
61
  }
46
62
  }
47
63
  /** `ctx.tuiPluginHost` — plugin-interop anchor (generation, grants, descriptor). */
48
- export declare class TuiPluginHostRuntime extends Service {
64
+ export declare class TuiPluginHostRuntime extends Service implements TuiPluginHost {
49
65
  /** Runtime generation id (C-050): fresh per activation of this row. */
50
- readonly generationId: `${string}-${string}-${string}-${string}-${string}`;
66
+ get generationId(): string;
51
67
  /** Live scoped grant store; every operation observes the current file. */
52
- readonly grants: GrantStore;
53
- private descriptorBuild;
54
- private descriptorCommandsMounted;
68
+ get grants(): GrantStore;
55
69
  constructor(ctx: Context);
56
70
  /**
57
71
  * The C-010 Host Descriptor, built lazily and cached while the
@@ -69,6 +83,11 @@ export declare class TuiPluginHostRuntime extends Service {
69
83
  source?: string;
70
84
  activationId?: string;
71
85
  }): VerifiedComponentIdentity;
86
+ /** @internal Host loader entry; the unexported token prevents proxy calls. */
87
+ admitInternal(pluginCtx: Context, source: string, options?: {
88
+ source?: string;
89
+ activationId?: string;
90
+ }, token?: symbol): VerifiedComponentIdentity;
72
91
  /**
73
92
  * Host-mediated DecisionEvents activation surface. A plugin cannot use a
74
93
  * raw `ctx.on` for these points: the verified Component identity, static
@@ -98,6 +117,20 @@ export declare class TuiPluginHostRuntime extends Service {
98
117
  */
99
118
  selfCheck(): string[];
100
119
  }
120
+ /**
121
+ * Loader-only admission capability. It is intentionally omitted from the
122
+ * package `plugin-host` export; tests and the in-process loader can obtain it
123
+ * from this adapter module, while a plugin calling the public service proxy
124
+ * receives a deterministic denial instead of being able to impersonate a
125
+ * different manifest identity.
126
+ */
127
+ export interface HostAdmission {
128
+ admit(pluginCtx: Context, source: string, options?: {
129
+ source?: string;
130
+ activationId?: string;
131
+ }): VerifiedComponentIdentity;
132
+ }
133
+ export declare function getHostAdmission(runtime: TuiPluginHost | TuiPluginHostRuntime | undefined): HostAdmission | undefined;
101
134
  export declare const name = "dsh-tui-plugin-host";
102
135
  export declare function apply(ctx: Context): void;
103
136
  //# sourceMappingURL=plugin-host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-host.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAEtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAI7D,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,EAAiD,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAM9G,OAAO,EAKL,KAAK,2BAA2B,EACjC,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAKL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAEhC,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,aAAa,EAAE,oBAAoB,CAAA;KACpC;CACF;AAED,oFAAoF;AACpF,qBAAa,oBAAqB,SAAQ,OAAO;IAC/C,uEAAuE;IACvE,QAAQ,CAAC,YAAY,sDAAe;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAE3B,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,yBAAyB,CAAqB;gBAE1C,GAAG,EAAE,OAAO;IAexB;;;OAGG;IACH,cAAc,IAAI,cAAc;IAIhC,2EAA2E;IAC3E,QAAQ,IAAI,mBAAmB;IAI/B,OAAO,CAAC,KAAK;IAuBb;;;OAGG;IACH,KAAK,CACH,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAO,GACvD,yBAAyB;IA4B5B;;;;;;OAMG;IACH,iBAAiB,CACf,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,EACvD,OAAO,GAAE,2BAAgC,GACxC,MAAM,OAAO;IAgDhB;;;;;;;;;;;MAWE;IACF,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAC9E,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAyFtG;;;;OAIG;IACH,SAAS,IAAI,MAAM,EAAE;CAKtB;AAED,eAAO,MAAM,IAAI,wBAAwB,CAAA;AAEzC,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAaxC"}
1
+ {"version":3,"file":"plugin-host.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin-host.ts"],"names":[],"mappings":"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"}