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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/README.md +32 -15
  2. package/cordis.patch.yml +21 -2
  3. package/cordis.yml +12 -1
  4. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  5. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  6. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  7. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  8. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  9. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  10. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  11. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  12. package/dsh-ecosystem-spec/registry/README.md +14 -0
  13. package/dsh-ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
  14. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  15. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  16. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  17. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  18. package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
  19. package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -0
  20. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  21. package/dsh-ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
  22. package/dsh-ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
  23. package/dsh-ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
  24. package/lib/types/cc/figures.d.ts +4 -0
  25. package/lib/types/cc/figures.d.ts.map +1 -1
  26. package/lib/types/cc/figures.js +4 -0
  27. package/lib/types/command-trees.d.ts +2 -1
  28. package/lib/types/command-trees.d.ts.map +1 -1
  29. package/lib/types/command-trees.js +1 -1
  30. package/lib/types/commands.d.ts.map +1 -1
  31. package/lib/types/commands.js +2 -0
  32. package/lib/types/components/ExtensionDialog.d.ts +40 -0
  33. package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
  34. package/lib/types/components/ExtensionDialog.js +210 -0
  35. package/lib/types/components/HelpMenu.js +1 -1
  36. package/lib/types/components/LoadedContextPanel.d.ts +5 -5
  37. package/lib/types/components/LoadedContextPanel.js +6 -6
  38. package/lib/types/components/LogoV2.d.ts.map +1 -1
  39. package/lib/types/components/LogoV2.js +16 -8
  40. package/lib/types/components/Markdown.d.ts +13 -1
  41. package/lib/types/components/Markdown.d.ts.map +1 -1
  42. package/lib/types/components/Markdown.js +15 -1
  43. package/lib/types/components/MessageList.d.ts +3 -1
  44. package/lib/types/components/MessageList.d.ts.map +1 -1
  45. package/lib/types/components/MessageList.js +111 -6
  46. package/lib/types/components/PromptInput.d.ts.map +1 -1
  47. package/lib/types/components/PromptInput.js +26 -12
  48. package/lib/types/components/RewindPicker.d.ts +13 -1
  49. package/lib/types/components/RewindPicker.d.ts.map +1 -1
  50. package/lib/types/components/RewindPicker.js +26 -2
  51. package/lib/types/components/StreamingMarkdown.d.ts +2 -8
  52. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  53. package/lib/types/components/StreamingMarkdown.js +51 -9
  54. package/lib/types/components/ToolUseLoader.d.ts +8 -3
  55. package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
  56. package/lib/types/components/ToolUseLoader.js +43 -9
  57. package/lib/types/components/activityFrames.d.ts +1 -1
  58. package/lib/types/components/activityFrames.d.ts.map +1 -1
  59. package/lib/types/components/activityFrames.js +4 -1
  60. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
  61. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  62. package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
  63. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  64. package/lib/types/components/messages/AssistantToolUseMessage.js +13 -2
  65. package/lib/types/dsh-adapter/channel.d.ts +61 -11
  66. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  67. package/lib/types/dsh-adapter/channel.js +767 -120
  68. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  69. package/lib/types/dsh-adapter/childStderr.js +10 -0
  70. package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
  71. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
  72. package/lib/types/dsh-adapter/command-attribution.js +93 -0
  73. package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
  74. package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
  75. package/lib/types/dsh-adapter/command-errors.js +63 -0
  76. package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
  77. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
  78. package/lib/types/dsh-adapter/command-trees.js +70 -20
  79. package/lib/types/dsh-adapter/component-identity.d.ts +33 -0
  80. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
  81. package/lib/types/dsh-adapter/component-identity.js +108 -0
  82. package/lib/types/dsh-adapter/contract.d.ts +1 -1
  83. package/lib/types/dsh-adapter/contract.js +2 -2
  84. package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
  85. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
  86. package/lib/types/dsh-adapter/decision-guard.js +348 -0
  87. package/lib/types/dsh-adapter/dialogs.d.ts +145 -0
  88. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
  89. package/lib/types/dsh-adapter/dialogs.js +316 -0
  90. package/lib/types/dsh-adapter/effect-ledger.d.ts +91 -0
  91. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
  92. package/lib/types/dsh-adapter/effect-ledger.js +251 -0
  93. package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
  94. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
  95. package/lib/types/dsh-adapter/extension-events.js +207 -0
  96. package/lib/types/dsh-adapter/extensions.d.ts +32 -0
  97. package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
  98. package/lib/types/dsh-adapter/extensions.js +42 -0
  99. package/lib/types/dsh-adapter/grants.d.ts +25 -0
  100. package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
  101. package/lib/types/dsh-adapter/grants.js +213 -0
  102. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  103. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  104. package/lib/types/dsh-adapter/host-access.js +652 -0
  105. package/lib/types/dsh-adapter/host-descriptor.d.ts +24 -0
  106. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
  107. package/lib/types/dsh-adapter/host-descriptor.js +169 -0
  108. package/lib/types/dsh-adapter/index.d.ts +4 -0
  109. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  110. package/lib/types/dsh-adapter/index.js +1 -0
  111. package/lib/types/dsh-adapter/message-observer.d.ts +173 -0
  112. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
  113. package/lib/types/dsh-adapter/message-observer.js +553 -0
  114. package/lib/types/dsh-adapter/plugin-host.d.ts +136 -0
  115. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
  116. package/lib/types/dsh-adapter/plugin-host.js +365 -0
  117. package/lib/types/dsh-adapter/plugin-storage.d.ts +108 -0
  118. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
  119. package/lib/types/dsh-adapter/plugin-storage.js +397 -0
  120. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  121. package/lib/types/dsh-adapter/plugin.js +124 -14
  122. package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
  123. package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
  124. package/lib/types/dsh-adapter/plugins-info.js +276 -0
  125. package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
  126. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/promptDebug.js +13 -4
  128. package/lib/types/dsh-adapter/renderers.d.ts +57 -0
  129. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
  130. package/lib/types/dsh-adapter/renderers.js +173 -0
  131. package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
  132. package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
  133. package/lib/types/dsh-adapter/sanitize.js +65 -0
  134. package/lib/types/dsh-adapter/scenes.d.ts +15 -5
  135. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  136. package/lib/types/dsh-adapter/scenes.js +149 -35
  137. package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
  138. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  139. package/lib/types/dsh-adapter/settings-sections.js +106 -26
  140. package/lib/types/dsh-adapter/shortcuts.d.ts +107 -0
  141. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
  142. package/lib/types/dsh-adapter/shortcuts.js +340 -0
  143. package/lib/types/dsh-adapter/status.d.ts +74 -0
  144. package/lib/types/dsh-adapter/status.d.ts.map +1 -0
  145. package/lib/types/dsh-adapter/status.js +234 -0
  146. package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
  147. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  148. package/lib/types/dsh-adapter/workspaces.js +287 -170
  149. package/lib/types/extensions.d.ts +13 -0
  150. package/lib/types/extensions.d.ts.map +1 -0
  151. package/lib/types/extensions.js +21 -0
  152. package/lib/types/force-production-react.d.ts +1 -0
  153. package/lib/types/force-production-react.d.ts.map +1 -0
  154. package/lib/types/force-production-react.js +12 -0
  155. package/lib/types/i18n.d.ts +174 -20
  156. package/lib/types/i18n.d.ts.map +1 -1
  157. package/lib/types/i18n.js +56 -6
  158. package/lib/types/index.d.ts +1 -0
  159. package/lib/types/index.d.ts.map +1 -1
  160. package/lib/types/index.js +1 -0
  161. package/lib/types/ink/components/App.d.ts +2 -0
  162. package/lib/types/ink/components/App.d.ts.map +1 -1
  163. package/lib/types/ink/components/App.js +4 -0
  164. package/lib/types/ink/ink.d.ts +31 -3
  165. package/lib/types/ink/ink.d.ts.map +1 -1
  166. package/lib/types/ink/ink.js +90 -5
  167. package/lib/types/ink/log-update.d.ts.map +1 -1
  168. package/lib/types/ink/log-update.js +225 -56
  169. package/lib/types/ink/output.d.ts +35 -2
  170. package/lib/types/ink/output.d.ts.map +1 -1
  171. package/lib/types/ink/output.js +281 -14
  172. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  173. package/lib/types/ink/render-node-to-output.js +14 -6
  174. package/lib/types/ink/screen.d.ts +39 -0
  175. package/lib/types/ink/screen.d.ts.map +1 -1
  176. package/lib/types/ink/screen.js +117 -0
  177. package/lib/types/ink/terminal.d.ts.map +1 -1
  178. package/lib/types/ink/terminal.js +26 -6
  179. package/lib/types/ink/wrapAnsi.d.ts +1 -1
  180. package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
  181. package/lib/types/ink/wrapAnsi.js +29 -2
  182. package/lib/types/plugin-host.d.ts +15 -0
  183. package/lib/types/plugin-host.d.ts.map +1 -0
  184. package/lib/types/plugin-host.js +17 -0
  185. package/lib/types/plugin-spec/negotiate.d.ts +11 -0
  186. package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
  187. package/lib/types/plugin-spec/negotiate.js +97 -0
  188. package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
  189. package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
  190. package/lib/types/plugin-spec/permission-scope.js +90 -0
  191. package/lib/types/plugin-spec/registry.d.ts +23 -0
  192. package/lib/types/plugin-spec/registry.d.ts.map +1 -0
  193. package/lib/types/plugin-spec/registry.js +252 -0
  194. package/lib/types/plugin-spec/schema-check.d.ts +17 -0
  195. package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
  196. package/lib/types/plugin-spec/schema-check.js +165 -0
  197. package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
  198. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
  199. package/lib/types/plugin-spec/tui-extension.js +79 -0
  200. package/lib/types/plugin-spec/types.d.ts +114 -0
  201. package/lib/types/plugin-spec/types.d.ts.map +1 -0
  202. package/lib/types/plugin-spec/types.js +10 -0
  203. package/lib/types/plugin-spec/validate.d.ts +21 -0
  204. package/lib/types/plugin-spec/validate.d.ts.map +1 -0
  205. package/lib/types/plugin-spec/validate.js +138 -0
  206. package/lib/types/scenes.d.ts +2 -1
  207. package/lib/types/scenes.d.ts.map +1 -1
  208. package/lib/types/scenes.js +1 -1
  209. package/lib/types/screens/Chat.d.ts +14 -1
  210. package/lib/types/screens/Chat.d.ts.map +1 -1
  211. package/lib/types/screens/Chat.js +173 -49
  212. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  213. package/lib/types/screens/SessionBrowser.js +10 -3
  214. package/lib/types/sessions/view.d.ts +3 -2
  215. package/lib/types/sessions/view.d.ts.map +1 -1
  216. package/lib/types/sessions/view.js +18 -0
  217. package/lib/types/settings-sections.d.ts +2 -1
  218. package/lib/types/settings-sections.d.ts.map +1 -1
  219. package/lib/types/settings-sections.js +1 -1
  220. package/lib/types/theme.d.ts +5 -0
  221. package/lib/types/theme.d.ts.map +1 -1
  222. package/lib/types/theme.js +15 -0
  223. package/lib/types/update.d.ts +20 -0
  224. package/lib/types/update.d.ts.map +1 -1
  225. package/lib/types/update.js +54 -7
  226. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  227. package/lib/types/utils/execFileNoThrow.js +3 -0
  228. package/lib/types/utils/loaded-context.d.ts +8 -3
  229. package/lib/types/utils/loaded-context.d.ts.map +1 -1
  230. package/lib/types/utils/loaded-context.js +39 -3
  231. package/lib/types/utils/modifiers.d.ts.map +1 -1
  232. package/lib/types/utils/modifiers.js +3 -2
  233. package/lib/types/working-activity.d.ts +12 -0
  234. package/lib/types/working-activity.d.ts.map +1 -1
  235. package/lib/types/working-activity.js +13 -0
  236. package/lib/types/workspaces.d.ts +2 -1
  237. package/lib/types/workspaces.d.ts.map +1 -1
  238. package/lib/types/workspaces.js +1 -1
  239. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  240. package/node_modules/@dsh-std/command/LICENSE +21 -0
  241. package/node_modules/@dsh-std/command/README.md +26 -0
  242. package/node_modules/@dsh-std/command/README.zh.md +28 -0
  243. package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
  244. package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
  245. package/node_modules/@dsh-std/command/lib/index.js +252 -0
  246. package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
  247. package/node_modules/@dsh-std/command/package.json +22 -0
  248. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  249. package/node_modules/@dsh-std/connection/LICENSE +21 -0
  250. package/node_modules/@dsh-std/connection/README.md +42 -0
  251. package/node_modules/@dsh-std/connection/README.zh.md +42 -0
  252. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  253. package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  254. package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  255. package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  256. package/node_modules/@dsh-std/connection/lib/index.js +158 -0
  257. package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  258. package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  259. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  260. package/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  261. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  262. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  263. package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  264. package/node_modules/@dsh-std/connection/package.json +20 -0
  265. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  266. package/node_modules/@dsh-std/core/LICENSE +21 -0
  267. package/node_modules/@dsh-std/core/README.md +13 -0
  268. package/node_modules/@dsh-std/core/README.zh.md +13 -0
  269. package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  270. package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  271. package/node_modules/@dsh-std/core/lib/index.js +424 -0
  272. package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  273. package/node_modules/@dsh-std/core/package.json +21 -0
  274. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  275. package/node_modules/@dsh-std/manifest/LICENSE +21 -0
  276. package/node_modules/@dsh-std/manifest/README.md +5 -0
  277. package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  278. package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  279. package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  280. package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  281. package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  282. package/node_modules/@dsh-std/manifest/package.json +20 -0
  283. package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  284. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  285. package/node_modules/@dsh-std/messages/LICENSE +21 -0
  286. package/node_modules/@dsh-std/messages/README.md +5 -0
  287. package/node_modules/@dsh-std/messages/README.zh.md +7 -0
  288. package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
  289. package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
  290. package/node_modules/@dsh-std/messages/lib/index.js +151 -0
  291. package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
  292. package/node_modules/@dsh-std/messages/package.json +20 -0
  293. package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
  294. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  295. package/node_modules/@dsh-std/presentation/LICENSE +21 -0
  296. package/node_modules/@dsh-std/presentation/README.md +27 -0
  297. package/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  298. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  299. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  300. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  301. package/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  302. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  303. package/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  304. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  305. package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  306. package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  307. package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  308. package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  309. package/node_modules/@dsh-std/presentation/package.json +25 -0
  310. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  311. package/node_modules/@dsh-std/storage/LICENSE +21 -0
  312. package/node_modules/@dsh-std/storage/README.md +5 -0
  313. package/node_modules/@dsh-std/storage/README.zh.md +7 -0
  314. package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
  315. package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
  316. package/node_modules/@dsh-std/storage/lib/index.js +104 -0
  317. package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
  318. package/node_modules/@dsh-std/storage/package.json +20 -0
  319. package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
  320. package/package.json +110 -70
  321. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  322. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
  323. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
  324. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
  325. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  326. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  327. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  328. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  329. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
  330. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  331. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  332. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  333. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  334. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  335. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  336. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  337. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
  338. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  339. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
  340. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
  341. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
  342. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  343. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  344. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
  345. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  346. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
  347. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  348. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
  349. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
  350. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
  351. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
  352. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
  353. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
  354. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
  355. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
  356. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
  357. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  358. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
  359. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -0
  360. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -0
  361. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  362. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  363. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  364. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +262 -0
  365. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
  366. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +550 -0
  367. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
  368. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
  369. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
  370. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
  371. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
  372. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -0
  373. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  374. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
  375. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
  376. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
  377. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  378. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  379. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
  380. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  381. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
  382. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  383. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
  384. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
  385. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
  386. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  387. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  388. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
  389. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  390. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
  391. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  392. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
  393. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
  394. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
  395. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  396. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  397. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
  398. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  399. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
  400. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  401. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
  402. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
  403. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
  404. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
  405. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
  406. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
  407. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
  408. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
  409. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
  410. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
  411. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
  412. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +258 -0
  413. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
  414. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
  415. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
  416. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
  417. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  418. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
  419. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
  420. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
  421. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  422. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  423. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
  424. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  425. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
  426. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  427. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
  428. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
  429. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
  430. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
  431. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
  432. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
  433. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
  434. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
