@deepseek-harness-tui/dsh-tui 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -15
- package/cordis.patch.yml +21 -2
- package/cordis.yml +12 -1
- 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/decision-events-v1alpha1.json +13 -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/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
- package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -0
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
- package/dsh-ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
- package/dsh-ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
- package/dsh-ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
- package/lib/types/cc/figures.d.ts +4 -0
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +4 -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/commands.d.ts.map +1 -1
- package/lib/types/commands.js +2 -0
- package/lib/types/components/ExtensionDialog.d.ts +40 -0
- package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
- package/lib/types/components/ExtensionDialog.js +210 -0
- package/lib/types/components/HelpMenu.js +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts +5 -5
- package/lib/types/components/LoadedContextPanel.js +6 -6
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +16 -8
- 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 +111 -6
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +26 -12
- package/lib/types/components/RewindPicker.d.ts +13 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +26 -2
- 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/ToolUseLoader.d.ts +8 -3
- package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
- package/lib/types/components/ToolUseLoader.js +43 -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 +13 -2
- package/lib/types/dsh-adapter/channel.d.ts +61 -11
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +767 -120
- 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 +51 -0
- package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-attribution.js +93 -0
- package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
- package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-errors.js +63 -0
- 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 +33 -0
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
- package/lib/types/dsh-adapter/component-identity.js +108 -0
- package/lib/types/dsh-adapter/contract.d.ts +1 -1
- package/lib/types/dsh-adapter/contract.js +2 -2
- package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/decision-guard.js +348 -0
- package/lib/types/dsh-adapter/dialogs.d.ts +145 -0
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
- package/lib/types/dsh-adapter/dialogs.js +316 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts +91 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
- package/lib/types/dsh-adapter/effect-ledger.js +251 -0
- package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extension-events.js +207 -0
- package/lib/types/dsh-adapter/extensions.d.ts +32 -0
- package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extensions.js +42 -0
- package/lib/types/dsh-adapter/grants.d.ts +25 -0
- package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
- package/lib/types/dsh-adapter/grants.js +213 -0
- 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 +24 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-descriptor.js +169 -0
- 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 +173 -0
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
- package/lib/types/dsh-adapter/message-observer.js +553 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts +136 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-host.js +365 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts +108 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-storage.js +397 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +124 -14
- package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
- package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugins-info.js +276 -0
- 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 +57 -0
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
- package/lib/types/dsh-adapter/renderers.js +173 -0
- package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
- package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sanitize.js +65 -0
- package/lib/types/dsh-adapter/scenes.d.ts +15 -5
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +149 -35
- 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 +107 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
- package/lib/types/dsh-adapter/shortcuts.js +340 -0
- package/lib/types/dsh-adapter/status.d.ts +74 -0
- package/lib/types/dsh-adapter/status.d.ts.map +1 -0
- package/lib/types/dsh-adapter/status.js +234 -0
- 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 +13 -0
- package/lib/types/extensions.d.ts.map +1 -0
- package/lib/types/extensions.js +21 -0
- 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 +174 -20
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +56 -6
- 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 +31 -3
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +90 -5
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +225 -56
- package/lib/types/ink/output.d.ts +35 -2
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +281 -14
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +14 -6
- 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 +26 -6
- 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 +15 -0
- package/lib/types/plugin-host.d.ts.map +1 -0
- package/lib/types/plugin-host.js +17 -0
- package/lib/types/plugin-spec/negotiate.d.ts +11 -0
- package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
- package/lib/types/plugin-spec/negotiate.js +97 -0
- package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
- package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
- package/lib/types/plugin-spec/permission-scope.js +90 -0
- package/lib/types/plugin-spec/registry.d.ts +23 -0
- package/lib/types/plugin-spec/registry.d.ts.map +1 -0
- package/lib/types/plugin-spec/registry.js +252 -0
- package/lib/types/plugin-spec/schema-check.d.ts +17 -0
- package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
- package/lib/types/plugin-spec/schema-check.js +165 -0
- package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
- package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
- package/lib/types/plugin-spec/tui-extension.js +79 -0
- package/lib/types/plugin-spec/types.d.ts +114 -0
- package/lib/types/plugin-spec/types.d.ts.map +1 -0
- package/lib/types/plugin-spec/types.js +10 -0
- package/lib/types/plugin-spec/validate.d.ts +21 -0
- package/lib/types/plugin-spec/validate.d.ts.map +1 -0
- package/lib/types/plugin-spec/validate.js +138 -0
- 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 +14 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +173 -49
- 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/theme.d.ts +5 -0
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +15 -0
- package/lib/types/update.d.ts +20 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +54 -7
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +3 -0
- package/lib/types/utils/loaded-context.d.ts +8 -3
- package/lib/types/utils/loaded-context.d.ts.map +1 -1
- package/lib/types/utils/loaded-context.js +39 -3
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +3 -2
- package/lib/types/working-activity.d.ts +12 -0
- package/lib/types/working-activity.d.ts.map +1 -1
- package/lib/types/working-activity.js +13 -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/LICENSE +21 -0
- package/node_modules/@dsh-std/command/README.md +26 -0
- package/node_modules/@dsh-std/command/README.zh.md +28 -0
- package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
- package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/command/lib/index.js +252 -0
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/command/package.json +22 -0
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/connection/LICENSE +21 -0
- package/node_modules/@dsh-std/connection/README.md +42 -0
- package/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.js +258 -0
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/node_modules/@dsh-std/connection/package.json +20 -0
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/core/LICENSE +21 -0
- package/node_modules/@dsh-std/core/README.md +13 -0
- package/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/core/package.json +21 -0
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/manifest/LICENSE +21 -0
- package/node_modules/@dsh-std/manifest/README.md +5 -0
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
- package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
- package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/manifest/package.json +20 -0
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/messages/LICENSE +21 -0
- package/node_modules/@dsh-std/messages/README.md +5 -0
- package/node_modules/@dsh-std/messages/README.zh.md +7 -0
- package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
- package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/messages/lib/index.js +151 -0
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/messages/package.json +20 -0
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/presentation/LICENSE +21 -0
- package/node_modules/@dsh-std/presentation/README.md +27 -0
- package/node_modules/@dsh-std/presentation/README.zh.md +29 -0
- 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 +262 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/index.js +550 -0
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
- package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
- package/node_modules/@dsh-std/presentation/package.json +25 -0
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/storage/LICENSE +21 -0
- package/node_modules/@dsh-std/storage/README.md +5 -0
- package/node_modules/@dsh-std/storage/README.zh.md +7 -0
- package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
- package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/storage/lib/index.js +104 -0
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/storage/package.json +20 -0
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
- package/package.json +110 -70
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +258 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -0
- 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 +262 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +550 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +25 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +258 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
- 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/LICENSE +21 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
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
|
|
@@ -988,6 +1034,39 @@ export default class Ink {
|
|
|
988
1034
|
}
|
|
989
1035
|
}
|
|
990
1036
|
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Fully detach stdin before handing the terminal to a child process that
|
|
1039
|
+
* inherits it (the /update restart). `detachForShutdown()` restores
|
|
1040
|
+
* cooked mode but leaves the App's 'readable' pump attached — ordinary
|
|
1041
|
+
* exits don't care because the process dies right after, but a parent
|
|
1042
|
+
* that lingers waiting on the child keeps a libuv read pending on the
|
|
1043
|
+
* console and races the child for every keypress: the restarted TUI
|
|
1044
|
+
* sees dropped or entirely swallowed input (issues #284/#307). Remove
|
|
1045
|
+
* the listeners and pause the pump so the child is the sole reader.
|
|
1046
|
+
*/
|
|
1047
|
+
detachStdinForHandoff() {
|
|
1048
|
+
const stdin = this.options.stdin;
|
|
1049
|
+
try {
|
|
1050
|
+
this.drainStdin();
|
|
1051
|
+
}
|
|
1052
|
+
catch {
|
|
1053
|
+
// A destroyed stream must not block the handoff.
|
|
1054
|
+
}
|
|
1055
|
+
stdin.removeAllListeners('readable');
|
|
1056
|
+
stdin.removeAllListeners('data');
|
|
1057
|
+
try {
|
|
1058
|
+
stdin.pause();
|
|
1059
|
+
}
|
|
1060
|
+
catch {
|
|
1061
|
+
// Same destroyed-stream tolerance as above.
|
|
1062
|
+
}
|
|
1063
|
+
try {
|
|
1064
|
+
stdin.unref();
|
|
1065
|
+
}
|
|
1066
|
+
catch {
|
|
1067
|
+
// unref on a closed stream can throw on some Node versions.
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
991
1070
|
/** @see drainStdin */
|
|
992
1071
|
drainStdin() {
|
|
993
1072
|
drainStdin(this.options.stdin);
|
|
@@ -1468,9 +1547,12 @@ export default class Ink {
|
|
|
1468
1547
|
}
|
|
1469
1548
|
this.cursorDeclaration = decl;
|
|
1470
1549
|
};
|
|
1550
|
+
setAppRef(app) {
|
|
1551
|
+
this.app = app;
|
|
1552
|
+
}
|
|
1471
1553
|
render(node) {
|
|
1472
1554
|
this.currentNode = node;
|
|
1473
|
-
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 }) });
|
|
1474
1556
|
// @ts-ignore -- ported CC build; type drift tolerated updateContainerSync exists in react-reconciler but not in @types/react-reconciler
|
|
1475
1557
|
reconciler.updateContainerSync(tree, this.container, null, noop);
|
|
1476
1558
|
// @ts-ignore -- ported CC build; type drift tolerated flushSyncWork exists in react-reconciler but not in @types/react-reconciler
|
|
@@ -1588,6 +1670,9 @@ export default class Ink {
|
|
|
1588
1670
|
// them at the new pools so the next frame's IDs are comparable.
|
|
1589
1671
|
this.backFrame.screen.charPool = this.charPool;
|
|
1590
1672
|
this.backFrame.screen.hyperlinkPool = this.hyperlinkPool;
|
|
1673
|
+
if (this.mainScreenFrameState) {
|
|
1674
|
+
migrateScreenPools(this.mainScreenFrameState.frontFrame.screen, this.charPool, this.hyperlinkPool);
|
|
1675
|
+
}
|
|
1591
1676
|
}
|
|
1592
1677
|
patchConsole() {
|
|
1593
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,
|
|
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,
|
|
@@ -207,19 +227,35 @@ export class LogUpdate {
|
|
|
207
227
|
const prevHadScrollback = cursorAtBottom && prev.screen.height >= prev.viewport.height;
|
|
208
228
|
const isShrinking = next.screen.height < prev.screen.height;
|
|
209
229
|
const nextFitsViewport = next.screen.height <= prev.viewport.height;
|
|
210
|
-
// When shrinking from above-viewport to at-or-below-viewport,
|
|
211
|
-
// that
|
|
212
|
-
//
|
|
213
|
-
//
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
//
|
|
230
|
+
// When shrinking from above-viewport to at-or-below-viewport, the rows
|
|
231
|
+
// that scrolled into scrollback during growth come BACK into the live
|
|
232
|
+
// frame, so their scrollback snapshots are now duplicates (seen as the
|
|
233
|
+
// duplicated whale logo after the first turn). Use a clear-terminal
|
|
234
|
+
// reset, not an in-place repaint: at this point the UI's scrollback
|
|
235
|
+
// footprint is at most a viewport tall (prev was at most one row past
|
|
236
|
+
// the viewport), which is exactly what the clear sequence blanks — the
|
|
237
|
+
// in-place repaint kept both copies (snapshot + live). The former full
|
|
238
|
+
// reset here was once changed to an in-place repaint to stop the
|
|
239
|
+
// per-shrink stale-copy deposits (#38 #39 #19), but that fix traded
|
|
240
|
+
// them for a different duplication: the repainted viewport overlaps
|
|
241
|
+
// rows whose growth snapshots are still in scrollback.
|
|
217
242
|
// Use <= (not <) because even when next height equals viewport height,
|
|
218
243
|
// the scrollback depth from the previous render differs from a fresh
|
|
219
244
|
// render.
|
|
220
|
-
if (prevHadScrollback && nextFitsViewport && isShrinking) {
|
|
221
|
-
|
|
222
|
-
|
|
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;
|
|
223
259
|
}
|
|
224
260
|
// Steady-state scrollback check removed: rows above the viewport used
|
|
225
261
|
// to force a full reset (ESC[2J+ESC[3J) whenever they changed, which
|
|
@@ -240,21 +276,42 @@ export class LogUpdate {
|
|
|
240
276
|
const linesToClear = prev.screen.height - next.screen.height;
|
|
241
277
|
// Main-screen mode + content taller than the viewport: the terminal
|
|
242
278
|
// viewport does NOT follow the content bottom when content shrinks —
|
|
243
|
-
// a diff-loop path would write rows at stale physical offsets.
|
|
244
|
-
//
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
279
|
+
// a diff-loop path would write rows at stale physical offsets. Two
|
|
280
|
+
// sub-cases:
|
|
281
|
+
//
|
|
282
|
+
// 1. Frame shrinks but stays >= viewport height: take the ordinary
|
|
283
|
+
// diff loop. Its viewportY bookkeeping (the shrinking formula plus
|
|
284
|
+
// cursorRestoreScroll below) addresses rows through the parked
|
|
285
|
+
// cursor correctly, and the diff only touches the few rows that
|
|
286
|
+
// actually changed. A viewport repaint here re-paints the whole
|
|
287
|
+
// window from the viewport top while the frame top sits a few rows
|
|
288
|
+
// ABOVE it (frame is taller than the window) — the growth frames
|
|
289
|
+
// around the shrink freeze those overlapped rows into scrollback
|
|
290
|
+
// as snapshots while the same rows stay live in the window, which
|
|
291
|
+
// the user sees as duplicated transcript rows when scrolling up.
|
|
292
|
+
// 2. Frame shrinks to BELOW the viewport (content now fits): the rows
|
|
293
|
+
// that scrolled into scrollback during growth come BACK into the
|
|
294
|
+
// live frame, so their scrollback snapshots are now duplicates
|
|
295
|
+
// (seen as the duplicated whale logo after the first turn). Use a
|
|
296
|
+
// clear-terminal reset here, not an in-place repaint: at this
|
|
297
|
+
// point the UI's scrollback footprint is at most a viewport tall,
|
|
298
|
+
// which is exactly what the clear sequence blanks, while the
|
|
299
|
+
// in-place repaint would keep both copies. Only fires early in a
|
|
300
|
+
// session (frame ~= viewport); once the transcript outgrows the
|
|
301
|
+
// viewport, case 1 handles every shrink.
|
|
302
|
+
if (!altScreen &&
|
|
303
|
+
prev.screen.height > prev.viewport.height &&
|
|
304
|
+
next.screen.height < next.viewport.height) {
|
|
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;
|
|
258
315
|
}
|
|
259
316
|
// eraseLines only works within the viewport - it can't clear scrollback.
|
|
260
317
|
// If we need to clear more lines than fit in the viewport, some are in
|
|
@@ -280,11 +337,18 @@ export class LogUpdate {
|
|
|
280
337
|
// an additional row out of view at the end of the previous frame. Without
|
|
281
338
|
// this, the diff loop treats that row as reachable — but the cursor clamps
|
|
282
339
|
// at viewport top, causing writes to land 1 row off and garbling the output.
|
|
283
|
-
|
|
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
|
|
284
348
|
? Math.max(0, prev.screen.height - prev.viewport.height + cursorRestoreScroll)
|
|
285
349
|
: Math.max(prev.screen.height, next.screen.height) -
|
|
286
350
|
next.viewport.height +
|
|
287
|
-
cursorRestoreScroll;
|
|
351
|
+
cursorRestoreScroll);
|
|
288
352
|
// Rows above viewportY live in terminal scrollback and are skipped by the
|
|
289
353
|
// diff loop (see below). Clip the damage region to the visible area so the
|
|
290
354
|
// loop doesn't scan scrollback rows cell-by-cell every frame — with a tall
|
|
@@ -518,9 +582,82 @@ function fullResetSequence_CAUSES_FLICKER(frame, reason, stylePool, debug) {
|
|
|
518
582
|
const contentRows = Math.min(height, Math.max(1, frame.viewport.height - 1));
|
|
519
583
|
const startY = height - contentRows;
|
|
520
584
|
const screen = new VirtualScreen({ x: 0, y: startY }, frame.viewport.width);
|
|
521
|
-
renderFrameSlice(screen, frame, startY, height, stylePool);
|
|
585
|
+
renderFrameSlice(screen, frame, startY, height, stylePool, false);
|
|
522
586
|
return [{ type: 'clearTerminal', reason, debug }, ...screen.diff];
|
|
523
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
|
+
}
|
|
524
661
|
/**
|
|
525
662
|
* Repaint the visible viewport in place — the main-screen shrink recovery
|
|
526
663
|
* that replaces fullResetSequence's clearTerminal + whole-frame reprint.
|
|
@@ -576,27 +713,42 @@ function viewportRepaintPatches(prev, next, stylePool, resetPrefix, origin) {
|
|
|
576
713
|
// steady state, where the park LF materializes one row below the frame).
|
|
577
714
|
const contentRows = Math.min(height, viewportHeight - 1);
|
|
578
715
|
const startY = height - contentRows;
|
|
579
|
-
//
|
|
580
|
-
//
|
|
581
|
-
//
|
|
582
|
-
//
|
|
583
|
-
//
|
|
584
|
-
//
|
|
716
|
+
// Anchor with CSI H (cursor to viewport origin) instead of a RELATIVE
|
|
717
|
+
// cursor-up walk. The relative form assumed the physical cursor sits
|
|
718
|
+
// exactly on the park row — an assumption that breaks after a terminal
|
|
719
|
+
// reflow (a width change rewraps scrollback, shifting the buffer/cursor
|
|
720
|
+
// bookkeeping by a row or two). The over-shot cursor-up lands ABOVE the
|
|
721
|
+
// viewport top, and the subsequent erase+repaint writes a full UI copy
|
|
722
|
+
// into the scrollback (duplicated-history reports). CSI H has absolute
|
|
723
|
+
// semantics — it always lands on the current viewport's top-left — so the
|
|
724
|
+
// repaint can never cross into scrollback regardless of cursor drift.
|
|
725
|
+
// Erase down from there (BCE fill — the SGR reset guarantees the default
|
|
726
|
+
// background). The erase also blanks the park row, so no stale
|
|
585
727
|
// prompt/status pixels survive below short content.
|
|
586
|
-
const rowsToStart = origin === 'viewport-bottom' ? viewportHeight - 1 : contentRows;
|
|
587
728
|
const anchor = (resetPrefix ? SGR_RESET + LINK_END : '') +
|
|
588
|
-
|
|
589
|
-
cursorUp(rowsToStart) +
|
|
729
|
+
CURSOR_HOME +
|
|
590
730
|
eraseToEndOfScreen();
|
|
591
731
|
const screen = new VirtualScreen({ x: 0, y: startY }, next.viewport.width);
|
|
592
|
-
renderFrameSlice(screen, next, startY, height, stylePool);
|
|
732
|
+
renderFrameSlice(screen, next, startY, height, stylePool, false);
|
|
593
733
|
return [{ type: 'stdout', content: anchor }, ...screen.diff];
|
|
594
734
|
}
|
|
595
735
|
/**
|
|
596
736
|
* Render a slice of rows from the frame's screen.
|
|
597
737
|
* Each row is rendered followed by a newline. Cursor ends at (0, endY).
|
|
598
738
|
*/
|
|
599
|
-
function renderFrameSlice(screen, frame, startY, endY, stylePool
|
|
739
|
+
function renderFrameSlice(screen, frame, startY, endY, stylePool,
|
|
740
|
+
/**
|
|
741
|
+
* When false (repaint / full-reset paths), advance rows with
|
|
742
|
+
* CR + cursor-down instead of bare LFs. The repaint paints exactly a
|
|
743
|
+
* viewport of rows starting at the viewport top; a trailing LF on the
|
|
744
|
+
* bottom row SCROLLS the terminal, pushing a copy of the just-painted
|
|
745
|
+
* rows into the scrollback that the cursor bookkeeping never accounted
|
|
746
|
+
* for — every later relative move lands offset, writing content into
|
|
747
|
+
* the history (duplicated transcript rows on scroll-up). cursor-down
|
|
748
|
+
* clamps at the bottom margin instead of scrolling, so the physical
|
|
749
|
+
* cursor stays exactly where the model expects it.
|
|
750
|
+
*/
|
|
751
|
+
allowScroll = true) {
|
|
600
752
|
let currentStyleId = stylePool.none;
|
|
601
753
|
let currentHyperlink = undefined;
|
|
602
754
|
// Track the styleId of the last rendered cell on this line (-1 if none).
|
|
@@ -605,22 +757,30 @@ function renderFrameSlice(screen, frame, startY, endY, stylePool) {
|
|
|
605
757
|
const { width: screenWidth, cells, charPool, hyperlinkPool } = frame.screen;
|
|
606
758
|
let index = startY * screenWidth;
|
|
607
759
|
for (let y = startY; y < endY; y += 1) {
|
|
608
|
-
// Advance cursor to this row
|
|
609
|
-
// CSI CUD stops at the viewport bottom margin and cannot
|
|
610
|
-
// but LF scrolls the viewport to create new lines. Without this,
|
|
760
|
+
// Advance cursor to this row. With allowScroll, use LF (not CSI CUD /
|
|
761
|
+
// cursor-down): CSI CUD stops at the viewport bottom margin and cannot
|
|
762
|
+
// scroll, but LF scrolls the viewport to create new lines. Without this,
|
|
611
763
|
// when the cursor is at the viewport bottom, moveCursorTo's
|
|
612
764
|
// cursor-down silently fails, creating a permanent off-by-one
|
|
613
765
|
// between the virtual cursor and the real terminal cursor.
|
|
614
766
|
if (screen.cursor.y < y) {
|
|
615
767
|
const rowsToAdvance = y - screen.cursor.y;
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
768
|
+
if (allowScroll) {
|
|
769
|
+
screen.txn(prev => {
|
|
770
|
+
const patches = new Array(1 + rowsToAdvance);
|
|
771
|
+
patches[0] = CARRIAGE_RETURN;
|
|
772
|
+
for (let i = 0; i < rowsToAdvance; i++) {
|
|
773
|
+
patches[1 + i] = NEWLINE;
|
|
774
|
+
}
|
|
775
|
+
return [patches, { dx: -prev.x, dy: rowsToAdvance }];
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
screen.txn(prev => [
|
|
780
|
+
[CARRIAGE_RETURN, { type: 'cursorMove', x: 0, y: rowsToAdvance }],
|
|
781
|
+
{ dx: -prev.x, dy: rowsToAdvance },
|
|
782
|
+
]);
|
|
783
|
+
}
|
|
624
784
|
}
|
|
625
785
|
// Reset at start of each line — no cell rendered yet
|
|
626
786
|
lastRenderedStyleId = -1;
|
|
@@ -650,10 +810,19 @@ function renderFrameSlice(screen, frame, startY, endY, stylePool) {
|
|
|
650
810
|
// skip empty cells, we must reset explicitly.
|
|
651
811
|
currentStyleId = transitionStyle(screen.diff, stylePool, currentStyleId, stylePool.none);
|
|
652
812
|
currentHyperlink = transitionHyperlink(screen.diff, currentHyperlink, undefined);
|
|
653
|
-
// CR+LF at end of row —
|
|
654
|
-
// Without \r, the terminal cursor stays at
|
|
655
|
-
// (since we skip trailing spaces, this
|
|
656
|
-
|
|
813
|
+
// CR+LF (or CR+cursor-down for non-scrolling slices) at end of row —
|
|
814
|
+
// \r resets to column 0. Without \r, the terminal cursor stays at
|
|
815
|
+
// whatever column content ended (since we skip trailing spaces, this
|
|
816
|
+
// can be mid-row).
|
|
817
|
+
if (allowScroll) {
|
|
818
|
+
screen.txn(prev => [[CARRIAGE_RETURN, NEWLINE], { dx: -prev.x, dy: 1 }]);
|
|
819
|
+
}
|
|
820
|
+
else {
|
|
821
|
+
screen.txn(prev => [
|
|
822
|
+
[CARRIAGE_RETURN, { type: 'cursorMove', x: 0, y: 1 }],
|
|
823
|
+
{ dx: -prev.x, dy: 1 },
|
|
824
|
+
]);
|
|
825
|
+
}
|
|
657
826
|
}
|
|
658
827
|
// Reset any open style/hyperlink at end of slice
|
|
659
828
|
transitionStyle(screen.diff, stylePool, currentStyleId, stylePool.none);
|
|
@@ -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,26 @@ 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;
|
|
159
|
+
/**
|
|
160
|
+
* Streaming-tail slot, shared by every writeLineToScreen call of this
|
|
161
|
+
* Output (only one line grows per frame during streaming). Survives reset()
|
|
162
|
+
* like charCache - it is keyed by strict line extension, so stale entries
|
|
163
|
+
* can never produce a wrong hit.
|
|
164
|
+
*/
|
|
165
|
+
private streamingSlot;
|
|
133
166
|
constructor(options: Options);
|
|
134
167
|
/**
|
|
135
168
|
* Reuse this Output for a new frame. Zeroes the screen buffer, clears
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/ink/output.ts"],"names":[],"mappings":"
|
|
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,EAaL,KAAK,MAAM,EACX,KAAK,SAAS,EAIf,MAAM,aAAa,CAAA;AAIpB;;;;;;;;;GASG;AACH,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAC9B,CAAA;AAsCD;;;;GAIG;AACH,qBAAa,SAAS;IACpB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,GAAG,CAAqC;IAChD,OAAO,CAAC,KAAK,CAAI;IAEjB;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,SAAS;IAS9C;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,IAAI;IAuBpD,mEAAmE;IACnE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,qCAAqC;IACrC,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED;;;;GAIG;AACH,KAAK,OAAO,GAAG;IACb,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,CAAA;IACpB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,sFAAsF;AACtF,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,aAAa,GACb,eAAe,GACf,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,cAAc,CAAA;AAElB,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,OAAO,CAAA;IACb,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;CACrB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACX,CAAA;AAED,uEAAuE;AACvE,MAAM,MAAM,IAAI,GAAG;IACjB,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;CACvB,CAAA;AAoCD,KAAK,eAAe,GAAG;IACrB,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,SAAS,CAAA;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,KAAK,iBAAiB,GAAG;IACvB,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,SAAS,CAAA;CAClB,CAAA;AAkKD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAE7C,OAAO,CAAC,SAAS,CAAkB;IAEnC;;;;;;OAMG;IACH,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,WAAW,CAAI;IAEvB,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAK3B;IAED,2EAA2E;IAC3E,OAAO,CAAC,aAAa;IAmBrB;;;;;OAKG;IACH,OAAO,CAAC,aAAa,CAA2D;gBAEpE,OAAO,EAAE,OAAO;IAW5B;;;;;;;;;OASG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAW1D;;;;;;;OAOG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5E;;;;;;;OAOG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAInD;;;;;OAKG;IACH,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI;IAItD;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIjC;;;;;;OAMG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI;IAcrE;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAOtB,uCAAuC;IACvC,MAAM,IAAI,IAAI;IAMd;;;OAGG;IACH,GAAG,IAAI,MAAM;CA+Qd"}
|