@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
@@ -26,10 +26,10 @@
26
26
  * The map is keyed by the cordis ROOT so the row and the channel (two
27
27
  * different contexts of one runtime) share one view.
28
28
  */
29
+ import { compositionRoot } from './host-access.js';
29
30
  const ownerMaps = new WeakMap();
30
31
  function rootKeyOf(ctx) {
31
- const root = ctx.root ?? ctx;
32
- return typeof root === 'object' && root !== null ? root : undefined;
32
+ return compositionRoot(ctx);
33
33
  }
34
34
  /** The registrant's display name for diagnostics only: the passed context's
35
35
  * fiber name (nearest named ancestor), 'root' for host-side or degraded
@@ -9,6 +9,12 @@ export interface TuiCommandTreeProvider {
9
9
  /** Children for the full canonical path, including `root` at index zero. */
10
10
  children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
11
11
  }
12
+ /** Host-only completion access. Plugins see only their own provider through
13
+ * the traceable service; the channel uses this facade to merge all providers. */
14
+ export interface TuiCommandTreeHost {
15
+ children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
16
+ descriptions(root: string): LocalizedDescriptions | undefined;
17
+ }
12
18
  declare module '@deepseek-ai/cordis' {
13
19
  interface Context {
14
20
  tuiCommandTrees: TuiCommandTreeRuntime;
@@ -17,11 +23,11 @@ declare module '@deepseek-ai/cordis' {
17
23
  export declare const name = "dsh-tui-command-trees";
18
24
  /** Small host-only registry; command execution remains owned by dsh-commands. */
19
25
  export declare class TuiCommandTreeRuntime extends Service {
20
- private readonly providers;
21
26
  constructor(ctx: Context);
22
27
  register(provider: TuiCommandTreeProvider): () => void;
23
28
  children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
24
29
  descriptions(root: string): LocalizedDescriptions | undefined;
25
30
  }
31
+ export declare function getHostCommandTrees(runtime: TuiCommandTreeRuntime | undefined): TuiCommandTreeHost | undefined;
26
32
  export default TuiCommandTreeRuntime;
27
33
  //# sourceMappingURL=command-trees.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAElF,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;CAC7E;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,qBAAqB,CAAA;KACvC;CACF;AAED,eAAO,MAAM,IAAI,0BAA0B,CAAA;AAE3C,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,OAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;gBAE1D,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAWtD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE;IAa5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;CAG9D;AAED,eAAe,qBAAqB,CAAA"}
1
+ {"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGlF,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;CAC7E;AAED;iFACiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;IAC5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAA;CAC9D;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,qBAAqB,CAAA;KACvC;CACF;AAED,eAAO,MAAM,IAAI,0BAA0B,CAAA;AAE3C,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,OAAO;gBACpC,GAAG,EAAE,OAAO;IAYxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAoBtD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE;IAM5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;CAK9D;AAyCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAO9G;AAED,eAAe,qBAAqB,CAAA"}
@@ -1,42 +1,92 @@
1
1
  /** Provider-neutral subcommand completion registry for terminal front doors. */
2
2
  import { Service } from '@deepseek-ai/cordis';
3
+ import { activationFiber, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
3
4
  export const name = 'dsh-tui-command-trees';
4
5
  /** Small host-only registry; command execution remains owned by dsh-commands. */
5
6
  export class TuiCommandTreeRuntime extends Service {
6
- providers = new Map();
7
7
  constructor(ctx) {
8
8
  super(ctx, 'tuiCommandTrees');
9
+ compositionRoot(ctx);
10
+ const runtime = this;
11
+ const state = { providers: new Map(), owners: new Map(), host: undefined };
12
+ state.host = Object.freeze({
13
+ children: path => childrenFor(runtime, path),
14
+ descriptions: root => descriptionsFor(runtime, root),
15
+ });
16
+ commandTreeStates.set(this, state);
9
17
  }
10
18
  register(provider) {
19
+ const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.register', this);
20
+ const state = commandTreeStateFor(this);
21
+ const owner = activationFiber(caller);
22
+ if (owner === undefined)
23
+ throw new Error('dsh-tui: tuiCommandTrees.register requires a live activation');
11
24
  const root = provider.root.trim().toLowerCase();
12
25
  if (!/^[a-z][a-z0-9_-]*$/u.test(root))
13
26
  throw new TypeError(`invalid TUI command-tree root: ${provider.root}`);
14
- if (this.providers.has(root))
27
+ if (state.providers.has(root))
15
28
  throw new Error(`TUI command-tree root "${root}" is already registered`);
16
29
  const normalized = { ...provider, root };
17
- this.providers.set(root, normalized);
18
- return () => {
19
- if (this.providers.get(root) === normalized)
20
- this.providers.delete(root);
30
+ state.providers.set(root, normalized);
31
+ state.owners.set(root, owner);
32
+ const dispose = () => {
33
+ if (state.providers.get(root) !== normalized)
34
+ return;
35
+ state.providers.delete(root);
36
+ state.owners.delete(root);
21
37
  };
38
+ bindCallerEffect(caller, dispose);
39
+ return dispose;
22
40
  }
23
41
  children(canonicalPath) {
24
- const root = canonicalPath[0]?.toLowerCase();
25
- if (root === undefined)
26
- return [];
27
- const provider = this.providers.get(root);
28
- if (provider === undefined)
29
- return [];
30
- try {
31
- return provider.children(canonicalPath);
32
- }
33
- catch {
34
- // Completion is optional UI metadata and must never block execution.
35
- return [];
36
- }
42
+ const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.children', this);
43
+ const owner = activationFiber(caller);
44
+ return childrenFor(this, canonicalPath, owner);
37
45
  }
38
46
  descriptions(root) {
39
- return this.providers.get(root.trim().toLowerCase())?.descriptions;
47
+ const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.descriptions', this);
48
+ const owner = activationFiber(caller);
49
+ return descriptionsFor(this, root, owner);
50
+ }
51
+ }
52
+ const commandTreeStates = new WeakMap();
53
+ function commandTreeStateFor(runtime) {
54
+ const state = commandTreeStates.get(concreteService(runtime));
55
+ if (state === undefined)
56
+ throw new Error('tuiCommandTrees host state is unavailable');
57
+ return state;
58
+ }
59
+ function childrenFor(runtime, canonicalPath, owner) {
60
+ const state = commandTreeStateFor(runtime);
61
+ const root = canonicalPath[0]?.toLowerCase();
62
+ if (root === undefined || (owner !== undefined && state.owners.get(root) !== owner))
63
+ return [];
64
+ const provider = state.providers.get(root);
65
+ if (provider === undefined)
66
+ return [];
67
+ try {
68
+ return provider.children(canonicalPath);
69
+ }
70
+ catch {
71
+ // Completion is optional UI metadata and must never block execution.
72
+ return [];
73
+ }
74
+ }
75
+ function descriptionsFor(runtime, root, owner) {
76
+ const state = commandTreeStateFor(runtime);
77
+ const normalized = root.trim().toLowerCase();
78
+ if (owner !== undefined && state.owners.get(normalized) !== owner)
79
+ return undefined;
80
+ return state.providers.get(normalized)?.descriptions;
81
+ }
82
+ export function getHostCommandTrees(runtime) {
83
+ if (runtime === undefined)
84
+ return undefined;
85
+ try {
86
+ return commandTreeStateFor(runtime).host;
87
+ }
88
+ catch {
89
+ return undefined;
40
90
  }
41
91
  }
42
92
  export default TuiCommandTreeRuntime;
@@ -25,4 +25,9 @@ export declare function declaresPermission(identity: VerifiedComponentIdentity,
25
25
  export declare function declaresCommand(identity: VerifiedComponentIdentity, commandId: string): boolean;
26
26
  export declare function declaresObserverScope(identity: VerifiedComponentIdentity, actualScope: string): boolean;
27
27
  export declare function requiresDecisionEvents(identity: VerifiedComponentIdentity): boolean;
28
+ /** Whether admission negotiated the protocol that backs a mediated runtime
29
+ * capability. Permissions alone are not a capability grant: a plugin must
30
+ * explicitly require the corresponding contract before the host can expose
31
+ * its calls. */
32
+ export declare function requiresContract(identity: VerifiedComponentIdentity, apiVersion: string, kind: string): boolean;
28
33
  //# sourceMappingURL=component-identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component-identity.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/component-identity.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAG1E,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,GAAG,4BAA4B,CAAA;AAEhG,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,0BAA0B;gBAAhC,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM;CAIvE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;CACvC;AAED;;oDAEoD;AACpD,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAyB3C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,GAAE,MAAqB,GAClC,yBAAyB,CA2B3B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAM3F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CASpF;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAQT;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAUvG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,OAAO,CAGnF"}
1
+ {"version":3,"file":"component-identity.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/component-identity.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAI1E,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,GAAG,4BAA4B,CAAA;AAEhG,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,0BAA0B;gBAAhC,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM;CAIvE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;CACvC;AAED;;oDAEoD;AACpD,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAqB3C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,GAAE,MAAqB,GAClC,yBAAyB,CAyB3B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAM3F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CASpF;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAQT;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAUvG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,OAAO,CAEnF;AAED;;;gBAGgB;AAChB,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAGT"}
@@ -1,6 +1,7 @@
1
1
  /** Verified Component identity bound to one Cordis activation owner. */
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { normalizePermissionScope, scopeCovers } from '../plugin-spec/permission-scope.js';
4
+ import { activationFiber, bindCallerEffect } from './host-access.js';
4
5
  export class ComponentIdentityError extends Error {
5
6
  code;
6
7
  constructor(code, message) {
@@ -22,14 +23,9 @@ function validateActivationId(value) {
22
23
  }
23
24
  const identities = new WeakMap();
24
25
  function ownerKey(context) {
25
- try {
26
- const fiber = context.fiber;
27
- if (typeof fiber === 'object' && fiber !== null)
28
- return fiber;
29
- }
30
- catch {
31
- // A real plugin context always has a fiber; reject degraded callers below.
32
- }
26
+ const fiber = activationFiber(context);
27
+ if (fiber !== undefined)
28
+ return fiber;
33
29
  throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED', 'a Component activation requires an owning Cordis fiber');
34
30
  }
35
31
  export function bindComponentIdentity(context, manifest, projection, activationId = randomUUID()) {
@@ -50,12 +46,9 @@ export function bindComponentIdentity(context, manifest, projection, activationI
50
46
  if (identities.get(key) === identity)
51
47
  identities.delete(key);
52
48
  };
53
- try {
54
- context.effect(() => release);
55
- }
56
- catch (error) {
49
+ if (!bindCallerEffect(context, release)) {
57
50
  identities.delete(key);
58
- throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED', `cannot bind Component identity to an inactive activation: ${error instanceof Error ? error.message : String(error)}`);
51
+ throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED', 'cannot bind Component identity to an inactive activation');
59
52
  }
60
53
  return identity;
61
54
  }
@@ -104,5 +97,12 @@ export function declaresObserverScope(identity, actualScope) {
104
97
  });
105
98
  }
106
99
  export function requiresDecisionEvents(identity) {
107
- return identity.manifest.requires.contracts.some(requirement => requirement.apiVersion === 'tui.dsh/v1alpha1' && requirement.kind === 'DecisionEvents');
100
+ return requiresContract(identity, 'tui.dsh/v1alpha1', 'DecisionEvents');
101
+ }
102
+ /** Whether admission negotiated the protocol that backs a mediated runtime
103
+ * capability. Permissions alone are not a capability grant: a plugin must
104
+ * explicitly require the corresponding contract before the host can expose
105
+ * its calls. */
106
+ export function requiresContract(identity, apiVersion, kind) {
107
+ return identity.manifest.requires.contracts.some(requirement => requirement.apiVersion === apiVersion && requirement.kind === kind);
108
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"decision-guard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/decision-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EACL,qBAAqB,EAGrB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAQhC;;qDAEqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKvE,CAAA;AAMD,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,eAAe,GAAG,UAAU,CAAA;AAExC,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAA4B,CAAA;AAEjF,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,UAA2B,CAAA;AAgB/E,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAGD;;;cAGc;AACd,MAAM,WAAW,2BAA2B;IAC1C;kFAC8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;sEACkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAA;IAC5C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAA;CACjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAA;IAClB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAA;CAC9D;AAsBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAEjE;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,SAAS,yBAAyB,EAAE,CA6BtC;AAsCD,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,yBAAyB,EACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,EACvD,OAAO,GAAE,2BAAgC,EACzC,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,MAAM,OAAO,CA4Ff;AAkBD,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAI9E;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB,GAAG,SAAS,CAEjG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+D3E"}
1
+ {"version":3,"file":"decision-guard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/decision-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EACL,qBAAqB,EAGrB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAShC;;qDAEqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKtE,CAAA;AAMF,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,eAAe,GAAG,UAAU,CAAA;AAExC,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAA4B,CAAA;AAEjF,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,UAA2B,CAAA;AAgB/E,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAGD;;;cAGc;AACd,MAAM,WAAW,2BAA2B;IAC1C;kFAC8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;sEACkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAA;IAC5C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAA;CACjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAA;IAClB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAA;CAC9D;AAoBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAEjE;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,SAAS,yBAAyB,EAAE,CA6BtC;AAsCD,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,yBAAyB,EACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,EACvD,OAAO,GAAE,2BAAgC,EACzC,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,MAAM,OAAO,CA8Ff;AAkBD,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAI9E;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB,GAAG,SAAS,CAEjG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+D3E"}
@@ -30,15 +30,16 @@ import { EXTENSION_GRANTS_FILE, parseGrantStore, readGrantStore, } from './grant
30
30
  import { componentIdentityOf, requiresDecisionEvents, } from './component-identity.js';
31
31
  import { INTERCEPT_EVENT_SCOPE_BY_PERMISSION, normalizePermissionScope, permissionScopeCovers, } from '../plugin-spec/permission-scope.js';
32
32
  import { TUI_DECISION_EVENT_NAMES } from '../plugin-spec/tui-extension.js';
33
+ import { bindCallerEffect, compositionRoot } from './host-access.js';
33
34
  /** The intercept permission each decision event requires (D-7 naming:
34
35
  * `domain.resource.intercept`). Observe-class events (tui/rewind-done,
35
36
  * tui/session-switched) are deliberately absent. */
36
- export const DECISION_EVENT_PERMISSIONS = {
37
+ export const DECISION_EVENT_PERMISSIONS = Object.freeze({
37
38
  'tui/input': 'session.input.intercept',
38
39
  'tui/rewind-prompt': 'session.rewind.intercept',
39
40
  'tui/session-switch': 'session.switch.intercept',
40
41
  'tui/compact': 'session.compact.intercept',
41
- };
42
+ });
42
43
  // ── Compatibility aliases (pre-GrantStore names) ────────────────────────────
43
44
  // The grant-file format and these entry points predate the unified store;
44
45
  // keep them working — verify batteries and any embedder code import them
@@ -65,10 +66,7 @@ const guardedRoots = new WeakSet();
65
66
  const handlerMetadata = new WeakMap();
66
67
  const registries = new WeakMap();
67
68
  function rootKey(ctx) {
68
- const root = ctx.root;
69
- if (typeof root === 'object' && root !== null)
70
- return root;
71
- return ctx;
69
+ return compositionRoot(ctx);
72
70
  }
73
71
  function registryFor(ctx, grants) {
74
72
  const key = rootKey(ctx);
@@ -244,11 +242,10 @@ export function registerDecisionHandler(pluginCtx, identity, event, listener, op
244
242
  }
245
243
  return true;
246
244
  };
247
- // Both deactivation and grant-file revocation are release boundaries.
248
- try {
249
- pluginCtx.effect(() => release);
250
- }
251
- catch { /* degraded test context */ }
245
+ // Both deactivation and grant-file revocation are release boundaries. Bind
246
+ // through the host-captured Fiber effect so an explicit Context shadow
247
+ // cannot replace the cleanup function.
248
+ bindCallerEffect(pluginCtx, release);
252
249
  if (permission !== undefined) {
253
250
  const stop = registry.grants.onChange?.(() => {
254
251
  const principal = { componentId: identity.componentId, activationId: identity.activationId };
@@ -257,10 +254,7 @@ export function registerDecisionHandler(pluginCtx, identity, event, listener, op
257
254
  });
258
255
  stopGrantWatch = stop;
259
256
  if (stop !== undefined) {
260
- try {
261
- pluginCtx.effect(() => stop);
262
- }
263
- catch { /* degraded test context */ }
257
+ bindCallerEffect(pluginCtx, stop);
264
258
  }
265
259
  }
266
260
  return release;
@@ -295,7 +289,7 @@ export function installDecisionGuard(ctx, grants) {
295
289
  // `root` or `on` entirely — the gate is best-effort there, matching the
296
290
  // channel's soft-degradation posture: no dedup bookkeeping without a root
297
291
  // object, no hook without an `on`.
298
- const root = ctx.root ?? ctx;
292
+ const root = compositionRoot(ctx);
299
293
  // Keep the live grant source even when another row installed the Cordis
300
294
  // hook first. The file-backed GrantStore evaluates each operation again.
301
295
  registryFor(ctx, grants);
@@ -89,7 +89,7 @@ export declare class TuiDialogStore {
89
89
  private readonly queue;
90
90
  private active;
91
91
  /** Park a request. The snapshot argument must already be sanitized. */
92
- ask(snapshot: WithoutKey<TuiDialogSnapshot>, signal?: AbortSignal, timeoutMs?: number, owner?: Context): Promise<TuiDialogAnswer>;
92
+ ask(snapshot: WithoutKey<TuiDialogSnapshot>, signal?: AbortSignal, timeoutMs?: number, owner?: Context, bindOwnerEffect?: (disposer: () => unknown, onRegistered: (cleanup: () => unknown) => void) => boolean): Promise<TuiDialogAnswer>;
93
93
  /** The dialog the UI should render right now, if any. */
94
94
  getSnapshot(): TuiDialogSnapshot | null;
95
95
  /**
@@ -124,8 +124,6 @@ declare module '@deepseek-ai/cordis' {
124
124
  * down; callers get a logger warning instead.
125
125
  */
126
126
  export declare class TuiDialogRuntime extends Service {
127
- /** The queue the chat screen renders. Exposed for the host, not plugins. */
128
- readonly store: TuiDialogStore;
129
127
  constructor(ctx: Context);
130
128
  /** Cordis traceable services normally provide the caller through `this.ctx`;
131
129
  * the explicit overloads below make ownership unambiguous for embedders and
@@ -142,5 +140,6 @@ export declare class TuiDialogRuntime extends Service {
142
140
  input(request: TuiDialogInputRequest): Promise<string | undefined>;
143
141
  input(owner: Context, request: TuiDialogInputRequest): Promise<string | undefined>;
144
142
  }
143
+ export declare function getHostDialogStore(runtime: TuiDialogRuntime | undefined): TuiDialogStore | undefined;
145
144
  export default TuiDialogRuntime;
146
145
  //# sourceMappingURL=dialogs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/dialogs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/dialogs.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@
20
20
  */
21
21
  import { Context, Service } from '@deepseek-ai/cordis';
22
22
  import { cleanScalarText } from './sanitize.js';
23
+ import { activationContext, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
23
24
  /** Render-path strings are untrusted: sanitization (control-char stripping,
24
25
  * cell-width caps, scalar-only coercion) lives in ./sanitize.js — the one
25
26
  * implementation of the Track A contract. `clean` drops non-scalars to ''
@@ -45,7 +46,7 @@ export class TuiDialogStore {
45
46
  queue = [];
46
47
  active = null;
47
48
  /** Park a request. The snapshot argument must already be sanitized. */
48
- ask(snapshot, signal, timeoutMs, owner) {
49
+ ask(snapshot, signal, timeoutMs, owner, bindOwnerEffect) {
49
50
  if (signal?.aborted)
50
51
  return Promise.resolve(undefined);
51
52
  return new Promise((resolve) => {
@@ -98,12 +99,10 @@ export class TuiDialogStore {
98
99
  pending.timer = setTimeout(pending.onAbort, timeoutMs);
99
100
  }
100
101
  if (owner !== undefined) {
101
- try {
102
- const disposer = owner.effect(() => pending.onAbort);
103
- pending.ownerCleanup = typeof disposer === 'function' ? disposer : undefined;
104
- }
105
- catch {
106
- // An inactive activation must never leave an orphan in the queue.
102
+ const bound = bindOwnerEffect?.(pending.onAbort, cleanup => { pending.ownerCleanup = cleanup; }) ?? false;
103
+ if (!bound) {
104
+ // An inactive or untrusted activation must never leave an orphan in
105
+ // the queue. The binder also rolls back partial owner state.
107
106
  pending.onAbort();
108
107
  return;
109
108
  }
@@ -179,17 +178,32 @@ export class TuiDialogStore {
179
178
  * down; callers get a logger warning instead.
180
179
  */
181
180
  export class TuiDialogRuntime extends Service {
182
- /** The queue the chat screen renders. Exposed for the host, not plugins. */
183
- store = new TuiDialogStore();
184
181
  constructor(ctx) {
185
182
  super(ctx, 'tuiDialogs');
186
- ctx.effect(() => () => this.store.settleAll());
183
+ compositionRoot(ctx);
184
+ // Keep queue state off the service object. Cordis invokes public methods
185
+ // through a caller-bound proxy, so JS `#private` fields are unsuitable
186
+ // here; the module-local WeakMap preserves both encapsulation and proxy
187
+ // compatibility.
188
+ const store = new TuiDialogStore();
189
+ hostDialogStores.set(this, store);
190
+ ctx.effect(() => () => store.settleAll());
187
191
  }
188
192
  /** Cordis traceable services normally provide the caller through `this.ctx`;
189
193
  * the explicit overloads below make ownership unambiguous for embedders and
190
194
  * tests that retain the service instance directly. */
191
195
  callContext(value) {
192
- return Context.is(value) ? value : this.ctx;
196
+ const caller = requirePluginCaller(this.ctx, 'tuiDialogs', this);
197
+ if (!Context.is(value))
198
+ return caller;
199
+ // An explicit owner is accepted only when it is the activation that made
200
+ // the service call. Otherwise a plugin could pass the root (or another
201
+ // plugin's context) and leave an orphaned dialog alive after deactivation.
202
+ const canonical = activationContext(value);
203
+ if (canonical === undefined || activationContext(caller) !== canonical) {
204
+ throw new Error('tuiDialogs owner context must be the calling activation');
205
+ }
206
+ return canonical;
193
207
  }
194
208
  timeoutOf(value) {
195
209
  return typeof value === 'number' && Number.isFinite(value) && value > 0
@@ -197,66 +211,106 @@ export class TuiDialogRuntime extends Service {
197
211
  : DIALOG_DEFAULT_TIMEOUT_MS;
198
212
  }
199
213
  select(ownerOrRequest, explicitRequest) {
200
- const owner = this.callContext(ownerOrRequest);
201
- const request = (explicitRequest ?? ownerOrRequest);
202
- const title = clean(request?.title, TITLE_CELLS);
203
- const rawOptions = Array.isArray(request?.options) ? request.options : [];
204
- const options = [];
205
- for (const raw of rawOptions.slice(0, MAX_OPTIONS)) {
206
- // The id is NOT render-path data — it is the opaque token the promise
207
- // resolves with, matched by the plugin against its own options. Sanitizing
208
- // it (whitespace collapse, cell truncation) would hand back a DIFFERENT
209
- // string the plugin cannot look up; validate and keep it verbatim.
210
- const id = raw?.id;
211
- const label = clean(raw?.label, LABEL_CELLS);
212
- if (typeof id !== 'string' || id === '' || !label)
213
- continue;
214
- // '' (absent, blank, or a dropped non-scalar) means no description row.
215
- const description = clean(raw?.description, MESSAGE_CELLS);
216
- options.push({ id, label, ...(description === '' ? {} : { description }) });
214
+ try {
215
+ const owner = this.callContext(ownerOrRequest);
216
+ const request = (explicitRequest ?? ownerOrRequest);
217
+ const title = clean(request?.title, TITLE_CELLS);
218
+ const rawOptions = Array.isArray(request?.options) ? request.options : [];
219
+ const options = [];
220
+ for (const raw of rawOptions.slice(0, MAX_OPTIONS)) {
221
+ // The id is NOT render-path data — it is the opaque token the promise
222
+ // resolves with, matched by the plugin against its own options. Sanitizing
223
+ // it (whitespace collapse, cell truncation) would hand back a DIFFERENT
224
+ // string the plugin cannot look up; validate and keep it verbatim.
225
+ const id = raw?.id;
226
+ const label = clean(raw?.label, LABEL_CELLS);
227
+ if (typeof id !== 'string' || id === '' || !label)
228
+ continue;
229
+ // '' (absent, blank, or a dropped non-scalar) means no description row.
230
+ const description = clean(raw?.description, MESSAGE_CELLS);
231
+ options.push({ id, label, ...(description === '' ? {} : { description }) });
232
+ }
233
+ if (!title || options.length === 0) {
234
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.select called without a title or options; cancelled');
235
+ return Promise.resolve(undefined);
236
+ }
237
+ return dialogStoreFor(this)
238
+ .ask({ kind: 'select', title, options }, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
239
+ .then(value => (typeof value === 'string' ? value : undefined));
217
240
  }
218
- if (!title || options.length === 0) {
219
- this.ctx.logger.warn('dsh-tui: tuiDialogs.select called without a title or options; cancelled');
241
+ catch {
242
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.select received malformed data; cancelled');
220
243
  return Promise.resolve(undefined);
221
244
  }
222
- return this.store
223
- .ask({ kind: 'select', title, options }, request.signal, this.timeoutOf(request.timeoutMs), owner)
224
- .then(value => (typeof value === 'string' ? value : undefined));
225
245
  }
226
246
  confirm(ownerOrRequest, explicitRequest) {
227
- const owner = this.callContext(ownerOrRequest);
228
- const request = (explicitRequest ?? ownerOrRequest);
229
- const title = clean(request?.title, TITLE_CELLS);
230
- if (!title) {
231
- this.ctx.logger.warn('dsh-tui: tuiDialogs.confirm called without a title; cancelled');
247
+ try {
248
+ const owner = this.callContext(ownerOrRequest);
249
+ const request = (explicitRequest ?? ownerOrRequest);
250
+ const title = clean(request?.title, TITLE_CELLS);
251
+ if (!title) {
252
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.confirm called without a title; cancelled');
253
+ return Promise.resolve(false);
254
+ }
255
+ const message = clean(request?.message, MESSAGE_CELLS);
256
+ const confirmLabel = clean(request?.confirmLabel, LABEL_CELLS);
257
+ const cancelLabel = clean(request?.cancelLabel, LABEL_CELLS);
258
+ return dialogStoreFor(this)
259
+ .ask({
260
+ kind: 'confirm',
261
+ title,
262
+ ...(message === '' ? {} : { message }),
263
+ confirmLabel,
264
+ cancelLabel,
265
+ }, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
266
+ .then(value => value === true);
267
+ }
268
+ catch {
269
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.confirm received malformed data; cancelled');
232
270
  return Promise.resolve(false);
233
271
  }
234
- const message = clean(request?.message, MESSAGE_CELLS);
235
- const confirmLabel = clean(request?.confirmLabel, LABEL_CELLS);
236
- const cancelLabel = clean(request?.cancelLabel, LABEL_CELLS);
237
- return this.store
238
- .ask({
239
- kind: 'confirm',
240
- title,
241
- ...(message === '' ? {} : { message }),
242
- confirmLabel,
243
- cancelLabel,
244
- }, request.signal, this.timeoutOf(request.timeoutMs), owner)
245
- .then(value => value === true);
246
272
  }
247
273
  input(ownerOrRequest, explicitRequest) {
248
- const owner = this.callContext(ownerOrRequest);
249
- const request = (explicitRequest ?? ownerOrRequest);
250
- const title = clean(request?.title, TITLE_CELLS);
251
- if (!title) {
252
- this.ctx.logger.warn('dsh-tui: tuiDialogs.input called without a title; cancelled');
274
+ try {
275
+ const owner = this.callContext(ownerOrRequest);
276
+ const request = (explicitRequest ?? ownerOrRequest);
277
+ const title = clean(request?.title, TITLE_CELLS);
278
+ if (!title) {
279
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.input called without a title; cancelled');
280
+ return Promise.resolve(undefined);
281
+ }
282
+ const placeholder = clean(request?.placeholder, LABEL_CELLS);
283
+ const initial = clean(request?.initial, INPUT_CELLS);
284
+ return dialogStoreFor(this)
285
+ .ask({ kind: 'input', title, ...(placeholder === '' ? {} : { placeholder }), initial }, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
286
+ .then(value => (typeof value === 'string' ? value : undefined));
287
+ }
288
+ catch {
289
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.input received malformed data; cancelled');
253
290
  return Promise.resolve(undefined);
254
291
  }
255
- const placeholder = clean(request?.placeholder, LABEL_CELLS);
256
- const initial = clean(request?.initial, INPUT_CELLS);
257
- return this.store
258
- .ask({ kind: 'input', title, ...(placeholder === '' ? {} : { placeholder }), initial }, request.signal, this.timeoutOf(request.timeoutMs), owner)
259
- .then(value => (typeof value === 'string' ? value : undefined));
292
+ }
293
+ }
294
+ /**
295
+ * Host-only queue accessor. This module is intentionally not a package
296
+ * export; plugins receive only the traceable `tuiDialogs` capability, whose
297
+ * public surface is select/confirm/input.
298
+ */
299
+ const hostDialogStores = new WeakMap();
300
+ function dialogStoreFor(runtime) {
301
+ const store = hostDialogStores.get(concreteService(runtime));
302
+ if (store === undefined)
303
+ throw new Error('tuiDialogs host store is unavailable');
304
+ return store;
305
+ }
306
+ export function getHostDialogStore(runtime) {
307
+ if (runtime === undefined)
308
+ return undefined;
309
+ try {
310
+ return hostDialogStores.get(concreteService(runtime));
311
+ }
312
+ catch {
313
+ return undefined;
260
314
  }
261
315
  }
262
316
  export default TuiDialogRuntime;
@@ -66,14 +66,6 @@ declare module '@deepseek-ai/cordis' {
66
66
  }
67
67
  /** `ctx.tuiEffectLedger` — append-only effect journal (C-060). */
68
68
  export declare class TuiEffectLedgerRuntime extends Service {
69
- private readonly file;
70
- private readonly optionsGenerationId;
71
- private generationId;
72
- private readonly ledgerSchema;
73
- private readonly activations;
74
- private nextActivation;
75
- private sequence;
76
- private schemaWarned;
77
69
  constructor(ctx: Context, options?: {
78
70
  file?: string;
79
71
  generationId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"effect-ledger.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/effect-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMtD,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,QAAwC,CAAA;AAEvE,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,oHASxB,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,gBAAgB,CAAA;AAC1F,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3D,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,eAAe,CAAA;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,MAAM,EAAE,YAAY,CAAA;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/D,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,sBAAsB,CAAA;KACxC;CACF;AAWD,kEAAkE;AAClE,qBAAa,sBAAuB,SAAQ,OAAO;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAoB;IACxD,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqC;IAClE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,YAAY,CAAQ;gBAG1B,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAO;IAehG;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI;IA2DpD;;yCAEqC;IACrC,OAAO,CAAC,UAAU;IAMlB,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,YAAY;CAYrB;AAED,eAAe,sBAAsB,CAAA"}
1
+ {"version":3,"file":"effect-ledger.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/effect-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOtD,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,QAAwC,CAAA;AAEvE,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,oHASxB,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,gBAAgB,CAAA;AAC1F,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3D,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,eAAe,CAAA;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,MAAM,EAAE,YAAY,CAAA;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/D,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,sBAAsB,CAAA;KACxC;CACF;AAWD,kEAAkE;AAClE,qBAAa,sBAAuB,SAAQ,OAAO;gBAE/C,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAO;IA0BhG;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI;IA6DpD;;yCAEqC;IACrC,OAAO,CAAC,UAAU;IAOlB,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,YAAY;CAarB;AA6CD,eAAe,sBAAsB,CAAA"}