@@ -37,7 +37,7 @@ const DEFAULT_ROW_HEIGHT = 2;
37
37
  /** Cold-start estimate of the header block above the rows; corrected by the
38
38
  * first layout measurement. */
39
39
  const DEFAULT_HEADER_LINES = 14;
40
- export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout = 'auto', showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
40
+ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout = 'auto', thinkingFold = 'preview', showAll, onToggleAll, onLoadOlder, thinkingVisible = true, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }) {
41
41
  const hiddenCount = rows.length - MAX_RENDERED_ROWS;
42
42
  // The thinking filter runs BEFORE virtualization so window indices line up.
43
43
  const visibleRows = (showAll || hiddenCount <= 0
@@ -65,7 +65,7 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
65
65
  return undefined;
66
66
  };
67
67
  // --- layout virtualization ---------------------------------------------
68
- const { columns } = useTerminalSize();
68
+ const { columns, rows: termRows } = useTerminalSize();
69
69
  // Measured row heights, remembered after a row unmounts so virtualization
70
70
  // can compute total content height. Bounded: row ids grow monotonically
71
71
  // and rows are never removed from the transcript (foldRows keeps the
@@ -75,6 +75,31 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
75
75
  const HEIGHTS_CACHE_MAX = 5000;
76
76
  const heightsRef = React.useRef(new Map());
77
77
  const localRefs = React.useRef(new Map());
78
+ /** Row ids that have been mounted (and therefore painted into the
79
+ * terminal) at least once. The sticky window may skip a row ONLY after
80
+ * this: an unpainted row above the window has no scrollback copy, so
81
+ * skipping it would erase it from the user's history entirely — preset
82
+ * history at boot (session resume) landed exactly there. Cleared when
83
+ * the list head changes identity (rewind / new session / loadOlder
84
+ * prepends restored rows that must paint again). */
85
+ const paintedOnceRef = React.useRef(new Set());
86
+ const paintedBaseRef = React.useRef(undefined);
87
+ /** Window-expansion hold: after the window WIDENS (new rows mounted),
88
+ * refuse to tighten for a short hold so the mounted rows actually reach
89
+ * the terminal. React commits within one ink frame coalesce — a render
90
+ * that mounts rows followed by the measure-tick re-render that drops
91
+ * them paints only the DROPPED layout, and never-mounted rows have no
92
+ * scrollback copy (preset history at boot vanished — CI
93
+ * repro-inline-scrollback). After the hold, tightening is visually
94
+ * free: those rows sit in scrollback and the diff skips them. */
95
+ const lastStartRef = React.useRef(-1);
96
+ const holdUntilRef = React.useRef(0);
97
+ const listHeadId = visibleRows[0]?.id;
98
+ if (listHeadId !== undefined && paintedBaseRef.current !== undefined && listHeadId !== paintedBaseRef.current) {
99
+ paintedOnceRef.current = new Set();
100
+ }
101
+ if (listHeadId !== undefined)
102
+ paintedBaseRef.current = listHeadId;
78
103
  /** Content-space offset of visibleRows[0] (header + dividers), measured. */
79
104
  const baseRef = React.useRef(null);
80
105
  const measureQueuedRef = React.useRef(false);
@@ -128,7 +153,60 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
128
153
  // back to the real bottom: a self-sustaining ping-pong that blanks the
129
154
  // transcript mid-stream.
130
155
  if (sticky && visibleRows.length > 0) {
156
+ // Sticky (follow-bottom): the viewport shows the TAIL of the content —
157
+ // mount exactly the tail window the floor walk covers, not everything
158
+ // from the scrollTop scan. Main-screen ScrollBox reports its viewport
159
+ // as the CONTENT height (the terminal itself is the scroller), so both
160
+ // the scan and an unclamped floor walk mount EVERY row in long
161
+ // sessions — and React's commit traverses every fiber of every mounted
162
+ // row per frame (measured as the dominant long-session stall). The
163
+ // user only ever sees terminal rows: clamp the walk-back coverage to
164
+ // the TERMINAL viewport plus overscan.
131
165
  start = Math.min(start, visibleRows.length - 1);
166
+ // Blank-band guard: sticky scrollTop tracks the renderer's FRESH Yoga
167
+ // scrollHeight, while these offsets use per-row heights measured one to
168
+ // two commits late. During fast streaming the accurate scrollTop scans
169
+ // deeper through the underestimated offsets than the real viewport does,
170
+ // unmounting rows that are still on screen (visible spacer band). Walk
171
+ // backwards from the tail with the known heights and mount at least one
172
+ // terminal viewport plus overscan of content above it, so the window
173
+ // can never open a gap inside what the user is looking at.
174
+ let covered = Math.min(viewport, termRows) + OVERSCAN_LINES;
175
+ let floor = visibleRows.length - 1;
176
+ while (floor > 0 && covered > 0) {
177
+ covered -= heightOf(visibleRows[floor]);
178
+ floor--;
179
+ }
180
+ // The walk exhausted the whole list: every row is within coverage —
181
+ // floor+1 here would drop row 0 (its content then has no terminal copy
182
+ // anywhere; preset history lost its head — CI repro-inline-scrollback).
183
+ start = floor === 0 && covered > 0 ? 0 : floor + 1;
184
+ // Paint-at-least-once: extend the window over any row that has never
185
+ // been mounted. A row the window skips keeps only its terminal/scrollback
186
+ // copy — a row that was never painted has NO copy anywhere, so preset
187
+ // history (session resume, repro-inline-scrollback's #39 family) would
188
+ // vanish from the user's scrollback. Extending mounts everything above
189
+ // on the first frame (topPad 0, full paint), then the set fills and the
190
+ // window tightens to the tail.
191
+ const paintedOnce = paintedOnceRef.current;
192
+ for (let i = 0; i < start; i++) {
193
+ if (!paintedOnce.has(visibleRows[i].id)) {
194
+ start = i;
195
+ break;
196
+ }
197
+ }
198
+ // Expansion hold — AFTER the extension so it tracks the FINAL window:
199
+ // never tighten within the hold window after a widen. React commits
200
+ // inside one ink frame coalesce; a mount followed by the measure-tick
201
+ // re-render that drops the row paints only the DROPPED layout, and the
202
+ // row's painted-once mark (set at the first commit) is a lie.
203
+ if (lastStartRef.current >= 0 && start > lastStartRef.current && performance.now() < holdUntilRef.current) {
204
+ start = lastStartRef.current;
205
+ }
206
+ if (lastStartRef.current < 0 || start < lastStartRef.current) {
207
+ holdUntilRef.current = performance.now() + 120;
208
+ }
209
+ lastStartRef.current = start;
132
210
  }
133
211
  if (forceMountRowId !== undefined && forceMountRowId !== null) {
134
212
  const idx = visibleRows.findIndex(row => row.id === forceMountRowId);
@@ -137,6 +215,15 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
137
215
  end = Math.max(end, idx + 1);
138
216
  }
139
217
  }
