@deepseek-harness-tui/dsh-tui 0.8.0 → 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 (330) hide show
  1. package/README.md +13 -5
  2. package/cordis.patch.yml +21 -2
  3. package/cordis.yml +12 -1
  4. package/ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
  5. package/ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
  6. package/ecosystem-spec/registry/permissions-0.1.json +13 -0
  7. package/ecosystem-spec/registry/registry-0.15.json +57 -0
  8. package/ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
  9. package/ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
  10. package/ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
  11. package/lib/types/cc/figures.d.ts +4 -0
  12. package/lib/types/cc/figures.d.ts.map +1 -1
  13. package/lib/types/cc/figures.js +4 -0
  14. package/lib/types/commands.d.ts.map +1 -1
  15. package/lib/types/commands.js +2 -0
  16. package/lib/types/components/ExtensionDialog.d.ts +40 -0
  17. package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
  18. package/lib/types/components/ExtensionDialog.js +210 -0
  19. package/lib/types/components/HelpMenu.js +1 -1
  20. package/lib/types/components/LoadedContextPanel.d.ts +5 -10
  21. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  22. package/lib/types/components/LoadedContextPanel.js +7 -18
  23. package/lib/types/components/LogoV2.d.ts.map +1 -1
  24. package/lib/types/components/LogoV2.js +1 -2
  25. package/lib/types/components/MessageList.d.ts.map +1 -1
  26. package/lib/types/components/MessageList.js +25 -1
  27. package/lib/types/components/RewindPicker.d.ts +13 -1
  28. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  29. package/lib/types/components/RewindPicker.js +26 -2
  30. package/lib/types/components/ToolUseLoader.d.ts +8 -3
  31. package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
  32. package/lib/types/components/ToolUseLoader.js +43 -9
  33. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  34. package/lib/types/components/messages/AssistantToolUseMessage.js +1 -1
  35. package/lib/types/dsh-adapter/channel.d.ts +30 -7
  36. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  37. package/lib/types/dsh-adapter/channel.js +503 -21
  38. package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
  39. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
  40. package/lib/types/dsh-adapter/command-attribution.js +93 -0
  41. package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
  42. package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
  43. package/lib/types/dsh-adapter/command-errors.js +63 -0
  44. package/lib/types/dsh-adapter/component-identity.d.ts +28 -0
  45. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
  46. package/lib/types/dsh-adapter/component-identity.js +108 -0
  47. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  48. package/lib/types/dsh-adapter/contract.js +2 -2
  49. package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
  50. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
  51. package/lib/types/dsh-adapter/decision-guard.js +354 -0
  52. package/lib/types/dsh-adapter/dialogs.d.ts +146 -0
  53. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
  54. package/lib/types/dsh-adapter/dialogs.js +262 -0
  55. package/lib/types/dsh-adapter/effect-ledger.d.ts +99 -0
  56. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
  57. package/lib/types/dsh-adapter/effect-ledger.js +231 -0
  58. package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
  59. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
  60. package/lib/types/dsh-adapter/extension-events.js +169 -0
  61. package/lib/types/dsh-adapter/extensions.d.ts +32 -0
  62. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
  63. package/lib/types/dsh-adapter/extensions.js +42 -0
  64. package/lib/types/dsh-adapter/grants.d.ts +25 -0
  65. package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
  66. package/lib/types/dsh-adapter/grants.js +184 -0
  67. package/lib/types/dsh-adapter/host-descriptor.d.ts +24 -0
  68. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
  69. package/lib/types/dsh-adapter/host-descriptor.js +146 -0
  70. package/lib/types/dsh-adapter/message-observer.d.ts +178 -0
  71. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
  72. package/lib/types/dsh-adapter/message-observer.js +509 -0
  73. package/lib/types/dsh-adapter/plugin-host.d.ts +103 -0
  74. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
  75. package/lib/types/dsh-adapter/plugin-host.js +270 -0
  76. package/lib/types/dsh-adapter/plugin-storage.d.ts +113 -0
  77. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
  78. package/lib/types/dsh-adapter/plugin-storage.js +385 -0
  79. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  80. package/lib/types/dsh-adapter/plugin.js +47 -1
  81. package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
  82. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
  83. package/lib/types/dsh-adapter/plugins-info.js +276 -0
  84. package/lib/types/dsh-adapter/renderers.d.ts +65 -0
  85. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
  86. package/lib/types/dsh-adapter/renderers.js +138 -0
  87. package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
  88. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
  89. package/lib/types/dsh-adapter/sanitize.js +65 -0
  90. package/lib/types/dsh-adapter/scenes.d.ts +7 -1
  91. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  92. package/lib/types/dsh-adapter/scenes.js +17 -2
  93. package/lib/types/dsh-adapter/shortcuts.d.ts +109 -0
  94. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
  95. package/lib/types/dsh-adapter/shortcuts.js +268 -0
  96. package/lib/types/dsh-adapter/status.d.ts +75 -0
  97. package/lib/types/dsh-adapter/status.d.ts.map +1 -0
  98. package/lib/types/dsh-adapter/status.js +168 -0
  99. package/lib/types/extensions.d.ts +8 -0
  100. package/lib/types/extensions.d.ts.map +1 -0
  101. package/lib/types/extensions.js +15 -0
  102. package/lib/types/i18n.d.ts +162 -16
  103. package/lib/types/i18n.d.ts.map +1 -1
  104. package/lib/types/i18n.js +53 -5
  105. package/lib/types/ink/ink.d.ts +11 -0
  106. package/lib/types/ink/ink.d.ts.map +1 -1
  107. package/lib/types/ink/ink.js +33 -0
  108. package/lib/types/ink/log-update.d.ts.map +1 -1
  109. package/lib/types/ink/log-update.js +101 -51
  110. package/lib/types/ink/output.d.ts +7 -0
  111. package/lib/types/ink/output.d.ts.map +1 -1
  112. package/lib/types/ink/output.js +125 -4
  113. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  114. package/lib/types/ink/render-node-to-output.js +14 -6
  115. package/lib/types/ink/terminal.d.ts.map +1 -1
  116. package/lib/types/ink/terminal.js +18 -6
  117. package/lib/types/plugin-host.d.ts +13 -0
  118. package/lib/types/plugin-host.d.ts.map +1 -0
  119. package/lib/types/plugin-host.js +17 -0
  120. package/lib/types/plugin-spec/negotiate.d.ts +11 -0
  121. package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
  122. package/lib/types/plugin-spec/negotiate.js +97 -0
  123. package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
  124. package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
  125. package/lib/types/plugin-spec/permission-scope.js +90 -0
  126. package/lib/types/plugin-spec/registry.d.ts +23 -0
  127. package/lib/types/plugin-spec/registry.d.ts.map +1 -0
  128. package/lib/types/plugin-spec/registry.js +157 -0
  129. package/lib/types/plugin-spec/schema-check.d.ts +17 -0
  130. package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
  131. package/lib/types/plugin-spec/schema-check.js +165 -0
  132. package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
  133. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
  134. package/lib/types/plugin-spec/tui-extension.js +77 -0
  135. package/lib/types/plugin-spec/types.d.ts +114 -0
  136. package/lib/types/plugin-spec/types.d.ts.map +1 -0
  137. package/lib/types/plugin-spec/types.js +10 -0
  138. package/lib/types/plugin-spec/validate.d.ts +21 -0
  139. package/lib/types/plugin-spec/validate.d.ts.map +1 -0
  140. package/lib/types/plugin-spec/validate.js +119 -0
  141. package/lib/types/screens/Chat.d.ts +14 -1
  142. package/lib/types/screens/Chat.d.ts.map +1 -1
  143. package/lib/types/screens/Chat.js +142 -39
  144. package/lib/types/theme.d.ts +5 -0
  145. package/lib/types/theme.d.ts.map +1 -1
  146. package/lib/types/theme.js +15 -0
  147. package/lib/types/update.d.ts +20 -0
  148. package/lib/types/update.d.ts.map +1 -1
  149. package/lib/types/update.js +54 -7
  150. package/lib/types/utils/loaded-context.d.ts +8 -3
  151. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  152. package/lib/types/utils/loaded-context.js +39 -3
  153. package/lib/types/utils/modifiers.d.ts.map +1 -1
  154. package/lib/types/utils/modifiers.js +3 -2
  155. package/lib/types/working-activity.d.ts +12 -0
  156. package/lib/types/working-activity.d.ts.map +1 -1
  157. package/lib/types/working-activity.js +13 -0
  158. package/node_modules/@dsh-std/command/LICENSE +21 -0
  159. package/node_modules/@dsh-std/command/README.md +26 -0
  160. package/node_modules/@dsh-std/command/README.zh.md +28 -0
  161. package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
  162. package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
  163. package/node_modules/@dsh-std/command/lib/index.js +252 -0
  164. package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
  165. package/node_modules/@dsh-std/command/package.json +22 -0
  166. package/node_modules/@dsh-std/connection/LICENSE +21 -0
  167. package/node_modules/@dsh-std/connection/README.md +42 -0
  168. package/node_modules/@dsh-std/connection/README.zh.md +42 -0
  169. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  170. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  171. package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  172. package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  173. package/node_modules/@dsh-std/connection/lib/index.js +158 -0
  174. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  175. package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  176. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  177. package/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  178. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  179. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  180. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  181. package/node_modules/@dsh-std/connection/package.json +20 -0
  182. package/node_modules/@dsh-std/core/LICENSE +21 -0
  183. package/node_modules/@dsh-std/core/README.md +13 -0
  184. package/node_modules/@dsh-std/core/README.zh.md +13 -0
  185. package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  186. package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  187. package/node_modules/@dsh-std/core/lib/index.js +424 -0
  188. package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  189. package/node_modules/@dsh-std/core/package.json +21 -0
  190. package/node_modules/@dsh-std/manifest/LICENSE +21 -0
  191. package/node_modules/@dsh-std/manifest/README.md +5 -0
  192. package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  193. package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  194. package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  195. package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  196. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  197. package/node_modules/@dsh-std/manifest/package.json +20 -0
  198. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  199. package/node_modules/@dsh-std/messages/LICENSE +21 -0
  200. package/node_modules/@dsh-std/messages/README.md +5 -0
  201. package/node_modules/@dsh-std/messages/README.zh.md +7 -0
  202. package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
  203. package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
  204. package/node_modules/@dsh-std/messages/lib/index.js +151 -0
  205. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
  206. package/node_modules/@dsh-std/messages/package.json +20 -0
  207. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
  208. package/node_modules/@dsh-std/presentation/LICENSE +21 -0
  209. package/node_modules/@dsh-std/presentation/README.md +26 -0
  210. package/node_modules/@dsh-std/presentation/README.zh.md +28 -0
  211. package/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
  212. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  213. package/node_modules/@dsh-std/presentation/lib/index.js +547 -0
  214. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  215. package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  216. package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  217. package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  218. package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  219. package/node_modules/@dsh-std/presentation/package.json +21 -0
  220. package/node_modules/@dsh-std/storage/LICENSE +21 -0
  221. package/node_modules/@dsh-std/storage/README.md +5 -0
  222. package/node_modules/@dsh-std/storage/README.zh.md +7 -0
  223. package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
  224. package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
  225. package/node_modules/@dsh-std/storage/lib/index.js +104 -0
  226. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
  227. package/node_modules/@dsh-std/storage/package.json +20 -0
  228. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
  229. package/package.json +105 -70
  230. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
  231. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
  232. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
  233. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  234. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  235. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  236. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  237. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
  238. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  239. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  240. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  241. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  242. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  243. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  244. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  245. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
  246. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
  247. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
  248. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
  249. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  250. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  251. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
  252. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  253. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
  254. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
  255. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
  256. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  257. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  258. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  259. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  260. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  261. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
  262. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  263. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
  264. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +26 -0
  265. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +28 -0
  266. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
  267. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  268. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +547 -0
  269. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  270. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  271. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  272. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  273. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  274. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +21 -0
  275. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
  276. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
  277. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
  278. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  279. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  280. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
  281. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  282. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
  283. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
  284. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
  285. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
  286. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  287. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  288. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
  289. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  290. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
  291. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
  292. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
  293. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
  294. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  295. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  296. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
  297. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  298. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
  299. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
  300. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
  301. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
  302. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  303. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  304. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  305. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  306. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
  307. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  308. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  309. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  310. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +257 -0
  311. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  312. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  313. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  314. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
  315. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
  316. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
  317. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
  318. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  319. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  320. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
  321. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  322. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
  323. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
  324. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
  325. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
  326. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  327. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  328. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
  329. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  330. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
