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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/README.md +15 -7
  2. package/bin/dsh-tui.js +19 -3
  3. package/cordis.patch.yml +43 -11
  4. package/cordis.yml +20 -1
  5. package/ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
  6. package/ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
  7. package/ecosystem-spec/registry/permissions-0.1.json +13 -0
  8. package/ecosystem-spec/registry/registry-0.15.json +57 -0
  9. package/ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
  10. package/ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
  11. package/ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
  12. package/lib/types/cc/figures.d.ts +4 -0
  13. package/lib/types/cc/figures.d.ts.map +1 -1
  14. package/lib/types/cc/figures.js +4 -0
  15. package/lib/types/commands.d.ts.map +1 -1
  16. package/lib/types/commands.js +4 -1
  17. package/lib/types/components/ExtensionDialog.d.ts +40 -0
  18. package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
  19. package/lib/types/components/ExtensionDialog.js +210 -0
  20. package/lib/types/components/HelpMenu.js +1 -1
  21. package/lib/types/components/LoadedContextPanel.d.ts +5 -10
  22. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  23. package/lib/types/components/LoadedContextPanel.js +7 -18
  24. package/lib/types/components/LogoV2.d.ts.map +1 -1
  25. package/lib/types/components/LogoV2.js +1 -2
  26. package/lib/types/components/MessageList.d.ts +3 -1
  27. package/lib/types/components/MessageList.d.ts.map +1 -1
  28. package/lib/types/components/MessageList.js +29 -5
  29. package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
  30. package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
  31. package/lib/types/components/PluginSceneBoundary.js +29 -0
  32. package/lib/types/components/RewindPicker.d.ts +13 -1
  33. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  34. package/lib/types/components/RewindPicker.js +26 -2
  35. package/lib/types/components/SkillsPicker.d.ts +18 -0
  36. package/lib/types/components/SkillsPicker.d.ts.map +1 -0
  37. package/lib/types/components/SkillsPicker.js +50 -0
  38. package/lib/types/components/SplitDiffView.d.ts +28 -0
  39. package/lib/types/components/SplitDiffView.d.ts.map +1 -0
  40. package/lib/types/components/SplitDiffView.js +417 -0
  41. package/lib/types/components/ToolUseLoader.d.ts +8 -3
  42. package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
  43. package/lib/types/components/ToolUseLoader.js +43 -9
  44. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +3 -1
  45. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  46. package/lib/types/components/messages/AssistantToolUseMessage.js +17 -7
  47. package/lib/types/dsh-adapter/channel.d.ts +98 -7
  48. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  49. package/lib/types/dsh-adapter/channel.js +623 -26
  50. package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
  51. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
  52. package/lib/types/dsh-adapter/command-attribution.js +93 -0
  53. package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
  54. package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
  55. package/lib/types/dsh-adapter/command-errors.js +63 -0
  56. package/lib/types/dsh-adapter/component-identity.d.ts +28 -0
  57. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
  58. package/lib/types/dsh-adapter/component-identity.js +108 -0
  59. package/lib/types/dsh-adapter/contract.d.ts +2 -2
  60. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  61. package/lib/types/dsh-adapter/contract.js +3 -2
  62. package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
  63. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
  64. package/lib/types/dsh-adapter/decision-guard.js +354 -0
  65. package/lib/types/dsh-adapter/dialogs.d.ts +146 -0
  66. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
  67. package/lib/types/dsh-adapter/dialogs.js +262 -0
  68. package/lib/types/dsh-adapter/effect-ledger.d.ts +99 -0
  69. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
  70. package/lib/types/dsh-adapter/effect-ledger.js +231 -0
  71. package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
  72. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
  73. package/lib/types/dsh-adapter/extension-events.js +169 -0
  74. package/lib/types/dsh-adapter/extensions.d.ts +32 -0
  75. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
  76. package/lib/types/dsh-adapter/extensions.js +42 -0
  77. package/lib/types/dsh-adapter/grants.d.ts +25 -0
  78. package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
  79. package/lib/types/dsh-adapter/grants.js +184 -0
  80. package/lib/types/dsh-adapter/host-descriptor.d.ts +24 -0
  81. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
  82. package/lib/types/dsh-adapter/host-descriptor.js +146 -0
  83. package/lib/types/dsh-adapter/index.d.ts +4 -0
  84. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  85. package/lib/types/dsh-adapter/index.js +1 -0
  86. package/lib/types/dsh-adapter/message-observer.d.ts +178 -0
  87. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
  88. package/lib/types/dsh-adapter/message-observer.js +509 -0
  89. package/lib/types/dsh-adapter/plugin-host.d.ts +103 -0
  90. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
  91. package/lib/types/dsh-adapter/plugin-host.js +270 -0
  92. package/lib/types/dsh-adapter/plugin-storage.d.ts +113 -0
  93. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
  94. package/lib/types/dsh-adapter/plugin-storage.js +385 -0
  95. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  96. package/lib/types/dsh-adapter/plugin.js +106 -1
  97. package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
  98. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
  99. package/lib/types/dsh-adapter/plugins-info.js +276 -0
  100. package/lib/types/dsh-adapter/promptDebug.d.ts +10 -0
  101. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
  102. package/lib/types/dsh-adapter/promptDebug.js +148 -0
  103. package/lib/types/dsh-adapter/renderers.d.ts +65 -0
  104. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
  105. package/lib/types/dsh-adapter/renderers.js +138 -0
  106. package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
  107. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
  108. package/lib/types/dsh-adapter/sanitize.js +65 -0
  109. package/lib/types/dsh-adapter/scenes.d.ts +81 -0
  110. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
  111. package/lib/types/dsh-adapter/scenes.js +93 -0
  112. package/lib/types/dsh-adapter/settings-sections.d.ts +116 -0
  113. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
  114. package/lib/types/dsh-adapter/settings-sections.js +63 -0
  115. package/lib/types/dsh-adapter/settingsEditor.d.ts +128 -0
  116. package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
  117. package/lib/types/dsh-adapter/settingsEditor.js +244 -0
  118. package/lib/types/dsh-adapter/shortcuts.d.ts +109 -0
  119. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
  120. package/lib/types/dsh-adapter/shortcuts.js +268 -0
  121. package/lib/types/dsh-adapter/status.d.ts +75 -0
  122. package/lib/types/dsh-adapter/status.d.ts.map +1 -0
  123. package/lib/types/dsh-adapter/status.js +168 -0
  124. package/lib/types/extensions.d.ts +8 -0
  125. package/lib/types/extensions.d.ts.map +1 -0
  126. package/lib/types/extensions.js +15 -0
  127. package/lib/types/i18n.d.ts +299 -26
  128. package/lib/types/i18n.d.ts.map +1 -1
  129. package/lib/types/i18n.js +89 -8
  130. package/lib/types/ink/ink.d.ts +11 -0
  131. package/lib/types/ink/ink.d.ts.map +1 -1
  132. package/lib/types/ink/ink.js +33 -0
  133. package/lib/types/ink/log-update.d.ts.map +1 -1
  134. package/lib/types/ink/log-update.js +101 -51
  135. package/lib/types/ink/output.d.ts +7 -0
  136. package/lib/types/ink/output.d.ts.map +1 -1
  137. package/lib/types/ink/output.js +125 -4
  138. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  139. package/lib/types/ink/render-node-to-output.js +14 -6
  140. package/lib/types/ink/terminal.d.ts.map +1 -1
  141. package/lib/types/ink/terminal.js +18 -6
  142. package/lib/types/jsx-runtime.d.ts +2 -0
  143. package/lib/types/jsx-runtime.d.ts.map +1 -0
  144. package/lib/types/jsx-runtime.js +13 -0
  145. package/lib/types/modelRoute.d.ts +10 -2
  146. package/lib/types/modelRoute.d.ts.map +1 -1
  147. package/lib/types/modelRoute.js +33 -4
  148. package/lib/types/plugin-host.d.ts +13 -0
  149. package/lib/types/plugin-host.d.ts.map +1 -0
  150. package/lib/types/plugin-host.js +17 -0
  151. package/lib/types/plugin-spec/negotiate.d.ts +11 -0
  152. package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
  153. package/lib/types/plugin-spec/negotiate.js +97 -0
  154. package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
  155. package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
  156. package/lib/types/plugin-spec/permission-scope.js +90 -0
  157. package/lib/types/plugin-spec/registry.d.ts +23 -0
  158. package/lib/types/plugin-spec/registry.d.ts.map +1 -0
  159. package/lib/types/plugin-spec/registry.js +157 -0
  160. package/lib/types/plugin-spec/schema-check.d.ts +17 -0
  161. package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
  162. package/lib/types/plugin-spec/schema-check.js +165 -0
  163. package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
  164. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
  165. package/lib/types/plugin-spec/tui-extension.js +77 -0
  166. package/lib/types/plugin-spec/types.d.ts +114 -0
  167. package/lib/types/plugin-spec/types.d.ts.map +1 -0
  168. package/lib/types/plugin-spec/types.js +10 -0
  169. package/lib/types/plugin-spec/validate.d.ts +21 -0
  170. package/lib/types/plugin-spec/validate.d.ts.map +1 -0
  171. package/lib/types/plugin-spec/validate.js +119 -0
  172. package/lib/types/scenes.d.ts +3 -0
  173. package/lib/types/scenes.d.ts.map +1 -0
  174. package/lib/types/scenes.js +4 -0
  175. package/lib/types/screens/Chat.d.ts +14 -1
  176. package/lib/types/screens/Chat.d.ts.map +1 -1
  177. package/lib/types/screens/Chat.js +247 -48
  178. package/lib/types/screens/Settings.d.ts +20 -0
  179. package/lib/types/screens/Settings.d.ts.map +1 -0
  180. package/lib/types/screens/Settings.js +333 -0
  181. package/lib/types/screens/StatusLine.js +1 -1
  182. package/lib/types/settings-sections.d.ts +3 -0
  183. package/lib/types/settings-sections.d.ts.map +1 -0
  184. package/lib/types/settings-sections.js +4 -0
  185. package/lib/types/theme.d.ts +17 -0
  186. package/lib/types/theme.d.ts.map +1 -1
  187. package/lib/types/theme.js +51 -0
  188. package/lib/types/update.d.ts +20 -0
  189. package/lib/types/update.d.ts.map +1 -1
  190. package/lib/types/update.js +54 -7
  191. package/lib/types/utils/loaded-context.d.ts +8 -3
  192. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  193. package/lib/types/utils/loaded-context.js +39 -3
  194. package/lib/types/utils/modifiers.d.ts.map +1 -1
  195. package/lib/types/utils/modifiers.js +3 -2
  196. package/lib/types/working-activity.d.ts +12 -0
  197. package/lib/types/working-activity.d.ts.map +1 -1
  198. package/lib/types/working-activity.js +13 -0
  199. package/node_modules/@dsh-std/command/LICENSE +21 -0
  200. package/node_modules/@dsh-std/command/README.md +26 -0
  201. package/node_modules/@dsh-std/command/README.zh.md +28 -0
  202. package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
  203. package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
  204. package/node_modules/@dsh-std/command/lib/index.js +252 -0
  205. package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
  206. package/node_modules/@dsh-std/command/package.json +22 -0
  207. package/node_modules/@dsh-std/connection/LICENSE +21 -0
  208. package/node_modules/@dsh-std/connection/README.md +42 -0
  209. package/node_modules/@dsh-std/connection/README.zh.md +42 -0
  210. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  211. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  212. package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  213. package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  214. package/node_modules/@dsh-std/connection/lib/index.js +158 -0
  215. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  216. package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  217. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  218. package/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  219. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  220. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  221. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  222. package/node_modules/@dsh-std/connection/package.json +20 -0
  223. package/node_modules/@dsh-std/core/LICENSE +21 -0
  224. package/node_modules/@dsh-std/core/README.md +13 -0
  225. package/node_modules/@dsh-std/core/README.zh.md +13 -0
  226. package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  227. package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  228. package/node_modules/@dsh-std/core/lib/index.js +424 -0
  229. package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  230. package/node_modules/@dsh-std/core/package.json +21 -0
  231. package/node_modules/@dsh-std/manifest/LICENSE +21 -0
  232. package/node_modules/@dsh-std/manifest/README.md +5 -0
  233. package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  234. package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  235. package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  236. package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  237. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  238. package/node_modules/@dsh-std/manifest/package.json +20 -0
  239. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  240. package/node_modules/@dsh-std/messages/LICENSE +21 -0
  241. package/node_modules/@dsh-std/messages/README.md +5 -0
  242. package/node_modules/@dsh-std/messages/README.zh.md +7 -0
  243. package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
  244. package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
  245. package/node_modules/@dsh-std/messages/lib/index.js +151 -0
  246. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
  247. package/node_modules/@dsh-std/messages/package.json +20 -0
  248. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
  249. package/node_modules/@dsh-std/presentation/LICENSE +21 -0
  250. package/node_modules/@dsh-std/presentation/README.md +26 -0
  251. package/node_modules/@dsh-std/presentation/README.zh.md +28 -0
  252. package/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
  253. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  254. package/node_modules/@dsh-std/presentation/lib/index.js +547 -0
  255. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  256. package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  257. package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  258. package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  259. package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  260. package/node_modules/@dsh-std/presentation/package.json +21 -0
  261. package/node_modules/@dsh-std/storage/LICENSE +21 -0
  262. package/node_modules/@dsh-std/storage/README.md +5 -0
  263. package/node_modules/@dsh-std/storage/README.zh.md +7 -0
  264. package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
  265. package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
  266. package/node_modules/@dsh-std/storage/lib/index.js +104 -0
  267. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
  268. package/node_modules/@dsh-std/storage/package.json +20 -0
  269. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
  270. package/package.json +118 -67
  271. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
  272. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
  273. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
  274. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  275. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  276. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  277. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  278. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
  279. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  280. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  281. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  282. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  283. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  284. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  285. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  286. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
  287. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
  288. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
  289. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
  290. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  291. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  292. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
  293. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  294. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
  295. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
  296. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
  297. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  298. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  299. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  300. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  301. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  302. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
  303. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  304. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
  305. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +26 -0
  306. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +28 -0
  307. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
  308. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  309. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +547 -0
  310. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  311. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  312. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  313. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  314. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  315. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +21 -0
  316. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
  317. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
  318. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
  319. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  320. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  321. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
  322. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  323. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
  324. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
  325. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
  326. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
  327. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  328. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  329. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
  330. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  331. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
  332. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
  333. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
  334. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
  335. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  336. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  337. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
  338. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  339. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
  340. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
  341. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
  342. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
  343. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  344. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  345. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  346. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  347. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
  348. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  349. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  350. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  351. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  352. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  353. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  354. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  355. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
  356. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
  357. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
  358. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
  359. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  360. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  361. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
  362. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  363. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
  364. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
  365. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
  366. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
  367. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  368. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  369. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
  370. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  371. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
