@deepseek-harness-tui/dsh-tui 0.11.1 → 0.11.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 (427) hide show
  1. package/README.md +50 -20
  2. package/assets/whale-girl/whale-girl-dark.png +0 -0
  3. package/assets/whale-girl/whale-girl-happy.png +0 -0
  4. package/assets/whale-girl/whale-girl.png +0 -0
  5. package/bin/dsh-tui.js +63 -3
  6. package/cordis.patch.yml +39 -17
  7. package/cordis.yml +3 -2
  8. package/lib/settings.json +1272 -0
  9. package/lib/types/adapter/channel/ui-policy.d.ts +9 -2
  10. package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
  11. package/lib/types/adapter/channel/ui-policy.js +13 -0
  12. package/lib/types/adapter/kernel/replay.d.ts.map +1 -1
  13. package/lib/types/adapter/kernel/replay.js +2 -0
  14. package/lib/types/adapter/ports/channel-display.d.ts +12 -0
  15. package/lib/types/adapter/ports/channel-display.d.ts.map +1 -1
  16. package/lib/types/adapter/ports/channel-session.d.ts +38 -0
  17. package/lib/types/adapter/ports/channel-session.d.ts.map +1 -1
  18. package/lib/types/adapter/ports/channel-settings.d.ts +12 -0
  19. package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
  20. package/lib/types/adapter/ports/channel-ui.d.ts +46 -4
  21. package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
  22. package/lib/types/adapter/ports/channel-view.d.ts +43 -0
  23. package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
  24. package/lib/types/commands.d.ts.map +1 -1
  25. package/lib/types/commands.js +2 -0
  26. package/lib/types/components/BalanceReportRow.d.ts +10 -2
  27. package/lib/types/components/BalanceReportRow.d.ts.map +1 -1
  28. package/lib/types/components/BalanceReportRow.js +18 -4
  29. package/lib/types/components/CompactionStatusRow.d.ts +24 -0
  30. package/lib/types/components/CompactionStatusRow.d.ts.map +1 -0
  31. package/lib/types/components/CompactionStatusRow.js +72 -0
  32. package/lib/types/components/GoalTodoPanel.js +2 -2
  33. package/lib/types/components/HelpMenu.d.ts +2 -2
  34. package/lib/types/components/HelpMenu.d.ts.map +1 -1
  35. package/lib/types/components/HelpMenu.js +5 -4
  36. package/lib/types/components/InlineMathParagraph.d.ts +22 -0
  37. package/lib/types/components/InlineMathParagraph.d.ts.map +1 -0
  38. package/lib/types/components/InlineMathParagraph.js +178 -0
  39. package/lib/types/components/LogoV2.d.ts +41 -3
  40. package/lib/types/components/LogoV2.d.ts.map +1 -1
  41. package/lib/types/components/LogoV2.js +148 -24
  42. package/lib/types/components/Markdown.d.ts +10 -3
  43. package/lib/types/components/Markdown.d.ts.map +1 -1
  44. package/lib/types/components/Markdown.js +47 -14
  45. package/lib/types/components/MathBlock.d.ts +13 -0
  46. package/lib/types/components/MathBlock.d.ts.map +1 -0
  47. package/lib/types/components/MathBlock.js +136 -0
  48. package/lib/types/components/MessageList.d.ts +10 -1
  49. package/lib/types/components/MessageList.d.ts.map +1 -1
  50. package/lib/types/components/MessageList.js +13 -4
  51. package/lib/types/components/MigratePicker.d.ts +30 -0
  52. package/lib/types/components/MigratePicker.d.ts.map +1 -0
  53. package/lib/types/components/MigratePicker.js +38 -0
  54. package/lib/types/components/PromptInput.d.ts +17 -0
  55. package/lib/types/components/PromptInput.d.ts.map +1 -1
  56. package/lib/types/components/PromptInput.js +48 -7
  57. package/lib/types/components/SplitDiffView.d.ts.map +1 -1
  58. package/lib/types/components/SplitDiffView.js +2 -1
  59. package/lib/types/components/StarPrompt.d.ts +53 -0
  60. package/lib/types/components/StarPrompt.d.ts.map +1 -0
  61. package/lib/types/components/StarPrompt.js +281 -0
  62. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  63. package/lib/types/components/StreamingMarkdown.js +20 -3
  64. package/lib/types/components/TimelineRail.d.ts.map +1 -1
  65. package/lib/types/components/TimelineRail.js +9 -1
  66. package/lib/types/components/Whale.d.ts +17 -8
  67. package/lib/types/components/Whale.d.ts.map +1 -1
  68. package/lib/types/components/Whale.js +25 -15
  69. package/lib/types/components/WhaleGirl.d.ts +29 -0
  70. package/lib/types/components/WhaleGirl.d.ts.map +1 -0
  71. package/lib/types/components/WhaleGirl.js +32 -0
  72. package/lib/types/components/WorkingSpinner.d.ts +4 -1
  73. package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
  74. package/lib/types/components/WorkingSpinner.js +2 -2
  75. package/lib/types/components/bigfont.d.ts +47 -18
  76. package/lib/types/components/bigfont.d.ts.map +1 -1
  77. package/lib/types/components/bigfont.js +55 -40
  78. package/lib/types/components/design-system/ThemeProvider.d.ts +6 -0
  79. package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
  80. package/lib/types/components/design-system/ThemeProvider.js +40 -1
  81. package/lib/types/components/maidPortrait.d.ts +44 -0
  82. package/lib/types/components/maidPortrait.d.ts.map +1 -0
  83. package/lib/types/components/maidPortrait.js +178 -0
  84. package/lib/types/components/mathPreview.d.ts +25 -0
  85. package/lib/types/components/mathPreview.d.ts.map +1 -0
  86. package/lib/types/components/mathPreview.js +48 -0
  87. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  88. package/lib/types/components/messages/AssistantThinkingMessage.js +2 -1
  89. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  90. package/lib/types/components/messages/AssistantToolUseMessage.js +3 -2
  91. package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -1
  92. package/lib/types/components/messages/TranscriptImages.js +11 -1
  93. package/lib/types/components/questions/AskUserQuestionPanel.d.ts +14 -2
  94. package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
  95. package/lib/types/components/questions/AskUserQuestionPanel.js +80 -38
  96. package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
  97. package/lib/types/components/questions/PlanReviewPanel.js +3 -3
  98. package/lib/types/components/sessions/ForeignSessionRow.d.ts +34 -0
  99. package/lib/types/components/sessions/ForeignSessionRow.d.ts.map +1 -0
  100. package/lib/types/components/sessions/ForeignSessionRow.js +43 -0
  101. package/lib/types/components/sessions/SourceTabs.d.ts +52 -0
  102. package/lib/types/components/sessions/SourceTabs.d.ts.map +1 -0
  103. package/lib/types/components/sessions/SourceTabs.js +70 -0
  104. package/lib/types/components/splashEggs.d.ts +56 -0
  105. package/lib/types/components/splashEggs.d.ts.map +1 -0
  106. package/lib/types/components/splashEggs.js +67 -0
  107. package/lib/types/components/splashFonts.d.ts +119 -0
  108. package/lib/types/components/splashFonts.d.ts.map +1 -0
  109. package/lib/types/components/splashFonts.js +267 -0
  110. package/lib/types/components/splashLayout.d.ts +41 -0
  111. package/lib/types/components/splashLayout.d.ts.map +1 -0
  112. package/lib/types/components/splashLayout.js +40 -0
  113. package/lib/types/components/whaleGirlSprite.d.ts +17 -0
  114. package/lib/types/components/whaleGirlSprite.d.ts.map +1 -0
  115. package/lib/types/components/whaleGirlSprite.js +47 -0
  116. package/lib/types/deepseekPricing.d.ts +74 -0
  117. package/lib/types/deepseekPricing.d.ts.map +1 -1
  118. package/lib/types/deepseekPricing.js +110 -11
  119. package/lib/types/dsh-adapter/channel/action-readiness.d.ts +1 -1
  120. package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -1
  121. package/lib/types/dsh-adapter/channel/action-readiness.js +6 -1
  122. package/lib/types/dsh-adapter/channel/background-action.d.ts +1 -0
  123. package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -1
  124. package/lib/types/dsh-adapter/channel/background-action.js +1 -0
  125. package/lib/types/dsh-adapter/channel/binding-events.d.ts +8 -9
  126. package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
  127. package/lib/types/dsh-adapter/channel/binding-events.js +69 -21
  128. package/lib/types/dsh-adapter/channel/compaction.d.ts +2 -1
  129. package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
  130. package/lib/types/dsh-adapter/channel/compaction.js +35 -2
  131. package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -1
  132. package/lib/types/dsh-adapter/channel/local-actions.js +6 -1
  133. package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -1
  134. package/lib/types/dsh-adapter/channel/model-switch.js +5 -1
  135. package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -1
  136. package/lib/types/dsh-adapter/channel/paths.js +7 -1
  137. package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
  138. package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
  139. package/lib/types/dsh-adapter/channel/preferences.js +16 -0
  140. package/lib/types/dsh-adapter/channel/projection.d.ts +1 -2
  141. package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -1
  142. package/lib/types/dsh-adapter/channel/projection.js +127 -17
  143. package/lib/types/dsh-adapter/channel/question-record.d.ts +76 -0
  144. package/lib/types/dsh-adapter/channel/question-record.d.ts.map +1 -0
  145. package/lib/types/dsh-adapter/channel/question-record.js +107 -0
  146. package/lib/types/dsh-adapter/channel/session-lineage.d.ts +42 -0
  147. package/lib/types/dsh-adapter/channel/session-lineage.d.ts.map +1 -0
  148. package/lib/types/dsh-adapter/channel/session-lineage.js +51 -0
  149. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +2 -0
  150. package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -1
  151. package/lib/types/dsh-adapter/channel/session-live-adoption.js +9 -3
  152. package/lib/types/dsh-adapter/channel/session-metadata.d.ts +2 -1
  153. package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
  154. package/lib/types/dsh-adapter/channel/session-metadata.js +39 -7
  155. package/lib/types/dsh-adapter/channel/session-reset.d.ts +1 -1
  156. package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -1
  157. package/lib/types/dsh-adapter/channel/session-reset.js +7 -0
  158. package/lib/types/dsh-adapter/channel/session-resume.d.ts +1 -0
  159. package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
  160. package/lib/types/dsh-adapter/channel/session-resume.js +4 -2
  161. package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
  162. package/lib/types/dsh-adapter/channel/settings-host.js +8 -0
  163. package/lib/types/dsh-adapter/channel/state.d.ts +14 -1
  164. package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
  165. package/lib/types/dsh-adapter/channel/state.js +6 -1
  166. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +30 -35
  167. package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
  168. package/lib/types/dsh-adapter/channel/subagent-projection.js +138 -4
  169. package/lib/types/dsh-adapter/channel/types.d.ts +1 -1
  170. package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -1
  171. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  172. package/lib/types/dsh-adapter/channel.js +19 -4
  173. package/lib/types/dsh-adapter/compat/messages.d.ts +6 -0
  174. package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -1
  175. package/lib/types/dsh-adapter/compat/messages.js +9 -0
  176. package/lib/types/dsh-adapter/contract.d.ts +5 -5
  177. package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
  178. package/lib/types/dsh-adapter/contract.js +8 -6
  179. package/lib/types/dsh-adapter/index.d.ts +36 -1
  180. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  181. package/lib/types/dsh-adapter/index.js +22 -6
  182. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
  183. package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
  184. package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +131 -0
  185. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts +17 -0
  186. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.d.ts.map +1 -0
  187. package/lib/types/dsh-adapter/migrate/adapters/claude-code.parse.js +329 -0
  188. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
  189. package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
  190. package/lib/types/dsh-adapter/migrate/adapters/codex.js +102 -0
  191. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts +16 -0
  192. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.d.ts.map +1 -0
  193. package/lib/types/dsh-adapter/migrate/adapters/codex.parse.js +289 -0
  194. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
  195. package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
  196. package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +117 -0
  197. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts +13 -0
  198. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.d.ts.map +1 -0
  199. package/lib/types/dsh-adapter/migrate/adapters/grok-build.parse.js +178 -0
  200. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
  201. package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
  202. package/lib/types/dsh-adapter/migrate/adapters/omp.js +133 -0
  203. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts +60 -0
  204. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.d.ts.map +1 -0
  205. package/lib/types/dsh-adapter/migrate/adapters/scan-fs.js +178 -0
  206. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +8 -0
  207. package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
  208. package/lib/types/dsh-adapter/migrate/adapters/scan.js +40 -0
  209. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
  210. package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
  211. package/lib/types/dsh-adapter/migrate/adapters/zcode.js +93 -0
  212. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts +9 -0
  213. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.d.ts.map +1 -0
  214. package/lib/types/dsh-adapter/migrate/adapters/zcode.parse.js +89 -0
  215. package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
  216. package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
  217. package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
  218. package/lib/types/dsh-adapter/migrate/browse.d.ts +42 -0
  219. package/lib/types/dsh-adapter/migrate/browse.d.ts.map +1 -0
  220. package/lib/types/dsh-adapter/migrate/browse.js +90 -0
  221. package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
  222. package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
  223. package/lib/types/dsh-adapter/migrate/cli.js +106 -0
  224. package/lib/types/dsh-adapter/migrate/import-one.d.ts +89 -0
  225. package/lib/types/dsh-adapter/migrate/import-one.d.ts.map +1 -0
  226. package/lib/types/dsh-adapter/migrate/import-one.js +133 -0
  227. package/lib/types/dsh-adapter/migrate/index.d.ts +35 -0
  228. package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
  229. package/lib/types/dsh-adapter/migrate/index.js +107 -0
  230. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts +40 -0
  231. package/lib/types/dsh-adapter/migrate/parse/injection.d.ts.map +1 -0
  232. package/lib/types/dsh-adapter/migrate/parse/injection.js +127 -0
  233. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts +28 -0
  234. package/lib/types/dsh-adapter/migrate/parse/jsonl.d.ts.map +1 -0
  235. package/lib/types/dsh-adapter/migrate/parse/jsonl.js +40 -0
  236. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts +28 -0
  237. package/lib/types/dsh-adapter/migrate/parse/role-turns.d.ts.map +1 -0
  238. package/lib/types/dsh-adapter/migrate/parse/role-turns.js +50 -0
  239. package/lib/types/dsh-adapter/migrate/parse/title.d.ts +18 -0
  240. package/lib/types/dsh-adapter/migrate/parse/title.d.ts.map +1 -0
  241. package/lib/types/dsh-adapter/migrate/parse/title.js +29 -0
  242. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts +62 -0
  243. package/lib/types/dsh-adapter/migrate/parse/tools.d.ts.map +1 -0
  244. package/lib/types/dsh-adapter/migrate/parse/tools.js +110 -0
  245. package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
  246. package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
  247. package/lib/types/dsh-adapter/migrate/picker.js +86 -0
  248. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
  249. package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
  250. package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
  251. package/lib/types/dsh-adapter/migrate/sessionize.d.ts +39 -0
  252. package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
  253. package/lib/types/dsh-adapter/migrate/sessionize.js +271 -0
  254. package/lib/types/dsh-adapter/migrate/types.d.ts +176 -0
  255. package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
  256. package/lib/types/dsh-adapter/migrate/types.js +11 -0
  257. package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
  258. package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
  259. package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
  260. package/lib/types/dsh-adapter/plugin.d.ts +4 -2
  261. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  262. package/lib/types/dsh-adapter/plugin.js +143 -364
  263. package/lib/types/dsh-adapter/providerWizard.d.ts +17 -0
  264. package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
  265. package/lib/types/dsh-adapter/providerWizard.js +254 -66
  266. package/lib/types/dsh-adapter/questions.d.ts +22 -15
  267. package/lib/types/dsh-adapter/questions.d.ts.map +1 -1
  268. package/lib/types/dsh-adapter/questions.js +47 -45
  269. package/lib/types/dsh-adapter/sessions/digest.d.ts +11 -6
  270. package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -1
  271. package/lib/types/dsh-adapter/sessions/digest.js +20 -13
  272. package/lib/types/dsh-adapter/sessions/frames.d.ts +3 -1
  273. package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -1
  274. package/lib/types/dsh-adapter/sessions/frames.js +5 -4
  275. package/lib/types/dsh-adapter/sessions/list.d.ts +6 -1
  276. package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -1
  277. package/lib/types/dsh-adapter/sessions/list.js +188 -164
  278. package/lib/types/dsh-adapter/sessions/recovery.d.ts +16 -0
  279. package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
  280. package/lib/types/dsh-adapter/sessions/recovery.js +108 -0
  281. package/lib/types/dsh-adapter/sessions/snapshot.d.ts +7 -0
  282. package/lib/types/dsh-adapter/sessions/snapshot.d.ts.map +1 -0
  283. package/lib/types/dsh-adapter/sessions/snapshot.js +90 -0
  284. package/lib/types/dsh-adapter/sessions/store.d.ts +10 -4
  285. package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -1
  286. package/lib/types/dsh-adapter/sessions/store.js +62 -25
  287. package/lib/types/dsh-adapter/sideQuestion.d.ts +41 -2
  288. package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
  289. package/lib/types/dsh-adapter/sideQuestion.js +98 -2
  290. package/lib/types/dsh-adapter/subagents.d.ts +28 -3
  291. package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
  292. package/lib/types/dsh-adapter/subagents.js +77 -2
  293. package/lib/types/herdr.d.ts +2 -0
  294. package/lib/types/herdr.d.ts.map +1 -1
  295. package/lib/types/herdr.js +9 -3
  296. package/lib/types/i18n.d.ts +424 -42
  297. package/lib/types/i18n.d.ts.map +1 -1
  298. package/lib/types/i18n.js +145 -20
  299. package/lib/types/ink/components/App.d.ts +2 -2
  300. package/lib/types/ink/components/App.d.ts.map +1 -1
  301. package/lib/types/ink/components/App.js +5 -1
  302. package/lib/types/ink/components/Image.d.ts +14 -1
  303. package/lib/types/ink/components/Image.d.ts.map +1 -1
  304. package/lib/types/ink/components/Image.js +2 -2
  305. package/lib/types/ink/events/input-event.js +3 -3
  306. package/lib/types/ink/hooks/use-terminal-images.d.ts +12 -0
  307. package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -1
  308. package/lib/types/ink/hooks/use-terminal-images.js +13 -0
  309. package/lib/types/ink/ink.d.ts +6 -0
  310. package/lib/types/ink/ink.d.ts.map +1 -1
  311. package/lib/types/ink/ink.js +16 -1
  312. package/lib/types/ink/kitty-graphics.d.ts +44 -3
  313. package/lib/types/ink/kitty-graphics.d.ts.map +1 -1
  314. package/lib/types/ink/kitty-graphics.js +184 -23
  315. package/lib/types/ink/output.d.ts +24 -2
  316. package/lib/types/ink/output.d.ts.map +1 -1
  317. package/lib/types/ink/output.js +83 -5
  318. package/lib/types/ink/parse-keypress.d.ts +26 -1
  319. package/lib/types/ink/parse-keypress.d.ts.map +1 -1
  320. package/lib/types/ink/parse-keypress.js +156 -13
  321. package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
  322. package/lib/types/ink/render-node-to-output.js +8 -1
  323. package/lib/types/ink/screen.d.ts +24 -0
  324. package/lib/types/ink/screen.d.ts.map +1 -1
  325. package/lib/types/ink/screen.js +89 -0
  326. package/lib/types/ink/selection.d.ts +40 -18
  327. package/lib/types/ink/selection.d.ts.map +1 -1
  328. package/lib/types/ink/selection.js +142 -30
  329. package/lib/types/ink/sixel-codec.d.ts +12 -1
  330. package/lib/types/ink/sixel-codec.d.ts.map +1 -1
  331. package/lib/types/ink/sixel-codec.js +29 -5
  332. package/lib/types/ink/sixel-graphics.d.ts.map +1 -1
  333. package/lib/types/ink/sixel-graphics.js +5 -3
  334. package/lib/types/ink/styles.d.ts +9 -0
  335. package/lib/types/ink/styles.d.ts.map +1 -1
  336. package/lib/types/ink/terminal-image.d.ts +8 -0
  337. package/lib/types/ink/terminal-image.d.ts.map +1 -1
  338. package/lib/types/ink/terminal-querier.d.ts +7 -1
  339. package/lib/types/ink/terminal-querier.d.ts.map +1 -1
  340. package/lib/types/ink/terminal-querier.js +12 -2
  341. package/lib/types/ink/timeline-rail.d.ts +5 -0
  342. package/lib/types/ink/timeline-rail.d.ts.map +1 -1
  343. package/lib/types/math/inline-layout.d.ts +29 -0
  344. package/lib/types/math/inline-layout.d.ts.map +1 -0
  345. package/lib/types/math/inline-layout.js +106 -0
  346. package/lib/types/math/layout.d.ts +58 -0
  347. package/lib/types/math/layout.d.ts.map +1 -0
  348. package/lib/types/math/layout.js +59 -0
  349. package/lib/types/math/renderer.d.ts +64 -0
  350. package/lib/types/math/renderer.d.ts.map +1 -0
  351. package/lib/types/math/renderer.js +256 -0
  352. package/lib/types/screens/Chat.d.ts +14 -1
  353. package/lib/types/screens/Chat.d.ts.map +1 -1
  354. package/lib/types/screens/Chat.js +606 -53
  355. package/lib/types/screens/SessionSupervisor.d.ts +2 -1
  356. package/lib/types/screens/SessionSupervisor.d.ts.map +1 -1
  357. package/lib/types/screens/SessionSupervisor.js +156 -19
  358. package/lib/types/screens/Settings.d.ts.map +1 -1
  359. package/lib/types/screens/Settings.js +49 -11
  360. package/lib/types/screens/StatusLine.d.ts.map +1 -1
  361. package/lib/types/screens/StatusLine.js +45 -15
  362. package/lib/types/screens/chatOverlay.d.ts +5 -0
  363. package/lib/types/screens/chatOverlay.d.ts.map +1 -1
  364. package/lib/types/screens/chatOverlay.js +1 -0
  365. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts +47 -0
  366. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.d.ts.map +1 -0
  367. package/lib/types/screens/sessionSupervisor/ForeignSessionPanes.js +65 -0
  368. package/lib/types/screens/sessionSupervisor/model.d.ts +12 -0
  369. package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -1
  370. package/lib/types/screens/sessionSupervisor/model.js +26 -0
  371. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts +107 -0
  372. package/lib/types/screens/sessionSupervisor/useForeignSessions.d.ts.map +1 -0
  373. package/lib/types/screens/sessionSupervisor/useForeignSessions.js +312 -0
  374. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +4 -1
  375. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -1
  376. package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +97 -14
  377. package/lib/types/sessionHistory.d.ts +2 -2
  378. package/lib/types/sessionHistory.d.ts.map +1 -1
  379. package/lib/types/sessionHistory.js +31 -5
  380. package/lib/types/settings/definitions.d.ts +681 -0
  381. package/lib/types/settings/definitions.d.ts.map +1 -0
  382. package/lib/types/settings/definitions.js +511 -0
  383. package/lib/types/starAction.d.ts +44 -0
  384. package/lib/types/starAction.d.ts.map +1 -0
  385. package/lib/types/starAction.js +52 -0
  386. package/lib/types/terminal-utils/latex.d.ts +10 -0
  387. package/lib/types/terminal-utils/latex.d.ts.map +1 -0
  388. package/lib/types/terminal-utils/latex.js +1417 -0
  389. package/lib/types/terminal-utils/markdown.d.ts +3 -1
  390. package/lib/types/terminal-utils/markdown.d.ts.map +1 -1
  391. package/lib/types/terminal-utils/markdown.js +26 -1
  392. package/lib/types/terminal-utils/math.d.ts +66 -0
  393. package/lib/types/terminal-utils/math.d.ts.map +1 -0
  394. package/lib/types/terminal-utils/math.js +337 -0
  395. package/lib/types/tips.d.ts.map +1 -1
  396. package/lib/types/tips.js +6 -0
  397. package/lib/types/tuiDisplayPrefs.d.ts +67 -0
  398. package/lib/types/tuiDisplayPrefs.d.ts.map +1 -1
  399. package/lib/types/tuiDisplayPrefs.js +59 -0
  400. package/lib/types/ui.d.ts +1 -1
  401. package/lib/types/ui.d.ts.map +1 -1
  402. package/lib/types/ui.js +1 -1
  403. package/lib/types/usageStats.d.ts +98 -0
  404. package/lib/types/usageStats.d.ts.map +1 -0
  405. package/lib/types/usageStats.js +169 -0
  406. package/lib/types/utils/bmp.d.ts +17 -0
  407. package/lib/types/utils/bmp.d.ts.map +1 -0
  408. package/lib/types/utils/bmp.js +154 -0
  409. package/lib/types/utils/clipboard.d.ts +14 -2
  410. package/lib/types/utils/clipboard.d.ts.map +1 -1
  411. package/lib/types/utils/clipboard.js +143 -8
  412. package/lib/types/utils/fold-long-lines.d.ts.map +1 -1
  413. package/lib/types/utils/fold-long-lines.js +2 -1
  414. package/lib/types/utils/keymap.d.ts +4 -1
  415. package/lib/types/utils/keymap.d.ts.map +1 -1
  416. package/lib/types/utils/keymap.js +8 -0
  417. package/lib/types/utils/modifiers.d.ts +4 -3
  418. package/lib/types/utils/modifiers.d.ts.map +1 -1
  419. package/lib/types/utils/modifiers.js +4 -3
  420. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/LICENSE +202 -0
  421. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/NOTICE +20 -0
  422. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/index.d.ts +16 -0
  423. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/bundled-packages.json +4 -0
  424. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs +20 -0
  425. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/lib/index.mjs.LEGAL.txt +35 -0
  426. package/node_modules/@dsh-tui-vendor/mathjax-tex-svg/package.json +29 -0
  427. package/package.json +111 -97
