@deepseek-harness-tui/dsh-tui 0.10.2 → 0.11.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 (351) hide show
  1. package/README.md +175 -123
  2. package/bin/dsh-tui.js +748 -22
  3. package/cordis.patch.yml +42 -13
  4. package/cordis.yml +5 -2
  5. package/lib/types/activityPrefs.d.ts +24 -0
  6. package/lib/types/activityPrefs.d.ts.map +1 -1
  7. package/lib/types/activityPrefs.js +50 -1
  8. package/lib/types/adapter/channel/session-projection.d.ts.map +1 -1
  9. package/lib/types/adapter/channel/session-projection.js +2 -0
  10. package/lib/types/adapter/channel/state.d.ts.map +1 -1
  11. package/lib/types/adapter/channel/state.js +3 -1
  12. package/lib/types/adapter/channel/ui-policy.d.ts +4 -1
  13. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  14. package/lib/types/adapter/channel/ui-policy.js +6 -2
  15. package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -1
  16. package/lib/types/adapter/kernel/host-facade.js +1 -0
  17. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  18. package/lib/types/adapter/kernel/replay.js +3 -0
  19. package/lib/types/adapter/kernel/runtime.d.ts.map +1 -1
  20. package/lib/types/adapter/kernel/runtime.js +2 -0
  21. package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -1
  22. package/lib/types/adapter/kernel/slices/workspace.js +1 -0
  23. package/lib/types/adapter/ports/channel-ui.d.ts +29 -5
  24. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  25. package/lib/types/adapter/ports/channel-view.d.ts +66 -12
  26. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  27. package/lib/types/adapter/ports/channel-workspace.d.ts +23 -0
  28. package/lib/types/adapter/ports/channel-workspace.d.ts.map +1 -1
  29. package/lib/types/adapter/ports/channel.d.ts +4 -1
  30. package/lib/types/adapter/ports/channel.d.ts.map +1 -1
  31. package/lib/types/adapter/ports/workspace.d.ts +2 -0
  32. package/lib/types/adapter/ports/workspace.d.ts.map +1 -1
  33. package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -1
  34. package/lib/types/adapter/upstream/workspace-driver.js +10 -2
  35. package/lib/types/commands.d.ts.map +1 -1
  36. package/lib/types/commands.js +1 -0
  37. package/lib/types/components/ActivityLine.d.ts +7 -2
  38. package/lib/types/components/ActivityLine.d.ts.map +1 -1
  39. package/lib/types/components/ActivityLine.js +0 -8
  40. package/lib/types/components/ContextBarView.d.ts +15 -7
  41. package/lib/types/components/ContextBarView.d.ts.map +1 -1
  42. package/lib/types/components/ContextBarView.js +26 -22
  43. package/lib/types/components/ImagePreviewOverlay.d.ts.map +1 -1
  44. package/lib/types/components/ImagePreviewOverlay.js +11 -5
  45. package/lib/types/components/Markdown.d.ts +11 -1
  46. package/lib/types/components/Markdown.d.ts.map +1 -1
  47. package/lib/types/components/Markdown.js +20 -2
  48. package/lib/types/components/MermaidDiagram.d.ts +13 -0
  49. package/lib/types/components/MermaidDiagram.d.ts.map +1 -0
  50. package/lib/types/components/MermaidDiagram.js +61 -0
  51. package/lib/types/components/MessageList.d.ts +26 -1
  52. package/lib/types/components/MessageList.d.ts.map +1 -1
  53. package/lib/types/components/MessageList.js +74 -8
  54. package/lib/types/components/PageMargin.d.ts +1 -1
  55. package/lib/types/components/PromptInput.d.ts +37 -1
  56. package/lib/types/components/PromptInput.d.ts.map +1 -1
  57. package/lib/types/components/PromptInput.js +291 -30
  58. package/lib/types/components/ScrollbarGutter.d.ts +20 -5
  59. package/lib/types/components/ScrollbarGutter.d.ts.map +1 -1
  60. package/lib/types/components/ScrollbarGutter.js +88 -10
  61. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  62. package/lib/types/components/SplitDiffView.js +2 -1
  63. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  64. package/lib/types/components/StreamingMarkdown.js +30 -28
  65. package/lib/types/components/SubagentCard.d.ts.map +1 -1
  66. package/lib/types/components/SubagentCard.js +12 -6
  67. package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
  68. package/lib/types/components/SubagentDetailScene.js +8 -3
  69. package/lib/types/components/Tooltip.d.ts.map +1 -1
  70. package/lib/types/components/Tooltip.js +45 -7
  71. package/lib/types/components/design-system/HintLine.d.ts +1 -2
  72. package/lib/types/components/design-system/HintLine.d.ts.map +1 -1
  73. package/lib/types/components/design-system/HintLine.js +1 -2
  74. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -1
  75. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  76. package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
  77. package/lib/types/components/messages/AssistantToolUseMessage.d.ts +2 -2
  78. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  79. package/lib/types/components/messages/AssistantToolUseMessage.js +30 -26
  80. package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -1
  81. package/lib/types/components/messages/UserPromptMessage.js +5 -7
  82. package/lib/types/components/messages/useImageInspection.d.ts.map +1 -1
  83. package/lib/types/components/messages/useImageInspection.js +19 -9
  84. package/lib/types/components/promptDraftCache.d.ts +102 -0
  85. package/lib/types/components/promptDraftCache.d.ts.map +1 -0
  86. package/lib/types/components/promptDraftCache.js +76 -0
  87. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +17 -1
  88. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  89. package/lib/types/components/questions/AskUserQuestionPanel.js +40 -7
  90. package/lib/types/components/questions/QuestionMinimizedBar.d.ts +12 -0
  91. package/lib/types/components/questions/QuestionMinimizedBar.d.ts.map +1 -0
  92. package/lib/types/components/questions/QuestionMinimizedBar.js +43 -0
  93. package/lib/types/components/sessions/SessionListRow.d.ts +23 -1
  94. package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -1
  95. package/lib/types/components/sessions/SessionListRow.js +52 -5
  96. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +49 -0
  97. package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -0
  98. package/lib/types/components/workspaces/HomeWorkspaceRow.js +50 -0
  99. package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
  100. package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
  101. package/lib/types/dsh-adapter/activity-store.js +359 -0
  102. package/lib/types/dsh-adapter/bundled-presets.d.ts +10 -0
  103. package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -0
  104. package/lib/types/dsh-adapter/bundled-presets.js +80 -0
  105. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  106. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  107. package/lib/types/dsh-adapter/channel/action-readiness.js +3 -0
  108. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +1 -1
  109. package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -1
  110. package/lib/types/dsh-adapter/channel/agent-view-projection.js +19 -2
  111. package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -1
  112. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  113. package/lib/types/dsh-adapter/channel/background-action.js +53 -29
  114. package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -6
  115. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  116. package/lib/types/dsh-adapter/channel/binding-events.js +5 -4
  117. package/lib/types/dsh-adapter/channel/binding.d.ts +19 -2
  118. package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -1
  119. package/lib/types/dsh-adapter/channel/binding.js +78 -18
  120. package/lib/types/dsh-adapter/channel/compaction.d.ts +0 -1
  121. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  122. package/lib/types/dsh-adapter/channel/compaction.js +0 -2
  123. package/lib/types/dsh-adapter/channel/composer-images.d.ts +5 -0
  124. package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -1
  125. package/lib/types/dsh-adapter/channel/composer-images.js +105 -6
  126. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +8 -0
  127. package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -1
  128. package/lib/types/dsh-adapter/channel/context-bookkeeping.js +3 -2
  129. package/lib/types/dsh-adapter/channel/ide-selection.d.ts +58 -0
  130. package/lib/types/dsh-adapter/channel/ide-selection.d.ts.map +1 -0
  131. package/lib/types/dsh-adapter/channel/ide-selection.js +226 -0
  132. package/lib/types/dsh-adapter/channel/input-delivery.d.ts +6 -1
  133. package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/channel/input-delivery.js +9 -1
  135. package/lib/types/dsh-adapter/channel/local-actions.d.ts +3 -19
  136. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  137. package/lib/types/dsh-adapter/channel/local-actions.js +2 -1
  138. package/lib/types/dsh-adapter/channel/model-actions.d.ts +4 -1
  139. package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
  140. package/lib/types/dsh-adapter/channel/model-actions.js +82 -6
  141. package/lib/types/dsh-adapter/channel/model-switch.d.ts +1 -2
  142. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  143. package/lib/types/dsh-adapter/channel/model-switch.js +49 -31
  144. package/lib/types/dsh-adapter/channel/projection.d.ts +4 -0
  145. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  146. package/lib/types/dsh-adapter/channel/projection.js +29 -19
  147. package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -1
  148. package/lib/types/dsh-adapter/channel/reports.js +4 -12
  149. package/lib/types/dsh-adapter/channel/session-adoption.d.ts +1 -1
  150. package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/session-adoption.js +1 -0
  152. package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -1
  153. package/lib/types/dsh-adapter/channel/session-fork.js +26 -2
  154. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +4 -1
  155. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  156. package/lib/types/dsh-adapter/channel/session-live-adoption.js +2 -0
  157. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +10 -0
  158. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  159. package/lib/types/dsh-adapter/channel/session-metadata.js +6 -4
  160. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  161. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/session-reset.js +0 -1
  163. package/lib/types/dsh-adapter/channel/session-resume.d.ts +12 -3
  164. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/session-resume.js +292 -94
  166. package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -1
  167. package/lib/types/dsh-adapter/channel/session-rewind.js +34 -16
  168. package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -1
  169. package/lib/types/dsh-adapter/channel/session-tree-actions.js +19 -3
  170. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel/settings-host.js +4 -3
  172. package/lib/types/dsh-adapter/channel/state.d.ts +6 -1
  173. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  174. package/lib/types/dsh-adapter/channel/state.js +3 -3
  175. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +21 -1
  176. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  177. package/lib/types/dsh-adapter/channel/subagent-projection.js +173 -6
  178. package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
  179. package/lib/types/dsh-adapter/channel/transcript.js +6 -12
  180. package/lib/types/dsh-adapter/channel/types.d.ts +6 -1
  181. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  182. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +4 -1
  183. package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -1
  184. package/lib/types/dsh-adapter/channel/workspace-actions.js +41 -1
  185. package/lib/types/dsh-adapter/channel.d.ts +1 -1
  186. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  187. package/lib/types/dsh-adapter/channel.js +82 -20
  188. package/lib/types/dsh-adapter/compat/index.d.ts +1 -1
  189. package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -1
  190. package/lib/types/dsh-adapter/compat/index.js +1 -1
  191. package/lib/types/dsh-adapter/compat/messages.d.ts +15 -0
  192. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -0
  193. package/lib/types/dsh-adapter/compat/messages.js +15 -0
  194. package/lib/types/dsh-adapter/compat/sessionLog.d.ts +18 -0
  195. package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -1
  196. package/lib/types/dsh-adapter/compat/sessionLog.js +18 -3
  197. package/lib/types/dsh-adapter/compat/settings.d.ts +35 -0
  198. package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -0
  199. package/lib/types/dsh-adapter/compat/settings.js +57 -0
  200. package/lib/types/dsh-adapter/compat/shell.d.ts +25 -0
  201. package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -0
  202. package/lib/types/dsh-adapter/compat/shell.js +11 -0
  203. package/lib/types/dsh-adapter/contract.d.ts +5 -4
  204. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  205. package/lib/types/dsh-adapter/contract.js +17 -6
  206. package/lib/types/dsh-adapter/ide-channel.d.ts +224 -0
  207. package/lib/types/dsh-adapter/ide-channel.d.ts.map +1 -0
  208. package/lib/types/dsh-adapter/ide-channel.js +556 -0
  209. package/lib/types/dsh-adapter/index.d.ts +18 -3
  210. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  211. package/lib/types/dsh-adapter/index.js +32 -5
  212. package/lib/types/dsh-adapter/plugin.d.ts +4 -1
  213. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  214. package/lib/types/dsh-adapter/plugin.js +197 -49
  215. package/lib/types/dsh-adapter/preset-resolution.d.ts +8 -0
  216. package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -1
  217. package/lib/types/dsh-adapter/preset-resolution.js +10 -0
  218. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts +53 -0
  219. package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/session-mount-heartbeat.js +100 -0
  221. package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -1
  222. package/lib/types/dsh-adapter/sessionTree.js +3 -2
  223. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  224. package/lib/types/dsh-adapter/settings-sections.js +7 -4
  225. package/lib/types/dsh-adapter/subagents.d.ts +16 -3
  226. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  227. package/lib/types/dsh-adapter/subagents.js +92 -29
  228. package/lib/types/dsh-adapter/workspaces.d.ts +46 -3
  229. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  230. package/lib/types/dsh-adapter/workspaces.js +116 -0
  231. package/lib/types/effortPrefs.d.ts +15 -3
  232. package/lib/types/effortPrefs.d.ts.map +1 -1
  233. package/lib/types/effortPrefs.js +37 -3
  234. package/lib/types/history.d.ts +13 -1
  235. package/lib/types/history.d.ts.map +1 -1
  236. package/lib/types/history.js +15 -2
  237. package/lib/types/homePrefs.d.ts +15 -0
  238. package/lib/types/homePrefs.d.ts.map +1 -0
  239. package/lib/types/homePrefs.js +53 -0
  240. package/lib/types/i18n.d.ts +347 -297
  241. package/lib/types/i18n.d.ts.map +1 -1
  242. package/lib/types/i18n.js +133 -85
  243. package/lib/types/ink/colorize.d.ts +10 -0
  244. package/lib/types/ink/colorize.d.ts.map +1 -1
  245. package/lib/types/ink/colorize.js +21 -0
  246. package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
  247. package/lib/types/ink/components/ScrollBox.js +12 -1
  248. package/lib/types/ink/dom.d.ts +1 -0
  249. package/lib/types/ink/dom.d.ts.map +1 -1
  250. package/lib/types/ink/hooks/use-copy-on-select.d.ts +5 -1
  251. package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -1
  252. package/lib/types/ink/hooks/use-copy-on-select.js +15 -1
  253. package/lib/types/ink/ink.d.ts.map +1 -1
  254. package/lib/types/ink/ink.js +36 -1
  255. package/lib/types/ink/log-update.d.ts.map +1 -1
  256. package/lib/types/ink/log-update.js +19 -1
  257. package/lib/types/ink/output.d.ts +10 -1
  258. package/lib/types/ink/output.d.ts.map +1 -1
  259. package/lib/types/ink/output.js +109 -17
  260. package/lib/types/ink/render-border.d.ts +6 -1
  261. package/lib/types/ink/render-border.d.ts.map +1 -1
  262. package/lib/types/ink/render-border.js +25 -9
  263. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  264. package/lib/types/ink/render-node-to-output.js +48 -6
  265. package/lib/types/ink/renderer.d.ts +6 -0
  266. package/lib/types/ink/renderer.d.ts.map +1 -1
  267. package/lib/types/ink/renderer.js +2 -1
  268. package/lib/types/ink/selection.d.ts +88 -0
  269. package/lib/types/ink/selection.d.ts.map +1 -1
  270. package/lib/types/ink/selection.js +164 -0
  271. package/lib/types/ink/sixel-graphics.d.ts +19 -1
  272. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  273. package/lib/types/ink/sixel-graphics.js +124 -12
  274. package/lib/types/ink/terminal-image.d.ts +18 -1
  275. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  276. package/lib/types/ink/terminal.d.ts +17 -0
  277. package/lib/types/ink/terminal.d.ts.map +1 -1
  278. package/lib/types/ink/terminal.js +20 -1
  279. package/lib/types/screens/Chat.d.ts +20 -1
  280. package/lib/types/screens/Chat.d.ts.map +1 -1
  281. package/lib/types/screens/Chat.js +296 -76
  282. package/lib/types/screens/SessionSupervisor.d.ts +84 -0
  283. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -0
  284. package/lib/types/screens/SessionSupervisor.js +350 -0
  285. package/lib/types/screens/SessionTree.js +2 -2
  286. package/lib/types/screens/Settings.d.ts.map +1 -1
  287. package/lib/types/screens/Settings.js +32 -9
  288. package/lib/types/screens/StatusLine.d.ts +18 -1
  289. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  290. package/lib/types/screens/StatusLine.js +38 -19
  291. package/lib/types/screens/StatusMetrics.d.ts +79 -22
  292. package/lib/types/screens/StatusMetrics.d.ts.map +1 -1
  293. package/lib/types/screens/StatusMetrics.js +153 -88
  294. package/lib/types/screens/sessionSupervisor/model.d.ts +83 -0
  295. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -0
  296. package/lib/types/screens/sessionSupervisor/model.js +69 -0
  297. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +120 -0
  298. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -0
  299. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +593 -0
  300. package/lib/types/sessionMounts.d.ts +272 -0
  301. package/lib/types/sessionMounts.d.ts.map +1 -0
  302. package/lib/types/sessionMounts.js +706 -0
  303. package/lib/types/sessions/format.d.ts.map +1 -1
  304. package/lib/types/sessions/format.js +4 -1
  305. package/lib/types/sessions/resumeFailure.d.ts +38 -0
  306. package/lib/types/sessions/resumeFailure.d.ts.map +1 -0
  307. package/lib/types/sessions/resumeFailure.js +58 -0
  308. package/lib/types/terminal-utils/mermaid.d.ts +44 -0
  309. package/lib/types/terminal-utils/mermaid.d.ts.map +1 -0
  310. package/lib/types/terminal-utils/mermaid.js +83 -0
  311. package/lib/types/tips.d.ts.map +1 -1
  312. package/lib/types/tips.js +175 -19
  313. package/lib/types/tuiDisplayPrefs.d.ts +7 -9
  314. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  315. package/lib/types/tuiDisplayPrefs.js +31 -28
  316. package/lib/types/update.d.ts +61 -0
  317. package/lib/types/update.d.ts.map +1 -1
  318. package/lib/types/update.js +194 -0
  319. package/lib/types/utils/fold-long-lines.d.ts +1 -1
  320. package/lib/types/utils/fold-long-lines.js +1 -1
  321. package/lib/types/utils/imageResize.d.ts +90 -0
  322. package/lib/types/utils/imageResize.d.ts.map +1 -0
  323. package/lib/types/utils/imageResize.js +272 -0
  324. package/lib/types/utils/keymap.d.ts +5 -1
  325. package/lib/types/utils/keymap.d.ts.map +1 -1
  326. package/lib/types/utils/keymap.js +23 -0
  327. package/lib/types/working-activity.d.ts +10 -9
  328. package/lib/types/working-activity.d.ts.map +1 -1
  329. package/lib/types/working-activity.js +17 -10
  330. package/lib/types/workspaces.d.ts +2 -1
  331. package/lib/types/workspaces.d.ts.map +1 -1
  332. package/lib/types/workspaces.js +1 -1
  333. package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +10 -10
  334. package/package.json +126 -105
  335. package/presets/liangshen/.dsh-tui-managed.json +1 -1
  336. package/presets/liangshen/agent.cordis.yml +15 -0
  337. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +0 -19
  338. package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +0 -1
  339. package/lib/types/components/design-system/KeyboardShortcutHint.js +0 -14
  340. package/lib/types/dsh-adapter/channel/activity.d.ts +0 -20
  341. package/lib/types/dsh-adapter/channel/activity.d.ts.map +0 -1
  342. package/lib/types/dsh-adapter/channel/activity.js +0 -113
  343. package/lib/types/screens/AgentView.d.ts +0 -23
  344. package/lib/types/screens/AgentView.d.ts.map +0 -1
  345. package/lib/types/screens/AgentView.js +0 -546
  346. package/lib/types/screens/SessionBrowser.d.ts +0 -42
  347. package/lib/types/screens/SessionBrowser.d.ts.map +0 -1
  348. package/lib/types/screens/SessionBrowser.js +0 -911
  349. package/lib/types/terminal-utils/terminal.d.ts +0 -18
  350. package/lib/types/terminal-utils/terminal.d.ts.map +0 -1
  351. package/lib/types/terminal-utils/terminal.js +0 -96