218
+ // The newest failed tool call carries the trajectory footnote
219
+ // (failureHint). Virtualization must not unmount it: before the window
220
+ // clamp the row was always mounted, now keep mounting it explicitly while
221
+ // the hint is live (verify-trace-scene's footnote check).
222
+ if (failureHintRowId !== undefined && failureHintRowId !== null) {
223
+ const idx = visibleRows.findIndex(row => row.id === failureHintRowId);
224
+ if (idx !== -1)
225
+ start = Math.min(start, idx);
226
+ }
140
227
  const topPad = offsets[start] ?? 0;
141
228
  const mountedBottom = end < visibleRows.length ? offsets[end] : total;
142
229
  const bottomPad = total - mountedBottom;
@@ -170,6 +257,12 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
170
257
  // mounted coverage so burst scrolls never show blank spacer.
171
258
  React.useLayoutEffect(() => {
172
259
  let changed = false;
260
+ // Mounted ⇒ painted: record rows eligible for window skipping.
261
+ const paintedOnce = paintedOnceRef.current;
262
+ for (const id of localRefs.current.keys()) {
263
+ if (!paintedOnce.has(id))
264
+ paintedOnce.add(id);
265
+ }
173
266
  for (const [id, el] of localRefs.current) {
174
267
  const h = el.yogaNode?.getComputedHeight();
175
268
  if (h !== undefined && h > 0 && heightsRef.current.get(id) !== h) {
@@ -195,7 +288,16 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
195
288
  }
196
289
  if (scrollHandle) {
197
290
  if (sticky || (start === 0 && end >= visibleRows.length)) {
198
- scrollHandle.setClampBounds(undefined, undefined);
291
+ // Sticky still needs the MIN clamp: the first wheel-up breaks sticky
292
+ // on the DOM (ScrollBox.scrollBy) several frames before React
293
+ // commits a new mount window, and the drain frames in between paint
294
+ // unmounted spacer rows as a blank band. Clamping to the currently
295
+ // mounted top shows the edge content until React catches up - same
296
+ // behavior as the steady-state scroll path. The MAX clamp stays
297
+ // disabled: sticky follow pushes scrollTop to each frame's new
298
+ // maxScroll, which a stale mounted max would clamp away.
299
+ const min = start > 0 ? Math.max(0, base + topPad - viewport) : undefined;
300
+ scrollHandle.setClampBounds(min, undefined);
199
301
  }
200
302
  else {
201
303
  const min = Math.max(0, base + topPad - viewport);
@@ -232,10 +334,10 @@ export function MessageList({ rows, expanded, expandedRows, selectedId, onToggle
232
334
  // spacing; only the very first row of the whole list has none.
233
335
  const addMargin = margins.get(row.id) === true;
234
336
  const tool = row.tool;
235
- return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
337
+ return (_jsx(MemoRow, { rowId: row.id, kind: row.kind, text: row.text, executionTarget: row.executionTarget, streaming: row.streaming === true, durationMs: row.durationMs, time: row.time, addMargin: addMargin, isSelected: selectedId === row.id, isExpanded: expandedRows.has(row.id), expanded: expanded, model: model, diffLayout: diffLayout, thinkingFold: thinkingFold, background: rowBackground(row.id), toolCallId: tool?.callId, toolName: tool?.name, toolArgsText: tool?.argsText, toolArgsFull: tool?.argsFull, toolStatus: tool?.status, toolResultText: tool?.resultText, toolResultFull: tool?.resultFull, toolErrorText: tool?.errorText, toolFootnote: failureHintRowId === row.id ? failureHint : undefined, toolCallView: tool?.callView, toolResultView: tool?.resultView, toolStartedAt: tool?.startedAt, toolDurationMs: tool?.durationMs, nowSec: tool?.status === 'running' ? nowSec : undefined, onToggleRow: onToggleRow, setRowRef: setRowRef }, row.id));
236
338
  }), bottomPad > 0 && _jsx(Box, { height: bottomPad, flexShrink: 0 })] }));
237
339
  }
