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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/README.md +22 -13
  2. package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
  3. package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
  4. package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
  5. package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
  6. package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
  7. package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
  8. package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
  9. package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
  10. package/dsh-ecosystem-spec/registry/README.md +14 -0
  11. package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
  12. package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
  13. package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
  14. package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
  15. package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
  16. package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
  17. package/lib/types/command-trees.d.ts +2 -1
  18. package/lib/types/command-trees.d.ts.map +1 -1
  19. package/lib/types/command-trees.js +1 -1
  20. package/lib/types/components/LoadedContextPanel.d.ts +10 -5
  21. package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
  22. package/lib/types/components/LoadedContextPanel.js +18 -7
  23. package/lib/types/components/LogoV2.d.ts.map +1 -1
  24. package/lib/types/components/LogoV2.js +16 -7
  25. package/lib/types/components/Markdown.d.ts +13 -1
  26. package/lib/types/components/Markdown.d.ts.map +1 -1
  27. package/lib/types/components/Markdown.js +15 -1
  28. package/lib/types/components/MessageList.d.ts +3 -1
  29. package/lib/types/components/MessageList.d.ts.map +1 -1
  30. package/lib/types/components/MessageList.js +90 -9
  31. package/lib/types/components/PromptInput.d.ts.map +1 -1
  32. package/lib/types/components/PromptInput.js +26 -12
  33. package/lib/types/components/StreamingMarkdown.d.ts +2 -8
  34. package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
  35. package/lib/types/components/StreamingMarkdown.js +51 -9
  36. package/lib/types/components/activityFrames.d.ts +1 -1
  37. package/lib/types/components/activityFrames.d.ts.map +1 -1
  38. package/lib/types/components/activityFrames.js +4 -1
  39. package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
  40. package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
  41. package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
  42. package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
  43. package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
  44. package/lib/types/dsh-adapter/channel.d.ts +31 -4
  45. package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
  46. package/lib/types/dsh-adapter/channel.js +267 -102
  47. package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
  48. package/lib/types/dsh-adapter/childStderr.js +10 -0
  49. package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
  50. package/lib/types/dsh-adapter/command-attribution.js +2 -2
  51. package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
  52. package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
  53. package/lib/types/dsh-adapter/command-trees.js +70 -20
  54. package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
  55. package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
  56. package/lib/types/dsh-adapter/component-identity.js +14 -14
  57. package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
  58. package/lib/types/dsh-adapter/decision-guard.js +10 -16
  59. package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
  60. package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
  61. package/lib/types/dsh-adapter/dialogs.js +114 -60
  62. package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
  63. package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
  64. package/lib/types/dsh-adapter/effect-ledger.js +73 -53
  65. package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
  66. package/lib/types/dsh-adapter/extension-events.js +39 -1
  67. package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
  68. package/lib/types/dsh-adapter/grants.js +43 -14
  69. package/lib/types/dsh-adapter/host-access.d.ts +37 -0
  70. package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
  71. package/lib/types/dsh-adapter/host-access.js +652 -0
  72. package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
  73. package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
  74. package/lib/types/dsh-adapter/host-descriptor.js +31 -8
  75. package/lib/types/dsh-adapter/index.d.ts +4 -0
  76. package/lib/types/dsh-adapter/index.d.ts.map +1 -1
  77. package/lib/types/dsh-adapter/index.js +1 -0
  78. package/lib/types/dsh-adapter/message-observer.d.ts +10 -15
  79. package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
  80. package/lib/types/dsh-adapter/message-observer.js +114 -70
  81. package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
  82. package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
  83. package/lib/types/dsh-adapter/plugin-host.js +139 -44
  84. package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
  85. package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
  86. package/lib/types/dsh-adapter/plugin-storage.js +48 -36
  87. package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
  88. package/lib/types/dsh-adapter/plugin.js +80 -16
  89. package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
  90. package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
  91. package/lib/types/dsh-adapter/promptDebug.js +13 -4
  92. package/lib/types/dsh-adapter/renderers.d.ts +6 -14
  93. package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
  94. package/lib/types/dsh-adapter/renderers.js +81 -46
  95. package/lib/types/dsh-adapter/scenes.d.ts +8 -4
  96. package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
  97. package/lib/types/dsh-adapter/scenes.js +136 -37
  98. package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
  99. package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
  100. package/lib/types/dsh-adapter/settings-sections.js +106 -26
  101. package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
  102. package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
  103. package/lib/types/dsh-adapter/shortcuts.js +108 -36
  104. package/lib/types/dsh-adapter/status.d.ts +6 -7
  105. package/lib/types/dsh-adapter/status.d.ts.map +1 -1
  106. package/lib/types/dsh-adapter/status.js +88 -22
  107. package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
  108. package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
  109. package/lib/types/dsh-adapter/workspaces.js +287 -170
  110. package/lib/types/extensions.d.ts +10 -5
  111. package/lib/types/extensions.d.ts.map +1 -1
  112. package/lib/types/extensions.js +11 -5
  113. package/lib/types/force-production-react.d.ts +1 -0
  114. package/lib/types/force-production-react.d.ts.map +1 -0
  115. package/lib/types/force-production-react.js +12 -0
  116. package/lib/types/i18n.d.ts +14 -6
  117. package/lib/types/i18n.d.ts.map +1 -1
  118. package/lib/types/i18n.js +4 -2
  119. package/lib/types/index.d.ts +1 -0
  120. package/lib/types/index.d.ts.map +1 -1
  121. package/lib/types/index.js +1 -0
  122. package/lib/types/ink/components/App.d.ts +2 -0
  123. package/lib/types/ink/components/App.d.ts.map +1 -1
  124. package/lib/types/ink/components/App.js +4 -0
  125. package/lib/types/ink/ink.d.ts +20 -3
  126. package/lib/types/ink/ink.d.ts.map +1 -1
  127. package/lib/types/ink/ink.js +57 -5
  128. package/lib/types/ink/log-update.d.ts.map +1 -1
  129. package/lib/types/ink/log-update.js +128 -9
  130. package/lib/types/ink/output.d.ts +28 -2
  131. package/lib/types/ink/output.d.ts.map +1 -1
  132. package/lib/types/ink/output.js +158 -12
  133. package/lib/types/ink/screen.d.ts +39 -0
  134. package/lib/types/ink/screen.d.ts.map +1 -1
  135. package/lib/types/ink/screen.js +117 -0
  136. package/lib/types/ink/terminal.d.ts.map +1 -1
  137. package/lib/types/ink/terminal.js +10 -2
  138. package/lib/types/ink/wrapAnsi.d.ts +1 -1
  139. package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
  140. package/lib/types/ink/wrapAnsi.js +29 -2
  141. package/lib/types/plugin-host.d.ts +13 -11
  142. package/lib/types/plugin-host.d.ts.map +1 -1
  143. package/lib/types/plugin-host.js +16 -16
  144. package/lib/types/plugin-spec/registry.d.ts +2 -2
  145. package/lib/types/plugin-spec/registry.d.ts.map +1 -1
  146. package/lib/types/plugin-spec/registry.js +113 -18
  147. package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
  148. package/lib/types/plugin-spec/tui-extension.js +2 -0
  149. package/lib/types/plugin-spec/validate.d.ts.map +1 -1
  150. package/lib/types/plugin-spec/validate.js +20 -1
  151. package/lib/types/scenes.d.ts +2 -1
  152. package/lib/types/scenes.d.ts.map +1 -1
  153. package/lib/types/scenes.js +1 -1
  154. package/lib/types/screens/Chat.d.ts +3 -3
  155. package/lib/types/screens/Chat.d.ts.map +1 -1
  156. package/lib/types/screens/Chat.js +38 -17
  157. package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
  158. package/lib/types/screens/SessionBrowser.js +10 -3
  159. package/lib/types/sessions/view.d.ts +3 -2
  160. package/lib/types/sessions/view.d.ts.map +1 -1
  161. package/lib/types/sessions/view.js +18 -0
  162. package/lib/types/settings-sections.d.ts +2 -1
  163. package/lib/types/settings-sections.d.ts.map +1 -1
  164. package/lib/types/settings-sections.js +1 -1
  165. package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
  166. package/lib/types/utils/execFileNoThrow.js +3 -0
  167. package/lib/types/workspaces.d.ts +2 -1
  168. package/lib/types/workspaces.d.ts.map +1 -1
  169. package/lib/types/workspaces.js +1 -1
  170. package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
  171. package/node_modules/@dsh-std/command/package.json +1 -1
  172. package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  173. package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  174. package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  175. package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  176. package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  177. package/node_modules/@dsh-std/connection/package.json +1 -1
  178. package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  179. package/node_modules/@dsh-std/core/package.json +1 -1
  180. package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  181. package/node_modules/@dsh-std/manifest/package.json +1 -1
  182. package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
  183. package/node_modules/@dsh-std/messages/package.json +1 -1
  184. package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  185. package/node_modules/@dsh-std/presentation/README.md +2 -1
  186. package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  187. package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  188. package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  189. package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  190. package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  191. package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  192. package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  193. package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  194. package/node_modules/@dsh-std/presentation/package.json +7 -3
  195. package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
  196. package/node_modules/@dsh-std/storage/package.json +1 -1
  197. package/package.json +10 -5
  198. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  199. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  200. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  201. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  202. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  203. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
  204. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  205. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
  206. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
  207. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
  208. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
  209. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
  210. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
  211. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
  212. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
  213. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
  214. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
  215. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
  216. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
  217. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
  218. package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
  219. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  220. package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
  221. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  222. package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
  223. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  224. package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
  225. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
  226. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
  227. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
  228. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
  229. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
  230. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
  231. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  232. package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
  233. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
  234. package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
  235. package/ecosystem-spec/registry/registry-0.15.json +0 -57
  236. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
  237. /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
  238. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
  239. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
  240. /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/host-descriptor.schema.json +0 -0