@@ -76,6 +76,37 @@ export type SelectionState = {
76
76
  * were on, xterm.js would have consumed the event for native selection
77
77
  * and we'd never receive it. Used by the footer to show the right hint. */
78
78
  lastPressHadAlt: boolean;
79
+ /** Rolling fingerprint (hash) of the rows under the highlight. Ink's
80
+ * render loop refreshes it every frame; a change between frames
81
+ * WITHOUT a paired follow-shift means screen content was replaced in
82
+ * place under a stationary selection (a streaming transcript
83
+ * overwriting the rows the highlight covers), and a copy from these
84
+ * coordinates would read whatever text now sits there — not what the
85
+ * user highlighted. Null until the first frame observes the
86
+ * selection. */
87
+ coveredFingerprint: number | null;
88
+ /** The text `getSelectedText` emitted for `coveredFingerprint`'s frame.
89
+ * The fingerprint is a cheap per-frame pre-filter: it hashes the covered
90
+ * cells plus the two soft-wrap inputs that decide how those cells lay out,
91
+ * so it can move while the COPIED TEXT stays byte-identical (flipping the
92
+ * next row's wrap bit from 0 to a value past the selection's last column
93
+ * only toggles trailing-blank trimming, which is invisible when the
94
+ * selected columns are already full). Judging staleness on that hash alone
95
+ * refused legitimate copies — "content under the selection changed; copy
96
+ * cancelled" while a streaming tail wrote somewhere else entirely. The
97
+ * verdict therefore re-checks the emitted text, exactly the bytes the copy
98
+ * would ship, and only latches when THEY differ. Null until baselined. */
99
+ coveredText: string | null;
100
+ /** Geometry key (start/end row:col) the fingerprint was taken at. Any
101
+ * user-driven geometry change (drag motion, word/line extension,
102
+ * keyboard pan, multi-click) re-baselines instead of judging — the
103
+ * guard only ever indicts a STATIONARY highlight whose text was
104
+ * swapped underneath. Owned by refreshSelectionFingerprint. */
105
+ coveredGeometry: string | null;
106
+ /** Sticky once the covered rows changed without follow coordination.
107
+ * Commit-time copy (copySelectionNoClear) refuses and clears instead
108
+ * of shipping the replaced text. Cleared on start/clear. */
109
+ stale: boolean;
79
110
  };