238
- function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, diffLayout, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
340
+ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, durationMs, time, addMargin, isSelected, isExpanded, expanded, model, diffLayout, thinkingFold, background, toolCallId, toolName, toolArgsText, toolArgsFull, toolStatus, toolResultText, toolResultFull, toolErrorText, toolFootnote, toolCallView, toolResultView, toolStartedAt, toolDurationMs, onToggleRow, setRowRef, }) {
239
341
  const ref = React.useCallback((el) => {
240
342
  setRowRef(rowId, el);
241
343
  }, [setRowRef, rowId]);
@@ -248,7 +350,10 @@ function TranscriptRow({ rowId, kind, text, executionTarget, streaming, duration
248
350
  case 'assistant':
249
351
  return streaming ? (_jsxs(Box, { alignItems: "flex-start", flexDirection: "row", marginTop: addMargin ? 1 : 0, width: "100%", backgroundColor: background, children: [_jsx(Box, { minWidth: 2, children: _jsx(Text, { color: "text", children: "\u25CF" }) }), _jsx(Box, { flexDirection: "column", children: _jsx(StreamingMarkdown, { children: stripNarration(text) }) })] })) : (_jsxs(Box, { width: "100%", flexDirection: "column", backgroundColor: background, ref: ref, children: [expanded && (_jsx(Box, { flexDirection: "row", justifyContent: "flex-end", gap: 1, marginTop: 1, children: _jsx(MessageMetadata, { timestamp: time, model: model }) })), _jsx(AssistantTextMessage, { text: stripNarration(text), addMargin: addMargin, isSelected: isSelected, isExpanded: isExpanded, onClick: onClick })] }));
250
352
  case 'reasoning':
251
- return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin,
353
+ return (_jsx(Box, { flexDirection: "column", ref: ref, children: _jsx(AssistantThinkingMessage, { thinking: text, addMargin: addMargin, preview: streaming &&
354
+ thinkingFold === 'preview' &&
355
+ !expanded &&
356
+ !isExpanded,
252
357
  // Streaming reasoning shows expanded live, then folds
253
358
  // automatically once the turn settles (unless Ctrl+O or a
254
359
  // single-row expansion keeps it open).
@@ -1 +1 @@
1
- {"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,qBAg5BlB"}
1
+ {"version":3,"file":"PromptInput.d.ts","sourceRoot":"","sources":["../../../src/components/PromptInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAkDxD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,IAAI,OAAO,CAAA;IAClB,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,IAAI,IAAI,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,6EAA6E;IAC7E,eAAe,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,IAAI,IAAI,CAAA;IACvB,8EAA8E;IAC9E,eAAe,CAAC,IAAI,IAAI,CAAA;IACxB,0EAA0E;IAC1E,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;CACzD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,cAAc,EACd,eAAe,EACf,aAAa,GACd,EAAE,gBAAgB,qBA65BlB"}
@@ -116,6 +116,7 @@ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, sel
116
116
  const [selectedCommand, setSelectedCommand] = React.useState(0);
117
117
  const history = React.useRef([]);
118
118
  const historyIndex = React.useRef(-1);
119
+ const historyDraft = React.useRef('');
119
120
  // ctrl+r history fill: replace the input when a new fill arrives, then
120
121
  // tell the caller to clear it.
121
122
  const lastFill = React.useRef(null);
@@ -528,11 +529,17 @@ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, sel
528
529
  if (!tryRunCommand(value))
529
530
  submitText(value);
530
531
  };
532
+ // Ctrl+J is the only portable multiline fallback when a terminal cannot
533
+ // report modifiers on Enter. The parser names its bare LF `enter`, while
534
+ // the physical Enter key arrives as CR (`return`).
535
+ if (input === '\n' && event?.keypress.name === 'enter') {
536
+ insertAtCaret('\n');
537
+ return;
538
+ }
531
539
  // Whole-line input from Windows ConPTY pipelines (cmd batch -> node):
532
- // the trailing CR/LF marks a complete line to submit. A bare Enter
533
- // arrives as `\r`/`\n`/`\r\n` — treat it as Enter, NOT a direct
534
- // submit. Only real multi-char piped lines keep the legacy
535
- // direct-submit path.
540
+ // the trailing CR/LF marks a complete line to submit. A bare CR/CRLF is
541
+ // Enter, while real multi-char piped lines keep the legacy direct-submit
542
+ // path.
536
543
  if (input.includes('\n') || input.includes('\r')) {
537
544
  if (/^[\r\n]+$/.test(input)) {
538
545
  handleEnter();
@@ -622,9 +629,13 @@ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, sel
622
629
  }
623
630
  if (history.current.length === 0)
624
631
  return;
625
- historyIndex.current = historyIndex.current < 0
626
- ? history.current.length - 1
627
- : Math.max(0, historyIndex.current - 1);
632
+ if (historyIndex.current < 0) {
633
+ historyDraft.current = value;
634
+ historyIndex.current = history.current.length - 1;
635
+ }
636
+ else {
637
+ historyIndex.current = Math.max(0, historyIndex.current - 1);
638
+ }
628
639
  const entry = history.current[historyIndex.current] ?? '';
629
640
  setInput(entry);
630
641
  return;
@@ -649,11 +660,14 @@ export function PromptInput({ channel, helpOpen, onToggleHelp, onRunCommand, sel
649
660
  }
650
661
  if (historyIndex.current < 0)
651
662
  return;
652
- historyIndex.current += 1;
653
- const entry = historyIndex.current >= history.current.length
654
- ? ''
655
- : (history.current[historyIndex.current] ?? '');
656
- setInput(entry);
663
+ if (historyIndex.current >= history.current.length - 1) {
664
+ historyIndex.current = -1;
665
+ setInput(historyDraft.current);
666
+ }
667
+ else {
668
+ historyIndex.current += 1;
669
+ setInput(history.current[historyIndex.current] ?? '');
670
+ }
657
671
  return;
658
672
  }
659
673
  if (isMod(key) && key.leftArrow) {
@@ -1,14 +1,26 @@
1
1
  import React from 'react';
2
2
  import type { ChatRow } from '../dsh-adapter/channel.js';
3
+ import type { TuiRewindMode } from '../dsh-adapter/extension-events.js';
3
4
  /**
4
5
  * Double-Esc rewind picker (CC's "Double-tap esc to rewind the code and/or
5
6
  * conversation to a previous point in time"): lists the user's past messages
6
7
  * newest-first; selecting one and confirming rewinds the conversation to
7
8
  * that point (the message comes back into the input for re-editing).
9
+ *
10
+ * The confirm pane has two shapes: the plain one (Enter rewinds), and —
11
+ * when a plugin answered the tui/rewind-prompt decision with extra modes —
12
+ * a choice list whose option zero is always the built-in conversation-only
13
+ * rewind, followed by the plugin's modes (e.g. "also restore files").
8
14
  */
9
- export declare function RewindPicker({ rows, focusIndex, confirmRow, }: {
15
+ export declare function RewindPicker({ rows, focusIndex, confirmRow, modes, modeIndex, busy, }: {
10
16
  rows: readonly ChatRow[];
11
17
  focusIndex: number;
12
18
  confirmRow: ChatRow | null;
19
+ /** Plugin-offered rewind modes (tui/rewind-prompt); null = plain confirm. */
20
+ modes?: readonly TuiRewindMode[] | null;
21
+ /** Focused option in the modes list (0 = conversation-only). */
22
+ modeIndex?: number;
23
+ /** True while the plugin decision is in flight. */
24
+ busy?: boolean;
13
25
  }): React.ReactNode;
14
26
  //# sourceMappingURL=RewindPicker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RewindPicker.d.ts","sourceRoot":"","sources":["../../../src/components/RewindPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAMxD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,UAAU,EACV,UAAU,GACX,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAA;CAC3B,GAAG,KAAK,CAAC,SAAS,CA+DlB"}
1
+ {"version":3,"file":"RewindPicker.d.ts","sourceRoot":"","sources":["../../../src/components/RewindPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AAMvE;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,UAAU,EACV,UAAU,EACV,KAAY,EACZ,SAAa,EACb,IAAY,GACb,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,6EAA6E;IAC7E,KAAK,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAA;IACvC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mDAAmD;IACnD,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,KAAK,CAAC,SAAS,CA4GlB"}
@@ -10,9 +10,33 @@ import { listWindow } from './listWindow.js';
10
10
  * conversation to a previous point in time"): lists the user's past messages
11
11
  * newest-first; selecting one and confirming rewinds the conversation to
12
12
  * that point (the message comes back into the input for re-editing).
13
+ *
14
+ * The confirm pane has two shapes: the plain one (Enter rewinds), and —
15
+ * when a plugin answered the tui/rewind-prompt decision with extra modes —
16
+ * a choice list whose option zero is always the built-in conversation-only
17
+ * rewind, followed by the plugin's modes (e.g. "also restore files").
13
18
  */
14
- export function RewindPicker({ rows, focusIndex, confirmRow, }) {
19
+ export function RewindPicker({ rows, focusIndex, confirmRow, modes = null, modeIndex = 0, busy = false, }) {
15
20
  if (confirmRow !== null) {
21
+ if (modes !== null) {
22
+ // Plugin modes: a described choice list (one extra row per
23
+ // description), windowed like the message list below.
24
+ const { rows: terminalRows } = useTerminalSize();
25
+ const rowCosts = [2, ...modes.map(mode => (mode.description === undefined ? 1 : 2))];
26
+ const { start, end } = listWindow(rowCosts, modeIndex, Math.max(terminalRows - 10, 2));
27
+ const options = [
28
+ { key: 'conversation', label: t('rewind-mode-default'), description: t('rewind-confirm-desc') },
29
+ ...modes.map(mode => ({
30
+ key: mode.id,
31
+ label: mode.label,
32
+ ...(mode.description === undefined ? {} : { description: mode.description }),
33
+ })),
34
+ ];
35
+ return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('rewind-confirm-title') }), _jsx(Text, { dimColor: true, children: preview(confirmRow.text) })] }), options.slice(start, end).map((option, index) => {
36
+ const absoluteIndex = start + index;
37
+ return (_jsx(ListItem, { isFocused: absoluteIndex === modeIndex, description: option.description, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < options.length, children: option.label }, option.key));
38
+ })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
39
+ }
16
40
  return (_jsx(Pane, { color: "permission", children: _jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "remember", bold: true, children: t('rewind-confirm-title') }) }), _jsx(ListItem, { isFocused: false, description: t('rewind-confirm-desc'), children: preview(confirmRow.text) }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-rewind-back') }) })] }) }));
17
41
  }
18
42
  const { rows: terminalRows } = useTerminalSize();
@@ -23,7 +47,7 @@ export function RewindPicker({ rows, focusIndex, confirmRow, }) {
23
47
  return (_jsxs(Pane, { color: "permission", children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "remember", bold: true, children: t('rewind-title') }), _jsx(Text, { dimColor: true, children: t('rewind-subtitle') })] }), rows.length === 0 ? (_jsx(ListItem, { isFocused: false, children: t('rewind-empty') })) : (rows.slice(start, end).map((row, index) => {
24
48
  const absoluteIndex = start + index;
25
49
  return (_jsx(ListItem, { isFocused: absoluteIndex === focusIndex, description: absoluteIndex === 0 ? t('rewind-last-message') : undefined, showScrollUp: absoluteIndex === start && start > 0, showScrollDown: absoluteIndex === end - 1 && end < rows.length, children: preview(row.text) }, row.id));
26
- }))] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
50
+ })), busy && _jsx(Text, { dimColor: true, children: t('rewind-waiting-plugins') })] }), _jsx(Text, { dimColor: true, italic: true, children: _jsx(HintLine, { text: t('hint-select-exit') }) })] }));
27
51
  }
