@deepseek-harness-tui/dsh-tui 0.8.0 → 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 (434) hide show
  1. package/README.md +32 -15
  2. package/cordis.patch.yml +21 -2
  3. package/cordis.yml +12 -1
  4. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  5. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  6. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  7. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  8. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  9. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  10. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  11. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  12. package/dsh-ecosystem-spec/registry/README.md +14 -0
  13. package/dsh-ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
  14. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  15. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  16. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  17. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  18. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
  19. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -0
  20. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  21. package/dsh-ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
  22. package/dsh-ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
  23. package/dsh-ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
  24. package/lib/types/cc/figures.d.ts +4 -0
  25. package/lib/types/cc/figures.d.ts.map +1 -1
  26. package/lib/types/cc/figures.js +4 -0
  27. package/lib/types/command-trees.d.ts +2 -1
  28. package/lib/types/command-trees.d.ts.map +1 -1
  29. package/lib/types/command-trees.js +1 -1
  30. package/lib/types/commands.d.ts.map +1 -1
  31. package/lib/types/commands.js +2 -0
  32. package/lib/types/components/ExtensionDialog.d.ts +40 -0
  33. package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
  34. package/lib/types/components/ExtensionDialog.js +210 -0
  35. package/lib/types/components/HelpMenu.js +1 -1
  36. package/lib/types/components/LoadedContextPanel.d.ts +5 -5
  37. package/lib/types/components/LoadedContextPanel.js +6 -6
  38. package/lib/types/components/LogoV2.d.ts.map +1 -1
  39. package/lib/types/components/LogoV2.js +16 -8
  40. package/lib/types/components/Markdown.d.ts +13 -1
  41. package/lib/types/components/Markdown.d.ts.map +1 -1
  42. package/lib/types/components/Markdown.js +15 -1
  43. package/lib/types/components/MessageList.d.ts +3 -1
  44. package/lib/types/components/MessageList.d.ts.map +1 -1
  45. package/lib/types/components/MessageList.js +111 -6
  46. package/lib/types/components/PromptInput.d.ts.map +1 -1
  47. package/lib/types/components/PromptInput.js +26 -12
  48. package/lib/types/components/RewindPicker.d.ts +13 -1
  49. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  50. package/lib/types/components/RewindPicker.js +26 -2
  51. package/lib/types/components/StreamingMarkdown.d.ts +2 -8
  52. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  53. package/lib/types/components/StreamingMarkdown.js +51 -9
  54. package/lib/types/components/ToolUseLoader.d.ts +8 -3
  55. package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
  56. package/lib/types/components/ToolUseLoader.js +43 -9
  57. package/lib/types/components/activityFrames.d.ts +1 -1
  58. package/lib/types/components/activityFrames.d.ts.map +1 -1
  59. package/lib/types/components/activityFrames.js +4 -1
  60. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
  61. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  62. package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
  63. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  64. package/lib/types/components/messages/AssistantToolUseMessage.js +13 -2
  65. package/lib/types/dsh-adapter/channel.d.ts +61 -11
  66. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  67. package/lib/types/dsh-adapter/channel.js +767 -120
  68. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  69. package/lib/types/dsh-adapter/childStderr.js +10 -0
  70. package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
  71. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
  72. package/lib/types/dsh-adapter/command-attribution.js +93 -0
  73. package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
  74. package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
  75. package/lib/types/dsh-adapter/command-errors.js +63 -0
  76. package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
  77. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
  78. package/lib/types/dsh-adapter/command-trees.js +70 -20
  79. package/lib/types/dsh-adapter/component-identity.d.ts +33 -0
  80. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
  81. package/lib/types/dsh-adapter/component-identity.js +108 -0
  82. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  83. package/lib/types/dsh-adapter/contract.js +2 -2
  84. package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
  85. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
  86. package/lib/types/dsh-adapter/decision-guard.js +348 -0
  87. package/lib/types/dsh-adapter/dialogs.d.ts +145 -0
  88. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
  89. package/lib/types/dsh-adapter/dialogs.js +316 -0
  90. package/lib/types/dsh-adapter/effect-ledger.d.ts +91 -0
  91. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
  92. package/lib/types/dsh-adapter/effect-ledger.js +251 -0
  93. package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
  94. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
  95. package/lib/types/dsh-adapter/extension-events.js +207 -0
  96. package/lib/types/dsh-adapter/extensions.d.ts +32 -0
  97. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
  98. package/lib/types/dsh-adapter/extensions.js +42 -0
  99. package/lib/types/dsh-adapter/grants.d.ts +25 -0
  100. package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
  101. package/lib/types/dsh-adapter/grants.js +213 -0
  102. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  103. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  104. package/lib/types/dsh-adapter/host-access.js +652 -0
  105. package/lib/types/dsh-adapter/host-descriptor.d.ts +24 -0
  106. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
  107. package/lib/types/dsh-adapter/host-descriptor.js +169 -0
  108. package/lib/types/dsh-adapter/index.d.ts +4 -0
  109. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  110. package/lib/types/dsh-adapter/index.js +1 -0
  111. package/lib/types/dsh-adapter/message-observer.d.ts +173 -0
  112. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
  113. package/lib/types/dsh-adapter/message-observer.js +553 -0
  114. package/lib/types/dsh-adapter/plugin-host.d.ts +136 -0
  115. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
  116. package/lib/types/dsh-adapter/plugin-host.js +365 -0
  117. package/lib/types/dsh-adapter/plugin-storage.d.ts +108 -0
  118. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
  119. package/lib/types/dsh-adapter/plugin-storage.js +397 -0
  120. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  121. package/lib/types/dsh-adapter/plugin.js +124 -14
  122. package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
  123. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
  124. package/lib/types/dsh-adapter/plugins-info.js +276 -0
  125. package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
  126. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/promptDebug.js +13 -4
  128. package/lib/types/dsh-adapter/renderers.d.ts +57 -0
  129. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
  130. package/lib/types/dsh-adapter/renderers.js +173 -0
  131. package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
  132. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
  133. package/lib/types/dsh-adapter/sanitize.js +65 -0
  134. package/lib/types/dsh-adapter/scenes.d.ts +15 -5
  135. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  136. package/lib/types/dsh-adapter/scenes.js +149 -35
  137. package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
  138. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  139. package/lib/types/dsh-adapter/settings-sections.js +106 -26
  140. package/lib/types/dsh-adapter/shortcuts.d.ts +107 -0
  141. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
  142. package/lib/types/dsh-adapter/shortcuts.js +340 -0
  143. package/lib/types/dsh-adapter/status.d.ts +74 -0
  144. package/lib/types/dsh-adapter/status.d.ts.map +1 -0
  145. package/lib/types/dsh-adapter/status.js +234 -0
  146. package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
  147. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  148. package/lib/types/dsh-adapter/workspaces.js +287 -170
  149. package/lib/types/extensions.d.ts +13 -0
  150. package/lib/types/extensions.d.ts.map +1 -0
  151. package/lib/types/extensions.js +21 -0
  152. package/lib/types/force-production-react.d.ts +1 -0
  153. package/lib/types/force-production-react.d.ts.map +1 -0
  154. package/lib/types/force-production-react.js +12 -0
  155. package/lib/types/i18n.d.ts +174 -20
  156. package/lib/types/i18n.d.ts.map +1 -1
  157. package/lib/types/i18n.js +56 -6
  158. package/lib/types/index.d.ts +1 -0
  159. package/lib/types/index.d.ts.map +1 -1
  160. package/lib/types/index.js +1 -0
  161. package/lib/types/ink/components/App.d.ts +2 -0
  162. package/lib/types/ink/components/App.d.ts.map +1 -1
  163. package/lib/types/ink/components/App.js +4 -0
  164. package/lib/types/ink/ink.d.ts +31 -3
  165. package/lib/types/ink/ink.d.ts.map +1 -1
  166. package/lib/types/ink/ink.js +90 -5
  167. package/lib/types/ink/log-update.d.ts.map +1 -1
  168. package/lib/types/ink/log-update.js +225 -56
  169. package/lib/types/ink/output.d.ts +35 -2
  170. package/lib/types/ink/output.d.ts.map +1 -1
  171. package/lib/types/ink/output.js +281 -14
  172. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  173. package/lib/types/ink/render-node-to-output.js +14 -6
  174. package/lib/types/ink/screen.d.ts +39 -0
  175. package/lib/types/ink/screen.d.ts.map +1 -1
  176. package/lib/types/ink/screen.js +117 -0
  177. package/lib/types/ink/terminal.d.ts.map +1 -1
  178. package/lib/types/ink/terminal.js +26 -6
  179. package/lib/types/ink/wrapAnsi.d.ts +1 -1
  180. package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
  181. package/lib/types/ink/wrapAnsi.js +29 -2
  182. package/lib/types/plugin-host.d.ts +15 -0
  183. package/lib/types/plugin-host.d.ts.map +1 -0
  184. package/lib/types/plugin-host.js +17 -0
  185. package/lib/types/plugin-spec/negotiate.d.ts +11 -0
  186. package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
  187. package/lib/types/plugin-spec/negotiate.js +97 -0
  188. package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
  189. package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
  190. package/lib/types/plugin-spec/permission-scope.js +90 -0
  191. package/lib/types/plugin-spec/registry.d.ts +23 -0
  192. package/lib/types/plugin-spec/registry.d.ts.map +1 -0
  193. package/lib/types/plugin-spec/registry.js +252 -0
  194. package/lib/types/plugin-spec/schema-check.d.ts +17 -0
  195. package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
  196. package/lib/types/plugin-spec/schema-check.js +165 -0
  197. package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
  198. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
  199. package/lib/types/plugin-spec/tui-extension.js +79 -0
  200. package/lib/types/plugin-spec/types.d.ts +114 -0
  201. package/lib/types/plugin-spec/types.d.ts.map +1 -0
  202. package/lib/types/plugin-spec/types.js +10 -0
  203. package/lib/types/plugin-spec/validate.d.ts +21 -0
  204. package/lib/types/plugin-spec/validate.d.ts.map +1 -0
  205. package/lib/types/plugin-spec/validate.js +138 -0
  206. package/lib/types/scenes.d.ts +2 -1
  207. package/lib/types/scenes.d.ts.map +1 -1
  208. package/lib/types/scenes.js +1 -1
  209. package/lib/types/screens/Chat.d.ts +14 -1
  210. package/lib/types/screens/Chat.d.ts.map +1 -1
  211. package/lib/types/screens/Chat.js +173 -49
  212. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  213. package/lib/types/screens/SessionBrowser.js +10 -3
  214. package/lib/types/sessions/view.d.ts +3 -2
  215. package/lib/types/sessions/view.d.ts.map +1 -1
  216. package/lib/types/sessions/view.js +18 -0
  217. package/lib/types/settings-sections.d.ts +2 -1
  218. package/lib/types/settings-sections.d.ts.map +1 -1
  219. package/lib/types/settings-sections.js +1 -1
  220. package/lib/types/theme.d.ts +5 -0
  221. package/lib/types/theme.d.ts.map +1 -1
  222. package/lib/types/theme.js +15 -0
  223. package/lib/types/update.d.ts +20 -0
  224. package/lib/types/update.d.ts.map +1 -1
  225. package/lib/types/update.js +54 -7
  226. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  227. package/lib/types/utils/execFileNoThrow.js +3 -0
  228. package/lib/types/utils/loaded-context.d.ts +8 -3
  229. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  230. package/lib/types/utils/loaded-context.js +39 -3
  231. package/lib/types/utils/modifiers.d.ts.map +1 -1
  232. package/lib/types/utils/modifiers.js +3 -2
  233. package/lib/types/working-activity.d.ts +12 -0
  234. package/lib/types/working-activity.d.ts.map +1 -1
  235. package/lib/types/working-activity.js +13 -0
  236. package/lib/types/workspaces.d.ts +2 -1
  237. package/lib/types/workspaces.d.ts.map +1 -1
  238. package/lib/types/workspaces.js +1 -1
  239. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  240. package/node_modules/@dsh-std/command/LICENSE +21 -0
  241. package/node_modules/@dsh-std/command/README.md +26 -0
  242. package/node_modules/@dsh-std/command/README.zh.md +28 -0
  243. package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
  244. package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
  245. package/node_modules/@dsh-std/command/lib/index.js +252 -0
  246. package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
  247. package/node_modules/@dsh-std/command/package.json +22 -0
  248. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  249. package/node_modules/@dsh-std/connection/LICENSE +21 -0
  250. package/node_modules/@dsh-std/connection/README.md +42 -0
  251. package/node_modules/@dsh-std/connection/README.zh.md +42 -0
  252. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  253. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  254. package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  255. package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  256. package/node_modules/@dsh-std/connection/lib/index.js +158 -0
  257. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  258. package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  259. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  260. package/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  261. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  262. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  263. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  264. package/node_modules/@dsh-std/connection/package.json +20 -0
  265. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  266. package/node_modules/@dsh-std/core/LICENSE +21 -0
  267. package/node_modules/@dsh-std/core/README.md +13 -0
  268. package/node_modules/@dsh-std/core/README.zh.md +13 -0
  269. package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  270. package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  271. package/node_modules/@dsh-std/core/lib/index.js +424 -0
  272. package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  273. package/node_modules/@dsh-std/core/package.json +21 -0
  274. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  275. package/node_modules/@dsh-std/manifest/LICENSE +21 -0
  276. package/node_modules/@dsh-std/manifest/README.md +5 -0
  277. package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  278. package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  279. package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  280. package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  281. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  282. package/node_modules/@dsh-std/manifest/package.json +20 -0
  283. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  284. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  285. package/node_modules/@dsh-std/messages/LICENSE +21 -0
  286. package/node_modules/@dsh-std/messages/README.md +5 -0
  287. package/node_modules/@dsh-std/messages/README.zh.md +7 -0
  288. package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
  289. package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
  290. package/node_modules/@dsh-std/messages/lib/index.js +151 -0
  291. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
  292. package/node_modules/@dsh-std/messages/package.json +20 -0
  293. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
  294. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  295. package/node_modules/@dsh-std/presentation/LICENSE +21 -0
  296. package/node_modules/@dsh-std/presentation/README.md +27 -0
  297. package/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  298. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  299. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  300. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  301. package/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  302. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  303. package/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  304. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  305. package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  306. package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  307. package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  308. package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  309. package/node_modules/@dsh-std/presentation/package.json +25 -0
  310. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  311. package/node_modules/@dsh-std/storage/LICENSE +21 -0
  312. package/node_modules/@dsh-std/storage/README.md +5 -0
  313. package/node_modules/@dsh-std/storage/README.zh.md +7 -0
  314. package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
  315. package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
  316. package/node_modules/@dsh-std/storage/lib/index.js +104 -0
  317. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
  318. package/node_modules/@dsh-std/storage/package.json +20 -0
  319. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
  320. package/package.json +110 -70
  321. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  322. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
  323. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
  324. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
  325. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  326. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  327. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  328. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  329. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
  330. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  331. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  332. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  333. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  334. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  335. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  336. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  337. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
  338. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  339. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
  340. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
  341. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
  342. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  343. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  344. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
  345. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  346. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
  347. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  348. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
  349. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
  350. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  351. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  352. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  353. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  354. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  355. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
  356. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  357. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  358. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
  359. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -0
  360. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  361. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  362. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  363. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  364. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  365. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  366. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  367. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  368. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  369. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  370. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  371. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  372. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -0
  373. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  374. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
  375. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
  376. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
  377. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  378. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  379. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
  380. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  381. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
  382. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  383. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
  384. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
  385. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
  386. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  387. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  388. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
  389. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  390. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
  391. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  392. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
  393. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
  394. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
  395. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  396. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  397. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
  398. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  399. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
  400. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  401. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
  402. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
  403. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
  404. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  405. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  406. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  407. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  408. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
  409. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  410. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  411. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  412. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  413. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  414. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  415. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  416. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
  417. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  418. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
  419. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
  420. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
  421. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  422. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  423. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
  424. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  425. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
  426. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  427. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
  428. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
  429. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
  430. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  431. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  432. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
  433. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  434. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Managed plugin dialogs — the pi `ctx.ui.select/confirm/input` seam for