@@ -8,10 +8,13 @@ import { isMod, isPlainReturnInput, modLabel } from '../utils/modifiers.js';
8
8
  import { formatTokens } from '../cc/format.js';
9
9
  import { homeDir } from '../utils/paths.js';
10
10
  import { sessionCwdMatches } from '../dsh-adapter/channel.js';
11
+ import { TuiDialogStore } from '../dsh-adapter/dialogs.js';
12
+ import { TuiStatusStore } from '../dsh-adapter/status.js';
11
13
  import { runProviderWizard } from '../dsh-adapter/providerWizard.js';
12
14
  import { ApprovalStore } from '../dsh-adapter/approvals.js';
13
15
  import { AskUserQuestionPanel } from '../components/questions/AskUserQuestionPanel.js';
14
16
  import { ApprovalPanel } from '../components/approvals/ApprovalPanel.js';
17
+ import { ExtensionDialog } from '../components/ExtensionDialog.js';
15
18
  import { useSearchHighlight } from '../ink/hooks/use-search-highlight.js';
16
19
  import { useTerminalTitle } from '../ink/hooks/use-terminal-title.js';
17
20
  import { useTerminalFocus } from '../ink/hooks/use-terminal-focus.js';
@@ -53,6 +56,7 @@ import { readTrajectorySeen, writeTrajectorySeen } from '../trajectoryPrefs.js';
53
56
  import { LoadingState } from '../components/design-system/LoadingState.js';