28
52
  /** One-line preview of a message (newlines flattened, capped). */
29
53
  function preview(text) {
@@ -1,12 +1,6 @@
1
1
  import React from 'react';
2
- /**
3
- * Renders markdown during streaming by splitting at the last top-level block
4
- * boundary: everything before is stable (memoized, never re-parsed), only the
5
- * final block is re-parsed per delta, mirroring Claude Code's
6
- * `StreamingMarkdown.tsx`). marked.lexer() correctly handles unclosed code
7
- * fences as a single token, so block boundaries are always safe.
8
- */
9
- export declare function StreamingMarkdown({ children, }: {
2
+ export declare function StreamingMarkdown({ children, dimColor, }: {
10
3
  children: string;
4
+ dimColor?: boolean;
11
5
  }): React.ReactNode;
12
6
  //# sourceMappingURL=StreamingMarkdown.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StreamingMarkdown.d.ts","sourceRoot":"","sources":["../../../src/components/StreamingMarkdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;CACjB,GAAG,KAAK,CAAC,SAAS,CAoClB"}
1
+ {"version":3,"file":"StreamingMarkdown.d.ts","sourceRoot":"","sources":["../../../src/components/StreamingMarkdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAmDzB,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,QAAgB,GACjB,EAAE;IACD,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,GAAG,KAAK,CAAC,SAAS,CA0ClB"}
@@ -3,6 +3,7 @@ import React from 'react';
3
3
  import { marked } from 'marked';
4
4
  import Box from '../ink/components/Box.js';
5
5
  import { stripPromptXMLTags } from '../cc/markdown.js';
6
+ import { t } from '../i18n.js';
6
7
  import { Markdown } from './Markdown.js';
7
8
  /**
8
9
  * Renders markdown during streaming by splitting at the last top-level block
@@ -11,15 +12,56 @@ import { Markdown } from './Markdown.js';
11
12
  * `StreamingMarkdown.tsx`). marked.lexer() correctly handles unclosed code
12
13
  * fences as a single token, so block boundaries are always safe.
13
14
  */
14
- export function StreamingMarkdown({ children, }) {
15
- const stablePrefixRef = React.useRef('');
15
+ /**
16
+ * Tail budget for the unstable suffix during streaming. The sticky view only
17
+ * ever shows the last viewport of rows, but the suffix Text is re-wrapped
18
+ * every frame — an unbounded suffix (a single huge paragraph with no block
19
+ * boundary to advance the prefix) made that O(total) per frame. The suffix
20
+ * is clipped to this many characters (preferring a paragraph boundary),
21
+ * with a leading marker naming the dropped amount; settling renders the
22
+ * full text once through the non-streaming path.
23
+ *
24
+ * The cut point is STICKY (advances only when the suffix outgrows budget +
25
+ * step): a cut that slid every frame would break append-only growth, and
26
+ * the layout layer's incremental wrap would fall back to a full re-wrap of
27
+ * the whole tail on every token.
28
+ */
29
+ const SUFFIX_TAIL_BUDGET = 3584;
30
+ const SUFFIX_BOUNDARY_LOOKBACK = 2048;
31
+ const SUFFIX_CUT_STEP = 1024;
32
+ function clipSuffixTail(suffix, cut) {
33
+ const total = suffix.length;
34
+ if (total <= SUFFIX_TAIL_BUDGET) {
35
+ cut.current = 0;
36
+ return suffix;
37
+ }
38
+ // Advance the sticky cut only once the suffix outgrew the budget by a
39
+ // full step, preferring a paragraph boundary inside the lookback window.
40
+ if (total - cut.current > SUFFIX_TAIL_BUDGET + SUFFIX_CUT_STEP) {
41
+ const windowStart = total - SUFFIX_TAIL_BUDGET;
42
+ const boundary = suffix.lastIndexOf('\n\n', windowStart + SUFFIX_BOUNDARY_LOOKBACK);
43
+ cut.current = boundary !== -1 && boundary >= windowStart - SUFFIX_BOUNDARY_LOOKBACK
44
+ ? boundary + 2
45
+ : windowStart;
46
+ }
47
+ const dropped = cut.current;
48
+ return `${t('streaming-folded', { count: dropped })}\n\n${suffix.slice(cut.current)}`;
49
+ }
50
+ export function StreamingMarkdown({ children, dimColor = false, }) {
51
+ // The stable prefix is kept as ONE string identity across renders: a
52
+ // fresh substring per render would break Markdown's React.memo and
53
+ // re-layout the entire finished transcript tail on every token. The
54
+ // identity only changes when a new block boundary advances the prefix.
55
+ const prefixRef = React.useRef('');
56
+ const cutRef = React.useRef(0);
16
57
  const stripped = stripPromptXMLTags(children);
17
58
  // Reset if text was replaced (defensive; normally unmount handles this)
18
- if (!stripped.startsWith(stablePrefixRef.current)) {
19
- stablePrefixRef.current = '';
59
+ if (!stripped.startsWith(prefixRef.current)) {
60
+ prefixRef.current = '';
61
+ cutRef.current = 0;
20
62
  }
21
63
  // Lex only from current boundary — O(unstable length), not O(full text)
22
- const boundary = stablePrefixRef.current.length;
64
+ const boundary = prefixRef.current.length;
23
65
  const tokens = marked.lexer(stripped.substring(boundary));
24
66
  // Last non-space token is the growing block; everything before is final
25
67
  let lastContentIdx = tokens.length - 1;
@@ -31,9 +73,9 @@ export function StreamingMarkdown({ children, }) {
31
73
  advance += tokens[i].raw.length;
32
74
  }
33
75
  if (advance > 0) {
34
- stablePrefixRef.current = stripped.substring(0, boundary + advance);
76
+ prefixRef.current = stripped.substring(0, boundary + advance);
35
77
  }
36
- const stablePrefix = stablePrefixRef.current;
37
- const unstableSuffix = stripped.substring(stablePrefix.length);
38
- return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [stablePrefix && _jsx(Markdown, { children: stablePrefix }), unstableSuffix && _jsx(Markdown, { cacheTokens: false, children: unstableSuffix })] }));
78
+ const stablePrefix = prefixRef.current;
79
+ const unstableSuffix = clipSuffixTail(stripped.substring(stablePrefix.length), cutRef);
80
+ return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [stablePrefix && _jsx(Markdown, { dimColor: dimColor, children: stablePrefix }), unstableSuffix && _jsx(Markdown, { dimColor: dimColor, cacheTokens: false, children: unstableSuffix })] }));
39
81
  }