80
111
  /**
81
112
  * Create a new selection state with no active selection.
@@ -379,6 +410,63 @@ export declare function selectionBounds(s: SelectionState): {
379
410
  * @returns true when the cell lies inside the selection range.
380
411
  */
381
412
  export declare function isCellSelected(s: SelectionState, col: number, row: number): boolean;
413
+ /**
414
+ * Rehash the rows under the highlight and latch `stale` when they changed
415
+ * without a coordinated shift this frame.
416
+ *
417
+ * Copy reads whatever text occupies the highlight's screen coordinates at
418
+ * commit time. When the transcript REPLACES those rows in place while the
419
+ * highlight sits still (streaming output overwriting folded rows, a card
420
+ * collapsing under the anchor), the copied text is whatever moved in —
421
+ * visibly wrong text, not mojibake from a width bug. The follow/resize
422
+ * shifts keep the highlight anchored to text that MOVES; this guard catches
423
+ * the complementary case: stationary coordinates, moving content.
424
+ *
425
+ * Called once per rendered frame (post-render, pre-swap) on the frame the
426
+ * copy would read. The hash covers every visible cell of every covered row
427
+ * (same visibility rules as getSelectedText: noSelect and spacer cells
428
+ * skipped) via the cell's TEXT — `charPool.get(charId)` — not its pool
429
+ * index, plus the two soft-wrap inputs that decide how those cells are laid
430
+ * out into lines (the row's own `softWrap[row]`, and the `softWrap[row + 1]`
431
+ * extractRowText reads as this row's content end). styleId is excluded so
432
+ * the selection overlay and syntax highlighting themselves cannot trip the
433
+ * guard.
434
+ *
435
+ * Why content and not charId: a charId is an index into a generational
436
+ * CharPool, not a stable identity. Ink.resetPools() (ink.tsx) swaps in a
437
+ * fresh CharPool every ~5 minutes and re-interns the front frame through
438
+ * migrateScreenPools, so the SAME glyph comes back under a different
439
+ * number. Hashing ids would read that renumbering as "the covered rows
440
+ * changed" and refuse a perfectly legitimate copy with the stale-content
441
+ * notice — a false positive on a screen where nothing was replaced. The
442
+ * pool lookup is an array index plus a 1-2 code-unit hash loop, measured
443
+ * at ~0.05ms for a full 200x50 selection (~0.14ms at 200x200), i.e. no
444
+ * worse than hashing the ids themselves.
445
+ *
446
+ * The hash is only a PRE-FILTER; the verdict is the copied text. Hashing the
447
+ * wrap inputs keeps a cheap screen-signature, but those inputs can move while
448
+ * the bytes a copy would ship stay identical: flipping the next row's wrap bit
449
+ * from 0 to a value past the selection's last column only toggles
450
+ * trailing-blank trimming, which is invisible when the selected columns are
451
+ * already full (measured live: a streaming tail wrote a row far below the
452
+ * highlight, the wrap bookkeeping moved, and the guard refused a legitimate
453
+ * copy — the "content under the selection changed" toast with the highlight
454
+ * still sitting on exactly the right text). So when the hash moves, this
455
+ * compares `getSelectedText` against the baselined text and latches only when
456
+ * THE BYTES differ — the same expression the copy itself ships, which makes
457
+ * the verdict complete (no real replacement is missed) and sound (no
458
+ * unchanged text is refused). The text is compared, not stored per frame: the
459
+ * extraction runs on a geometry change (once per drag motion) and on a
460
+ * suspected change, never on the steady-state frame.
461
+ *
462
+ * @param s - the selection state to fingerprint.
463
+ * @param screen - the frame's screen buffer.
464
+ * @param coordinated - true when this frame translated the selection
465
+ * endpoints (follow-shift or viewport resize); a fingerprint change in
466
+ * such a frame is the expected content scroll, not an overwrite.
467
+ * @returns true when an uncoordinated change latched `stale` this call.
468
+ */
469
+ export declare function refreshSelectionFingerprint(s: SelectionState, screen: Screen, coordinated: boolean): boolean;
382
470
  /**
383
471
  * Extract text from the screen buffer within the selection range.
384
472
  * Rows are joined with newlines unless the screen's softWrap bitmap
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/ink/selection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/ink/selection.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,10 @@ export function createSelectionState() {
26
26
  scrolledOffAboveSW: [],
27
27
  scrolledOffBelowSW: [],
28
28
  lastPressHadAlt: false,
29
+ coveredFingerprint: null,
30
+ coveredText: null,
31
+ coveredGeometry: null,
32
+ stale: false,
29
33
  };
30
34
  }
31
35
  /**
@@ -52,6 +56,10 @@ export function startSelection(s, col, row) {
52
56
  s.virtualFocusRow = undefined;
53
57
  s.dragBounds = undefined;
54
58
  s.lastPressHadAlt = false;
59
+ s.coveredFingerprint = null;
60
+ s.coveredText = null;
61
+ s.coveredGeometry = null;
62
+ s.stale = false;
55
63
  }
56
64
  /**
57
65
  * Track the drag position: update focus to (col, row). No-op while not
@@ -120,6 +128,10 @@ export function clearSelection(s) {
120
128
  s.virtualFocusRow = undefined;
121
129
  s.dragBounds = undefined;
122
130
  s.lastPressHadAlt = false;
131
+ s.coveredFingerprint = null;
132
+ s.coveredText = null;
133
+ s.coveredGeometry = null;
134
+ s.stale = false;
123
135
  }
124
136
  // Unicode-aware word character matcher: letters (any script), digits,
125
137
  // and the punctuation set iTerm2 treats as word-part by default.
@@ -969,6 +981,158 @@ function joinRows(lines, text, sw) {
969
981
  lines.push(text);
970
982
  }
971
983
  }
984
+ /**
985
+ * Rehash the rows under the highlight and latch `stale` when they changed
986
+ * without a coordinated shift this frame.
987
+ *
988
+ * Copy reads whatever text occupies the highlight's screen coordinates at
989
+ * commit time. When the transcript REPLACES those rows in place while the
990
+ * highlight sits still (streaming output overwriting folded rows, a card
991
+ * collapsing under the anchor), the copied text is whatever moved in —
992
+ * visibly wrong text, not mojibake from a width bug. The follow/resize
993
+ * shifts keep the highlight anchored to text that MOVES; this guard catches
994
+ * the complementary case: stationary coordinates, moving content.
995
+ *
996
+ * Called once per rendered frame (post-render, pre-swap) on the frame the
997
+ * copy would read. The hash covers every visible cell of every covered row
998
+ * (same visibility rules as getSelectedText: noSelect and spacer cells
999
+ * skipped) via the cell's TEXT — `charPool.get(charId)` — not its pool
1000
+ * index, plus the two soft-wrap inputs that decide how those cells are laid
1001
+ * out into lines (the row's own `softWrap[row]`, and the `softWrap[row + 1]`
1002
+ * extractRowText reads as this row's content end). styleId is excluded so
1003
+ * the selection overlay and syntax highlighting themselves cannot trip the
1004
+ * guard.
1005
+ *
1006
+ * Why content and not charId: a charId is an index into a generational
1007
+ * CharPool, not a stable identity. Ink.resetPools() (ink.tsx) swaps in a
1008
+ * fresh CharPool every ~5 minutes and re-interns the front frame through
1009
+ * migrateScreenPools, so the SAME glyph comes back under a different
1010
+ * number. Hashing ids would read that renumbering as "the covered rows
1011
+ * changed" and refuse a perfectly legitimate copy with the stale-content
1012
+ * notice — a false positive on a screen where nothing was replaced. The
1013
+ * pool lookup is an array index plus a 1-2 code-unit hash loop, measured
1014
+ * at ~0.05ms for a full 200x50 selection (~0.14ms at 200x200), i.e. no
1015
+ * worse than hashing the ids themselves.
1016
+ *
1017
+ * The hash is only a PRE-FILTER; the verdict is the copied text. Hashing the
1018
+ * wrap inputs keeps a cheap screen-signature, but those inputs can move while
1019
+ * the bytes a copy would ship stay identical: flipping the next row's wrap bit
1020
+ * from 0 to a value past the selection's last column only toggles
1021
+ * trailing-blank trimming, which is invisible when the selected columns are
1022
+ * already full (measured live: a streaming tail wrote a row far below the
1023
+ * highlight, the wrap bookkeeping moved, and the guard refused a legitimate
1024
+ * copy — the "content under the selection changed" toast with the highlight
1025
+ * still sitting on exactly the right text). So when the hash moves, this
1026
+ * compares `getSelectedText` against the baselined text and latches only when
1027
+ * THE BYTES differ — the same expression the copy itself ships, which makes
1028
+ * the verdict complete (no real replacement is missed) and sound (no
1029
+ * unchanged text is refused). The text is compared, not stored per frame: the
1030
+ * extraction runs on a geometry change (once per drag motion) and on a
1031
+ * suspected change, never on the steady-state frame.
1032
+ *
1033
+ * @param s - the selection state to fingerprint.
1034
+ * @param screen - the frame's screen buffer.
1035
+ * @param coordinated - true when this frame translated the selection
1036
+ * endpoints (follow-shift or viewport resize); a fingerprint change in
1037
+ * such a frame is the expected content scroll, not an overwrite.
1038
+ * @returns true when an uncoordinated change latched `stale` this call.
1039
+ */
1040
+ export function refreshSelectionFingerprint(s, screen, coordinated) {
1041
+ if (s.stale)
1042
+ return false;
1043
+ const b = selectionBounds(s);
1044
+ if (!b) {
1045
+ s.coveredFingerprint = null;
1046
+ s.coveredText = null;
1047
+ s.coveredGeometry = null;
1048
+ return false;
1049
+ }
1050
+ // Any geometry change re-baselines: drag motion, word/line extension,
1051
+ // keyboard pan, multi-click — the user redefined what is highlighted, so
1052
+ // the next copy legitimately reads the new band's CURRENT text. Only a
1053
+ // stationary highlight can go stale.
1054
+ const geometry = `${b.start.row}:${b.start.col}-${b.end.row}:${b.end.col}`;
1055
+ if (geometry !== s.coveredGeometry) {
1056
+ s.coveredGeometry = geometry;
1057
+ s.coveredFingerprint = null;
1058
+ s.coveredText = null;
1059
+ }
1060
+ const { cells, noSelect, width, height, charPool, softWrap } = screen;
1061
+ let h = 0x811c9dc5;
1062
+ for (let row = b.start.row; row <= b.end.row; row++) {
1063
+ if (row < 0 || row >= height)
1064
+ continue;
1065
+ const rowOff = row * width;
1066
+ // Column bounds mirror getSelectedText exactly: the boundary rows hash
1067
+ // only from start.col / through end.col. Streaming text appended to a
1068
+ // covered row OUTSIDE the selected column range (stable head selected,
1069
+ // live tail still writing) must not latch stale — the copy would not
1070
+ // read those columns anyway.
1071
+ const colStart = row === b.start.row ? b.start.col : 0;
1072
+ const colEnd = row === b.end.row ? b.end.col : width - 1;
1073
+ for (let col = colStart; col <= colEnd; col++) {
1074
+ const ci = (rowOff + col) * 2;
1075
+ // word1's low 2 bits are the cell width; SpacerTail/SpacerHead carry
1076
+ // no text of their own.
1077
+ if ((cells[ci + 1] & 3) >= 2 /* CellWidth.SpacerTail */)
1078
+ continue;
1079
+ if (noSelect[rowOff + col] === 1)
1080
+ continue;
1081
+ // Resolve the id through the pool and hash the actual characters —
1082
+ // the exact string getSelectedText would emit for this cell. Two
1083
+ // pools holding the same glyph hash identically, so a generational
1084
+ // pool swap is invisible here; a different glyph is not.
1085
+ const ch = charPool.get(cells[ci]);
1086
+ for (let k = 0; k < ch.length; k++) {
1087
+ h = Math.imul(h ^ ch.charCodeAt(k), 0x01000193);
1088
+ }
1089
+ }
1090
+ // Row separator + the row's soft-wrap bit: getSelectedText joins a
1091
+ // wrapped row onto the previous line with NO newline (softWrap[row]>0)
1092
+ // but emits a real newline otherwise — identical cells with a flipped
1093
+ // wrap bit produce a different copy, so the fingerprint must see it.
1094
+ h = Math.imul(h ^ 0x9e3779b9 ^ (softWrap[row] > 0 ? 0x51ed270b : 0), 0x85ebca6b);
1095
+ // The row BELOW is an input to THIS row's copy. extractRowText reads
1096
+ // softWrap[row + 1] as this row's content end: > 0 means the row wraps
1097
+ // into the next one, which both clamps the last column to
1098
+ // min(colEnd, contentEnd - 1) and suppresses the trailing-blank trim.
1099
+ // Flipping only the next row's wrap bit therefore rewrites the last
1100
+ // covered line's trailing columns ("A" → "A ") with every
1101
+ // covered CELL unchanged — the guard has to see the wrap, not just the
1102
+ // cells. Hash exactly what extractRowText consumes (0 = not wrapped) so
1103
+ // a contentEnd change that does not move the clamp stays invisible
1104
+ // instead of becoming a false positive.
1105
+ const contentEnd = row + 1 < height ? softWrap[row + 1] : 0;
1106
+ const wrapClamp = contentEnd > 0 ? Math.min(colEnd, contentEnd - 1) + 1 : 0;
1107
+ h = Math.imul(h ^ 0x27d4eb2f ^ wrapClamp, 0x165667b1);
1108
+ }
1109
+ if (s.coveredFingerprint === null) {
1110
+ // First frame observing this selection: baseline, no verdict. The text is
1111
+ // captured here too — it is the ground truth the next hash change is
1112
+ // judged against, and it can only be read while the baselined frame is
1113
+ // still on screen.
1114
+ s.coveredFingerprint = h;
1115
+ s.coveredText = getSelectedText(s, screen);
1116
+ return false;
1117
+ }
1118
+ if (h === s.coveredFingerprint)
1119
+ return false;
1120
+ // The hash moved: decide on the emitted text, not on the hash. A wrap-bit
1121
+ // flip below the selection (or any other term that does not change the
1122
+ // bytes the copy would ship) must not refuse a legitimate copy.
1123
+ const text = getSelectedText(s, screen);
1124
+ if (text === s.coveredText) {
1125
+ // Same bytes, different layout bookkeeping: accept and re-baseline.
1126
+ s.coveredFingerprint = h;
1127
+ return false;
1128
+ }
1129
+ s.coveredFingerprint = h;
1130
+ s.coveredText = text;
1131
+ if (coordinated)
1132
+ return false;
1133
+ s.stale = true;
1134
+ return true;
1135
+ }
972
1136
  /**
973
1137
  * Extract text from the screen buffer within the selection range.
974
1138
  * Rows are joined with newlines unless the screen's softWrap bitmap
@@ -19,6 +19,8 @@ export declare class SixelGraphicsManager {
19
19
  private desired;
20
20
  private displayed;
21
21
  private nextDisplay;
22
+ /** Rects kept on screen this frame (replacement pending or covered). */
23
+ private readonly held;
22
24
  private readonly repaint;