54
57
  import { Pane } from '../components/design-system/Pane.js';
55
58
  import { loadHistory } from '../history.js';
59
+ import { formatLoadedContextReport } from '../utils/loaded-context.js';
56
60
  /** Shared empty snapshot for hosts whose channel has no event log. */
57
61
  const NO_EVENTS = [];
58
62
  /** Row kinds the message-selection cursor can land on. */
@@ -121,7 +125,15 @@ function searchableText(row) {
121
125
  * snapshot stays null and the approval panel never mounts.
122
126
  */
123
127
  let fallbackApprovalStore;
124
- export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate, fullscreen = false, trajectorySeen: trajectorySeenProp, }) {
128
+ /**
129
+ * Shared inert extension stores for hosts that render Chat without the
130
+ * dsh-tui-extensions row (headless verify scripts, bare embeds). Never
131
+ * written, so the dialog panel and the plugin status line never mount and
132
+ * no shortcut ever matches.
133
+ */
134
+ let fallbackDialogStore;
135
+ let fallbackStatusStore;
136
+ export function Chat({ channel, questionStore, approvalStore, extensionDialogs, extensionStatus, extensionShortcuts, onExit, onUpdate, fullscreen = false, trajectorySeen: trajectorySeenProp, }) {
125
137
  // Re-render whenever the channel mutates; rows/status are read fresh below.
126
138
  React.useSyncExternalStore(channel.subscribe, () => channel.version);
127
139
  // Re-render on language switches so the whole UI hot-swaps its strings.
@@ -135,6 +147,30 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
135
147
  // approvalStore share one inert instance that never holds an ask.
136
148
  const approvals = approvalStore ?? (fallbackApprovalStore ??= new ApprovalStore());
137
149
  const approvalSnapshot = React.useSyncExternalStore(listener => approvals.subscribe(listener), () => approvals.getSnapshot());
150
+ // The pending managed plugin dialog (tuiDialogs seam): a plugin's
151
+ // select/confirm/input request parks here until the panel settles it.
152
+ // Priority sits right below the approval panel (a gated tool outranks a
153
+ // plugin's question) and above the questionnaire. Hosts without the
154
+ // extensions row share one inert store that never holds a dialog.
155
+ const dialogs = extensionDialogs ?? (fallbackDialogStore ??= new TuiDialogStore());
156
+ const dialogSnapshot = React.useSyncExternalStore(listener => dialogs.subscribe(listener), () => dialogs.getSnapshot());
157
+ // Plugin status-line contributions (tuiStatus seam): keyed texts joined
158
+ // into one line above the prompt.
159
+ const statusContributions = extensionStatus ?? (fallbackStatusStore ??= new TuiStatusStore());
160
+ const statusEntries = React.useSyncExternalStore(listener => statusContributions.subscribe(listener), () => statusContributions.getSnapshot());
161
+ // Shortcut handler failures surface as toasts (the registry also logs
162
+ // them); the hook is re-pointed on every mount so a stale closure never
163
+ // outlives its channel.
164
+ React.useEffect(() => {
165
+ if (extensionShortcuts === undefined)
166
+ return;
167
+ extensionShortcuts.onError = combo => {
168
+ channel.notify(t('ext-shortcut-failed', { combo }), { color: 'error', timeoutMs: 4000 });
169
+ };
170
+ return () => {
171
+ extensionShortcuts.onError = undefined;
172
+ };
173
+ }, [extensionShortcuts, channel]);
138
174
  // When a questionnaire batch completes, fold a Q&A summary into the
139
175
  // transcript (the tool card itself is hidden from the message list).
140
176
  const questionOpenRef = React.useRef(questionSnapshot !== null);
@@ -209,6 +245,17 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
209
245
  const [rewindOpen, setRewindOpen] = React.useState(false);
210
246
  const [rewindIndex, setRewindIndex] = React.useState(0);
211
247
  const [rewindConfirm, setRewindConfirm] = React.useState(null);
248
+ /** Plugin rewind modes (tui/rewind-prompt seam): extra choices offered in
249
+ * the confirm pane; null = the plain conversation-only confirm. */
250
+ const [rewindModes, setRewindModes] = React.useState(null);
251
+ const [rewindModeIndex, setRewindModeIndex] = React.useState(0);
252
+ /** True while the tui/rewind-prompt decision is in flight (a plugin may be
253
+ * showing its own dialog); keys except Esc are swallowed meanwhile. */
254
+ const [rewindBusy, setRewindBusy] = React.useState(false);
255
+ /** Monotonic token: only the latest rewind decision may land (a slow
256
+ * plugin answering after the user moved on must not open a confirm for
257
+ * a row they are no longer looking at). */
258
+ const rewindRequestRef = React.useRef(0);
212
259
  /** /btw side-question overlay (CC): pure UI state — the answer never
213
260
  * enters the transcript or the session log. */
214
261
  const [btw, setBtw] = React.useState(null);
@@ -253,15 +300,7 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
253
300
  });
254
301
  setSceneOpen(true);
255
302
  }, []);
256
- /** Startup context panel: expanded by header click or Ctrl+T. */
257
- const [loadedContextOpen, setLoadedContextOpen] = React.useState(false);
258
- /**
259
- * Whether the startup context panel is on screen. Derived once and read by
260
- * BOTH the Ctrl+T handler and the render below: the key's meaning depends on
261
- * the panel being visible, so a second copy of this condition is a place for
262
- * the two to disagree — which is how the key came to advertise one thing and
263
- * do another in the first place.
264
- */
303
+ /** The startup summary gives way to transcript rows after the first local command or message. */
265
304
  const loadedContextVisible = channel.rows.length === 0 && channel.loadedContext !== undefined;
266
305
  /** `/` transcript search (less-style incsearch, ported from CC's REPL). */
267
306
  const [searchOpen, setSearchOpen] = React.useState(false);
@@ -635,6 +674,16 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
635
674
  setHelpOpen(false);
636
675
  openScene();
637
676
  return true;
677
+ case 'context': {
678
+ setHelpOpen(false);
679
+ const context = channel.loadedContext;
680
+ if (context === undefined) {
681
+ channel.notify(t('context-unavailable'), { color: 'warning' });
682
+ return true;
683
+ }
684
+ channel.pushLocal('/context', formatLoadedContextReport(context));
685
+ return true;
686
+ }
638
687
  case 'help':
639
688
  setHelpOpen(true);
640
689
  return true;