@@ -1,29 +1,70 @@
1
1
  import { type TerminalCellSize, type TerminalImagePlacement, type TerminalImageSource } from './terminal-image.js';
2
+ /** Pixel rectangle of the uploaded raster to show (Kitty `x,y,w,h`). */
3
+ export type KittySourceRect = {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ readonly width: number;
7
+ readonly height: number;
8
+ };
2
9
  export interface KittyGraphicsManagerOptions {
3
10
  /** Deterministic seed used by protocol tests; production chooses a random range. */
4
11
  readonly firstImageId?: number;
5
12
  /** Physical pixels per cell; defaults to a conventional 8×16 cell. */
6
13
  readonly cellSize?: TerminalCellSize;
14
+ /** Clock for the re-upload failure window; protocol tests pin it. */
15
+ readonly now?: () => number;
7
16
  }
8
17
  /**
9
18
  * Reconcile renderer image requests with Kitty image/placement state.
10
19
  *
11
20
  * Pixel content owns an image id while each DOM node owns a placement id.
12
21
  * Equal immutable RGBA content is uploaded once and can back several nodes;
13
- * geometry changes replace only that node's placement without flicker.
22
+ * geometry changes replace only that node's placement without flicker. An
23
+ * image no node places stays uploaded (dormant) within the retention budget,
24
+ * so content that scrolls back into view is re-placed, not re-sent.
14
25
  */