@@ -3,11 +3,16 @@ type Props = {
3
3
  isError: boolean;
4
4
  isUnresolved: boolean;
5
5
  shouldAnimate: boolean;
6
+ /** Raw tool id (bash/read/edit/…) — picks the category color for a settled dot. */
7
+ toolName?: string;
6
8
  };
7
9
  /**
8
- * The status dot on tool-call rows, mirroring Claude Code's ToolUseLoader:
9
- * blinking `●` while running, green on success, red on error, dim when queued.
10
+ * The status dot on tool-call rows. State shapes the glyph, the tool
11
+ * category picks the settled color: blinking `●` while running (attention),
12
+ * a smaller category-colored `•` once settled (quiet), and a red `✗` on
13
+ * error — a glyph swap, not just a hue, so failures read at a glance
14
+ * (Codex-style category colors; every color is a theme token).
10
15
  */
11
- export declare function ToolUseLoader({ isError, isUnresolved, shouldAnimate, }: Props): React.ReactNode;
16
+ export declare function ToolUseLoader({ isError, isUnresolved, shouldAnimate, toolName, }: Props): React.ReactNode;
12
17
  export {};
13
18
  //# sourceMappingURL=ToolUseLoader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolUseLoader.d.ts","sourceRoot":"","sources":["../../../src/components/ToolUseLoader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,YAAY,EACZ,aAAa,GACd,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAezB"}