@@ -841,6 +890,13 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
841
890
  setHelpOpen(false);
842
891
  channel.pushLocal('/doctor', channel.doctorInfo());
843
892
  return true;
893
+ case 'plugins':
894
+ // Plugin diagnostics (C-070): trust banner first, then descriptor /
895
+ // grant matrix / ledger tail — or validate+negotiate for
896
+ // `/plugins check <path>` (rawInput carries the subcommand).
897
+ setHelpOpen(false);
898
+ channel.pushLocal('/plugins', channel.pluginsInfo(rawInput));
899
+ return true;
844
900
  case 'export': {
845
901
  const target = channel.exportSession();
846
902
  channel.notify(target === null
@@ -1048,11 +1104,32 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1048
1104
  }
1049
1105
  setRewindIndex(0);
1050
1106
  setRewindConfirm(null);
1107
+ setRewindModes(null);
1108
+ setRewindBusy(false);
1109
+ rewindRequestRef.current += 1;
1051
1110
  setRewindOpen(true);
1052
1111
  };
1112
+ /**
1113
+ * Enter on a rewind candidate: ask the plugins first (tui/rewind-prompt).
1114
+ * A veto keeps the list open; offered modes turn the confirm pane into a
1115
+ * choice list; "no opinion" lands on the plain confirm as before.
1116
+ */
1117
+ const requestRewindConfirm = async (row) => {
1118
+ const token = ++rewindRequestRef.current;
1119
+ setRewindBusy(true);
1120
+ const decision = await channel.promptRewind(row);
1121
+ if (token !== rewindRequestRef.current)
1122
+ return;
1123
+ setRewindBusy(false);
1124
+ if (decision === 'cancel')
1125
+ return;
1126
+ setRewindConfirm(row);
1127
+ setRewindModes(decision?.modes ?? null);
1128
+ setRewindModeIndex(0);
1129
+ };
1053
1130
  /** Execute the confirmed rewind; the message comes back into the input. */