15
26
  export declare class KittyGraphicsManager {
16
27
  private readonly images;
17
28
  private readonly placements;
29
+ /**
30
+ * Ids given up by a re-upload. The ENOENT that triggered it may be stale
31
+ * (the id was re-sent in between), so the terminal can still hold data
32
+ * under the old id; it is deleted on the next frame (or at exit).
33
+ */
34
+ private readonly retiredImageIds;
18
35
  private readonly contentHashes;
19
36
  private nextImageId;
20
37
  private nextPlacementId;
21
38
  private cellSize;
39
+ private pass;
40
+ private readonly now;
22
41
  constructor(options?: KittyGraphicsManagerOptions);
23
42
  /** Update the physical cell ratio used by future image variants. */
24
43
  setCellSize(cellSize: TerminalCellSize): boolean;
25
44
  reconcile(placements: readonly TerminalImagePlacement[]): string;
26
- /** A clear/screen swap invalidated terminal-side data; resend next frame. */
45
+ /**
46
+ * Forget images no node placed this pass once they are unusable (fitted for
47
+ * another cell geometry) or past the retention budget, oldest first.
48
+ */
49
+ private evictDormant;
50
+ /**
51
+ * Handle a Kitty graphics reply the renderer did not ask for. ENOENT for
52
+ * one of our images means the terminal evicted its data (its own quota is
53
+ * smaller than our retention budget): upload it again and re-place every
54
+ * node showing it on the next frame. A second ENOENT within
55
+ * REUPLOAD_FAILURE_WINDOW_MS of that re-upload means the terminal refuses
56
+ * the image outright, so it is left as is (never an upload loop); a new
57
+ * content or size variant is a new image and tries again. The re-upload
58
+ * takes a fresh image id: every placement of the old id may still answer
59
+ * ENOENT, and those late replies must not count as the re-upload failing.
60
+ * Returns whether a repaint is needed.
61
+ */
62
+ handleResponse(imageId: number, status: string): boolean;
63
+ /**
64
+ * A clear/screen swap invalidated terminal-side data; resend next frame.
65
+ * The terminal state an abandoned image was judged against is gone too, so
66
+ * it gets a fresh ENOENT budget; one clear still buys at most one retry.
67
+ */
27
68
  invalidateAll(): void;
28
69
  /** Delete every image owned by this renderer and forget their ids. */
29
70
  deleteAll(): string;
@@ -34,7 +75,7 @@ export declare class KittyGraphicsManager {
34
75
  }
35
76
  /** Zlib-compressed direct RGBA split into protocol-compliant base64 chunks. */
36
77
  export declare function transmitKittyRgba(imageId: number, source: TerminalImageSource): string;
37
- export declare function kittyPlacement(imageId: number, placementId: number, x: number, y: number, columns: number, rows: number, zIndex?: number): string;
78
+ export declare function kittyPlacement(imageId: number, placementId: number, x: number, y: number, columns: number, rows: number, zIndex?: number, source?: KittySourceRect): string;
38
79
  export declare function deleteKittyPlacement(imageId: number, placementId: number): string;
39
80
  export declare function deleteKittyImage(imageId: number): string;
40
81
  export declare function kittyCommand(control: string, payload?: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"kitty-graphics.d.ts","sourceRoot":"","sources":["../../../src/ink/kitty-graphics.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAA;AAkC5B,MAAM,WAAW,2BAA2B;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CACrC;AAED;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,OAAO,GAAE,2BAAgC;IASrD,oEAAoE;IACpE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO;IAYhD,SAAS,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,GAAG,MAAM;IA0GhE,6EAA6E;IAC7E,aAAa,IAAI,IAAI;IAOrB,sEAAsE;IACtE,SAAS,IAAI,MAAM;IASnB,OAAO,CAAC,QAAQ;IA+BhB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,mBAAmB;CAQ5B;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAER;AAoCD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,SAAgB,GACrB,MAAM,CAOR;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,MAAM,CAElE"}
1
+ {"version":3,"file":"kitty-graphics.d.ts","sourceRoot":"","sources":["../../../src/ink/kitty-graphics.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAA;AAmE5B,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,MAAM,WAAW,2BAA2B;IAC1C,oFAAoF;IACpF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IACpC,qEAAqE;IACrE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAwC;IACnE;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAe;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoC;IAClE,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,IAAI,CAAI;IAChB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAc;gBAEtB,OAAO,GAAE,2BAAgC;IAUrD,oEAAoE;IACpE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO;IAYhD,SAAS,CAAC,UAAU,EAAE,SAAS,sBAAsB,EAAE,GAAG,MAAM;IAkHhE;;;OAGG;IACH,OAAO,CAAC,YAAY;IAmCpB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAsBxD;;;;OAIG;IACH,aAAa,IAAI,IAAI;IAWrB,sEAAsE;IACtE,SAAS,IAAI,MAAM;IASnB,OAAO,CAAC,QAAQ;IAoChB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,mBAAmB;CAQ5B;AAyCD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,mBAAmB,GAC1B,MAAM,CAER;AAoCD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,SAAgB,EACtB,MAAM,CAAC,EAAE,eAAe,GACvB,MAAM,CAUR;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,SAAK,GAAG,MAAM,CAElE"}
@@ -9,23 +9,54 @@ const ID_MAX_EXCLUSIVE = 0x7fffffff;
9
9
  const PLACEMENT_ID_MAX_EXCLUSIVE = 0x40000000;
10
10
  // Keep raster content behind terminal text and explicit panel backgrounds.
11
11
  const IMAGE_Z_INDEX = -0x80000000;
12
+ /**
13
+ * Retention for uploaded images that no node places this frame. Leaving the
14
+ * viewport deletes only the placement (`d=i`), so scrolling back re-places
15
+ * the terminal-side data with one `a=p` instead of re-fitting, re-compressing
16
+ * and re-sending the whole raster — the protocol's intended use, and what
17
+ * mature terminal UIs do. Dormant images are evicted least-recently-used past
18
+ * either bound. The byte bound counts decoded RGBA (what the terminal keeps)
19
+ * and stays a small fraction of default terminal image quotas. A terminal
20
+ * configured with a smaller quota may still evict a dormant image, so
21
+ * placements report failures (`q=1`): an ENOENT reply marks the image for
22
+ * re-upload (see handleResponse).
23
+ */
24
+ const DORMANT_MAX_IMAGES = 128;
25
+ const RETAINED_MAX_BYTES = 64 * 1024 * 1024;
26
+ /**
27
+ * An ENOENT this soon after re-uploading the same image means the terminal
28
+ * cannot keep it at all (e.g. the image exceeds its whole quota and the
29
+ * upload was refused): stop re-uploading instead of looping.
30
+ */
31
+ const REUPLOAD_FAILURE_WINDOW_MS = 5000;
12
32
  /**
13
33
  * Reconcile renderer image requests with Kitty image/placement state.
14
34
  *
15
35
  * Pixel content owns an image id while each DOM node owns a placement id.
16
36
  * Equal immutable RGBA content is uploaded once and can back several nodes;
17
- * geometry changes replace only that node's placement without flicker.
37
+ * geometry changes replace only that node's placement without flicker. An
38
+ * image no node places stays uploaded (dormant) within the retention budget,
39
+ * so content that scrolls back into view is re-placed, not re-sent.
18
40
  */
19
41
  export class KittyGraphicsManager {
20
42
  images = new Map();
21
43
  placements = new Map();
44
+ /**
45
+ * Ids given up by a re-upload. The ENOENT that triggered it may be stale
46
+ * (the id was re-sent in between), so the terminal can still hold data
47
+ * under the old id; it is deleted on the next frame (or at exit).
48
+ */
49
+ retiredImageIds = [];
22
50
  contentHashes = new WeakMap();
23
51
  nextImageId;
24
52
  nextPlacementId = 1;
25
53
  cellSize;
54
+ pass = 0;
55
+ now;
26
56
  constructor(options = {}) {
27
57
  this.nextImageId = normalizeFirstId(options.firstImageId ?? randomInt(ID_MIN, ID_MAX_EXCLUSIVE));
28
58
  this.cellSize = normalizeTerminalCellSize(options.cellSize ?? DEFAULT_TERMINAL_CELL_SIZE);
59
+ this.now = options.now ?? Date.now;
29
60
  }
30
61
  /** Update the physical cell ratio used by future image variants. */
31
62
  setCellSize(cellSize) {
@@ -38,15 +69,17 @@ export class KittyGraphicsManager {
38
69
  return true;
39
70
  }
40
71
  reconcile(placements) {
72
+ this.pass += 1;
41
73
  const desiredNodes = new Set();
42
74
  const desiredImages = new Set();
43
75
  const desired = [];
44
- const output = [];
76
+ const output = this.retiredImageIds.splice(0).map(deleteKittyImage);
45
77
  for (const placement of placements) {
46
78
  if (desiredNodes.has(placement.node))
47
79
  continue;
48
80
  desiredNodes.add(placement.node);
49
81
  const image = this.imageFor(placement);
82
+ image.lastUsed = this.pass;
50
83
  desiredImages.add(image);
51
84
  desired.push({ placement, image });
52
85
  }
@@ -64,6 +97,7 @@ export class KittyGraphicsManager {
64
97
  y: -1,
65
98
  columns: 0,
66
99
  rows: 0,
100
+ crop: '',
67
101
  };
68
102
  this.placements.set(placement.node, state);
69
103
  }
@@ -79,16 +113,22 @@ export class KittyGraphicsManager {
79
113
  output.push(transmitPreparedKittyRgba(image.imageId, image.payload));
80
114
  image.uploaded = true;
81
115
  }
82
- const moved = state.x !== placement.x ||
83
- state.y !== placement.y ||
84
- state.columns !== placement.columns ||
85
- state.rows !== placement.rows;
116
+ const visible = visiblePlacement(placement, image.payload);
117
+ const crop = visible.source === undefined
118
+ ? ''
119
+ : `${visible.source.x},${visible.source.y},${visible.source.width},${visible.source.height}`;
120
+ const moved = state.x !== visible.x ||
121
+ state.y !== visible.y ||
122
+ state.columns !== visible.columns ||
123
+ state.rows !== visible.rows ||
124
+ state.crop !== crop;
86
125
  if (!state.placed || moved) {
87
- output.push(kittyPlacement(image.imageId, state.placementId, placement.x, placement.y, placement.columns, placement.rows, state.zIndex));
88
- state.x = placement.x;
89
- state.y = placement.y;
90
- state.columns = placement.columns;
91
- state.rows = placement.rows;
126
+ output.push(kittyPlacement(image.imageId, state.placementId, visible.x, visible.y, visible.columns, visible.rows, state.zIndex, visible.source));
127
+ state.x = visible.x;
128
+ state.y = visible.y;
129
+ state.columns = visible.columns;
130
+ state.rows = visible.rows;
131
+ state.crop = crop;
92
132
  state.placed = true;
93
133
  }
94
134
  }
@@ -101,31 +141,111 @@ export class KittyGraphicsManager {
101
141
  });
102
142
  this.placements.delete(node);
103
143
  }
144
+ // Deleting an image's data also removes its placements, so an evicted
145
+ // image needs no separate placement delete.
146
+ const evicted = this.evictDormant(desiredImages);
104
147
  for (const obsolete of obsoletePlacements) {
105
- if (!desiredImages.has(obsolete.image))
148
+ if (evicted.has(obsolete.image))
106
149
  continue;
107
150
  output.push(deleteKittyPlacement(obsolete.image.imageId, obsolete.placementId));
108
151
  }
109
- for (const [key, image] of this.images) {
110
- if (desiredImages.has(image))
111
- continue;
152
+ for (const image of evicted)
112
153
  output.push(deleteKittyImage(image.imageId));
113
- this.images.delete(key);
114
- }
115
154
  return output.join('');
116
155
  }
117
- /** A clear/screen swap invalidated terminal-side data; resend next frame. */
156
+ /**
157
+ * Forget images no node placed this pass once they are unusable (fitted for
158
+ * another cell geometry) or past the retention budget, oldest first.
159
+ */
160
+ evictDormant(desiredImages) {
161
+ const evicted = new Set();
162
+ const dormant = [];
163
+ let retainedBytes = 0;
164
+ for (const entry of this.images) {
165
+ const image = entry[1];
166
+ if (desiredImages.has(image)) {
167
+ retainedBytes += image.retainedBytes;
168
+ }
169
+ else if (image.cellSize.width !== this.cellSize.width ||
170
+ image.cellSize.height !== this.cellSize.height) {
171
+ evicted.add(image);
172
+ }
173
+ else {
174
+ retainedBytes += image.retainedBytes;
175
+ dormant.push(entry);
176
+ }
177
+ }
178
+ dormant.sort((a, b) => a[1].lastUsed - b[1].lastUsed);
179
+ let index = 0;
180
+ while (index < dormant.length &&
181
+ (dormant.length - index > DORMANT_MAX_IMAGES || retainedBytes > RETAINED_MAX_BYTES)) {
182
+ const image = dormant[index][1];
183
+ evicted.add(image);
184
+ retainedBytes -= image.retainedBytes;
185
+ index += 1;
186
+ }
187
+ for (const [key, image] of this.images) {
188
+ if (evicted.has(image))
189
+ this.images.delete(key);
190
+ }
191
+ return evicted;
192
+ }
193
+ /**
194
+ * Handle a Kitty graphics reply the renderer did not ask for. ENOENT for
195
+ * one of our images means the terminal evicted its data (its own quota is
196
+ * smaller than our retention budget): upload it again and re-place every
197
+ * node showing it on the next frame. A second ENOENT within
198
+ * REUPLOAD_FAILURE_WINDOW_MS of that re-upload means the terminal refuses
199
+ * the image outright, so it is left as is (never an upload loop); a new
200
+ * content or size variant is a new image and tries again. The re-upload
201
+ * takes a fresh image id: every placement of the old id may still answer
202
+ * ENOENT, and those late replies must not count as the re-upload failing.
203
+ * Returns whether a repaint is needed.
204
+ */
205
+ handleResponse(imageId, status) {
206
+ if (!status.startsWith('ENOENT'))
207
+ return false;
208
+ let image;
209
+ for (const candidate of this.images.values()) {
210
+ if (candidate.imageId === imageId)
211
+ image = candidate;
212
+ }
213
+ if (image === undefined || !image.uploaded || image.abandoned)
214
+ return false;
215
+ const now = this.now();
216
+ if (image.reuploadedAt !== 0 && now - image.reuploadedAt < REUPLOAD_FAILURE_WINDOW_MS) {
217
+ image.abandoned = true;
218
+ return false;
219
+ }
220
+ image.reuploadedAt = now;
221
+ this.retiredImageIds.push(image.imageId);
222
+ image.imageId = this.allocateImageId();
223
+ image.uploaded = false;
224
+ for (const state of this.placements.values()) {
225
+ if (state.image === image)
226
+ state.placed = false;
227
+ }
228
+ return true;
229
+ }
230
+ /**
231
+ * A clear/screen swap invalidated terminal-side data; resend next frame.
232
+ * The terminal state an abandoned image was judged against is gone too, so
233
+ * it gets a fresh ENOENT budget; one clear still buys at most one retry.
234
+ */
118
235
  invalidateAll() {
119
- for (const image of this.images.values())
236
+ for (const image of this.images.values()) {
120
237
  image.uploaded = false;
238
+ image.abandoned = false;
239
+ image.reuploadedAt = 0;
240
+ }
121
241
  for (const state of this.placements.values()) {
122
242
  state.placed = false;
123
243
  }
124
244
  }
125
245
  /** Delete every image owned by this renderer and forget their ids. */
126
246
  deleteAll() {
127
- const output = [...this.images.values()]
128
- .map(image => deleteKittyImage(image.imageId))
247
+ const output = [...this.retiredImageIds.splice(0), ...[...this.images.values()].map(image => image.imageId)]
248
+ .map(deleteKittyImage)
129
249
  .join('');
130
250
  this.images.clear();
131
251
  this.placements.clear();
@@ -150,7 +270,12 @@ export class KittyGraphicsManager {
150
270
  const image = {
151
271
  imageId: this.allocateImageId(),
152
272
  payload: prepareKittyRgba(fitted),
273
+ retainedBytes: fitted.width * fitted.height * 4,
274
+ cellSize: this.cellSize,
153
275
  uploaded: false,
276
+ lastUsed: this.pass,
277
+ reuploadedAt: 0,
278
+ abandoned: false,
154
279
  };
155
280
  this.images.set(key, image);
156
281
  return image;
@@ -179,6 +304,39 @@ export class KittyGraphicsManager {
179
304
  return id;
180
305
  }
181
306
  }
307
+ /**
308
+ * The cells a placement actually occupies and, when it is clipped, the part
309
+ * of the uploaded raster behind them. The raster has the full cell box's
310
+ * exact physical aspect (see fitTerminalImageSource), so a cell edge maps to
311
+ * a pixel edge proportionally; the start rounds down and the end up, so a
312
+ * partially covered pixel row is shown rather than dropped.
313
+ */
314
+ function visiblePlacement(placement, payload) {
315
+ const clip = placement.clip;
316
+ if (clip === undefined ||
317
+ (clip.x === placement.x && clip.y === placement.y &&
318
+ clip.columns === placement.columns && clip.rows === placement.rows)) {
319
+ return { x: placement.x, y: placement.y, columns: placement.columns, rows: placement.rows };
320
+ }
321
+ const left = clip.x - placement.x;
322
+ const top = clip.y - placement.y;
323
+ const sourceX = Math.floor((payload.width * left) / placement.columns);
324
+ const sourceY = Math.floor((payload.height * top) / placement.rows);
325
+ const sourceRight = Math.min(payload.width, Math.ceil((payload.width * (left + clip.columns)) / placement.columns));
326
+ const sourceBottom = Math.min(payload.height, Math.ceil((payload.height * (top + clip.rows)) / placement.rows));
327
+ return {
328
+ x: clip.x,
329
+ y: clip.y,
330
+ columns: clip.columns,
331
+ rows: clip.rows,
332
+ source: {
333
+ x: sourceX,
334
+ y: sourceY,
335
+ width: Math.max(1, sourceRight - sourceX),
336
+ height: Math.max(1, sourceBottom - sourceY),
337
+ },
338
+ };
339
+ }
182
340
  /** Zlib-compressed direct RGBA split into protocol-compliant base64 chunks. */
183
341
  export function transmitKittyRgba(imageId, source) {
184
342
  return transmitPreparedKittyRgba(imageId, prepareKittyRgba(source));
@@ -208,9 +366,12 @@ function transmitPreparedKittyRgba(imageId, payload) {
208
366
  })
209
367
  .join('');
210
368
  }
211
- export function kittyPlacement(imageId, placementId, x, y, columns, rows, zIndex = IMAGE_Z_INDEX) {
369
+ export function kittyPlacement(imageId, placementId, x, y, columns, rows, zIndex = IMAGE_Z_INDEX, source) {
370
+ const crop = source === undefined
371
+ ? ''
372
+ : `,x=${source.x},y=${source.y},w=${source.width},h=${source.height}`;
212
373
  return (`\u001b[${y + 1};${x + 1}H` +
213
- kittyCommand(`a=p,i=${imageId},p=${placementId},c=${columns},r=${rows},z=${zIndex},C=1,q=2`));
374
+ kittyCommand(`a=p,i=${imageId},p=${placementId},c=${columns},r=${rows}${crop},z=${zIndex},C=1,q=1`));
214
375
  }
215
376
  export function deleteKittyPlacement(imageId, placementId) {
216
377
  return kittyCommand(`a=d,d=i,i=${imageId},p=${placementId},q=2`);
@@ -85,7 +85,7 @@ type Options = {
85
85
  previousImages?: readonly TerminalImagePlacement[];
86
86
  };
87
87
  /** A queued paint operation: write, clip, unclip, blit, clear, shade, noSelect, or shift. */
88
- export type Operation = WriteOperation | ClipOperation | UnclipOperation | BlitOperation | ClearOperation | ShadeOperation | NoSelectOperation | ShiftOperation;
88
+ export type Operation = WriteOperation | ClipOperation | UnclipOperation | BlitOperation | ClearOperation | ShadeOperation | NoSelectOperation | CopyRegionOperation | SoftWrapRowOperation | ShiftOperation;
89
89
  /**
90
90
  * Restyle the cells already in the region at this point of the paint
91
91
  * order: a modal layer's backdrop. Applied in sequence like a write, so
@@ -108,7 +108,8 @@ type WriteOperation = {
108
108
  * means line i is a continuation of line i-1 (the `\n` before it was
109
109
  * inserted by word-wrap, not in the source). Index 0 is always false.
110
110
  * Undefined means the producer didn't track wrapping (e.g. fills,
111
- * raw-ansi) — the screen's per-row bitmap is left untouched.
111
+ * raw-ansi): the rows it paints are marked "not a continuation", since it
112
+ * replaced whatever was there — see the write case in `get()`.
112
113
  */
113
114
  softWrap?: boolean[];
114
115
  };
@@ -156,6 +157,19 @@ type NoSelectOperation = {
156
157
  type: 'noSelect';
157
158
  region: Rectangle;
158
159
  };
160
+ /** Row `y` continues the row above, whose content ends at `contentEnd`. */
161
+ type SoftWrapRowOperation = {
162
+ type: 'softWrapRow';
163
+ y: number;
164
+ contentEnd: number;
165
+ };
166
+ /** A region that copies as `text` (see Screen.copyRegion); paints nothing. */
167
+ type CopyRegionOperation = {
168
+ type: 'copyRegion';
169
+ region: Rectangle;
170
+ text: string;
171
+ id: number;
172
+ };
159
173
  /**
160
174
  * Collects write/blit/clear/clip operations from the render tree, then
161
175
  * applies them to a Screen buffer in get(). The Screen is what gets
@@ -250,6 +264,8 @@ export default class Output {
250
264
  * the mark wins regardless of what's blitted into the region.
251
265
  * @param region - the region to mark.
252
266
  */
267
+ /** Mark row `y` as a wrap continuation (see Styles.softWrapContinuation). */
268
+ softWrapRow(y: number, contentEnd: number): void;
253
269
  noSelect(region: Rectangle): void;
254
270
  /**
255
271
  * Record a fully visible, frame-budgeted image request. Rejected placements
@@ -272,6 +288,12 @@ export default class Output {
272
288
  getImages(): readonly TerminalImagePlacement[];
273
289
  /** Pixel ownership is determined by paint order, not just final text values. */
274
290
  imageBacking(node: DOMElement): void;
291
+ /**
292
+ * The admitted placement's backing colour, or undefined when the raster
293
+ * composites transparently: its cells are then blanks, not a painted
294
+ * surface, so whatever the terminal shows behind the UI stays visible.
295
+ */
296
+ imagePlacementBackground(node: DOMElement): string | undefined;
275
297
  /**
276
298
  * Queue a text write at a position, split across lines on newlines.
277
299
  * @param x - the left column.
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/ink/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/ink/output.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { getGraphemeSegmenter } from '../utils/intl.js';
4
4
  import sliceAnsi from '../utils/sliceAnsi.js';
5
5
  import { reorderBidi } from './bidi.js';
6
6
  import { unionRect } from './layout/geometry.js';
7
- import { blitRegion, cellRunSpan, createCellRun, extractHyperlinkFromStyles, filterOutHyperlinkStyles, markNoSelectRegion, OSC8_PREFIX, shadeRegion, recordCellRunEntry, recordSpacerRunEntry, replayCellRun, resetScreen, setCellAt, shiftRows, } from './screen.js';
7
+ import { blitRegion, cellRunSpan, createCellRun, extractHyperlinkFromStyles, filterOutHyperlinkStyles, allocateCopyRegionId, clearCopyRegionSpan, markCopyRegion, pruneCopyTexts, markNoSelectRegion, OSC8_PREFIX, shadeRegion, recordCellRunEntry, recordSpacerRunEntry, replayCellRun, resetScreen, setCellAt, shiftRows, } from './screen.js';
8
8
  import { stringWidth } from './stringWidth.js';
9
9
  import { expandTabs } from './tabstops.js';
10
10
  import { TERMINAL_IMAGE_MAX_CELLS, TERMINAL_IMAGE_MAX_FRAME_BYTES, TERMINAL_IMAGE_MAX_PLACEMENTS, } from './terminal-image.js';
@@ -152,6 +152,22 @@ function isNodeInSubtree(node, root) {
152
152
  }
153
153
  return false;
154
154
  }
155
+ /**
156
+ * One copy region id per image node for its lifetime, so rows captured
157
+ * during drag-to-scroll and rows still on screen name the same formula.
158
+ */
159
+ const copyRegionIds = new WeakMap();
160
+ /**
161
+ * Copy text reaches the clipboard without passing through cells, so it never
162
+ * met the render path's control-character rules. Drop C0/C1 (newlines
163
+ * excepted: a block formula's source is multi-line) and the
164
+ * interlinear-annotation code points, which the copy pipeline reserves for
165
+ * its own row metadata.
166
+ */
167
+ const COPY_TEXT_STRIP = /[\u0000-\u0009\u000b-\u001f\u007f-\u009f\uFFF9-\uFFFB]/g;
168
+ function cleanCopyText(value) {
169
+ return value.replace(COPY_TEXT_STRIP, '');
170
+ }
155
171
  /**
156
172
  * Slot-reuse ceiling: the clustered array is a second full memory image of
157
173
  * the line, and pathological single-line output (base64 blobs, minified
@@ -502,6 +518,10 @@ export default class Output {
502
518
  * the mark wins regardless of what's blitted into the region.
503
519
  * @param region - the region to mark.
504
520
  */
521
+ /** Mark row `y` as a wrap continuation (see Styles.softWrapContinuation). */
522
+ softWrapRow(y, contentEnd) {
523
+ this.operations.push({ type: 'softWrapRow', y, contentEnd });
524
+ }
505
525
  noSelect(region) {
506
526
  this.operations.push({ type: 'noSelect', region });
507
527
  }
@@ -525,7 +545,11 @@ export default class Output {
525
545
  return false;
526
546
  }
527
547
  const presentation = node.attributes.imagePresentation;
528
- const canCrop = this.imageReady !== undefined && (presentation === 'preview' || presentation === 'transcript');
548
+ const transparent = node.attributes.imageTransparent === 'transparent';
549
+ // Both protocols crop a partially visible content image to its visible
550
+ // cells (Sixel re-encodes the slice, Kitty places a source rectangle), so
551
+ // scrolling past a viewport edge never flips it to its text fallback.
552
+ const canCrop = this.terminalImagesEnabled && (presentation === 'preview' || presentation === 'transcript');
529
553
  if (!canCrop && (left < 0 ||
530
554
  top < 0 ||
531
555
  left + width > this.width ||
@@ -559,6 +583,7 @@ export default class Output {
559
583
  rows: height,
560
584
  source,
561
585
  ...(presentation === 'preview' || presentation === 'transcript' ? { presentation } : {}),
586
+ ...(transparent ? { transparent: true } : {}),
562
587
  ...(canCrop ? { clip: { x: visibleLeft, y: visibleTop, columns: visibleRight - visibleLeft, rows: visibleBottom - visibleTop } } : {}),
563
588
  ...(background !== undefined ? { background } : {}),
564
589
  };
@@ -576,8 +601,9 @@ export default class Output {
576
601
  */
577
602
  reuseImages(node) {
578
603
  // A scrollable image's current clip is only known inside its ScrollBox.
579
- // Descend first rather than admitting stale placements from an ancestor blit.
580
- if (this.imageReady && this.previousImages.some(p => isNodeInSubtree(p.node, node)))
604
+ // Descend first rather than admitting stale placements from an ancestor
605
+ // blit: a crop computed without that clip would spill past the viewport.
606
+ if (this.terminalImagesEnabled && this.previousImages.some(p => isNodeInSubtree(p.node, node)))
581
607
  return false;
582
608
  let reusedAll = true;
583
609
  for (const placement of this.previousImages) {
@@ -650,11 +676,31 @@ export default class Output {
650
676
  const placement = this.imagePlacements.find(image => image.node === node);
651
677
  if (placement) {
652
678
  const visible = placement.clip ?? placement;
653
- this.noSelect({ x: visible.x, y: visible.y, width: visible.columns, height: visible.rows });
679
+ const region = { x: visible.x, y: visible.y, width: visible.columns, height: visible.rows };
680
+ // An image's backing cells are blank; one with copy text (a formula's
681
+ // source) copies as that text, any other image is left out of copies.
682
+ const copyText = node.attributes['imageCopyText'];
683
+ const copied = typeof copyText === 'string' ? cleanCopyText(copyText) : '';
684
+ if (copied !== '') {
685
+ let id = copyRegionIds.get(node);
686
+ if (id === undefined)
687
+ copyRegionIds.set(node, id = allocateCopyRegionId());
688
+ this.operations.push({ type: 'copyRegion', region, text: copied, id });
689
+ }
690
+ else
691
+ this.noSelect(region);
654
692
  }
655
693
  if (this.imageReady)
656
694
  this.imageBackingEnds.set(node, this.operations.length);
657
695
  }
696
+ /**
697
+ * The admitted placement's backing colour, or undefined when the raster
698
+ * composites transparently: its cells are then blanks, not a painted
699
+ * surface, so whatever the terminal shows behind the UI stays visible.
700
+ */
701
+ imagePlacementBackground(node) {
702
+ return this.imagePlacements.find(image => image.node === node)?.background;
703
+ }
658
704
  /**
659
705
  * Queue a text write at a position, split across lines on newlines.
660
706
  * @param x - the left column.
@@ -810,6 +856,24 @@ export default class Output {
810
856
  shiftRows(screen, operation.top, operation.bottom, operation.n);
811
857
  continue;
812
858
  }
859
+ case 'softWrapRow': {
860
+ // Paint order: the marker lands where the producer asked for it, and
861
+ // the write case above resets it when a later operation repaints that
862
+ // row. (This used to run in a pass after every write, which let a
863
+ // marker outlive an overlay that overwrote the row.)
864
+ if (operation.y > 0 && operation.y < screen.height) {
865
+ screen.softWrap[operation.y] = Math.max(1, operation.contentEnd);
866
+ }
867
+ continue;
868
+ }
869
+ case 'copyRegion': {
870
+ // In paint order: anything written over the image later (a menu,
871
+ // an overlay) clears the cells it covers, so a copy reads what is
872
+ // visible there rather than the formula beneath.
873
+ const { x, y, width, height } = operation.region;
874
+ markCopyRegion(screen, x, y, width, height, operation.text, operation.id);
875
+ continue;
876
+ }
813
877
  case 'shade': {
814
878
  // Honour the active clip like a write: a backdrop inside an
815
879
  // overflow-hidden ancestor must not shade cells outside it.
@@ -882,6 +946,9 @@ export default class Output {
882
946
  }
883
947
  const contentEnd = writeLineToScreen(screen, line, x, lineY, screenWidth, this.stylePool, this.charCache, this.streamingSlot, this.packedOwner);
884
948
  writeCells += contentEnd - x;
949
+ if (screen.copyTexts !== undefined && screen.copyTexts.size > 0) {
950
+ clearCopyRegionSpan(screen, lineY, x, contentEnd);
951
+ }
885
952
  // See Screen.softWrap docstring for the encoding. contentEnd
886
953
  // from writeLineToScreen is tab-expansion-aware, unlike
887
954
  // x+stringWidth(line) which treats tabs as width 0.
@@ -890,6 +957,14 @@ export default class Output {
890
957
  swBits[lineY] = isSW ? prevContentEnd : 0;
891
958
  prevContentEnd = contentEnd;
892
959
  }
960
+ else {
961
+ // Paint order: a producer that doesn't track wrapping (fills,
962
+ // raw-ansi, overlays) still replaces the row it paints, so a
963
+ // continuation marker an earlier softWrapRow set for this row
964
+ // is stale — keep it and a copy would glue the overlay's text
965
+ // onto the previous line.
966
+ swBits[lineY] = 0;
967
+ }
893
968
  offsetY++;
894
969
  }
895
970
  continue;
@@ -907,6 +982,9 @@ export default class Output {
907
982
  markNoSelectRegion(screen, x, y, width, height);
908
983
  }
909
984
  }
985
+ // Blits carry the previous frame's region texts; keep only the ones a
986
+ // cell still references, or the map grows by every redrawn formula.
987
+ pruneCopyTexts(screen);
910
988
  // Log blit/write ratio for debugging - high write count suggests blitting isn't working
911
989
  const totalCells = blitCells + writeCells;
912
990
  if (totalCells > 1000 && writeCells > blitCells) {