package/lib/types/i18n.js CHANGED
@@ -132,6 +132,8 @@ const dict = {
132
132
  'skill-release-notes-prompt': { zh: '请使用 release-notes 技能为当前项目生成发布说明。', en: 'Use the release-notes skill to generate release notes for the current project.' },
133
133
  'skill-vuln-check-prompt': { zh: '请使用 vuln-check 技能对当前项目做一次安全漏洞检查。', en: 'Use the vuln-check skill to run a security vulnerability check on the current project.' },
134
134
  'context-loaded': { zh: '已加载上下文', en: 'Context loaded' },
135
+ 'context-panel-expand': { zh: '展开', en: 'Expand' },
136
+ 'context-panel-collapse': { zh: '折叠', en: 'Collapse' },
135
137
  'copied-chars': { zh: '已复制 {{n}} 个字符', en: 'Copied {{n}} characters' },
136
138
  'activity-usage-name': { zh: '/activity frames <名>', en: '/activity frames <name>' },
137
139
  'activity-current-preset': { zh: '当前预设 {{name}}', en: 'Current preset {{name}}' },
@@ -224,6 +226,7 @@ const dict = {
224
226
  'update-check-failed': { zh: '无法确认新版本(网络或 registry 不可达),已尝试直接更新……', en: 'Could not confirm a newer version (network or registry unreachable); attempting the update anyway…' },
225
227
  'update-refused-deadlock': { zh: '已取消更新:镜像 registry 目前只能装到 v{{latest}},而该版本在旧全局启动器的 patch 下会启动死锁(#183/#307);官方最新为 v{{authoritative}},待镜像同步后再 /update。', en: 'Update cancelled: the mirror registry can only serve v{{latest}}, which deadlocks boot under older global-launcher patches (#183/#307); official latest is v{{authoritative}} — retry /update after the mirror syncs.' },
226
228
  'update-mirror-lag': { zh: '镜像 registry 滞后:本次安装 v{{latest}};官方最新 v{{authoritative}},镜像同步后可再 /update。', en: 'Mirror registry lag: installing v{{latest}} now; official latest is v{{authoritative}} — run /update again once the mirror syncs.' },
229
+ 'streaming-folded': { zh: '…(前 {{count}} 字符流式期间已折叠,落定后完整显示)', en: '…(first {{count}} chars folded while streaming; full text renders once the turn settles)' },
227
230
  'vim-not-implemented': { zh: 'vim 模式暂未实现', en: 'vim mode not implemented yet' },
228
231
  'terminal-setup-hint': { zh: '推荐 Windows Terminal(≥110 列、等宽字体、TrueColor)。', en: 'Recommended: Windows Terminal (≥110 columns, monospace, TrueColor).' },
229
232
  'terminal-paste-hint': { zh: '{{mod}}V 粘贴文本、文件路径或图片;Ctrl+Shift+V 终端原生粘贴;右键粘贴同样可用。', en: '{{mod}}V pastes text, file paths, or images; Ctrl+Shift+V is native terminal paste; right-click paste also works.' },
@@ -367,7 +370,6 @@ const dict = {
367
370
  // ── 会话浏览器:行、计数、筛选、预览 ───────────────────────────────
368
371
  'session-loading': { zh: '正在读取会话…', en: 'Reading sessions…' },
369
372
  'session-list-failed': { zh: '无法读取会话列表 · {{err}}', en: 'Could not read the session list · {{err}}' },
370
- 'session-resume-refused': { zh: '无法恢复这个会话——原因已记录在对话里(模型正在工作时无法切换)', en: 'That session could not be resumed — the reason is in the conversation (switching is refused while the model is working)' },
371
373
  'session-resume-failed': { zh: '恢复会话失败 · {{err}}', en: 'Resuming the session failed · {{err}}' },
372
374
  'session-when-now': { zh: '刚刚', en: 'just now' },
373
375
  'session-when-minutes': { zh: '{{n}} 分钟前', en: '{{n}}m ago' },
@@ -471,7 +473,7 @@ const dict = {
471
473
  'plugins-check-usage': { zh: '用法:/plugins check <dsh-plugin.json 路径>', en: 'Usage: /plugins check <path-to-dsh-plugin.json>' },
472
474
  'plugins-check-not-found': { zh: '文件不存在:{{path}}', en: 'File not found: {{path}}' },
473
475
  'plugins-check-invalid-json': { zh: '不是可解析的 JSON:{{err}}', en: 'Not parseable JSON: {{err}}' },
474
- 'plugins-check-spec-unavailable': { zh: 'vendored 规范数据不可用(ecosystem-spec/),无法校验。', en: 'Vendored spec data unavailable (ecosystem-spec/); cannot validate.' },
476
+ 'plugins-check-spec-unavailable': { zh: 'vendored 规范数据不可用(dsh-ecosystem-spec/),无法校验。', en: 'Vendored spec data unavailable (dsh-ecosystem-spec/); cannot validate.' },
475
477
  'plugins-check-schema-failed': { zh: 'schema 校验失败:{{err}}', en: 'Schema validation failed: {{err}}' },
476
478
  'plugins-check-invalid': { zh: '语义校验失败:{{err}}', en: 'Semantic validation failed: {{err}}' },
477
479
  'plugins-check-state': { zh: '协商结果:{{state}}', en: 'Negotiation decision: {{state}}' },
@@ -1,2 +1,3 @@
1
+ import './force-production-react.js';
1
2
  export * from './dsh-adapter/index.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAA;AAIpC,cAAc,wBAAwB,CAAA"}
@@ -1,3 +1,4 @@
1
+ import './force-production-react.js';
1
2
  // Re-export shim: the plugin factory lives in src/dsh-adapter/index.ts
2
3
  // (the only module tree allowed to import official @deepseek-ai/* packages).
3
4
  export * from './dsh-adapter/index.js';
@@ -57,6 +57,8 @@ export default class App extends PureComponent<Props, State> {
57
57
  render(): React.JSX.Element;
58
58
  componentDidMount(): void;
59
59
  componentWillUnmount(): void;
60
+ /** Release timers and stdin ownership without requiring a React unmount. */
61
+ detachForShutdown(): void;
60
62
  componentDidCatch(error: Error): void;
61
63
  handleSetRawMode: (isEnabled: boolean) => void;
62
64
  flushIncomplete: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../../src/ink/components/App.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../../src/ink/components/App.tsx"],"names":[],"mappings":"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"}
@@ -126,6 +126,10 @@ export default class App extends PureComponent {
126
126
  if (this.props.stdout.isTTY) {
127
127
  this.props.stdout.write(SHOW_CURSOR);
128
128
  }
129
+ this.detachForShutdown();
130
+ }
131
+ /** Release timers and stdin ownership without requiring a React unmount. */
132
+ detachForShutdown() {
129
133
  // Clear any pending timers
130
134
  if (this.incompleteEscapeTimer) {
131
135
  clearTimeout(this.incompleteEscapeTimer);
@@ -18,6 +18,7 @@ export default class Ink {
18
18
  private readonly options;
19
19
  private readonly log;
20
20
  private readonly terminal;
21
+ private app;
21
22
  private scheduleRender;
22
23
  private isUnmounted;
23
24
  private isPaused;
@@ -48,6 +49,7 @@ export default class Ink {
48
49
  private readonly hoveredNodes;
49
50
  private altScreenActive;
50
51
  private altScreenMouseTracking;
52
+ private mainScreenFrameState;
51
53
  private prevFrameContaminated;
52
54
  private needsEraseBeforePaint;
53
55
  private cursorDeclaration;
@@ -78,6 +80,20 @@ export default class Ink {
78
80
  * returns, fullscreen scroll is dead.
79
81
  */
80
82
  exitAlternateScreen(): void;
83
+ /**
84
+ * One-shot viewport re-anchor for the NEXT main-screen frame: repaint the
85
+ * visible viewport in place instead of diffing. Exposed for callers that
86
+ * know a layout flip just rewrote the whole frame (Ctrl+O transcript
87
+ * toggle): the ordinary scroll-based diff pushes rows into terminal
88
+ * scrollback on every expand and nothing removes them on collapse — rapid
89
+ * toggles drift the virtual↔scrollback mapping until writes misland.
90
+ * In-place repaint adds nothing to scrollback. No-op in alt-screen
91
+ * (already CSI H-anchored every frame). ONLY sets the flag: the caller's
92
+ * own state change (setExpanded) drives the render that consumes it —
93
+ * forcing an extra render here would paint the OLD layout once more and
94
+ * burn the flag before the real frame lands.
95
+ */
96
+ reanchorViewport(): void;
81
97
  onRender(): void;
82
98
  pause(): void;
83
99
  resume(): void;
@@ -110,9 +126,9 @@ export default class Ink {
110
126
  /**
111
127
  * Called by the <AlternateScreen> component on mount/unmount.
112
128
  * Controls cursor.y clamping in the renderer and gates alt-screen-aware
113
- * behavior in SIGCONT/resize/unmount handlers. Repaints on change so
114
- * the first alt-screen frame (and first main-screen frame on exit) is
115
- * a full redraw with no stale diff state.
129
+ * behavior in SIGCONT/resize/unmount handlers. The first alt-screen frame
130
+ * redraws from blank; exit restores the saved main frame for a physical-
131
+ * screen-matched diff, with repaint as the resize fallback.
116
132
  */
117
133
  setAltScreenActive(active: boolean, mouseTracking?: boolean): void;
118
134
  get isAltScreenActive(): boolean;
@@ -328,6 +344,7 @@ export default class Ink {
328
344
  resumeStdin(): void;
329
345
  private writeRaw;
330
346
  private setCursorDeclaration;
347
+ private setAppRef;
331
348
  render(node: ReactNode): void;
332
349
  unmount(error?: Error | number | null): void;
333
350
  waitUntilExit(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
@@ -64,6 +64,7 @@ export default class Ink {
64
64
  options;
65
65
  log;
66
66
  terminal;
67
+ app = null;
67
68
  scheduleRender;
68
69
  // Ignore last render after unmounting a tree to prevent empty output before exit
69
70
  isUnmounted = false;
@@ -124,6 +125,11 @@ export default class Ink {
124
125
  // Set alongside altScreenActive so SIGCONT resume knows whether to
125
126
  // re-enable mouse tracking (not all <AlternateScreen> uses want it).
126
127
  altScreenMouseTracking = false;
128
+ // DEC 1049 preserves the physical main screen and cursor. Keep the matching
129
+ // renderer state while an inline full-screen view is active so its exit can
130
+ // diff from what the terminal actually restores instead of printing a full
131
+ // duplicate frame into main-screen scrollback.
132
+ mainScreenFrameState = null;
127
133
  // True when the previous frame's screen buffer cannot be trusted for
128
134
  // blit — selection overlay mutated it, resetFramesForAltScreen()
129
135
  // replaced it with blanks, or forceRedraw() reset it to 0×0. Forces
@@ -417,6 +423,24 @@ export default class Ink {
417
423
  // without the pop we'd accumulate depth on each editor round-trip).
418
424
  this.options.stdout.write('\x1b[?1004h' + (supportsWin32InputMode() ? ENABLE_WIN32_INPUT_MODE : supportsExtendedKeys() ? DISABLE_KITTY_KEYBOARD + ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS : ''));
419
425
  }
426
+ /**
427
+ * One-shot viewport re-anchor for the NEXT main-screen frame: repaint the
428
+ * visible viewport in place instead of diffing. Exposed for callers that
429
+ * know a layout flip just rewrote the whole frame (Ctrl+O transcript
430
+ * toggle): the ordinary scroll-based diff pushes rows into terminal
431
+ * scrollback on every expand and nothing removes them on collapse — rapid
432
+ * toggles drift the virtual↔scrollback mapping until writes misland.
433
+ * In-place repaint adds nothing to scrollback. No-op in alt-screen
434
+ * (already CSI H-anchored every frame). ONLY sets the flag: the caller's
435
+ * own state change (setExpanded) drives the render that consumes it —
436
+ * forcing an extra render here would paint the OLD layout once more and
437
+ * burn the flag before the real frame lands.
438
+ */
439
+ reanchorViewport() {
440
+ if (this.altScreenActive)
441
+ return;
442
+ this.log.requestViewportReanchor();
443
+ }
420
444
  onRender() {
421
445
  if (this.isUnmounted || this.isPaused) {
422
446
  return;
@@ -855,9 +879,9 @@ export default class Ink {
855
879
  /**
856
880
  * Called by the <AlternateScreen> component on mount/unmount.
857
881
  * Controls cursor.y clamping in the renderer and gates alt-screen-aware
858
- * behavior in SIGCONT/resize/unmount handlers. Repaints on change so
859
- * the first alt-screen frame (and first main-screen frame on exit) is
860
- * a full redraw with no stale diff state.
882
+ * behavior in SIGCONT/resize/unmount handlers. The first alt-screen frame
883
+ * redraws from blank; exit restores the saved main frame for a physical-
884
+ * screen-matched diff, with repaint as the resize fallback.
861
885
  */
862
886
  setAltScreenActive(active, mouseTracking = false) {
863
887
  if (this.altScreenActive === active)
@@ -865,10 +889,31 @@ export default class Ink {
865
889
  this.altScreenActive = active;
866
890
  this.altScreenMouseTracking = active && mouseTracking;
867
891
  if (active) {
892
+ this.mainScreenFrameState = {
893
+ frontFrame: this.frontFrame,
894
+ displayCursor: this.displayCursor,
895
+ columns: this.terminalColumns,
896
+ rows: this.terminalRows
897
+ };
868
898
  this.resetFramesForAltScreen();
869
899
  }
870
900
  else {
871
- this.repaint();
901
+ const saved = this.mainScreenFrameState;
902
+ this.mainScreenFrameState = null;
903
+ if (saved && saved.columns === this.terminalColumns && saved.rows === this.terminalRows) {
904
+ this.frontFrame = saved.frontFrame;
905
+ this.displayCursor = saved.displayCursor;
906
+ this.log.reset();
907
+ // The main React subtree may have changed while the alternate screen
908
+ // was mounted. Disable blitting once, but keep the restored frame as
909
+ // the diff baseline that matches the terminal's physical contents.
910
+ this.prevFrameContaminated = true;
911
+ }
912
+ else {
913
+ // A resize reflows the terminal's saved main buffer, so the old frame
914
+ // is no longer a trustworthy physical baseline.
915
+ this.repaint();
916
+ }
872
917
  }
873
918
  }
874
919
  get isAltScreenActive() {
@@ -954,6 +999,7 @@ export default class Ink {
954
999
  // Cancel any pending throttled render so it doesn't fire between
955
1000
  // cleanupTerminalModes() and process.exit() and write to main screen.
956
1001
  this.scheduleRender.cancel?.();
1002
+ this.app?.detachForShutdown();
957
1003
  // Shutdown bypasses the normal unmount path, so release the process and
958
1004
  // stdout listeners here as well. Otherwise a SIGCONT or resize arriving
959
1005
  // while an updater is running can re-enter the alternate screen or render
@@ -1501,9 +1547,12 @@ export default class Ink {
1501
1547
  }
1502
1548
  this.cursorDeclaration = decl;
1503
1549
  };
1550
+ setAppRef(app) {
1551
+ this.app = app;
1552
+ }
1504
1553
  render(node) {
1505
1554
  this.currentNode = node;
1506
- const tree = _jsx(App, { stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, exitOnCtrlC: this.options.exitOnCtrlC, onExit: this.unmount, terminalColumns: this.terminalColumns, terminalRows: this.terminalRows, selection: this.selection, onSelectionChange: this.notifySelectionChange, onClickAt: this.dispatchClick, onHoverAt: this.dispatchHover, getHyperlinkAt: this.getHyperlinkAt, onOpenHyperlink: this.openHyperlink, onMultiClick: this.handleMultiClick, onSelectionDrag: this.handleSelectionDrag, onStdinResume: this.reassertTerminalModes, onCursorDeclaration: this.setCursorDeclaration, dispatchKeyboardEvent: this.dispatchKeyboardEvent, children: _jsx(TerminalWriteProvider, { value: this.writeRaw, children: node }) });
1555
+ const tree = _jsx(App, { ref: this.setAppRef, stdin: this.options.stdin, stdout: this.options.stdout, stderr: this.options.stderr, exitOnCtrlC: this.options.exitOnCtrlC, onExit: this.unmount, terminalColumns: this.terminalColumns, terminalRows: this.terminalRows, selection: this.selection, onSelectionChange: this.notifySelectionChange, onClickAt: this.dispatchClick, onHoverAt: this.dispatchHover, getHyperlinkAt: this.getHyperlinkAt, onOpenHyperlink: this.openHyperlink, onMultiClick: this.handleMultiClick, onSelectionDrag: this.handleSelectionDrag, onStdinResume: this.reassertTerminalModes, onCursorDeclaration: this.setCursorDeclaration, dispatchKeyboardEvent: this.dispatchKeyboardEvent, children: _jsx(TerminalWriteProvider, { value: this.writeRaw, children: node }) });
1507
1556
  // @ts-ignore -- ported CC build; type drift tolerated updateContainerSync exists in react-reconciler but not in @types/react-reconciler
1508
1557
  reconciler.updateContainerSync(tree, this.container, null, noop);
1509
1558
  // @ts-ignore -- ported CC build; type drift tolerated flushSyncWork exists in react-reconciler but not in @types/react-reconciler
@@ -1621,6 +1670,9 @@ export default class Ink {
1621
1670
  // them at the new pools so the next frame's IDs are comparable.
1622
1671
  this.backFrame.screen.charPool = this.charPool;
1623
1672
  this.backFrame.screen.hyperlinkPool = this.hyperlinkPool;
1673
+ if (this.mainScreenFrameState) {
1674
+ migrateScreenPools(this.mainScreenFrameState.frontFrame.screen, this.charPool, this.hyperlinkPool);
1675
+ }
1624
1676
  }
1625
1677
  patchConsole() {
1626
1678
  // biome-ignore lint/suspicious/noConsole: intentionally patching global console
@@ -1 +1 @@
1
- {"version":3,"file":"log-update.d.ts","sourceRoot":"","sources":["../../../src/ink/log-update.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAiB,KAAK,EAAE,MAAM,YAAY,CAAA;AAE5D,OAAO,EASL,KAAK,SAAS,EAGf,MAAM,aAAa,CAAA;AAsBpB,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAKD;;;GAGG;AACH,qBAAa,SAAS;IAGR,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,KAAK,CAAO;gBAES,OAAO,EAAE,OAAO;IAO7C;;;;;;;;;;;;;;;;;OAiBG;IACH,uBAAuB,IAAI,IAAI;IAI/B;;;;;OAKG;IACH,+BAA+B,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IASvD,+HAA+H;IAC/H,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,eAAe;IAiDvB,OAAO,CAAC,mBAAmB;IAS3B;;;;;;;;OAQG;IACH,MAAM,CACJ,IAAI,EAAE,KAAK,EACX,IAAI,EAAE,KAAK,EACX,SAAS,UAAQ,EACjB,WAAW,UAAO,GACjB,IAAI;CAwcR"}
1
+ {"version":3,"file":"log-update.d.ts","sourceRoot":"","sources":["../../../src/ink/log-update.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,IAAI,EAAiB,KAAK,EAAE,MAAM,YAAY,CAAA;AAE5D,OAAO,EASL,KAAK,SAAS,EAGf,MAAM,aAAa,CAAA;AA4BpB,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAKD;;;GAGG;AACH,qBAAa,SAAS;IAGR,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,KAAK,CAAO;gBAES,OAAO,EAAE,OAAO;IAQ7C;;;;;;;;;;;;;;;;;OAiBG;IACH,uBAAuB,IAAI,IAAI;IAI/B;;;;;OAKG;IACH,+BAA+B,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI;IASvD,+HAA+H;IAC/H,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,eAAe;IAiDvB,OAAO,CAAC,mBAAmB;IAS3B;;;;;;;;OAQG;IACH,MAAM,CACJ,IAAI,EAAE,KAAK,EACX,IAAI,EAAE,KAAK,EACX,SAAS,UAAQ,EACjB,WAAW,UAAO,GACjB,IAAI;CAsfR"}
@@ -1,7 +1,7 @@
1
1
  import { ansiCodesToString, diffAnsiCodes, } from '@alcalzone/ansi-tokenize';
2
2
  import { logForDebugging } from '../utils/debug.js';
3
3
  import { cellAt, charInCellAt, diffEach, isEmptyCellAt, shiftRows, visibleCellAtIndex, } from './screen.js';
4
- import { CURSOR_HOME, eraseToEndOfScreen, scrollDown as csiScrollDown, scrollUp as csiScrollUp, RESET_SCROLL_REGION, SGR_RESET, setScrollRegion, } from './termio/csi.js';
4
+ import { CURSOR_HOME, cursorDown, eraseToEndOfScreen, scrollDown as csiScrollDown, scrollUp as csiScrollUp, RESET_SCROLL_REGION, SGR_RESET, setScrollRegion, } from './termio/csi.js';
5
5
  import { isJetBrainsIdeTerminal } from './terminal.js';
6
6
  import { LINK_END, link as oscLink } from './termio/osc.js';
7
7
  const CARRIAGE_RETURN = { type: 'carriageReturn' };
@@ -18,6 +18,7 @@ export class LogUpdate {
18
18
  this.state = {
19
19
  previousOutput: '',
20
20
  reanchorPending: false,
21
+ anchoredPad: 0,
21
22
  };
22
23
  }
23
24
  /**
@@ -58,6 +59,11 @@ export class LogUpdate {
58
59
  /** Drop the previous-output state after the process resumes from suspension (SIGCONT) so terminal content is not clobbered. */
59
60
  reset() {
60
61
  this.state.previousOutput = '';
62
+ // Any anchored-pad offset is void: the next frame repaints from the
63
+ // physical cursor without it (SIGCONT resume, repaint(), forceRedraw,
64
+ // and alt-screen entry all land here — without the clear, rows the
65
+ // repaint just drew at the viewport top would stay marked unreachable).
66
+ this.state.anchoredPad = 0;
61
67
  }
62
68
  renderFullFrame(frame) {
63
69
  const { screen } = frame;
@@ -134,8 +140,13 @@ export class LogUpdate {
134
140
  // not reset here but that would involve predicting the current layout
135
141
  // _after_ the viewport change which means calcuating text wrapping.
136
142
  // Resizing is a rare enough event that it's not practically a big issue.
137
- if (next.viewport.height < prev.viewport.height ||
143
+ if (next.viewport.height !== prev.viewport.height ||
138
144
  (prev.viewport.width !== 0 && next.viewport.width !== prev.viewport.width)) {
145
+ // A resize re-aligns the whole terminal (reflow rewraps scrollback):
146
+ // any anchored-pad offset from a previous shrink repaint is void.
147
+ // Height-only growth is included: the shrink branches below would
148
+ // otherwise mix the old and new viewport heights in their geometry.
149
+ this.state.anchoredPad = 0;
139
150
  return fullResetSequence_CAUSES_FLICKER(next, 'resize', stylePool);
140
151
  }
141
152
  // One-shot viewport re-anchor (see requestViewportReanchor): repaint
@@ -147,6 +158,15 @@ export class LogUpdate {
147
158
  // mutually exclusive anyway).
148
159
  if (this.state.reanchorPending && !altScreen) {
149
160
  this.state.reanchorPending = false;
161
+ // Plain in-place viewport repaint, and the anchored layout (if any)
162
+ // is superseded: pad 0. An earlier revision routed pad>0 frames
163
+ // through shrinkAnchoredRepaint here to preserve the anchored layout
164
+ // — empirically that occasionally painted nothing after alt-screen
165
+ // exits (verify-trace-scene's settle-gap check, ~15% flake), while
166
+ // the plain path is verified stable; a reanchor-with-pad is rare
167
+ // (idle gap right after a settle shrink) and its cost is one stale
168
+ // scrollback copy, not a lost paint.
169
+ this.state.anchoredPad = 0;
150
170
  return repaintViewportInPlace(prev, next, stylePool);
151
171
  }
152
172
  // DECSTBM scroll optimization: when a ScrollBox's scrollTop changed,
@@ -222,9 +242,20 @@ export class LogUpdate {
222
242
  // Use <= (not <) because even when next height equals viewport height,
223
243
  // the scrollback depth from the previous render differs from a fresh
224
244
  // render.
225
- if (prevHadScrollback && nextFitsViewport && isShrinking) {
226
- logForDebugging(`Full reset (shrink->below): prevHeight=${prev.screen.height}, nextHeight=${next.screen.height}, viewport=${prev.viewport.height}`);
227
- return fullResetSequence_CAUSES_FLICKER(next, 'offscreen', stylePool);
245
+ if (!altScreen && prevHadScrollback && nextFitsViewport && isShrinking) {
246
+ // Anchored tail repaint (see shrinkAnchoredRepaint): rows already in
247
+ // scrollback keep their originals; only the changed tail is
248
+ // repainted. The former full reset here reprinted the whole short
249
+ // frame from the viewport top — duplicating every pre-shrink row the
250
+ // user scrolls up to (the whale-logo / duplicated-transcript
251
+ // reports).
252
+ const scrollbackRows = Math.max(0, Math.max(prev.screen.height, next.screen.height) -
253
+ next.viewport.height +
254
+ (prevHadScrollback ? 1 : 0));
255
+ const { patches, anchoredPad } = shrinkAnchoredRepaint(prev, next, stylePool, scrollbackRows);
256
+ this.state.anchoredPad = anchoredPad;
257
+ logForDebugging(`Anchored shrink repaint (shrink->below): prevHeight=${prev.screen.height}, nextHeight=${next.screen.height}, viewport=${prev.viewport.height}, skip=${anchoredPad}`);
258
+ return patches;
228
259
  }
229
260
  // Steady-state scrollback check removed: rows above the viewport used
230
261
  // to force a full reset (ESC[2J+ESC[3J) whenever they changed, which
@@ -271,8 +302,16 @@ export class LogUpdate {
271
302
  if (!altScreen &&
272
303
  prev.screen.height > prev.viewport.height &&
273
304
  next.screen.height < next.viewport.height) {
274
- logForDebugging(`Full reset (shrink to fit): prevHeight=${prev.screen.height}, nextHeight=${next.screen.height}, viewport=${prev.viewport.height}`);
275
- return fullResetSequence_CAUSES_FLICKER(next, 'offscreen', this.options.stylePool);
305
+ // Same anchored tail repaint as the shrink->below branch above —
306
+ // rows already in scrollback keep their originals; only the
307
+ // non-scrollback tail is repainted. The former full reset
308
+ // reprinted the whole frame, duplicating the scrollback rows
309
+ // (whale-logo / duplicated-transcript reports).
310
+ const scrollbackRows = Math.max(0, prev.screen.height - prev.viewport.height + cursorRestoreScroll);
311
+ const { patches, anchoredPad } = shrinkAnchoredRepaint(prev, next, this.options.stylePool, scrollbackRows);
312
+ this.state.anchoredPad = anchoredPad;
313
+ logForDebugging(`Anchored shrink repaint (shrink to fit): prevHeight=${prev.screen.height}, nextHeight=${next.screen.height}, viewport=${prev.viewport.height}, skip=${anchoredPad}`);
314
+ return patches;
276
315
  }
277
316
  // eraseLines only works within the viewport - it can't clear scrollback.
278
317
  // If we need to clear more lines than fit in the viewport, some are in
@@ -298,11 +337,18 @@ export class LogUpdate {
298
337
  // an additional row out of view at the end of the previous frame. Without
299
338
  // this, the diff loop treats that row as reachable — but the cursor clamps
300
339
  // at viewport top, causing writes to land 1 row off and garbling the output.
301
- const viewportY = growing
340
+ // Unreachable frame rows = terminal scrollback. Two contributors, take
341
+ // the MAX, never the sum: after an anchored shrink repaint the pad rows
342
+ // ARE the scrollback (heights undercount while H < V); once growth
343
+ // scrolls the blank band away, the heights formula takes over (summing
344
+ // would overcount and skip REACHABLE viewport rows — changes inside
345
+ // the viewport would never paint, scrambling the layout on mid-frame
346
+ // edits like Ctrl+O expansion).
347
+ const viewportY = Math.max(this.state.anchoredPad, growing
302
348
  ? Math.max(0, prev.screen.height - prev.viewport.height + cursorRestoreScroll)
303
349
  : Math.max(prev.screen.height, next.screen.height) -
304
350
  next.viewport.height +
305
- cursorRestoreScroll;
351
+ cursorRestoreScroll);
306
352
  // Rows above viewportY live in terminal scrollback and are skipped by the
307
353
  // diff loop (see below). Clip the damage region to the visible area so the
308
354
  // loop doesn't scan scrollback rows cell-by-cell every frame — with a tall
@@ -539,6 +585,79 @@ function fullResetSequence_CAUSES_FLICKER(frame, reason, stylePool, debug) {
539
585
  renderFrameSlice(screen, frame, startY, height, stylePool, false);
540
586
  return [{ type: 'clearTerminal', reason, debug }, ...screen.diff];
541
587
  }
588
+ /**
589
+ * Anchored tail repaint for shrink-to-fit frames — the fix for the
590
+ * duplicated-whale/duplicated-transcript family. When growth pushed frame
591
+ * rows into terminal scrollback and a shrink then brings the frame back
592
+ * below the viewport, repainting the whole (short) frame from the viewport
593
+ * top re-prints rows whose originals already sit in scrollback — the user
594
+ * scrolls up and sees every pre-shrink row twice.
595
+ *
596
+ * Two layouts, decided by content:
597
+ * - The new frame's top rows are UNCHANGED from the previous frame (the
598
+ * common small shrink — a fold, a spinner unmounting): those rows
599
+ * already live in scrollback and keep their originals. Erase the
600
+ * viewport in place (no 2J — history untouched) and repaint ONLY the
601
+ * changed tail, anchored at the viewport BOTTOM so the frame continues
602
+ * the scrollback seamlessly. The leading blank band is recorded as
603
+ * `anchoredPad` so later frames' viewportY math skips the scrollback
604
+ * rows and relative addressing stays consistent (the band scrolls away
605
+ * naturally as the next turn grows).
606
+ * - The frame's top content CHANGED (a panel collapsing, 38 rows → 2):
607
+ * nothing in scrollback represents the new frame — repaint the whole
608
+ * short frame top-anchored, matching a fresh render (collapse-shrink's
609
+ * contract), pad 0.
610
+ */
611
+ function shrinkAnchoredRepaint(prev, next, stylePool, scrollbackRows) {
612
+ // Seam check, not prefix equality: the scrollback's DEEPEST row (old row
613
+ // skip-1) sits directly above the region we are about to paint — if it
614
+ // equals the new frame's row at the same index, the frame's lineage is
615
+ // intact (the shrink removed rows from the bottom region) and the
616
+ // scrollback originals stay authoritative. Volatile top rows (the
617
+ // status header's ticking counters) don't matter — only the seam does.
618
+ // Walk the skip down until the seam matches; 0 means the frame's top
619
+ // content changed (a collapsing panel) and the whole short frame gets a
620
+ // top-anchored repaint instead.
621
+ const width = Math.min(prev.screen.width, next.screen.width);
622
+ const rowsDiffer = (y) => {
623
+ if (y >= prev.screen.height || y >= next.screen.height)
624
+ return true;
625
+ const po = y * prev.screen.width * 2;
626
+ const no = y * next.screen.width * 2;
627
+ for (let x = 0; x < width * 2; x++) {
628
+ if (prev.screen.cells[po + x] !== next.screen.cells[no + x])
629
+ return true;
630
+ }
631
+ return false;
632
+ };
633
+ let skip = Math.min(scrollbackRows, next.screen.height);
634
+ while (skip > 0 && rowsDiffer(skip - 1))
635
+ skip -= 1;
636
+ const viewportHeight = prev.viewport.height;
637
+ const height = next.screen.height;
638
+ if (skip <= 0) {
639
+ // Top-anchored whole-frame repaint — the fresh-render layout.
640
+ const contentRows = Math.min(height, Math.max(1, viewportHeight - 1));
641
+ const startY = height - contentRows;
642
+ const anchor = CURSOR_HOME + eraseToEndOfScreen();
643
+ const screen = new VirtualScreen({ x: 0, y: startY }, next.viewport.width);
644
+ renderFrameSlice(screen, next, startY, height, stylePool, false);
645
+ return { patches: [{ type: 'stdout', content: anchor }, ...screen.diff], anchoredPad: 0 };
646
+ }
647
+ const rowsToPaint = Math.max(1, Math.min(height, viewportHeight - 1, height - skip));
648
+ const startY = height - rowsToPaint;
649
+ const blankBand = Math.max(0, viewportHeight - 1 - rowsToPaint);
650
+ const anchor = CURSOR_HOME + eraseToEndOfScreen() + (blankBand > 0 ? cursorDown(blankBand) : '');
651
+ const screen = new VirtualScreen({ x: 0, y: startY }, next.viewport.width);
652
+ renderFrameSlice(screen, next, startY, height, stylePool, false);
653
+ return {
654
+ patches: [{ type: 'stdout', content: anchor }, ...screen.diff],
655
+ // Cap at height-1: a seam that matches every row of a very short frame
656
+ // must not mark the WHOLE frame as scrollback — the last row (the
657
+ // input area) stays live and repaintable.
658
+ anchoredPad: Math.min(skip, height - 1),
659
+ };
660
+ }
542
661
  /**
543
662
  * Repaint the visible viewport in place — the main-screen shrink recovery
544
663
  * that replaces fullResetSequence's clearTerminal + whole-frame reprint.
@@ -22,16 +22,29 @@ type ClusteredChar = {
22
22
  * no caller can accidentally grow it unboundedly.
23
23
  */
24
24
  export declare class CharCache {
25
+ /**
26
+ * LRU of line → clustered characters. A full clear on overflow
27
+ * (the original behavior) thrashes during long-session streaming: the
28
+ * mounted window's static lines alone approach the char budget, so the
29
+ * streaming row's per-frame new keys tip it over every frame or two,
30
+ * nuking the cache and forcing ~1800 line re-tokenizations per frame
31
+ * (measured ~100ms/frame at a 175-row session). Evicting oldest-first
32
+ * keeps the hot mounted lines resident while streaming churn falls out
33
+ * the back. Recency is refreshed on hit (delete + re-insert) so lines
34
+ * read every frame are never evicted by one-shot churn.
35
+ */
25
36
  private map;
26
37
  private chars;
27
38
  /**
28
- * Return the cached clustered characters for a line, if present.
39
+ * Return the cached clustered characters for a line, if present, and
40
+ * refresh the entry's recency.
29
41
  * @param line - the line to look up.
30
42
  * @returns the cached characters, or undefined on a miss.
31
43
  */
32
44
  get(line: string): ClusteredChar[] | undefined;
33
45
  /**
34
- * Cache clustered characters for a line, enforcing the cache bounds.
46
+ * Cache clustered characters for a line, enforcing the cache bounds by
47
+ * evicting least-recently-used entries (never a full clear).
35
48
  * @param line - the line key.
36
49
  * @param characters - the clustered characters to cache.
37
50
  */
@@ -130,6 +143,19 @@ export default class Output {
130
143
  private screen;
131
144
  private readonly operations;
132
145
  private charCache;
146
+ /**
147
+ * LRU of line → recorded packed cell run, mirroring charCache's bounds.
148
+ * The main-screen architecture repaints every settled line each frame;
149
+ * the recorded run replays as raw two-word stores (no interning, no
150
+ * packing, no guard branches) — the long-session streaming fix. Runs are
151
+ * validated against the screen they were interned on and die with it.
152
+ */
153
+ private packedLines;
154
+ private packedChars;
155
+ /** Stable owner handle passed to writeLineToScreen (no per-call closure). */
156
+ private readonly packedOwner;
157
+ /** Insert into the packed-lines LRU, evicting oldest entries on budget. */
158
+ private setPackedLine;
133
159
  /**
134
160
  * Streaming-tail slot, shared by every writeLineToScreen call of this
135
161
  * Output (only one line grows per frame during streaming). Survives reset()
@@ -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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"}