1054
- const performRewind = async (row) => {
1055
- const text = await channel.rewindTo(row);
1131
+ const performRewind = async (row, mode = null) => {
1132
+ const text = await channel.rewindTo(row, mode);
1056
1133
  if (text !== null) {
1057
1134
  // CC puts the restored message back in the prompt for re-editing.
1058
1135
  setHistoryFill(text);
@@ -1241,10 +1318,11 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1241
1318
  // turn was in flight — closing the view and killing the turn in one key.
1242
1319
  if (sceneOpen || channel.pluginScene !== undefined)
1243
1320
  return;
1244
- // The questionnaire / approval panel owns the keyboard while one is
1245
- // pending (the panel's own useInput handles ↑/↓/Space/Tab/Enter/Esc;
1246
- // the prompt input is unmounted, so nothing else should see these keys).
1247
- if (questionSnapshot !== null || approvalSnapshot !== null)
1321
+ // The questionnaire / approval panel / managed plugin dialog owns the
1322
+ // keyboard while one is pending (the panel's own useInput handles
1323
+ // ↑/↓/Space/Tab/Enter/Esc; the prompt input is unmounted, so nothing
1324
+ // else should see these keys).
1325
+ if (questionSnapshot !== null || approvalSnapshot !== null || dialogSnapshot !== null)
1248
1326
  return;
1249
1327
  const returnCandidate = isPlainReturnInput(input, key);
1250
1328
  const returnNow = Date.now();
@@ -1662,7 +1740,40 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1662
1740
  return;
1663
1741
  }
1664
1742
  if (rewindOpen) {
1743
+ // While the plugin decision is in flight the picker is read-only;
1744
+ // Esc abandons the wait (the stale answer is dropped by the token).
1745
+ if (rewindBusy) {
1746
+ if (key.escape) {
1747
+ rewindRequestRef.current += 1;
1748
+ setRewindBusy(false);
1749
+ }
1750
+ return;
1751
+ }
1665
1752
  if (rewindConfirm !== null) {
1753
+ if (rewindModes !== null) {
1754
+ // Plugin offered modes: the confirm pane is a choice list —
1755
+ // option 0 is always the built-in conversation-only rewind.
1756
+ const optionCount = rewindModes.length + 1;
1757
+ if (key.upArrow) {
1758
+ setRewindModeIndex(index => (index <= 0 ? optionCount - 1 : index - 1));
1759
+ }
1760
+ else if (key.downArrow) {
1761
+ setRewindModeIndex(index => (index >= optionCount - 1 ? 0 : index + 1));
1762
+ }
1763
+ else if (plainReturn) {
1764
+ const row = rewindConfirm;
1765
+ const mode = rewindModeIndex === 0 ? null : (rewindModes[rewindModeIndex - 1]?.id ?? null);
1766
+ setRewindOpen(false);
1767
+ setRewindConfirm(null);
1768
+ setRewindModes(null);
1769
+ void performRewind(row, mode);
1770
+ }
1771
+ else if (key.escape) {
1772
+ setRewindConfirm(null);
1773
+ setRewindModes(null);
1774
+ }
1775
+ return;
1776
+ }
1666
1777
  // Confirmation state: Enter rewinds, Esc backs out to the list.
1667
1778
  if (plainReturn) {
1668
1779
  const row = rewindConfirm;
@@ -1684,34 +1795,17 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1684
1795
  const row = rewindRows[rewindIndex];
1685
1796
  // oxlint-disable-next-line typescript/no-unnecessary-condition -- runtime guard: out-of-range index on an empty list
1686
1797
  if (row)
1687
- setRewindConfirm(row);
1798
+ void requestRewindConfirm(row);
1688
1799
  }
1689
1800
  else if (key.escape) {
1690
1801
  setRewindOpen(false);
1691
1802
  setRewindConfirm(null);
1803
+ setRewindModes(null);
1692
1804
  }
1693
1805
  return;
1694
1806
  }
1695
1807
  if (isMod(key) && input === 't') {
1696
- // Ctrl+T means "expand what is in front of you", and the two things it
1697
- // can expand never share the screen.
1698
- //
1699
- // The startup loaded-context panel renders only while the transcript is
1700
- // empty (see the render below) — and that is exactly the window where
1701
- // the trajectory has nothing in it yet, since the trajectory is folded
1702
- // from the session's own events. So the panel wins while it is up, and
1703
- // the scene takes over for the rest of the session.
1704
- //
1705
- // Claiming the key outright for the scene was wrong even though the
1706
- // panel binding looked dead: the panel prints its own `(Ctrl+T 展开)`
1707
- // hint, so the key still had a visible promise attached to it, and the
1708
- // scene it opened instead was necessarily empty at that moment. That
1709
- // left the panel reachable only by clicking its header, which is not a
1710
- // keyboard path at all.
1711
- if (loadedContextVisible) {
1712
- setLoadedContextOpen(previous => !previous);
1713
- return;
1714
- }
1808
+ // Ctrl+T has one stable meaning; loaded-context details live at /context.
1715
1809
  openScene();
1716
1810
  return;
1717
1811
  }
@@ -1803,6 +1897,15 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1803
1897
  else if (plainReturn && showPill) {
1804
1898
  handle?.scrollToBottom();
1805
1899
  }
1900
+ else if (extensionShortcuts !== undefined && extensionShortcuts.dispatch(input, key)) {
1901
+ // Plugin shortcut (tuiShortcuts seam): matched only after every
1902
+ // built-in global binding above declined — locals always win, and the
1903
+ // registry additionally refuses the prompt editor's own combos at
1904
+ // registration, so a plugin can never shadow anything. The handler
1905
+ // runs fire-and-forget; its errors arrive via the onError hook
1906
+ // (wired to the toast below).
1907
+ event.stopImmediatePropagation();
1908
+ }
1806
1909
  });
1807
1910
  // Working-activity line (spinner slot): context-pressure prefix shares the
1808
1911
  // StatusLine thresholds (amber ≥ 80, red ≥ 95).
@@ -1883,7 +1986,7 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1883
1986
  seekRow(lastUser.id);
1884
1987
  else
1885
1988
  handle?.scrollToBottom();
1886
- } })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext, open: loadedContextOpen, onToggle: () => { setLoadedContextOpen(previous => !previous); } })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
1989
+ } })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
1887
1990
  (channel.activityEnabled &&
1888
1991
  channel.workingActivity !== undefined &&
1889
1992
  channel.workingActivity.line !== '' &&
@@ -1892,7 +1995,7 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1892
1995
  // the animated chars/4 estimate, matching the classic
1893
1996
  // spinner's counter (the suffix used raw chars before,
1894
1997
  // inflating the reading next to a real upload number).
1895
- suffix: `${lastUploadTokens > 0 ? ` · ↑ ${formatTokens(lastUploadTokens)}` : ''} · ↓ ${formatTokens(Math.round(channel.responseChars / 4))} tokens` }) })) : (_jsx(WorkingSpinner, { mode: channel.spinnerMode, hasActiveTools: channel.activeToolCount > 0, responseLengthRef: responseLengthRef, uploadTokensRef: uploadTokensRef, loadingStartTimeRef: loadingStartTimeRef, totalPausedMsRef: totalPausedMsRef, pauseStartTimeRef: pauseStartTimeRef, thinkingStatus: thinkingStatus }))), _jsx(GoalTodoPanel, { channel: channel }), approvalSnapshot !== null ? (_jsx(ApprovalPanel, { approval: approvalSnapshot, onDecide: outcome => approvals.decide(outcome) }, approvalSnapshot.key)) : btw !== null ? (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(BtwPanel, { question: btw.question, answer: btw.answer, error: btw.error, streaming: !btw.done, onClose: closeBtw, onCopy: () => {
1998
+ suffix: `${lastUploadTokens > 0 ? ` · ↑ ${formatTokens(lastUploadTokens)}` : ''} · ↓ ${formatTokens(Math.round(channel.responseChars / 4))} tokens` }) })) : (_jsx(WorkingSpinner, { mode: channel.spinnerMode, hasActiveTools: channel.activeToolCount > 0, responseLengthRef: responseLengthRef, uploadTokensRef: uploadTokensRef, loadingStartTimeRef: loadingStartTimeRef, totalPausedMsRef: totalPausedMsRef, pauseStartTimeRef: pauseStartTimeRef, thinkingStatus: thinkingStatus }))), _jsx(GoalTodoPanel, { channel: channel }), statusEntries.length > 0 && (_jsx(Text, { dimColor: true, wrap: "truncate", children: statusEntries.map(entry => entry.text).join(' · ') })), approvalSnapshot !== null ? (_jsx(ApprovalPanel, { approval: approvalSnapshot, onDecide: outcome => approvals.decide(outcome) }, approvalSnapshot.key)) : dialogSnapshot !== null ? (_jsx(ExtensionDialog, { dialog: dialogSnapshot, onDecide: value => dialogs.decide(dialogSnapshot.key, value), onCancel: () => dialogs.cancel(dialogSnapshot.key) }, dialogSnapshot.key)) : btw !== null ? (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(BtwPanel, { question: btw.question, answer: btw.answer, error: btw.error, streaming: !btw.done, onClose: closeBtw, onCopy: () => {
1896
1999
  void setClipboard(btw.answer ?? '').then(raw => { if (raw)
1897
2000
  process.stdout.write(raw); });
1898
2001
  channel.notify(t('copied-chars', { n: (btw.answer ?? '').length }), { timeoutMs: 1500 });
@@ -1902,7 +2005,7 @@ export function Chat({ channel, questionStore, approvalStore, onExit, onUpdate,
1902
2005
  band: wakeBand,
1903
2006
  hint: trajectorySeen ? undefined : `${modLabel}t`,
1904
2007
  tick: Math.floor(wakeTime / 120),
1905
- } }), dialogOverlayOpen && (_jsxs(OverlayAbove, { maxHeight: Math.max(terminalRows - 8, 8), children: [thinkingOpen && (_jsx(ThinkingToggle, { currentValue: thinkingVisible, focusIndex: thinkingFocus, confirmationPending: thinkingConfirm })), workspacePickerOpen && workspaceTargets.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(WorkspacePicker, { targets: workspaceTargets, focusIndex: workspaceIndex, currentCwd: channel.cwd }) })), workspaceFlow !== null && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(WorkspaceFlowPicker, { title: workspaceFlow.title, choices: workspaceFlow.choices, focusIndex: workspaceFlowIndex, busy: workspaceFlowBusy, input: workspaceFlowInput }) })), modelPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: models.length === 0 ? (_jsx(ModelPickerLoading, {})) : (_jsx(ModelPicker, { models: models, focusIndex: modelIndex, currentModel: `${channel.provider}/${channel.model}` })) })), skillsPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: skillsList === null ? (_jsx(SkillsPickerLoading, {})) : (_jsx(SkillsPicker, { skills: skillsList, focusIndex: skillsIndex })) })), activityPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(ActivityPicker, { focusIndex: activityIndex, currentPreset: channel.activityFrames }) })), effortSliderOpen && effortOptions.length > 1 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(EffortSlider, { options: effortOptions, focusIndex: effortIndex, currentId: channel.reasoningEffort }) })), presetPickerOpen && presetOptions.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(PresetPicker, { presets: presetOptions, focusIndex: presetIndex, currentPreset: channel.agentPreset }) })), themePickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(ThemePicker, { focusIndex: themeIndex, currentTheme: themeName }) })), historyOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(HistorySearchDialog, { query: historyQuery, cursorOffset: historyCursor, matches: historyMatches, focusIndex: historyFocus }) })), rewindOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(RewindPicker, { rows: rewindRows, focusIndex: rewindIndex, confirmRow: rewindConfirm }) })), searchOpen && _jsx(TranscriptSearchBar, { query: searchQuery, cursorOffset: searchCursor, count: searchCount, current: searchCurrent })] }))] })] }));
2008
+ } }), dialogOverlayOpen && (_jsxs(OverlayAbove, { maxHeight: Math.max(terminalRows - 8, 8), children: [thinkingOpen && (_jsx(ThinkingToggle, { currentValue: thinkingVisible, focusIndex: thinkingFocus, confirmationPending: thinkingConfirm })), workspacePickerOpen && workspaceTargets.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(WorkspacePicker, { targets: workspaceTargets, focusIndex: workspaceIndex, currentCwd: channel.cwd }) })), workspaceFlow !== null && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(WorkspaceFlowPicker, { title: workspaceFlow.title, choices: workspaceFlow.choices, focusIndex: workspaceFlowIndex, busy: workspaceFlowBusy, input: workspaceFlowInput }) })), modelPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: models.length === 0 ? (_jsx(ModelPickerLoading, {})) : (_jsx(ModelPicker, { models: models, focusIndex: modelIndex, currentModel: `${channel.provider}/${channel.model}` })) })), skillsPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: skillsList === null ? (_jsx(SkillsPickerLoading, {})) : (_jsx(SkillsPicker, { skills: skillsList, focusIndex: skillsIndex })) })), activityPickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(ActivityPicker, { focusIndex: activityIndex, currentPreset: channel.activityFrames }) })), effortSliderOpen && effortOptions.length > 1 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(EffortSlider, { options: effortOptions, focusIndex: effortIndex, currentId: channel.reasoningEffort }) })), presetPickerOpen && presetOptions.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(PresetPicker, { presets: presetOptions, focusIndex: presetIndex, currentPreset: channel.agentPreset }) })), themePickerOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(ThemePicker, { focusIndex: themeIndex, currentTheme: themeName }) })), historyOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(HistorySearchDialog, { query: historyQuery, cursorOffset: historyCursor, matches: historyMatches, focusIndex: historyFocus }) })), rewindOpen && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: _jsx(RewindPicker, { rows: rewindRows, focusIndex: rewindIndex, confirmRow: rewindConfirm, modes: rewindModes, modeIndex: rewindModeIndex, busy: rewindBusy }) })), searchOpen && _jsx(TranscriptSearchBar, { query: searchQuery, cursorOffset: searchCursor, count: searchCount, current: searchCurrent })] }))] })] }));
1906
2009
  }