23
25
  private worker;
24
26
  private workerKeys;
@@ -35,7 +37,23 @@ export declare class SixelGraphicsManager {
35
37
  beginFrame(columns: number, rows: number): void;
36
38
  readonly prepare: (placement: TerminalImagePlacement) => boolean;
37
39
  private variant;
38
- /** Reconcile ALL old rectangles before diffing, with only one baseline copy. */
40
+ /**
41
+ * Reconcile ALL old rectangles before diffing, with only one baseline copy.
42
+ *
43
+ * A rect is erased only when this frame replaces it (a ready raster at a new
44
+ * key/geometry, erased and drawn in the same write) or drops it entirely.
45
+ * Rects whose replacement is still being encoded, or which a later paint
46
+ * covers, are held: erasing them without drawing a replacement in the same
47
+ * frame is exactly the black flash seen while scrolling and the vanishing
48
+ * image under an overlay. {@link paint} folds the held rects back into
49
+ * `displayed`, and the frame that finally replaces one forces a repaint
50
+ * through the `held` marker.
51
+ *
52
+ * A held rect that an overlay PARTLY covers still has to give up the covered
53
+ * cells: its pixels outlive cell writes (a background-only space cell diffs
54
+ * as unchanged, so the frame never rewrites it) and would show through the
55
+ * overlay. Those sub-rects are erased with the placement's surface color.
56
+ */
39
57
  reconcile(screen: Screen, previous: Screen, placements?: readonly TerminalImagePlacement[]): {
40
58
  erase: string;
41
59
  baseline: Screen;
@@ -1 +1 @@
1
- {"version":3,"file":"sixel-graphics.d.ts","sourceRoot":"","sources":["../../../src/ink/sixel-graphics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAA2C,MAAM,kBAAkB,CAAA;AAChH,OAAO,EAIL,KAAK,gBAAgB,EAAE,KAAK,sBAAsB,EACnD,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAatC,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;AAOpE,oFAAoF;AACpF,qBAAa,oBAAoB;IAuBnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAc,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAtB3E,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoC;IACxD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAC9D,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,IAAI,CAAI;IAChB,OAAO,CAAC,cAAc,CAAQ;gBAED,OAAO,EAAE,MAAM,IAAI,EAAmB,OAAO,CAAC,EAAE,OAAO,YAAA;IAEpF,IAAI,QAAQ,IAAI,OAAO,CAAgE;IAEvF,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKtC,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO;IAQ5C,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAO/C,QAAQ,CAAC,OAAO,GAAI,WAAW,sBAAsB,KAAG,OAAO,CAc9D;IAED,OAAO,CAAC,OAAO;IAgDf,gFAAgF;IAChF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IA6ChI,iFAAiF;IACjF,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAgBzB,aAAa,IAAI,IAAI;IAErB,KAAK,IAAI,MAAM;IAUf,OAAO,IAAI,MAAM;IAajB,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,cAAc;CAkEvB"}
1
+ {"version":3,"file":"sixel-graphics.d.ts","sourceRoot":"","sources":["../../../src/ink/sixel-graphics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAA2C,MAAM,kBAAkB,CAAA;AAChH,OAAO,EAIL,KAAK,gBAAgB,EAAE,KAAK,sBAAsB,EACnD,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAuB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAwBtC,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAA;AAiBpE,oFAAoF;AACpF,qBAAa,oBAAoB;IAyBnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAc,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IAxB3E,OAAO,CAAC,IAAI,CAA+C;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoC;IACxD,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAwC;IAC9D,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,WAAW,CAAmC;IACtD,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,IAAI,CAAI;IAChB,OAAO,CAAC,cAAc,CAAQ;gBAED,OAAO,EAAE,MAAM,IAAI,EAAmB,OAAO,CAAC,EAAE,OAAO,YAAA;IAEpF,IAAI,QAAQ,IAAI,OAAO,CAAgE;IAEvF,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKtC,WAAW,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO;IAQ5C,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAO/C,QAAQ,CAAC,OAAO,GAAI,WAAW,sBAAsB,KAAG,OAAO,CAc9D;IAED,OAAO,CAAC,OAAO;IAgDf;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,SAAS,sBAAsB,EAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAwGhI,iFAAiF;IACjF,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAmBzB,aAAa,IAAI,IAAI;IAErB,KAAK,IAAI,MAAM;IAWf,OAAO,IAAI,MAAM;IAajB,OAAO,CAAC,KAAK;IAiBb,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,UAAU;IAwBlB,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,cAAc;CAkEvB"}
@@ -2,10 +2,21 @@ import { Worker } from 'node:worker_threads';
2
2
  import { DEFAULT_TERMINAL_CELL_SIZE, normalizeTerminalCellSize, TERMINAL_IMAGE_MAX_EDGE, TERMINAL_IMAGE_MAX_BYTES, TERMINAL_IMAGE_PREVIEW_MAX_EDGE, TERMINAL_IMAGE_PREVIEW_MAX_BYTES, SIXEL_MAX_ENCODED_BYTES, SIXEL_THUMBNAIL_FRAME_BYTES, SIXEL_CACHE_BYTES, SIXEL_CACHE_ENTRIES, } from './terminal-image.js';
3
3
  import { cellAt, clearRegion } from './screen.js';
4
4
  import { stringWidth } from './stringWidth.js';
5
+ import { backgroundOpenCode } from './colorize.js';
5
6
  function overlaps(a, b) {
6
7
  return a.x < b.x + b.columns && a.x + a.columns > b.x &&
7
8
  a.y < b.y + b.rows && a.y + a.rows > b.y;
8
9
  }
10
+ /** Intersection of two cell rects, or undefined when they do not overlap. */
11
+ function intersectRects(a, b) {
12
+ const x = Math.max(a.x, b.x);
13
+ const y = Math.max(a.y, b.y);
14
+ const right = Math.min(a.x + a.columns, b.x + b.columns);
15
+ const bottom = Math.min(a.y + a.rows, b.y + b.rows);
16
+ if (right <= x || bottom <= y)
17
+ return undefined;
18
+ return { x, y, columns: right - x, rows: bottom - y };
19
+ }
9
20
  /** Viewport-owned pixels. Encoding is shared; placement/erasure is per DOM node. */
10
21
  export class SixelGraphicsManager {
11
22
  onReady;
@@ -22,6 +33,8 @@ export class SixelGraphicsManager {
22
33
  desired = new Set();
23
34
  displayed = new Map();
24
35
  nextDisplay = new Map();
36
+ /** Rects kept on screen this frame (replacement pending or covered). */
37
+ held = new Map();
25
38
  repaint = new Set();
26
39
  worker;
27
40
  workerKeys = new Set();
@@ -119,22 +132,59 @@ export class SixelGraphicsManager {
119
132
  crop: { left, top, width: cropWidth, height: cropHeight } },
120
133
  };
121
134
  }
122
- /** Reconcile ALL old rectangles before diffing, with only one baseline copy. */
135
+ /**
136
+ * Reconcile ALL old rectangles before diffing, with only one baseline copy.
137
+ *
138
+ * A rect is erased only when this frame replaces it (a ready raster at a new
139
+ * key/geometry, erased and drawn in the same write) or drops it entirely.
140
+ * Rects whose replacement is still being encoded, or which a later paint
141
+ * covers, are held: erasing them without drawing a replacement in the same
142
+ * frame is exactly the black flash seen while scrolling and the vanishing
143
+ * image under an overlay. {@link paint} folds the held rects back into
144
+ * `displayed`, and the frame that finally replaces one forces a repaint
145
+ * through the `held` marker.
146
+ *
147
+ * A held rect that an overlay PARTLY covers still has to give up the covered
148
+ * cells: its pixels outlive cell writes (a background-only space cell diffs
149
+ * as unchanged, so the frame never rewrites it) and would show through the
150
+ * overlay. Those sub-rects are erased with the placement's surface color.
151
+ */
123
152
  reconcile(screen, previous, placements) {
124
153
  const actual = placements ? new Map(placements.map(p => [p.node, p])) : undefined;
125
154
  const visible = [];
126
155
  this.desired = new Set();
127
156
  this.nextDisplay.clear();
157
+ this.held.clear();
128
158
  this.repaint.clear();
159
+ // Nodes whose raster this frame drops (the paint no longer registers an
160
+ // image, or a later paint covers every visible cell): their pixels must be
161
+ // erased, unlike the ones merely held below.
162
+ const dropped = new Set();
129
163
  for (const [node, variant] of this.frame) {
130
164
  const placement = actual?.get(node);
131
- if ((actual && !placement) || placement?.occluded)
165
+ if (actual && !placement) {
166
+ dropped.add(node);
167
+ continue;
168
+ }
169
+ if (placement?.occludedFully) {
170
+ dropped.add(node);
132
171
  continue;
172
+ }
133
173
  visible.push(variant);
134
174
  this.desired.add(variant.key);
175
+ // Partially covered: drawing would pierce the overlay that covers it, so
176
+ // keep the pixels already on screen and wait for the cover to clear.
177
+ if (placement?.occluded)
178
+ continue;
135
179
  const raster = this.cache.get(variant.key);
136
180
  if (variant.ready && raster && placement?.graphicsReady !== false && this.isUncovered(variant.rect, screen)) {
137
- this.nextDisplay.set(node, { ...variant.rect, key: variant.key, raster });
181
+ const background = variant.placement.background;
182
+ this.nextDisplay.set(node, {
183
+ ...variant.rect,
184
+ key: variant.key,
185
+ raster,
186
+ ...(background === undefined ? {} : { background }),
187
+ });
138
188
  }
139
189
  }
140
190
  const unique = new Map();
@@ -145,27 +195,71 @@ export class SixelGraphicsManager {
145
195
  this.pending = [...unique.values()].sort((a, b) => Number(b.placement.presentation === 'preview') - Number(a.placement.presentation === 'preview'));
146
196
  this.drain();
147
197
  const erased = [];
198
+ let coverErase = '';
148
199
  for (const [node, old] of this.displayed) {
149
200
  const next = this.nextDisplay.get(node);
150
- if (!next || this.dirty || old.key !== next.key || old.x !== next.x || old.y !== next.y)
151
- erased.push(old);
201
+ if (next !== undefined) {
202
+ if (this.dirty || old.key !== next.key || old.x !== next.x || old.y !== next.y)
203
+ erased.push(old);
204
+ continue;
205
+ }
206
+ // Still requested this frame, but its replacement raster is not ready
207
+ // (scrolling re-crops per row and the encoder is async) or a later paint
208
+ // covers it. Erasing here would leave a hole with no draw in the same
209
+ // frame — the black flash while scrolling and the vanishing image under
210
+ // a tooltip. Keep the pixels already on screen until a replacement can
211
+ // be drawn in the same write.
212
+ if (!this.dirty && this.frame.has(node) && !dropped.has(node)) {
213
+ const placement = actual?.get(node);
214
+ const coveredRects = placement?.coveredRects;
215
+ const coveredKey = coveredRects === undefined || coveredRects.length === 0
216
+ ? undefined
217
+ : coveredRects.map(rect => `${rect.x},${rect.y},${rect.width},${rect.height}`).join(';');
218
+ if (coveredKey !== undefined && coveredKey !== old.covered) {
219
+ // The overlay paints these cells, but only the ones whose style
220
+ // changes get a write: an unchanged background-only space keeps the
221
+ // raster's pixels. Erase the covered cells (with the surface color,
222
+ // so they match the cell model) and leave the rest held.
223
+ const visibleRect = { x: old.x, y: old.y, columns: old.columns, rows: old.rows };
224
+ for (const rect of coveredRects) {
225
+ const clipped = intersectRects(visibleRect, { x: rect.x, y: rect.y, columns: rect.width, rows: rect.height });
226
+ if (clipped !== undefined)
227
+ coverErase += this.erase(clipped, old.background);
228
+ }
229
+ }
230
+ this.held.set(node, coveredKey === undefined
231
+ ? { ...old, held: true }
232
+ : { ...old, held: true, covered: coveredKey });
233
+ continue;
234
+ }
235
+ erased.push(old);
152
236
  }
153
237
  for (const [node, next] of this.nextDisplay) {
154
238
  const old = this.displayed.get(node);
155
- if (!old || this.dirty || old.key !== next.key || old.x !== next.x || old.y !== next.y ||
239
+ if (!old || this.dirty || old.held === true ||
240
+ old.key !== next.key || old.x !== next.x || old.y !== next.y ||
156
241
  erased.some(rect => overlaps(rect, next)))
157
242
  this.repaint.add(node);
158
243
  }
159
- if (erased.length === 0)
160
- return { erase: '', baseline: previous };
244
+ if (erased.length === 0) {
245
+ return coverErase === ''
246
+ ? { erase: '', baseline: previous }
247
+ : { erase: coverErase + '\x1b[H', baseline: previous };
248
+ }
161
249
  const cells = previous.cells.slice();
162
250
  const baseline = { ...previous, cells, cells64: new BigInt64Array(cells.buffer), noSelect: previous.noSelect.slice() };
163
251
  let erase = '';
164
252
  for (const rect of erased) {
165
253
  clearRegion(baseline, rect.x, rect.y, rect.columns, rect.rows);
254
+ // Erase at the terminal default, never at the placement's surface color:
255
+ // clearRegion just reset these cells to a default blank in the model, so
256
+ // the frame writes back everything it has to show and leaves the rest
257
+ // alone — an erase filled with the surface color would keep that color
258
+ // on screen with no write to correct it (the white card of a closed
259
+ // light-theme preview, cleared only when unrelated text scrolls past).
166
260
  erase += this.erase(rect);
167
261
  }
168
- return { erase: erase + '\x1b[H', baseline };
262
+ return { erase: coverErase + erase + '\x1b[H', baseline };
169
263
  }
170
264
  /** Unchanged images have zero transport cost, including unrelated text ticks. */
171
265
  paint(diff) {
@@ -181,6 +275,10 @@ export class SixelGraphicsManager {
181
275
  draw += `\x1b[${next.y + 1};${next.x + 1}H${next.raster.data}`;
182
276
  }
183
277
  this.displayed = new Map(this.nextDisplay);
278
+ // Rects held this frame stay on screen: they were neither erased nor
279
+ // redrawn, so the terminal still shows them.
280
+ for (const [node, entry] of this.held)
281
+ this.displayed.set(node, entry);
184
282
  this.dirty = false;
185
283
  if (draw === '')
186
284
  return '';
@@ -191,6 +289,7 @@ export class SixelGraphicsManager {
191
289
  const output = [...this.displayed.values()].map(rect => this.erase(rect)).join('');
192
290
  this.displayed.clear();
193
291
  this.nextDisplay.clear();
292
+ this.held.clear();
194
293
  this.frame.clear();
195
294
  this.desired.clear();
196
295
  this.pending = [];
@@ -208,21 +307,34 @@ export class SixelGraphicsManager {
208
307
  this.workerKeys.clear();
209
308
  return output;
210
309
  }
211
- erase(rect) {
310
+ erase(rect, background) {
212
311
  const columns = Math.min(rect.columns, this.columns - rect.x);
213
312
  const rows = Math.min(rect.rows, this.rows - rect.y);
214
313
  if (columns <= 0 || rows <= 0)
215
314
  return '';
216
- let data = '\x1b[0m';
315
+ // Erase-Character fills with the cell's current background and is the only
316
+ // way to drop pixels a frame never rewrites. The surface color is for the
317
+ // one rect the frame cannot correct afterwards — cells a later paint
318
+ // covers while keeping their style (see reconcile); every caller that
319
+ // hands those cells back to the diff passes no color.
320
+ // The placement carries the raw color string; Color is its renderer form.
321
+ const open = background === undefined ? '' : backgroundOpenCode(background);
322
+ let data = `\x1b[0m${open}`;
217
323
  for (let y = rect.y; y < rect.y + rows; y++)
218
324
  data += `\x1b[${y + 1};${rect.x + 1}H\x1b[${columns}X`;
325
+ if (open !== '')
326
+ data += '\x1b[0m';
219
327
  return data;
220
328
  }
221
329
  isUncovered(rect, screen) {
330
+ // Any visible glyph under the raster blocks it; background-only cells do
331
+ // not. Image-owned cells carry the surface background in Sixel mode (an
332
+ // opaque backing is required there), and comparing against the empty
333
+ // style would reject the raster's own backing.
222
334
  for (let y = rect.y; y < rect.y + rect.rows; y++) {
223
335
  for (let x = rect.x; x < rect.x + rect.columns; x++) {
224
336
  const cell = cellAt(screen, x, y);
225
- if (cell && (cell.char !== ' ' || cell.styleId !== screen.emptyStyleId))
337
+ if (cell && cell.char !== ' ' && cell.char !== '')
226
338
  return false;
227
339
  }
228
340
  }
@@ -1,4 +1,5 @@
1
1
  import type { DOMElement } from './dom.js';
2
+ import type { Rectangle } from './layout/geometry.js';
2
3
  /** Hard bounds for one decoded image admitted to the terminal renderer. */
3
4
  export declare const TERMINAL_IMAGE_MAX_EDGE = 1024;
4
5
  export declare const TERMINAL_IMAGE_MAX_BYTES: number;
@@ -60,8 +61,24 @@ export interface TerminalImagePlacement {
60
61
  readonly background?: string;
61
62
  /** False while a protocol-specific raster is pending or unavailable. */
62
63
  readonly graphicsReady?: boolean;
63
- /** Later paint operations cover this backing, including blank overlays. */
64
+ /** Later paint operations cover part of this raster's visible cells. */
64
65
  readonly occluded?: boolean;
66
+ /**
67
+ * Later paint operations cover every visible cell of this raster, so it is
68
+ * unreachable and must be erased rather than kept (a blank `opaque` overlay
69
+ * would otherwise be pierced by the pixels beneath it). Partial coverage
70
+ * sets {@link occluded} only.
71
+ */
72
+ readonly occludedFully?: boolean;
73
+ /**
74
+ * The later paint operations that cover PART of this raster, in absolute
75
+ * screen cells. A protocol whose pixels outlive cell writes must erase these
76
+ * rects itself: with Sixel, a background-only space cell over the raster has
77
+ * the same style as the image's own backing cell, so the frame diff emits no
78
+ * write for it and the old pixels keep showing through the overlay (the white
79
+ * block between "100%" and "原像素" in a preview tooltip).
80
+ */
81
+ readonly coveredRects?: readonly Rectangle[];
65
82
  }
66
83
  /**
67
84
  * Normalize terminal-reported cell pixels before they reach allocation math.
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-image.d.ts","sourceRoot":"","sources":["../../../src/ink/terminal-image.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminal-image.d.ts","sourceRoot":"","sources":["../../../src/ink/terminal-image.ts"],"names":[],"mappings":"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"}