3
+ * dsh-TUI. Plugins hand the HOST a declarative request; the TUI renders the
4
+ * dialog in its own chrome (next to the approval panel), owns the keyboard,
5
+ * and settles the plugin's promise with the user's answer. Plugins never
6
+ * touch the TTY themselves.
7
+ *
8
+ * Split in two, mirroring QuestionStore/ApprovalStore:
9
+ *
10
+ * - {@link TuiDialogStore} — cordis-free queue + snapshot. The chat screen
11
+ * subscribes to it and renders the current dialog; tests can drive it
12
+ * without a cordis context.
13
+ * - {@link TuiDialogRuntime} — the cordis service (`ctx.tuiDialogs`)
14
+ * plugins call. Validation of untrusted request data lives here.
15
+ *
16
+ * Queue semantics mirror the approval store: parallel plugin calls park
17
+ * FIFO and surface one at a time. A request settles exactly once — user
18
+ * answer, Esc cancel, caller AbortSignal, caller timeout, or service
19
+ * teardown (`cancelled` outcomes map to `undefined`/`false` returns).
20
+ */
21
+ import { Context, Service } from '@deepseek-ai/cordis';
22
+ import { cleanScalarText } from './sanitize.js';
23
+ import { activationContext, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
24
+ /** Render-path strings are untrusted: sanitization (control-char stripping,
25
+ * cell-width caps, scalar-only coercion) lives in ./sanitize.js — the one
26
+ * implementation of the Track A contract. `clean` drops non-scalars to ''
27
+ * so callers take their refuse path instead of rendering "[object Object]". */
28
+ const clean = cleanScalarText;
29
+ const TITLE_CELLS = 120;
30
+ const LABEL_CELLS = 120;
31
+ const MESSAGE_CELLS = 400;
32
+ /** The documented bound of the resolved input text; the panel enforces it
33
+ * on every edit path (typing AND paste) so the promise never resolves with
34
+ * a larger value. */
35
+ export const INPUT_CELLS = 500;
36
+ const MAX_OPTIONS = 100;
37
+ /** Bound a request that omits both signal and timeout. */
38
+ export const DIALOG_DEFAULT_TIMEOUT_MS = 30_000;
39
+ let nextDialogId = 1;
40
+ /**
41
+ * Cordis-free dialog queue. `ask` parks a request; the UI drains one at a
42
+ * time via the snapshot and settles through {@link decide}/{@link cancel}.
43
+ */
44
+ export class TuiDialogStore {
45
+ listeners = new Set();
46
+ queue = [];
47
+ active = null;
48
+ /** Park a request. The snapshot argument must already be sanitized. */
49
+ ask(snapshot, signal, timeoutMs, owner, bindOwnerEffect) {
50
+ if (signal?.aborted)
51
+ return Promise.resolve(undefined);
52
+ return new Promise((resolve) => {
53
+ let settled = false;
54
+ const pending = {
55
+ // The key is stable per dialog (the panel remounts fresh per
56
+ // request, like ApprovalSnapshot.key) and unique across the queue.
57
+ key: `dlg-${nextDialogId++}`,
58
+ snapshot: undefined,
59
+ settle: () => { },
60
+ onAbort: () => { },
61
+ timer: undefined,
62
+ ownerCleanup: undefined,
63
+ };
64
+ pending.snapshot = { ...snapshot, key: pending.key };
65
+ pending.settle = (value) => {
66
+ if (settled)
67
+ return;
68
+ settled = true;
69
+ if (pending.timer !== undefined)
70
+ clearTimeout(pending.timer);
71
+ signal?.removeEventListener('abort', pending.onAbort);
72
+ const ownerCleanup = pending.ownerCleanup;
73
+ pending.ownerCleanup = undefined;
74
+ ownerCleanup?.();
75
+ resolve(value);
76
+ };
77
+ pending.onAbort = () => {
78
+ // Normal completion also disposes the owner effect. The effect's
79
+ // cleanup must not re-enter the abort path and advance the queue a
80
+ // second time.
81
+ if (settled)
82
+ return;
83
+ // Aborted while queued: drop silently. Aborted while active: close
84
+ // the dialog and advance the queue.
85
+ const index = this.queue.indexOf(pending);
86
+ if (index !== -1)
87
+ this.queue.splice(index, 1);
88
+ if (this.active === pending)
89
+ this.active = null;
90
+ pending.settle(undefined);
91
+ // Must advance (not just emit): with the active dialog gone, the
92
+ // next queued request has to become active — otherwise its Promise
93
+ // parks forever and the UI shows no dialog until an unrelated ask
94
+ // happens to trigger advance.
95
+ this.advance();
96
+ };
97
+ signal?.addEventListener('abort', pending.onAbort, { once: true });
98
+ if (timeoutMs !== undefined && timeoutMs > 0) {
99
+ pending.timer = setTimeout(pending.onAbort, timeoutMs);
100
+ }
101
+ if (owner !== undefined) {
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.
106
+ pending.onAbort();
107
+ return;
108
+ }
109
+ }
110
+ this.queue.push(pending);
111
+ this.advance();
112
+ });
113
+ }
114
+ /** The dialog the UI should render right now, if any. */
115
+ getSnapshot() {
116
+ return this.active?.snapshot ?? null;
117
+ }
118
+ /**
119
+ * Settle the active dialog with the user's answer. The caller passes the
120
+ * key of the snapshot IT rendered; a mismatched key is a stale callback
121
+ * and ignored. This is not paranoia: ConPTY can deliver one Enter as a
122
+ * same-batch CR+LF pair, firing the old panel's handler twice before
123
+ * React unmounts it — an unkeyed decide would settle the active dialog
124
+ * AND the successor the first call just promoted (one Enter answering two
125
+ * consecutive dialogs).
126
+ */
127
+ decide(key, value) {
128
+ const pending = this.active;
129
+ if (pending === null || pending.key !== key)
130
+ return;
131
+ this.active = null;
132
+ pending.settle(value);
133
+ this.advance();
134
+ }
135
+ /** Cancel the active dialog (Esc). Keyed like {@link decide}: a stale
136
+ * panel's Esc must not close the successor it never rendered. */
137
+ cancel(key) {
138
+ const pending = this.active;
139
+ if (pending === null || pending.key !== key)
140
+ return;
141
+ this.active = null;
142
+ pending.settle(undefined);
143
+ this.advance();
144
+ }
145
+ /** Settle everything queued + active (teardown): all resolve cancelled. */
146
+ settleAll() {
147
+ const pending = [...this.queue];
148
+ this.queue.length = 0;
149
+ if (this.active !== null)
150
+ pending.push(this.active);
151
+ this.active = null;
152
+ for (const item of pending)
153
+ item.settle(undefined);
154
+ this.emit();
155
+ }
156
+ subscribe(listener) {
157
+ this.listeners.add(listener);
158
+ return () => {
159
+ this.listeners.delete(listener);
160
+ };
161
+ }
162
+ advance() {
163
+ if (this.active === null && this.queue.length > 0) {
164
+ this.active = this.queue.shift() ?? null;
165
+ }
166
+ this.emit();
167
+ }
168
+ emit() {
169
+ for (const listener of this.listeners)
170
+ listener();
171
+ }
172
+ }
173
+ /**
174
+ * `ctx.tuiDialogs` — plugin-facing managed dialogs. Every method validates
175
+ * its request (untrusted data on the render path) and resolves with the
176
+ * cancelled value (`undefined`/`false`) rather than throwing when the
177
+ * request is malformed — a dialog must never take the plugin or the TUI
178
+ * down; callers get a logger warning instead.
179
+ */
180
+ export class TuiDialogRuntime extends Service {
181
+ constructor(ctx) {
182
+ super(ctx, 'tuiDialogs');
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());
191
+ }
192
+ /** Cordis traceable services normally provide the caller through `this.ctx`;
193
+ * the explicit overloads below make ownership unambiguous for embedders and
194
+ * tests that retain the service instance directly. */
195
+ callContext(value) {
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;
207
+ }
208
+ timeoutOf(value) {
209
+ return typeof value === 'number' && Number.isFinite(value) && value > 0
210
+ ? Math.min(Math.floor(value), 24 * 60 * 60 * 1000)
211
+ : DIALOG_DEFAULT_TIMEOUT_MS;
212
+ }
213
+ select(ownerOrRequest, explicitRequest) {
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));
240
+ }
241
+ catch {
242
+ this.ctx.logger.warn('dsh-tui: tuiDialogs.select received malformed data; cancelled');
243
+ return Promise.resolve(undefined);
244
+ }
245
+ }
246
+ confirm(ownerOrRequest, explicitRequest) {
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');
270
+ return Promise.resolve(false);
271
+ }
272
+ }
273
+ input(ownerOrRequest, explicitRequest) {
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');
290
+ return Promise.resolve(undefined);
291
+ }
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;
314
+ }
315
+ }
316
+ export default TuiDialogRuntime;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Effect ledger (C-060): an append-only JSONL journal of plugin-visible
3
+ * effects at `~/.dsh-tui/effect-ledger.jsonl`, mounted by the
4
+ * dsh-tui-plugin-host row as `ctx.tuiEffectLedger`.
5
+ *
6
+ * Every record carries the lifecycle triple:
7
+ *
8
+ * - `pluginId` — derived from the verified Component identity bound to the
9
+ * PASSED activation. `'host'` is used for host/root records and
10
+ * `'undeclared'` for a plugin-facing call without a verified identity; a
11
+ * display fiber name is never trusted as authorization identity.
12
+ * - `activationInstance` — stable per cordis fiber for the lifetime of this
13
+ * process (first-seen assignment from a WeakMap), so a hot-reloaded plugin
14
+ * shows up as a NEW instance while all effects of one activation share one
15
+ * id.
16
+ * - `runtimeGenerationId` — the plugin-host row's generation (C-050), so
17
+ * records from different process generations can never be confused.
18
+ *
19
+ * Recording rules:
20
+ *
21
+ * - FAIL-CLOSED ON SCHEMA: every record is validated against the vendored
22
+ * `effect-ledger-record.schema.json` BEFORE it is appended; a record that
23
+ * fails is dropped with a warning, never written. A missing vendored
24
+ * schema suppresses ALL writes (warned once) — the same posture as the
25
+ * messages.observe envelope check. The schema's `additionalProperties:
26
+ * false` is what structurally bans secrets from the ledger: callers
27
+ * cannot smuggle payload fields through.
28
+ * - SEQUENCE: continues across restarts (max sequence in the existing file
29
+ * + 1); corrupt lines are skipped, never rewritten.
30
+ * - NEVER THROWS: recording is observability, not a gate — internal errors
31
+ * (including disk failures) are caught and warned, the caller's path is
32
+ * unaffected.
33
+ *
34
+ * privacyClass: operational — records hold identifiers and error codes,
35
+ * never message content, storage values, or grant-file contents.
36
+ */
37
+ import { Context, Service } from '@deepseek-ai/cordis';
38
+ /** Default ledger file (JSONL, one record per line). */
39
+ export declare const EFFECT_LEDGER_FILE: string;
40
+ /** Resource kinds recorded by the host's wired emitters. */
41
+ export declare const LEDGER_RESOURCE_KINDS: readonly ["command", "scene", "shortcut", "status", "renderer", "storage-namespace", "subscription", "permission"];
42
+ export type LedgerOperation = 'create' | 'bind' | 'replace' | 'release' | 'cleanup-failed';
43
+ export type LedgerResult = 'applied' | 'pending' | 'failed';
44
+ /** Caller-facing record input; the runtime fills the lifecycle triple. */
45
+ export interface LedgerEntry {
46
+ operation: LedgerOperation;
47
+ resource: {
48
+ kind: string;
49
+ id: string;
50
+ };
51
+ result: LedgerResult;
52
+ /** Contract error code when result is 'failed' (e.g. PERMISSION_NOT_GRANTED). */
53
+ errorCode?: string;
54
+ /** What this record supersedes (operation 'replace'). */
55
+ replaces?: {
56
+ resourceId?: string;
57
+ activationInstance?: string;
58
+ };
59
+ /** `sha256:<64hex>` digest of an opaque value, when a record must reference one. */
60
+ valueDigest?: string;
61
+ }
62
+ declare module '@deepseek-ai/cordis' {
63
+ interface Context {
64
+ tuiEffectLedger: TuiEffectLedgerRuntime;
65
+ }
66
+ }
67
+ /** `ctx.tuiEffectLedger` — append-only effect journal (C-060). */
68
+ export declare class TuiEffectLedgerRuntime extends Service {
69
+ constructor(ctx: Context, options?: {
70
+ file?: string;
71
+ generationId?: string;
72
+ ledgerSchema?: Record<string, unknown>;
73
+ });
74
+ /**
75
+ * Append one record. `identity` is the caller's own context (plugins pass
76
+ * their plugin ctx through the managed services' optional trailing
77
+ * parameter); omitting it records `undeclared`, never a guess.
78
+ */
79
+ record(entry: LedgerEntry, identity?: Context): void;
80
+ /** Runtime generation (C-050): options override, else the plugin-host
81
+ * service's id — resolved on first record and cached (the host row mounts
82
+ * before any caller can record). */
83
+ private generation;
84
+ /** Continue numbering after the existing file's max sequence (restart-safe). */
85
+ private resumeSequence;
86
+ private fiberOf;
87
+ private pluginIdOf;
88
+ private activationOf;
89
+ }
90
+ export default TuiEffectLedgerRuntime;
91
+ //# sourceMappingURL=effect-ledger.d.ts.map
@@ -0,0 +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;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"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Effect ledger (C-060): an append-only JSONL journal of plugin-visible
3
+ * effects at `~/.dsh-tui/effect-ledger.jsonl`, mounted by the
4
+ * dsh-tui-plugin-host row as `ctx.tuiEffectLedger`.
5
+ *
6
+ * Every record carries the lifecycle triple:
7
+ *
8
+ * - `pluginId` — derived from the verified Component identity bound to the
9
+ * PASSED activation. `'host'` is used for host/root records and
10
+ * `'undeclared'` for a plugin-facing call without a verified identity; a
11
+ * display fiber name is never trusted as authorization identity.
12
+ * - `activationInstance` — stable per cordis fiber for the lifetime of this
13
+ * process (first-seen assignment from a WeakMap), so a hot-reloaded plugin
14
+ * shows up as a NEW instance while all effects of one activation share one
15
+ * id.
16
+ * - `runtimeGenerationId` — the plugin-host row's generation (C-050), so
17
+ * records from different process generations can never be confused.
18
+ *
19
+ * Recording rules:
20
+ *
21
+ * - FAIL-CLOSED ON SCHEMA: every record is validated against the vendored
22
+ * `effect-ledger-record.schema.json` BEFORE it is appended; a record that
23
+ * fails is dropped with a warning, never written. A missing vendored
24
+ * schema suppresses ALL writes (warned once) — the same posture as the
25
+ * messages.observe envelope check. The schema's `additionalProperties:
26
+ * false` is what structurally bans secrets from the ledger: callers
27
+ * cannot smuggle payload fields through.
28
+ * - SEQUENCE: continues across restarts (max sequence in the existing file
29
+ * + 1); corrupt lines are skipped, never rewritten.
30
+ * - NEVER THROWS: recording is observability, not a gate — internal errors
31
+ * (including disk failures) are caught and warned, the caller's path is
32
+ * unaffected.
33
+ *
34
+ * privacyClass: operational — records hold identifiers and error codes,
35
+ * never message content, storage values, or grant-file contents.
36
+ */
37
+ import { appendFileSync, mkdirSync, readFileSync } from 'node:fs';
38
+ import { dirname, join } from 'node:path';
39
+ import { Service } from '@deepseek-ai/cordis';
40
+ import { DATA_DIR } from '../utils/paths.js';
41
+ import { loadSpecData } from '../plugin-spec/registry.js';
42
+ import { check } from '../plugin-spec/schema-check.js';
43
+ import { componentIdentityOf } from './component-identity.js';
44
+ import { compositionRoot, concreteService } from './host-access.js';
45
+ /** Default ledger file (JSONL, one record per line). */
46
+ export const EFFECT_LEDGER_FILE = join(DATA_DIR, 'effect-ledger.jsonl');
47
+ /** Resource kinds recorded by the host's wired emitters. */
48
+ export const LEDGER_RESOURCE_KINDS = [
49
+ 'command',
50
+ 'scene',
51
+ 'shortcut',
52
+ 'status',
53
+ 'renderer',
54
+ 'storage-namespace',
55
+ 'subscription',
56
+ 'permission',
57
+ ];
58
+ /** Strip control chars and cap length so a hostile id cannot break the JSONL
59
+ * line format or blow the schema bounds (JSON.stringify would keep the line
60
+ * intact, but downstream tooling reads these fields raw). */
61
+ function cleanField(value, max, fallback) {
62
+ if (typeof value !== 'string')
63
+ return fallback;
64
+ const cleaned = value.replace(/[\x00-\x1f\x7f-\x9f]/g, '').slice(0, max);
65
+ return cleaned === '' ? fallback : cleaned;
66
+ }
67
+ /** `ctx.tuiEffectLedger` — append-only effect journal (C-060). */
68
+ export class TuiEffectLedgerRuntime extends Service {
69
+ constructor(ctx, options = {}) {
70
+ super(ctx, 'tuiEffectLedger');
71
+ const file = options.file ?? EFFECT_LEDGER_FILE;
72
+ // The generation is resolved LAZILY (per first record): cordis does not
73
+ // make sibling services visible to constructors of plugins mounted later
74
+ // by the same apply(), so a constructor-time probe would always miss the
75
+ // plugin-host service and fall back to 'unknown-generation'.
76
+ const state = {
77
+ hostContext: compositionRoot(ctx),
78
+ file,
79
+ optionsGenerationId: options.generationId,
80
+ generationId: undefined,
81
+ activations: new WeakMap(),
82
+ nextActivation: 1,
83
+ sequence: 0,
84
+ schemaWarned: false,
85
+ ledgerSchema: undefined,
86
+ };
87
+ // `'ledgerSchema' in options` lets a caller force-undefined (fail-closed
88
+ // test seam), same contract as the message observer's envelopeSchema.
89
+ state.ledgerSchema = 'ledgerSchema' in options ? options.ledgerSchema : loadSpecData()?.schemas.ledger;
90
+ state.sequence = resumeSequence(file);
91
+ ledgerStates.set(this, state);
92
+ }
93
+ /**
94
+ * Append one record. `identity` is the caller's own context (plugins pass
95
+ * their plugin ctx through the managed services' optional trailing
96
+ * parameter); omitting it records `undeclared`, never a guess.
97
+ */
98
+ record(entry, identity) {
99
+ let state;
100
+ try {
101
+ state = ledgerStateFor(this);
102
+ if (state.ledgerSchema === undefined) {
103
+ if (!state.schemaWarned) {
104
+ state.schemaWarned = true;
105
+ state.hostContext.logger.warn('dsh-tui: effect ledger schema unavailable — suppressing all ledger writes (fail-closed)');
106
+ }
107
+ return;
108
+ }
109
+ const fiber = this.fiberOf(identity);
110
+ const verified = identity === undefined ? undefined : componentIdentityOf(identity);
111
+ const pluginId = this.pluginIdOf(identity, fiber, verified?.componentId);
112
+ const record = {
113
+ ledgerVersion: '0.15',
114
+ sequence: state.sequence,
115
+ timestamp: new Date().toISOString(),
116
+ pluginId,
117
+ activationInstance: verified?.activationId ?? this.activationOf(fiber, pluginId),
118
+ runtimeGenerationId: this.generation(),
119
+ operation: entry.operation,
120
+ resource: {
121
+ kind: cleanField(entry.resource?.kind, 64, 'unknown'),
122
+ id: cleanField(entry.resource?.id, 128, 'unknown'),
123
+ },
124
+ result: entry.result,
125
+ ...(entry.errorCode !== undefined ? { errorCode: cleanField(entry.errorCode, 64, 'UNKNOWN') } : {}),
126
+ ...(entry.replaces !== undefined
127
+ ? {
128
+ replaces: {
129
+ ...(entry.replaces.resourceId !== undefined
130
+ ? { resourceId: cleanField(entry.replaces.resourceId, 128, 'unknown') }
131
+ : {}),
132
+ ...(entry.replaces.activationInstance !== undefined
133
+ ? { activationInstance: cleanField(entry.replaces.activationInstance, 128, 'unknown') }
134
+ : {}),
135
+ },
136
+ }
137
+ : {}),
138
+ ...(entry.valueDigest !== undefined ? { valueDigest: entry.valueDigest } : {}),
139
+ };
140
+ // Fail-closed self-check: a record that does not satisfy the vendored
141
+ // schema is DROPPED, not written (the schema's additionalProperties:
142
+ // false is the structural secret ban).
143
+ try {
144
+ check(record, state.ledgerSchema, state.ledgerSchema);
145
+ }
146
+ catch (error) {
147
+ state.hostContext.logger.warn(`dsh-tui: effect ledger record dropped (schema: ${error instanceof Error ? error.message : String(error)})`);
148
+ return;
149
+ }
150
+ mkdirSync(dirname(state.file), { recursive: true, mode: 0o700 });
151
+ appendFileSync(state.file, `${JSON.stringify(record)}\n`, { mode: 0o600 });
152
+ state.sequence += 1;
153
+ }
154
+ catch (error) {
155
+ ;
156
+ (state?.hostContext ?? this.ctx).logger.warn('dsh-tui: effect ledger write failed');
157
+ }
158
+ }
159
+ /** Runtime generation (C-050): options override, else the plugin-host
160
+ * service's id — resolved on first record and cached (the host row mounts
161
+ * before any caller can record). */
162
+ generation() {
163
+ const state = ledgerStateFor(this);
164
+ if (state.optionsGenerationId !== undefined)
165
+ return state.optionsGenerationId;
166
+ state.generationId ??= state.hostContext.get('tuiPluginHost')?.generationId ?? 'unknown-generation';
167
+ return state.generationId;
168
+ }
169
+ /** Continue numbering after the existing file's max sequence (restart-safe). */
170
+ resumeSequence() {
171
+ return resumeSequence(ledgerStateFor(this).file);
172
+ }
173
+ fiberOf(identity) {
174
+ if (identity === undefined)
175
+ return undefined;
176
+ try {
177
+ const fiber = identity.fiber;
178
+ return typeof fiber === 'object' && fiber !== null ? fiber : undefined;
179
+ }
180
+ catch {
181
+ return undefined;
182
+ }
183
+ }
184
+ pluginIdOf(identity, fiber, verifiedComponentId) {
185
+ if (identity === undefined)
186
+ return 'undeclared';
187
+ if (verifiedComponentId !== undefined)
188
+ return cleanField(verifiedComponentId, 128, 'undeclared');
189
+ let name = '';
190
+ try {
191
+ name = typeof identity.fiber?.name === 'string' ? identity.fiber.name : '';
192
+ }
193
+ catch {
194
+ name = '';
195
+ }
196
+ // A non-root fiber without a verified Component is intentionally not
197
+ // attributed by its Cordis export name. Names are display metadata and
198
+ // can differ from the manifest identity (or be impersonated).
199
+ if (fiber === undefined || name === '' || name === 'root')
200
+ return 'host';
201
+ return 'undeclared';
202
+ }
203
+ activationOf(fiber, pluginId) {
204
+ // 'host'/'undeclared' are single-tenant identities (one root fiber per
205
+ // process; 'undeclared' has no fiber at all) — the constant instance id
206
+ // is exact; per-fiber ids only matter for plugin fibers.
207
+ if (fiber === undefined || pluginId === 'host' || pluginId === 'undeclared')
208
+ return pluginId;
209
+ const state = ledgerStateFor(this);
210
+ let activation = state.activations.get(fiber);
211
+ if (activation === undefined) {
212
+ activation = `activation-${state.nextActivation++}`;
213
+ state.activations.set(fiber, activation);
214
+ }
215
+ return activation;
216
+ }
217
+ }
218
+ const ledgerStates = new WeakMap();
219
+ function ledgerStateFor(runtime) {
220
+ const state = ledgerStates.get(concreteService(runtime));
221
+ if (state === undefined)
222
+ throw new Error('tuiEffectLedger host state is unavailable');
223
+ return state;
224
+ }
225
+ /** Continue numbering after the existing file's max sequence (restart-safe). */
226
+ function resumeSequence(file) {
227
+ let text;
228
+ try {
229
+ text = readFileSync(file, 'utf8');
230
+ }
231
+ catch {
232
+ return 0; // missing file = fresh ledger, not corruption
233
+ }
234
+ let max = -1;
235
+ for (const line of text.split('\n')) {
236
+ if (line.trim() === '')
237
+ continue;
238
+ try {
239
+ const parsed = JSON.parse(line);
240
+ const sequence = parsed.sequence;
241
+ if (typeof sequence === 'number' && Number.isInteger(sequence) && sequence > max)
242
+ max = sequence;
243
+ }
244
+ catch {
245
+ // Corrupt line: skip it (never rewritten — the bytes stay for manual
246
+ // recovery, same posture as plugin-storage).
247
+ }
248
+ }
249
+ return max + 1;
250
+ }
251
+ export default TuiEffectLedgerRuntime;