1907
2010
  /**
1908
2011
  * The pinned prompt header shown above the ScrollBox while the user has
@@ -49,6 +49,11 @@ export type Theme = {
49
49
  diffRemovedWord: string;
50
50
  toolCardBackground: string;
51
51
  toolCardBackgroundDim: string;
52
+ toolDotExec: string;
53
+ toolDotRead: string;
54
+ toolDotWrite: string;
55
+ toolDotWeb: string;
56
+ toolDotTask: string;
52
57
  syntaxKeyword: string;
53
58
  syntaxString: string;
54
59
  syntaxComment: string;
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/theme.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/theme.ts"],"names":[],"mappings":"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"}
@@ -88,6 +88,11 @@ const darkTheme = {
88
88
  diffRemovedWord: rgb('#B26671'),
89
89
  toolCardBackground: rgb('#242B3A'), // lighter blue-grey card surface
90
90
  toolCardBackgroundDim: rgb('#1C2330'), // deeper blue substrate
91
+ toolDotExec: rgb('#7FAE99'), // sage green — bash/pwsh
92
+ toolDotRead: rgb('#82B8C7'), // cyan blue — read/grep/glob
93
+ toolDotWrite: rgb('#B3A0D4'), // soft violet — edit/write
94
+ toolDotWeb: rgb('#7DA1DE'), // mist blue — web search/fetch
95
+ toolDotTask: rgb('#D194AE'), // mist rose — subagent/jobs
91
96
  syntaxKeyword: rgb('#8FA8E8'), // mist blue
92
97
  syntaxString: rgb('#9FBF8F'), // soft sage
93
98
  syntaxComment: rgb('#6B7280'), // neutral grey
@@ -177,6 +182,11 @@ const lightTheme = {
177
182
  diffRemovedWord: rgb('#E5B3AE'),
178
183
  toolCardBackground: rgb('#E9EFF9'), // cool light blue card
179
184
  toolCardBackgroundDim: rgb('#DEE7F4'), // deeper blue-tinted substrate
185
+ toolDotExec: rgb('#4E7A4E'),
186
+ toolDotRead: rgb('#3F7E8F'),
187
+ toolDotWrite: rgb('#7A5CA8'),
188
+ toolDotWeb: rgb('#4A63A8'),
189
+ toolDotTask: rgb('#B04A5A'),
180
190
  syntaxKeyword: rgb('#4A63A8'),
181
191
  syntaxString: rgb('#4E7A4E'),
182
192
  syntaxComment: rgb('#8A8F98'),
@@ -268,6 +278,11 @@ const darkAnsiTheme = {
268
278
  diffRemovedWord: 'ansi:redBright',
269
279
  toolCardBackground: 'ansi:blackBright',
270
280
  toolCardBackgroundDim: 'ansi:black',
281
+ toolDotExec: 'ansi:greenBright',
282
+ toolDotRead: 'ansi:cyanBright',
283
+ toolDotWrite: 'ansi:magentaBright',
284
+ toolDotWeb: 'ansi:blueBright',
285
+ toolDotTask: 'ansi:redBright',
271
286
  syntaxKeyword: 'ansi:blueBright',
272
287
  syntaxString: 'ansi:greenBright',
273
288
  syntaxComment: 'ansi:blackBright',
@@ -9,6 +9,7 @@ export type TuiUpdateTarget = {
9
9
  kind: 'update';
10
10
  current: string;
11
11
  latest: string;
12
+ authoritative?: string;
12
13
  } | {
13
14
  kind: 'latest';
14
15
  current: string;
@@ -43,10 +44,29 @@ export declare function resolveDshProfileName(argv?: readonly string[]): string
43
44
  export declare function resolveRegistryBase(): string;
44
45
  /** True when `current` is a strictly newer valid version than `previous`. */
45
46
  export declare function isVersionNewer(current: string, previous: string): boolean;
