@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.
- package/README.md +22 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
- package/dsh-ecosystem-spec/registry/README.md +14 -0
- package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
- package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
- package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
- package/lib/types/command-trees.d.ts +2 -1
- package/lib/types/command-trees.d.ts.map +1 -1
- package/lib/types/command-trees.js +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts +10 -5
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +18 -7
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +16 -7
- package/lib/types/components/Markdown.d.ts +13 -1
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +15 -1
- package/lib/types/components/MessageList.d.ts +3 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +90 -9
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +26 -12
- package/lib/types/components/StreamingMarkdown.d.ts +2 -8
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +51 -9
- package/lib/types/components/activityFrames.d.ts +1 -1
- package/lib/types/components/activityFrames.d.ts.map +1 -1
- package/lib/types/components/activityFrames.js +4 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
- package/lib/types/dsh-adapter/channel.d.ts +31 -4
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +267 -102
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
- package/lib/types/dsh-adapter/childStderr.js +10 -0
- package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-attribution.js +2 -2
- package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-trees.js +70 -20
- package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
- package/lib/types/dsh-adapter/component-identity.js +14 -14
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/decision-guard.js +10 -16
- package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/dialogs.js +114 -60
- package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +73 -53
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/extension-events.js +39 -1
- package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
- package/lib/types/dsh-adapter/grants.js +43 -14
- package/lib/types/dsh-adapter/host-access.d.ts +37 -0
- package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-access.js +652 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-descriptor.js +31 -8
- package/lib/types/dsh-adapter/index.d.ts +4 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +1 -0
- package/lib/types/dsh-adapter/message-observer.d.ts +10 -15
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
- package/lib/types/dsh-adapter/message-observer.js +114 -70
- package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-host.js +139 -44
- package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-storage.js +48 -36
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +80 -16
- package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
- package/lib/types/dsh-adapter/promptDebug.js +13 -4
- package/lib/types/dsh-adapter/renderers.d.ts +6 -14
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/renderers.js +81 -46
- package/lib/types/dsh-adapter/scenes.d.ts +8 -4
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +136 -37
- package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +106 -26
- package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
- package/lib/types/dsh-adapter/shortcuts.js +108 -36
- package/lib/types/dsh-adapter/status.d.ts +6 -7
- package/lib/types/dsh-adapter/status.d.ts.map +1 -1
- package/lib/types/dsh-adapter/status.js +88 -22
- package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.js +287 -170
- package/lib/types/extensions.d.ts +10 -5
- package/lib/types/extensions.d.ts.map +1 -1
- package/lib/types/extensions.js +11 -5
- package/lib/types/force-production-react.d.ts +1 -0
- package/lib/types/force-production-react.d.ts.map +1 -0
- package/lib/types/force-production-react.js +12 -0
- package/lib/types/i18n.d.ts +14 -6
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +4 -2
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/ink/components/App.d.ts +2 -0
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +4 -0
- package/lib/types/ink/ink.d.ts +20 -3
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +57 -5
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +128 -9
- package/lib/types/ink/output.d.ts +28 -2
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +158 -12
- package/lib/types/ink/screen.d.ts +39 -0
- package/lib/types/ink/screen.d.ts.map +1 -1
- package/lib/types/ink/screen.js +117 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +10 -2
- package/lib/types/ink/wrapAnsi.d.ts +1 -1
- package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
- package/lib/types/ink/wrapAnsi.js +29 -2
- package/lib/types/plugin-host.d.ts +13 -11
- package/lib/types/plugin-host.d.ts.map +1 -1
- package/lib/types/plugin-host.js +16 -16
- package/lib/types/plugin-spec/registry.d.ts +2 -2
- package/lib/types/plugin-spec/registry.d.ts.map +1 -1
- package/lib/types/plugin-spec/registry.js +113 -18
- package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
- package/lib/types/plugin-spec/tui-extension.js +2 -0
- package/lib/types/plugin-spec/validate.d.ts.map +1 -1
- package/lib/types/plugin-spec/validate.js +20 -1
- package/lib/types/scenes.d.ts +2 -1
- package/lib/types/scenes.d.ts.map +1 -1
- package/lib/types/scenes.js +1 -1
- package/lib/types/screens/Chat.d.ts +3 -3
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +38 -17
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +10 -3
- package/lib/types/sessions/view.d.ts +3 -2
- package/lib/types/sessions/view.d.ts.map +1 -1
- package/lib/types/sessions/view.js +18 -0
- package/lib/types/settings-sections.d.ts +2 -1
- package/lib/types/settings-sections.d.ts.map +1 -1
- package/lib/types/settings-sections.js +1 -1
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +3 -0
- package/lib/types/workspaces.d.ts +2 -1
- package/lib/types/workspaces.d.ts.map +1 -1
- package/lib/types/workspaces.js +1 -1
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/command/package.json +1 -1
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +1 -1
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/core/package.json +1 -1
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/manifest/package.json +1 -1
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/messages/package.json +1 -1
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/presentation/README.md +2 -1
- package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +7 -3
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/storage/package.json +1 -1
- package/package.json +10 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
- package/ecosystem-spec/registry/registry-0.15.json +0 -57
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
- /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}}' },
|
package/lib/types/index.d.ts
CHANGED
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAA;AAIpC,cAAc,wBAAwB,CAAA"}
|
package/lib/types/index.js
CHANGED
|
@@ -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);
|
package/lib/types/ink/ink.d.ts
CHANGED
|
@@ -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.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
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":"AAIA,OAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAa9C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAQrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,EAA4B,KAAK,aAAa,EAAiB,MAAM,uBAAuB,CAAC;AAIpG,OAAO,EAAqG,KAAK,SAAS,EAAgE,KAAK,cAAc,EAAqH,MAAM,gBAAgB,CAAC;AAgCzV,MAAM,MAAM,OAAO,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC,CAAC;AACF,MAAM,CAAC,OAAO,OAAO,GAAG;
|
|
1
|
+
{"version":3,"file":"ink.d.ts","sourceRoot":"","sources":["../../../src/ink/ink.tsx"],"names":[],"mappings":"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"}
|
package/lib/types/ink/ink.js
CHANGED
|
@@ -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.
|
|
859
|
-
*
|
|
860
|
-
*
|
|
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.
|
|
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;
|
|
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
|
|
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
|
-
|
|
227
|
-
|
|
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
|
-
|
|
275
|
-
|
|
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
|
-
|
|
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":"AAWA,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,sBAAsB,CAAA;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/ink/output.ts"],"names":[],"mappings":"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"}
|