1
+ {"version":3,"file":"ToolUseLoader.d.ts","sourceRoot":"","sources":["../../../src/components/ToolUseLoader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB,aAAa,EAAE,OAAO,CAAA;IACtB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAmCD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,YAAY,EACZ,aAAa,EACb,QAAQ,GACT,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAoBzB"}
@@ -1,17 +1,51 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import Box from '../ink/components/Box.js';
3
- import Text from '../ink/components/Text.js';
3
+ import { Text } from '../ui.js';
4
4
  import { useBlink } from '../hooks/useBlink.js';
5
- import { BLACK_CIRCLE } from '../cc/figures.js';
5
+ import { BLACK_CIRCLE, BULLET, MULTIPLICATION_X } from '../cc/figures.js';
6
+ const CATEGORY_BY_TOOL = {
7
+ bash: 'exec',
8
+ powershell: 'exec',
9
+ pwsh: 'exec',
10
+ read: 'read',
11
+ grep: 'read',
12
+ glob: 'read',
13
+ search: 'read',
14
+ file_search: 'read',
15
+ edit: 'write',
16
+ write: 'write',
17
+ str_replace_editor: 'write',
18
+ multiedit: 'write',
19
+ web_search: 'web',
20
+ web_fetch: 'web',
21
+ browser: 'web',
22
+ subagent: 'task',
23
+ task: 'task',
24
+ job: 'task',
25
+ workflow: 'task',
26
+ };
27
+ const CATEGORY_TOKEN = {
28
+ exec: 'toolDotExec',
29
+ read: 'toolDotRead',
30
+ write: 'toolDotWrite',
31
+ web: 'toolDotWeb',
32
+ task: 'toolDotTask',
33
+ default: 'success',
34
+ };
6
35
  /**
7
- * The status dot on tool-call rows, mirroring Claude Code's ToolUseLoader:
8
- * blinking `●` while running, green on success, red on error, dim when queued.
36
+ * The status dot on tool-call rows. State shapes the glyph, the tool
37
+ * category picks the settled color: blinking `●` while running (attention),
38
+ * a smaller category-colored `•` once settled (quiet), and a red `✗` on
39
+ * error — a glyph swap, not just a hue, so failures read at a glance
40
+ * (Codex-style category colors; every color is a theme token).
9
41
  */
10
- export function ToolUseLoader({ isError, isUnresolved, shouldAnimate, }) {
42
+ export function ToolUseLoader({ isError, isUnresolved, shouldAnimate, toolName, }) {
11
43
  const [ref, isBlinking] = useBlink(shouldAnimate);
12
- const color = isUnresolved ? undefined : isError ? 'error' : 'success';
13
- const char = !shouldAnimate || isBlinking || isError || !isUnresolved
14
- ? BLACK_CIRCLE
15
- : ' ';
44
+ if (isError) {
45
+ return (_jsx(Box, { ref: ref, minWidth: 2, children: _jsx(Text, { color: "error", children: MULTIPLICATION_X }) }));
46
+ }
47
+ const category = CATEGORY_BY_TOOL[toolName ?? ''] ?? 'default';
48
+ const color = isUnresolved ? undefined : CATEGORY_TOKEN[category];
49
+ const char = shouldAnimate ? (isBlinking ? BLACK_CIRCLE : ' ') : BULLET;
16
50
  return (_jsx(Box, { ref: ref, minWidth: 2, children: _jsx(Text, { color: color, dimColor: isUnresolved, children: char }) }));
17
51
  }
@@ -13,7 +13,7 @@ export interface FramePreset {
13
13
  /** Named working-activity frame presets, keyed by preset name (`claude`, `moon`, `sand`, ...). */
14
14
  export declare const FRAME_PRESETS: Record<string, FramePreset>;
15
15
  /** The pi extension's default preset. */
16
- export declare const DEFAULT_PRESET = "moon";
16
+ export declare const DEFAULT_PRESET = "moon8";
17
17
  /** Every selectable preset name, `random` first (the pi selector order). */
18
18
  export declare const PRESET_NAMES: readonly string[];
19
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"activityFrames.d.ts","sourceRoot":"","sources":["../../../src/components/activityFrames.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,kGAAkG;AAClG,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CA6CrD,CAAA;AAED,yCAAyC;AACzC,eAAO,MAAM,cAAc,SAAS,CAAA;AAEpC,4EAA4E;AAC5E,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAA8C,CAAA;AAExF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CASnE"}
1
+ {"version":3,"file":"activityFrames.d.ts","sourceRoot":"","sources":["../../../src/components/activityFrames.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,kGAAkG;AAClG,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAgDrD,CAAA;AAED,yCAAyC;AACzC,eAAO,MAAM,cAAc,UAAU,CAAA;AAErC,4EAA4E;AAC5E,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAA8C,CAAA;AAExF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CASnE"}
@@ -32,6 +32,9 @@ export const FRAME_PRESETS = {
32
32
  },
33
33
  hamburger: { frames: ['☱', '☲', '☴'], intervalMs: 220 },
34
34
  moon: { frames: ['◐', '◓', '◑', '◒'], intervalMs: 240 },
35
+ // kimi-code MoonLoader 同款:8 帧 emoji 月相,120ms 一帧,比半圆版更丝滑。
36
+ // 不带 \uFE0E:保留彩色 emoji 渲染(Windows Terminal 等现代终端效果最佳)。
37
+ moon8: { frames: ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘'], intervalMs: 120 },
35
38
  comet: {
36
39
  frames: ['● ', ' ● ', ' ● ', ' ● ', ' ●', ' ● ', ' ● ', ' ● '],
37
40
  intervalMs: 160,
@@ -55,7 +58,7 @@ export const FRAME_PRESETS = {
55
58
  toggle: { frames: ['⊶', '⊷'], intervalMs: 300 },
56
59
  };
57
60
  /** The pi extension's default preset. */
58
- export const DEFAULT_PRESET = 'moon';
61
+ export const DEFAULT_PRESET = 'moon8';
59
62
  /** Every selectable preset name, `random` first (the pi selector order). */
60
63
  export const PRESET_NAMES = ['random', ...Object.keys(FRAME_PRESETS)];
61
64
  /**
@@ -5,6 +5,10 @@ type Props = {
5
5
  addMargin: boolean;
6
6
  /** True when Ctrl+O transcript/verbose mode is on — show the full text. */
7
7
  verbose: boolean;
8
+ /** Streaming compact mode (thinkingFold=preview): a 3-row live ticker of
9
+ * the model's latest reasoning lines instead of the full block —
10
+ * kimicode-style constant height; the block never resizes mid-stream. */
11
+ preview?: boolean;
8
12
  /** Thinking wall-clock duration once the reasoning block settled (ms). */
9
13
  durationMs?: number;
10
14
  /** Message-selection mode highlight. */
@@ -18,6 +22,6 @@ type Props = {
18
22
  * reasoning duration, the label carries it (`∴ Thinking · 12s …`) — dsh-tui's
19
23
  * take on making thinking time visible in the transcript.
20
24
  */
21
- export declare function AssistantThinkingMessage({ thinking, addMargin, verbose, durationMs, isSelected, onClick, }: Props): React.ReactNode;
25
+ export declare function AssistantThinkingMessage({ thinking, addMargin, verbose, preview, durationMs, isSelected, onClick, }: Props): React.ReactNode;
22
26
  export {};
23
27
  //# sourceMappingURL=AssistantThinkingMessage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAMzB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAuCzB"}
1
+ {"version":3,"file":"AssistantThinkingMessage.d.ts","sourceRoot":"","sources":["../../../../src/components/messages/AssistantThinkingMessage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,SAAS,EAAE,OAAO,CAAA;IAClB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;IAChB;;8EAE0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,OAAO,CAAC,IAAI,IAAI,CAAA;CACjB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,QAAQ,EACR,SAAS,EACT,OAAO,EACP,OAAe,EACf,UAAU,EACV,UAAkB,EAClB,OAAO,GACR,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CAqFzB"}