47
+ /**
48
+ * Versions whose compiled plugin hard-injects `tuiWorkspaces`
49
+ * ('0.7.0'–'0.7.1'; removed in 0.7.2). Installing one while the globally
50
+ * installed launcher copy predates the `dsh-tui-workspaces` patch row
51
+ * deadlocks boot forever at "pending (waiting for service: tuiWorkspaces)"
52
+ * (issues #183/#307) — and /update reaching such a target is exactly how
53
+ * stale-mirror installs stranded users. /update must refuse them.
54
+ * @param version - the candidate install target.
55
+ * @returns true for the known boot-deadlock version range.
56
+ */
57
+ export declare function isBootDeadlockTarget(version: string): boolean;
46
58
  /**
47
59
  * Classify this install against a fresh registry lookup: an update is
48
60
  * available, the install is already latest, or the answer is unknown
49
61
  * (offline / registry error / unreadable own version).
62
+ *
63
+ * The configured registry decides the install target (pnpm must be able to
64
+ * fetch it), but when that registry is a mirror it can lag behind npmjs —
65
+ * issue #307's users were pinned onto stale versions this way. A
66
+ * best-effort npmjs.org check runs in parallel and surfaces as
67
+ * `authoritative` when it knows a strictly newer release, so callers can
68
+ * say "installing X now, official latest is Y" instead of silently
69
+ * upgrading to yesterday's version.
50
70
  */
51
71
  export declare function resolveTuiUpdateTarget(): Promise<TuiUpdateTarget>;
52
72
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/update.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAIlD,OAAO,EAAE,UAAU,EAAE,CAAA;AAQrB,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAEvB,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAiBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,SAAS,MAAM,EAAiB,GAAG,MAAM,GAAG,SAAS,CAahG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIzE;AA4BD;;;;GAIG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC,CASvE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAG5E;AA6DD,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,eAAe,CAAC,CAgD1B"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/update.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAIlD,OAAO,EAAE,UAAU,EAAE,CAAA;AAQrB,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAED,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAA;AAEvB,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAiBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,SAAS,MAAM,EAAiB,GAAG,MAAM,GAAG,SAAS,CAahG;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAG7D;AA4BD;;;;;;;;;;;;GAYG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,eAAe,CAAC,CAcvE;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAG5E;AA6DD,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAIrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,eAAe,CAAC,CAuE1B"}
@@ -3,7 +3,7 @@ import { readFileSync } from 'node:fs';
3
3
  import { homedir } from 'node:os';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
- import { gt, valid } from 'semver';
6
+ import { gte, gt, lt, valid } from 'semver';
7
7
  import { shellQuote } from './utils/shellQuote.js';
8
8
  // Re-exported for scripts/verify-update.mjs and the bin launcher, which reads
9
9
  // the compiled copy at lib/types/utils/shellQuote.js.
@@ -81,15 +81,29 @@ export function isVersionNewer(current, previous) {
81
81
  const b = valid(previous);
82
82
  return a !== null && b !== null && gt(a, b);
83
83
  }
84
+ /**
85
+ * Versions whose compiled plugin hard-injects `tuiWorkspaces`
86
+ * ('0.7.0'–'0.7.1'; removed in 0.7.2). Installing one while the globally
87
+ * installed launcher copy predates the `dsh-tui-workspaces` patch row
88
+ * deadlocks boot forever at "pending (waiting for service: tuiWorkspaces)"
89
+ * (issues #183/#307) — and /update reaching such a target is exactly how
90
+ * stale-mirror installs stranded users. /update must refuse them.
91
+ * @param version - the candidate install target.
92
+ * @returns true for the known boot-deadlock version range.
93
+ */
94
+ export function isBootDeadlockTarget(version) {
95
+ const v = valid(version);
96
+ return v !== null && gte(v, '0.7.0') && lt(v, '0.7.2');
97
+ }
84
98
  function isRecord(value) {
85
99
  return value !== null && typeof value === 'object' && !Array.isArray(value);
86
100
  }