@@ -0,0 +1,385 @@
1
+ /**
2
+ * storage.local contract surface (C-040, `storage.dsh/v1alpha1#LocalStorage`):
3
+ * per-plugin private persistence, mounted by the dsh-tui-plugin-host row as
4
+ * `ctx.tuiPluginStorage`.
5
+ *
6
+ * The plugin-facing API is `open(ctx)` → `{ get, set, delete }`:
7
+ *
8
+ * - VERIFIED IDENTITY: the namespace is derived from the admitted Component
9
+ * identity bound to the PASSED activation — there is no parameter to name
10
+ * another plugin, so cross-plugin access is rejected by construction.
11
+ * - GRANTS AT CALL TIME: `get` requires `storage.local.read`, `set`/`delete`
12
+ * require `storage.local.write` — checked per call against the live grant
13
+ * store (a revoked grant blocks the very next operation without restart).
14
+ * - Backend: `~/.dsh-tui/plugin-storage/<namespace>.json`, one flat JSON
15
+ * object per namespace. Writes go through dsh-atomic-write (`withFileLock`
16
+ * for the read-modify-write cycle + `writeFileAtomic` for the commit), and
17
+ * an in-process per-namespace promise chain serializes operations in
18
+ * invocation order (contract concurrency rule — the lock alone does not
19
+ * order contenders).
20
+ * - QUOTA (host-defined): 256 keys AND 256 KiB of serialized content per
21
+ * namespace; a `set` that would cross either fails with QUOTA_EXCEEDED and
22
+ * changes nothing.
23
+ * - Keys stay ordinary data even when they collide with Object.prototype
24
+ * names ("__proto__", "toString", "constructor"): namespace tables are
25
+ * null-prototype and membership is decided with Object.hasOwn. Values
26
+ * must be EXACT JSON values — inputs JSON.stringify would silently
27
+ * mutate (undefined, NaN/±Infinity, functions, class instances, sparse
28
+ * arrays, cycles) are rejected instead of round-tripping a lie.
29
+ * - A corrupt namespace file is NEVER overwritten silently: every operation
30
+ * fails with STORAGE_UNAVAILABLE and the bytes stay on disk for manual
31
+ * recovery. Closing a handle (plugin unload) retains data (contract
32
+ * cleanup rule); later calls on a closed handle fail STORAGE_UNAVAILABLE.
33
+ * - privacyClass: sensitive — keys AND values are never logged.
34
+ */
35
+ import { mkdirSync, readFileSync } from 'node:fs';
36
+ import { join } from 'node:path';
37
+ import { writeFileAtomic, withFileLock } from '@deepseek-ai/dsh-atomic-write';
38
+ import { Service } from '@deepseek-ai/cordis';
39
+ import { validateDeleteInput, validateGetInput, validateSetInput, validateGetOutput, validateSetOutput, validateDeleteOutput, } from '@dsh-std/storage';
40
+ import { DATA_DIR } from '../utils/paths.js';
41
+ import { declaresPermission, requireComponentIdentity } from './component-identity.js';
42
+ import { readGrantStore } from './grants.js';
43
+ /** Quota: max distinct keys per namespace. */
44
+ export const STORAGE_MAX_KEYS = 256;
45
+ /** Quota: max serialized file size per namespace (bytes). */
46
+ export const STORAGE_MAX_BYTES = 256 * 1024;
47
+ /** Max key length (characters). */
48
+ export const STORAGE_KEY_MAX_LENGTH = 128;
49
+ /** Storage failure with the contract's error code on `.code`. */
50
+ export class PluginStorageError extends Error {
51
+ code;
52
+ constructor(code, message) {
53
+ super(message);
54
+ this.name = 'PluginStorageError';
55
+ this.code = code;
56
+ }
57
+ }
58
+ /** Namespace directory under the data dir. */
59
+ export const PLUGIN_STORAGE_DIR = 'plugin-storage';
60
+ /**
61
+ * Plugin name → safe, collision-free file name. encodeURIComponent keeps
62
+ * alphanumerics and `- _ . ! ~ * ' ( )`, so scoped names like `@foo/bar`
63
+ * encode reversibly; pathological results ('', '.', '..') map to '_'.
64
+ */
65
+ export function storageFileName(plugin) {
66
+ const encoded = encodeURIComponent(plugin);
67
+ return encoded === '' || encoded === '.' || encoded === '..' ? '_' : encoded;
68
+ }
69
+ function assertKey(key) {
70
+ if (typeof key !== 'string' || key === '' || key.length > STORAGE_KEY_MAX_LENGTH || /[\x00-\x1f\x7f-\x9f]/.test(key)) {
71
+ throw new PluginStorageError('INVALID_KEY', 'storage keys are non-empty control-free strings of at most 128 characters');
72
+ }
73
+ }
74
+ function validateStorageInput(operation, input) {
75
+ try {
76
+ if (operation === 'get')
77
+ validateGetInput(input);
78
+ else if (operation === 'set')
79
+ validateSetInput(input);
80
+ else
81
+ validateDeleteInput(input);
82
+ }
83
+ catch (error) {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ if (operation !== 'set')
86
+ throw new PluginStorageError('INVALID_KEY', message);
87
+ // The standard validator intentionally reports exact-record failures in a
88
+ // single stream. Preserve the contract's distinction: malformed/missing
89
+ // `key` is INVALID_KEY; once the key itself is valid, every value/shape
90
+ // failure (including a missing `value`) is INVALID_VALUE.
91
+ let keyValid = false;
92
+ try {
93
+ const candidate = input;
94
+ assertKey(candidate?.key);
95
+ keyValid = true;
96
+ }
97
+ catch {
98
+ keyValid = false;
99
+ }
100
+ throw new PluginStorageError(keyValid ? 'INVALID_VALUE' : 'INVALID_KEY', message);
101
+ }
102
+ }
103
+ /**
104
+ * Exact JSON values only. JSON.stringify silently MUTATES edge inputs
105
+ * (NaN/±Infinity → null, undefined array items → null, undefined object
106
+ * properties dropped, class instances reduced to own fields) — a storage
107
+ * contract must not round-trip a value the caller never stored, so those
108
+ * inputs are rejected instead. Accepts: null, boolean, string, finite
109
+ * number, arrays (dense), and plain objects (Object.prototype or null
110
+ * prototype only). Every own property is inspected because JSON.stringify
111
+ * ignores array side-properties, symbols, and non-enumerable fields, while
112
+ * accessors/toJSON can replace the value being serialized. Those inputs,
113
+ * cycles, and anything whose inspection throws are rejected.
114
+ */
115
+ function assertJsonValue(value) {
116
+ let ok = false;
117
+ try {
118
+ ok = isJsonValue(value, new Set());
119
+ }
120
+ catch {
121
+ ok = false;
122
+ }
123
+ if (!ok) {
124
+ throw new PluginStorageError('INVALID_VALUE', 'storage values must be exact JSON values (no undefined, functions, symbols, BigInt, NaN/Infinity, class instances, sparse arrays, or cycles)');
125
+ }
126
+ }
127
+ function isJsonValue(value, seen) {
128
+ if (value === null)
129
+ return true;
130
+ switch (typeof value) {
131
+ case 'boolean':
132
+ case 'string':
133
+ return true;
134
+ case 'number':
135
+ return Number.isFinite(value);
136
+ case 'object': {
137
+ const object = value;
138
+ if (seen.has(object))
139
+ return false;
140
+ seen.add(object);
141
+ try {
142
+ if (Array.isArray(value)) {
143
+ // Array subclasses/custom prototypes can supply an inherited toJSON
144
+ // hook. JSON would serialize its replacement, not this array.
145
+ if (Object.getPrototypeOf(value) !== Array.prototype)
146
+ return false;
147
+ if (Object.getOwnPropertySymbols(value).length > 0)
148
+ return false;
149
+ const ownNames = Object.getOwnPropertyNames(value);
150
+ for (const name of ownNames) {
151
+ if (name === 'length')
152
+ continue;
153
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
154
+ // JSON arrays serialize only their indexed elements. Any other
155
+ // own property (especially toJSON) would be silently lost.
156
+ const index = Number(name);
157
+ if (descriptor === undefined || !('value' in descriptor) ||
158
+ !Number.isSafeInteger(index) || index < 0 || String(index) !== name || index >= value.length)
159
+ return false;
160
+ }
161
+ for (let index = 0; index < value.length; index++) {
162
+ // A sparse hole would serialize as null — a value never stored.
163
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
164
+ if (descriptor === undefined || !('value' in descriptor))
165
+ return false;
166
+ if (!isJsonValue(descriptor.value, seen))
167
+ return false;
168
+ }
169
+ return true;
170
+ }
171
+ const proto = Object.getPrototypeOf(value);
172
+ if (proto !== Object.prototype && proto !== null)
173
+ return false;
174
+ // A modified Object.prototype can add an inherited toJSON hook; own
175
+ // non-enumerable/accessor properties are likewise not exact JSON.
176
+ if (typeof value.toJSON === 'function')
177
+ return false;
178
+ if (Object.getOwnPropertySymbols(value).length > 0)
179
+ return false;
180
+ for (const name of Object.getOwnPropertyNames(value)) {
181
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
182
+ if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor))
183
+ return false;
184
+ if (!isJsonValue(descriptor.value, seen))
185
+ return false;
186
+ }
187
+ return true;
188
+ }
189
+ finally {
190
+ // DAGs (shared references without cycles) serialize fine — only
191
+ // reject a value reachable from ITSELF.
192
+ seen.delete(object);
193
+ }
194
+ }
195
+ default:
196
+ // undefined / function / symbol / bigint
197
+ return false;
198
+ }
199
+ }
200
+ /**
201
+ * `ctx.tuiPluginStorage` — storage.local contract surface. Mounted by the
202
+ * dsh-tui-plugin-host row; grants come from that row's store when present
203
+ * (normal path) or a private read otherwise (bare mounts in tests).
204
+ */
205
+ export class TuiPluginStorageRuntime extends Service {
206
+ grantsOption;
207
+ fallbackGrants;
208
+ ledgerOption;
209
+ namespaces = new Map();
210
+ dir;
211
+ constructor(ctx, options = {}) {
212
+ super(ctx, 'tuiPluginStorage');
213
+ this.grantsOption = options.grants;
214
+ this.fallbackGrants = readGrantStore();
215
+ this.ledgerOption = options.ledger;
216
+ this.dir = options.dir ?? join(DATA_DIR, PLUGIN_STORAGE_DIR);
217
+ }
218
+ /** Grants: the plugin-host row's store when mounted, else a private read.
219
+ * Resolved PER CALL — sibling services mounted later by the same apply()
220
+ * are not visible to constructors (cordis), so a constructor-time probe
221
+ * would silently stick to the fallback. */
222
+ grants() {
223
+ return this.grantsOption ?? this.ctx.get('tuiPluginHost')?.grants ?? this.fallbackGrants;
224
+ }
225
+ /** Optional observability; a bare mount (tests) simply records nothing. */
226
+ ledger() {
227
+ return this.ledgerOption ?? this.ctx.get('tuiEffectLedger');
228
+ }
229
+ /**
230
+ * Open the caller's private namespace. Identity = the PASSED context's
231
+ * verified Component identity (no way to name another plugin). The handle
232
+ * closes automatically when the caller's context unloads (idempotent
233
+ * disposer); data is retained (contract cleanup rule).
234
+ */
235
+ open(pluginCtx) {
236
+ const identity = requireComponentIdentity(pluginCtx);
237
+ const plugin = identity.componentId;
238
+ let state = this.namespaces.get(plugin);
239
+ if (state === undefined) {
240
+ state = { chain: Promise.resolve() };
241
+ this.namespaces.set(plugin, state);
242
+ }
243
+ this.ledger()?.record({ operation: 'create', resource: { kind: 'storage-namespace', id: plugin }, result: 'applied' }, pluginCtx);
244
+ // `closed` is PER HANDLE, not per namespace: unloading one fiber must not
245
+ // kill another handle opened on the same namespace. Close on unload;
246
+ // idempotent (a double-close stays harmless by design); degraded contexts
247
+ // without `effect` simply never auto-close.
248
+ let closed = false;
249
+ try {
250
+ pluginCtx.effect(() => () => {
251
+ if (closed)
252
+ return;
253
+ closed = true;
254
+ this.ledger()?.record({ operation: 'release', resource: { kind: 'storage-namespace', id: plugin }, result: 'applied' }, pluginCtx);
255
+ });
256
+ }
257
+ catch {
258
+ // Degraded context: the handle lives until process end.
259
+ }
260
+ const file = join(this.dir, `${storageFileName(plugin)}.json`);
261
+ const grants = () => this.grants();
262
+ const ledger = () => this.ledger();
263
+ const enqueue = (operation) => {
264
+ if (closed) {
265
+ return Promise.reject(new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" handle is closed`));
266
+ }
267
+ const run = state.chain.then(operation);
268
+ // Keep the chain alive after a failure without unhandled rejections.
269
+ state.chain = run.catch(() => { });
270
+ return run;
271
+ };
272
+ const readTable = () => {
273
+ let raw;
274
+ try {
275
+ raw = readFileSync(file, 'utf8');
276
+ }
277
+ catch (error) {
278
+ if (error.code === 'ENOENT')
279
+ return Object.create(null);
280
+ throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" is unreadable; the file was left untouched for manual recovery`);
281
+ }
282
+ let parsed;
283
+ try {
284
+ parsed = JSON.parse(raw);
285
+ }
286
+ catch {
287
+ throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" is corrupt on disk; the file was left untouched for manual recovery`);
288
+ }
289
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
290
+ throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" holds a non-object document; the file was left untouched for manual recovery`);
291
+ }
292
+ // Rebuild on a NULL-PROTOTYPE table: key membership is decided with
293
+ // Object.hasOwn, and keys like "__proto__" / "toString" must behave
294
+ // as ordinary data (a prototype-chain read would leak host objects
295
+ // into plugin results and fake membership for never-stored keys).
296
+ const table = Object.create(null);
297
+ for (const [key, value] of Object.entries(parsed))
298
+ table[key] = value;
299
+ return table;
300
+ };
301
+ const requireGrant = (permission) => {
302
+ if (!declaresPermission(identity, permission, plugin)
303
+ || !grants().allows({ componentId: identity.componentId, activationId: identity.activationId }, permission, plugin)) {
304
+ ledger()?.record({
305
+ operation: 'bind',
306
+ resource: { kind: 'permission', id: permission },
307
+ result: 'failed',
308
+ errorCode: 'PERMISSION_NOT_GRANTED',
309
+ }, pluginCtx);
310
+ throw new PluginStorageError('PERMISSION_NOT_GRANTED', `storage.${permission.endsWith('.read') ? 'get' : 'set/delete'} from plugin "${plugin}" denied — grant "${permission}" ` +
311
+ `for "${plugin}" in ~/.dsh-tui/extension-grants.json first`);
312
+ }
313
+ };
314
+ // withFileLock creates its lock as a SIBLING of the file and does not
315
+ // create parent directories — ensure the tree exists before any write
316
+ // path (read paths tolerate ENOENT as an empty namespace and never
317
+ // materialize the tree).
318
+ const ensureDir = () => {
319
+ mkdirSync(this.dir, { recursive: true, mode: 0o700 });
320
+ };
321
+ return {
322
+ get: (input) => enqueue(async () => {
323
+ validateStorageInput('get', input);
324
+ const key = input.key;
325
+ assertKey(key);
326
+ requireGrant('storage.local.read');
327
+ const table = readTable();
328
+ const output = { value: Object.hasOwn(table, key) ? table[key] : null };
329
+ try {
330
+ validateGetOutput(output);
331
+ }
332
+ catch {
333
+ throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" contains an invalid JSON value`);
334
+ }
335
+ return output;
336
+ }),
337
+ set: (input) => enqueue(async () => {
338
+ validateStorageInput('set', input);
339
+ const key = input.key;
340
+ const value = input.value;
341
+ assertKey(key);
342
+ assertJsonValue(value);
343
+ requireGrant('storage.local.write');
344
+ ensureDir();
345
+ return withFileLock(file, async () => {
346
+ const table = readTable();
347
+ const isNewKey = !Object.hasOwn(table, key);
348
+ if (isNewKey && Object.keys(table).length >= STORAGE_MAX_KEYS) {
349
+ throw new PluginStorageError('QUOTA_EXCEEDED', `storage namespace "${plugin}" holds ${STORAGE_MAX_KEYS} keys already`);
350
+ }
351
+ table[key] = value;
352
+ const content = JSON.stringify(table);
353
+ if (Buffer.byteLength(content, 'utf8') > STORAGE_MAX_BYTES) {
354
+ throw new PluginStorageError('QUOTA_EXCEEDED', `storage namespace "${plugin}" would exceed ${STORAGE_MAX_BYTES} bytes`);
355
+ }
356
+ // 0o600/0o700: the namespace is privacyClass sensitive.
357
+ await writeFileAtomic(file, content, { mode: 0o600, dirMode: 0o700 });
358
+ const output = { stored: true };
359
+ validateSetOutput(output);
360
+ return output;
361
+ });
362
+ }),
363
+ delete: (input) => enqueue(async () => {
364
+ validateStorageInput('delete', input);
365
+ const key = input.key;
366
+ assertKey(key);
367
+ requireGrant('storage.local.write');
368
+ ensureDir();
369
+ return withFileLock(file, async () => {
370
+ const table = readTable();
371
+ if (!Object.hasOwn(table, key)) {
372
+ const output = { deleted: false };
373
+ validateDeleteOutput(output);
374
+ return output;
375
+ }
376
+ delete table[key];
377
+ await writeFileAtomic(file, JSON.stringify(table), { mode: 0o600, dirMode: 0o700 });
378
+ const output = { deleted: true };
379
+ validateDeleteOutput(output);
380
+ return output;
381
+ });
382
+ }),
383
+ };
384
+ }
385
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AA6BnC;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8bvE;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAcA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAiCnC;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6iBvE;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAcA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV"}
@@ -3,12 +3,15 @@ import React from 'react';
3
3
  import { SessionId } from '@deepseek-ai/dsh-session';
4
4
  import UserQuestionService from '@deepseek-ai/dsh-user-questions';
5
5
  import * as toolAskUser from '@deepseek-ai/dsh-tool-ask-user';
6
+ import { settingsNamespace } from '@deepseek-ai/dsh-settings';
7
+ import Schema from '@deepseek-ai/schemastery';
6
8
  import { createChannel } from './channel.js';
7
9
  import { createChildStderrReporter, installChildStderrGuard } from './childStderr.js';
8
10
  import { logForDebugging } from '../utils/debug.js';
9
11
  import { QuestionStore } from './questions.js';
10
12
  import { ApprovalStore } from './approvals.js';
11
13
  import { registerPackagedSkills } from './packaged-skills.js';
14
+ import { registerPromptDebug } from './promptDebug.js';
12
15
  import { readActivityFrames } from '../activityPrefs.js';
13
16
  import { readModelPref } from '../modelPrefs.js';
14
17
  import { explicitModelRoute, recordedModelRoute, resolveModelRoute, validateModelRoute } from '../modelRoute.js';
@@ -18,7 +21,7 @@ import { ensurePackagedPresets } from './packaged-presets.js';
18
21
  import { ensureLegacySessionEventTypes } from './compat/index.js';
19
22
  import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
20
23
  import { resolveSessionCwd } from '../utils/workspaceRoot.js';
21
- import { checkForTuiUpdate, installedTuiVersion, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
24
+ import { checkForTuiUpdate, installedTuiVersion, isBootDeadlockTarget, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
22
25
  import { isLang, resolveStartupLang, setLang, t } from '../i18n.js';
23
26
  import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
24
27
  import { Chat } from '../screens/Chat.js';
@@ -130,6 +133,9 @@ export async function apply(ctx, config) {
130
133
  // Packaged skills (/audit, /bug, …): contribute them through the host's
131
134
  // skill registry so they resolve with zero manual copying.
132
135
  registerPackagedSkills(ctx);
136
+ // `/debug-prompt` snapshots the final provider-neutral request at the
137
+ // llm/stream boundary, after every prompt and tool contributor has run.
138
+ registerPromptDebug(ctx);
133
139
  // Yield to an incumbent provider instead of crashing the whole plugin tree
134
140
  // (issue #98): the harness allows exactly ONE user-questions provider per
135
141
  // context, and stacking this TUI onto a profile that already carries
@@ -211,6 +217,32 @@ export async function apply(ctx, config) {
211
217
  'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
212
218
  }
213
219
  const workspaceService = mountedWorkspaceService ?? createLocalWorkspaceRuntime();
220
+ // Same skew guard for the plugin-scene registry (dsh-tui-scenes row): the
221
+ // channel degrades to never opening scenes when the service is absent, so
222
+ // say why on profile launches — a plugin's open() otherwise fails with only
223
+ // its own warn to go on.
224
+ if (ctx.get('tuiScenes') === undefined && resolveDshProfileName() !== undefined) {
225
+ ctx.logger.warn('dsh-tui: tuiScenes service is not mounted; plugin scenes will never open. ' +
226
+ 'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
227
+ }
228
+ // Same skew guard for the plugin-UI services (dsh-tui-extensions row):
229
+ // managed dialogs park unanswered, status contributions never render,
230
+ // shortcuts never match, and custom-entry renderers stay invisible when
231
+ // the row is absent — say why on profile launches.
232
+ if (ctx.get('tuiDialogs') === undefined && resolveDshProfileName() !== undefined) {
233
+ ctx.logger.warn('dsh-tui: tuiDialogs/tuiStatus/tuiShortcuts/tuiRenderers services are not mounted; plugin dialogs, status contributions, shortcuts and custom-entry renderers are off. ' +
234
+ 'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
235
+ }
236
+ // Same skew guard for the plugin-host row (dsh-tui-plugin-host): without
237
+ // it there is no runtime generation id, no unified grant store service,
238
+ // and no Host Descriptor — plugin interop surfaces degrade silently
239
+ // otherwise. The D-7 decision gate does NOT depend on this row (the
240
+ // channel installs its own), so interception gating stays intact either
241
+ // way — what breaks is everything that rides on tuiPluginHost.
242
+ if (ctx.get('tuiPluginHost') === undefined && resolveDshProfileName() !== undefined) {
243
+ ctx.logger.warn('dsh-tui: tuiPluginHost service is not mounted; plugin grant store, runtime generation and Host Descriptor are unavailable. ' +
244
+ 'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
245
+ }
214
246
  const initialWorkspace = requestedWorkspace === undefined
215
247
  ? undefined
216
248
  : await workspaceService.resolve(requestedWorkspace);
@@ -267,8 +299,53 @@ export async function apply(ctx, config) {
267
299
  // Shift+Tab session-mode cycle (undefined → the built-in default/
268
300
  // plan/full cycle in sessionModes.ts).
269
301
  modes: config.modes,
302
+ // Edit/Write diff presentation (schema default 'auto'); the /settings
303
+ // screen edits this key live through the dsh-tui namespace.
304
+ diffLayout: config.diffLayout,
270
305
  handle,
271
306
  });
307
+ // Register the dsh-tui settings namespace so the /settings screen can
308
+ // edit it (the section below was '命名空间未注册' without this): the
309
+ // user layer in settings.yaml wins over cordis.yml's diffLayout, and
310
+ // watch() lands commits on the live channel — no recompose needed.
311
+ ctx.inject(['settings'], (settingsCtx) => {
312
+ const scope = settingsCtx.settings.register(settingsNamespace('dsh-tui'), Schema.object({
313
+ diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
314
+ }));
315
+ const applyLayout = (value) => {
316
+ channel.setDiffLayout(value.diffLayout ?? config.diffLayout ?? 'auto');
317
+ };
318
+ applyLayout(scope.get());
319
+ scope.watch(next => {
320
+ applyLayout(next);
321
+ });
322
+ });
323
+ // The /settings screen's own section: the dsh-tui namespace comes from
324
+ // this plugin's Config schema, and the declared select writes diffLayout
325
+ // back through the settings service's revision-fenced mutate.
326
+ const settingsSections = ctx.get('tuiSettingsSections');
327
+ if (settingsSections !== undefined) {
328
+ const unregister = settingsSections.register({
329
+ ns: 'dsh-tui',
330
+ title: 'dsh-tui',
331
+ fields: [
332
+ {
333
+ path: ['diffLayout'],
334
+ label: 'Diff layout',
335
+ descriptions: { zh: 'diff 布局' },
336
+ hint: 'Edit/Write tool cards: auto picks by terminal width, or force one layout.',
337
+ hintDescriptions: { zh: 'Edit/Write 工具卡的 diff 呈现:auto 按终端宽度选择,或强制一种布局。' },
338
+ kind: 'select',
339
+ options: [
340
+ { value: 'auto', label: 'Auto (by width)', descriptions: { zh: '自动(按宽度)' } },
341
+ { value: 'split', label: 'Side-by-side', descriptions: { zh: '双栏对照' } },
342
+ { value: 'unified', label: 'Unified', descriptions: { zh: '统一式' } },
343
+ ],
344
+ },
345
+ ],
346
+ });
347
+ ctx.effect(() => unregister);
348
+ }
272
349
  // DSH approval seam: the permission layer asks ApprovalService.request(),
273
350
  // which dispatches an `approval/request` waterfall. With no answerer the
274
351
  // chain falls through to the fail-closed 'unavailable', so register this
@@ -369,6 +446,12 @@ export async function apply(ctx, config) {
369
446
  channel,
370
447
  questionStore,
371
448
  approvalStore,
449
+ // The dsh-tui-extensions row's services (managed dialogs, status line,
450
+ // shortcuts). Soft-consumed: absent the row (stale patch, bare embed),
451
+ // Chat falls back to inert stores and no shortcut registry.
452
+ extensionDialogs: ctx.get('tuiDialogs')?.store,
453
+ extensionStatus: ctx.get('tuiStatus')?.store,
454
+ extensionShortcuts: ctx.get('tuiShortcuts'),
372
455
  // Full-screen surfaces inside Chat — the trajectory scene and the session
373
456
  // browser — enter the alt screen themselves in inline mode; in fullscreen
374
457
  // the tree is already wrapped below, so they must not nest.
@@ -394,6 +477,21 @@ export async function apply(ctx, config) {
394
477
  channel.notify(t('update-check-failed'));
395
478
  }
396
479
  else {
480
+ // 0.7.0/0.7.1 hard-inject tuiWorkspaces at the code level; under
481
+ // an older global launcher patch (no service row) that is a
482
+ // permanent boot deadlock (issues #183/#307, the exact report
483
+ // "pending (waiting for service: tuiWorkspaces)"). A stale mirror
484
+ // pinning /update onto that range must be refused, not installed.
485
+ if (isBootDeadlockTarget(target.latest)) {
486
+ channel.notify(t('update-refused-deadlock', {
487
+ latest: target.latest,
488
+ authoritative: target.authoritative ?? target.latest,
489
+ }), { color: 'warning' });
490
+ return;
491
+ }
492
+ if (target.authoritative !== undefined) {
493
+ channel.notify(t('update-mirror-lag', { latest: target.latest, authoritative: target.authoritative }));
494
+ }
397
495
  updateTargetVersion = target.latest;
398
496
  }
399
497
  channel.notify(t('update-starting'));
@@ -585,6 +683,11 @@ async function finishExit(ctx, instance, fullscreen, notice, stderrNotice, done)
585
683
  const cursor = fullscreen ? '' : cursorMoveToFrameEnd(runtime);
586
684
  try {
587
685
  runtime?.detachForShutdown?.();
686
+ // The /update continuation spawns children that inherit this stdin;
687
+ // strip the readable pump so the parent cannot swallow their input
688
+ // (issues #284/#307). Harmless on plain exits — the process exits
689
+ // right after this cleanup anyway.
690
+ runtime?.detachStdinForHandoff?.();
588
691
  }
589
692
  catch {
590
693
  ctx.logger.debug('dsh-tui: Ink shutdown detach failed; continuing with generic terminal cleanup');
@@ -619,6 +722,8 @@ function readInkShutdownState(value) {
619
722
  const candidate = value;
620
723
  if (candidate.detachForShutdown !== undefined && typeof candidate.detachForShutdown !== 'function')
621
724
  return undefined;
725
+ if (candidate.detachStdinForHandoff !== undefined && typeof candidate.detachStdinForHandoff !== 'function')
726
+ return undefined;
622
727
  if (candidate.frontFrame !== undefined && !isFrameState(candidate.frontFrame))
623
728
  return undefined;
624
729
  if (candidate.displayCursor !== undefined && candidate.displayCursor !== null && !isCursorState(candidate.displayCursor))
@@ -0,0 +1,43 @@
1
+ /**
2
+ * /plugins diagnostics surface (C-070 trust disclosure + C-030 negotiation
3
+ * diagnostics): assembles the lines behind the `/plugins` command.
4
+ *
5
+ * Sections (overview):
6
+ *
7
+ * 1. TRUST BANNER — always the first line (C-070): plugins run in-process;
8
+ * grants are behavioral constraints, not a security boundary; passing
9
+ * validation is not proof of safety.
10
+ * 2. HOST DESCRIPTOR summary — what the running host actually advertises
11
+ * (coordinates + generation), including drift-dropped contracts.
12
+ * 3. GRANT MATRIX — plugins × the registered permissions. The plugin set is
13
+ * the union of FOOTPRINTS ONLY: keys of the grants file, pluginIds seen
14
+ * in the effect ledger, and storage namespaces on disk (the host cannot
15
+ * enumerate installed plugins — that knowledge lives in the dsh CLI
16
+ * Loader). The header says so honestly.
17
+ * 4. LEDGER TAIL — the last 5 effect-ledger records.
18
+ *
19
+ * `/plugins check <path>` uses the parser and projection from the pinned
20
+ * @dsh-std/manifest revision, then evaluates every public/private protocol
21
+ * through one ProtocolCatalog. Manifests and on-disk files are UNTRUSTED input:
22
+ * every derived line passes cleanScalarText before it reaches the
23
+ * transcript.
24
+ */
25
+ import type { GrantStore } from './grants.js';
26
+ import type { HostDescriptorBuild } from './host-descriptor.js';
27
+ /** How many plugins the matrix shows before an overflow note. */
28
+ export declare const PLUGINS_MATRIX_MAX_ROWS = 20;
29
+ /** How many ledger records the tail section shows. */
30
+ export declare const PLUGINS_LEDGER_TAIL = 5;
31
+ export interface PluginsInfoDeps {
32
+ /** Effective grant answers (the plugin-host row's store when mounted). */
33
+ grants: GrantStore;
34
+ /** The plugin-host row's descriptor build; undefined → row not mounted. */
35
+ host?: HostDescriptorBuild;
36
+ /** Test overrides; default under DATA_DIR. */
37
+ dataDir?: string;
38
+ ledgerFile?: string;
39
+ storageDir?: string;
40
+ }
41
+ /** The `/plugins` overview lines (banner always first). */
42
+ export declare function pluginsInfoLines(args: string, deps: PluginsInfoDeps): string[];
43
+ //# sourceMappingURL=plugins-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins-info.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugins-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAYH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAK/D,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAIpC,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,MAAM,EAAE,UAAU,CAAA;IAClB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,mBAAmB,CAAA;IAC1B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA2JD,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAmF9E"}