87
- /** Fetch `latest` from the configured registry; undefined on any failure. */
88
- async function fetchLatestVersion() {
101
+ /** Fetch `latest` from a registry; undefined on any failure. */
102
+ async function fetchLatestVersion(registryBase) {
89
103
  const controller = new AbortController();
90
104
  const timeout = setTimeout(() => controller.abort(), UPDATE_CHECK_TIMEOUT_MS);
91
105
  try {
92
- const response = await fetch(`${resolveRegistryBase()}/${PACKAGE_NAME}/latest`, {
106
+ const response = await fetch(`${registryBase}/${PACKAGE_NAME}/latest`, {
93
107
  headers: { accept: 'application/json' },
94
108
  signal: controller.signal,
95
109
  });
@@ -112,18 +126,31 @@ async function fetchLatestVersion() {
112
126
  * Classify this install against a fresh registry lookup: an update is
113
127
  * available, the install is already latest, or the answer is unknown
114
128
  * (offline / registry error / unreadable own version).
129
+ *
130
+ * The configured registry decides the install target (pnpm must be able to
131
+ * fetch it), but when that registry is a mirror it can lag behind npmjs —
132
+ * issue #307's users were pinned onto stale versions this way. A
133
+ * best-effort npmjs.org check runs in parallel and surfaces as
134
+ * `authoritative` when it knows a strictly newer release, so callers can
135
+ * say "installing X now, official latest is Y" instead of silently
136
+ * upgrading to yesterday's version.
115
137
  */
116
138
  export async function resolveTuiUpdateTarget() {
117
139
  const current = installedTuiVersion();
118
140
  const currentVersion = current === undefined ? null : valid(current);
119
141
  if (currentVersion === null)
120
142
  return { kind: 'unknown' };
121
- const latest = await fetchLatestVersion();
143
+ const registryBase = resolveRegistryBase();
144
+ const [latest, official] = await Promise.all([
145
+ fetchLatestVersion(registryBase),
146
+ registryBase === DEFAULT_REGISTRY ? undefined : fetchLatestVersion(DEFAULT_REGISTRY),
147
+ ]);
122
148
  if (latest === undefined)
123
149
  return { kind: 'unknown' };
124
150
  if (!gt(latest, currentVersion))
125
151
  return { kind: 'latest', current: currentVersion };
126
- return { kind: 'update', current: currentVersion, latest };
152
+ const authoritative = official !== undefined && gt(official, latest) ? official : undefined;
153
+ return { kind: 'update', current: currentVersion, latest, ...(authoritative === undefined ? {} : { authoritative }) };
127
154
  }
128
155
  /**
129
156
  * Check npm for a newer published TUI version. Network and registry errors
@@ -217,6 +244,12 @@ export function isTransientUpdateFailure(stderr) {
217
244
  * @returns Exit codes for the update run and the replacement process.
218
245
  */
219
246
  export async function updateTuiAndRestart(sessionId, profile, targetVersion) {
247
+ // Stamp the pre-update version BEFORE pnpm runs: it reads this package's
248
+ // manifest from disk, which the update replaces on the fly — a
249
+ // post-update read already sees the NEW version, and the restarted
250
+ // process then compares new-vs-new and false-alarms "version did not
251
+ // advance" on every successful update (issue #307's screenshots).
252
+ const updatedFrom = installedTuiVersion() ?? '';
220
253
  const dsh = process.platform === 'win32' ? 'dsh.cmd' : 'dsh';
221
254
  const updateArgs = tuiUpdatePluginArgs(profile, targetVersion);
222
255
  let updateStderr = '';
@@ -232,6 +265,20 @@ export async function updateTuiAndRestart(sessionId, profile, targetVersion) {
232
265
  }
233
266
  if (updateCode !== 0)
234
267
  return { updateCode, restartCode: updateCode };
268
+ // A --latest fallback (preflight failed) on a stale mirror can still land
269
+ // on the 0.7.0–0.7.1 hard-inject range — restarting into it under an older
270
+ // global-launcher patch is the permanent boot deadlock of issues
271
+ // #183/#307. Refuse the restart when the version JUST moved there; a user
272
+ // who was already on it keeps their restart (their combo demonstrably
273
+ // boots) and gets the repair hint on the next /update instead.
274
+ const installedNow = installedTuiVersion();
275
+ if (installedNow !== undefined && installedNow !== updatedFrom && isBootDeadlockTarget(installedNow)) {
276
+ process.stderr.write(`dsh-tui: update landed on ${installedNow}, which can permanently deadlock boot under older launcher patches ` +
277
+ `(#183/#307) — NOT restarting into it. Repair with:\n` +
278
+ ` dsh plugin --profile ${profile} add ${PACKAGE_NAME}@latest\n` +
279
+ `(if the mirror has not synced the latest release yet, retry later)\n`);
280
+ return { updateCode: 1, restartCode: 1 };
281
+ }
235
282
  // Post-update verification (issue #225): pnpm can report success yet leave
236
283
  // the profile half-updated (manifest old / lockfile new). Verify against
237
284
  // the preflight target; a full `install` reconciles lockfile →
@@ -257,7 +304,7 @@ export async function updateTuiAndRestart(sessionId, profile, targetVersion) {
257
304
  // still-old TUI build reads only DSH_CC_RESUME_SESSION.
258
305
  DSH_TUI_RESUME_SESSION: sessionId,
259
306
  DSH_CC_RESUME_SESSION: sessionId,
260
- [UPDATED_FROM_ENV]: installedTuiVersion() ?? '',
307
+ [UPDATED_FROM_ENV]: updatedFrom,
261
308
  },
262
309
  });
263
310
  return { updateCode, restartCode };
@@ -1,10 +1,9 @@
1
1
  import type { LoadedContext } from '../dsh-adapter/channel.js';
2
- /** Per-entry display cap: the panel shows the beginning of long texts. */
2
+ /** Per-entry display cap: `/context` shows the beginning of long texts. */
3
3
  export declare const CONTEXT_ENTRY_MAX_CHARS = 800;
4
4
  /**
5
5
  * Truncate one entry's text for the panel body. The model-visible text is
6
- * the source of truth and stays complete in the session log; the panel only
7
- * bounds its own rendering.
6
+ * the source of truth; the local report only bounds its own rendering.
8
7
  * @param text - the interpolated model-visible text.
9
8
  * @param max - character cap, defaults to {@link CONTEXT_ENTRY_MAX_CHARS}.
10
9
  * @returns the text, or its head plus a truncation marker.
@@ -17,4 +16,10 @@ export declare function truncateContextText(text: string, max?: number): string;
17
16
  * @returns the summary, or `''` when every group is empty.
18
17
  */
19
18
  export declare function summarizeLoadedContext(context: LoadedContext): string;
19
+ /**
20
+ * Format the loaded-context snapshot for the local `/context` report.
21
+ * The report preserves the former startup panel's grouping and truncation
22
+ * without keeping a second expandable surface in the transcript header.
23
+ */
24
+ export declare function formatLoadedContextReport(context: LoadedContext): string[];
20
25
  //# sourceMappingURL=loaded-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loaded-context.d.ts","sourceRoot":"","sources":["../../../src/utils/loaded-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAG9D,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAE1C;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAA0B,GAAG,MAAM,CAGvF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAQrE"}
1
+ {"version":3,"file":"loaded-context.d.ts","sourceRoot":"","sources":["../../../src/utils/loaded-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAG9D,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAE1C;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAA0B,GAAG,MAAM,CAGvF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAQrE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,EAAE,CA6B1E"}
@@ -1,10 +1,9 @@
1
1
  import { t } from '../i18n.js';
2
- /** Per-entry display cap: the panel shows the beginning of long texts. */
2
+ /** Per-entry display cap: `/context` shows the beginning of long texts. */
3
3
  export const CONTEXT_ENTRY_MAX_CHARS = 800;
4
4
  /**
5
5
  * Truncate one entry's text for the panel body. The model-visible text is
6
- * the source of truth and stays complete in the session log; the panel only
7
- * bounds its own rendering.
6
+ * the source of truth; the local report only bounds its own rendering.
8
7
  * @param text - the interpolated model-visible text.
9
8
  * @param max - character cap, defaults to {@link CONTEXT_ENTRY_MAX_CHARS}.
10
9
  * @returns the text, or its head plus a truncation marker.
@@ -34,3 +33,40 @@ export function summarizeLoadedContext(context) {
34
33
  parts.push(t('context-tools', { n: context.tools.length }));
35
34
  return parts.join(' · ');
36
35
  }
36
+ /**
37
+ * Format the loaded-context snapshot for the local `/context` report.
38
+ * The report preserves the former startup panel's grouping and truncation
39
+ * without keeping a second expandable surface in the transcript header.
40
+ */
41
+ export function formatLoadedContextReport(context) {
42
+ const lines = [];
43
+ const appendEntry = (name, text, max = CONTEXT_ENTRY_MAX_CHARS) => {
44
+ lines.push(` ${name}`);
45
+ lines.push(...truncateContextText(text, max).split('\n').map(line => ` ${line}`));
46
+ };
47
+ if (context.sections.length > 0) {
48
+ lines.push(t('context-panel-sections', { n: context.sections.length }));
49
+ for (const section of context.sections)
50
+ appendEntry(section.name, section.text);
51
+ }
52
+ if (context.files.length > 0) {
53
+ lines.push(t('context-panel-files', { n: context.files.length }));
54
+ lines.push(...context.files.map(file => ` ${file.displayPath}`));
55
+ }
56
+ if (context.contexts.length > 0) {
57
+ lines.push(t('context-panel-runtime', { n: context.contexts.length }));
58
+ for (const entry of context.contexts)
59
+ appendEntry(entry.name, entry.text);
60
+ }
61
+ if (context.skills.length > 0) {
62
+ lines.push(t('context-panel-skills', { n: context.skills.length }));
63
+ for (const skill of context.skills)
64
+ appendEntry(skill.name, skill.description);
65
+ }
66
+ if (context.tools.length > 0) {
67
+ lines.push(t('context-panel-tools', { n: context.tools.length }));
68
+ for (const tool of context.tools)
69
+ appendEntry(tool.name, tool.description, 160);
70
+ }
71
+ return lines;
72
+ }