@askdkc/dsh-cli 0.11.3
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/LICENSE +21 -0
- package/README.md +321 -0
- package/bin/dsh-tui.js +1366 -0
- package/cordis.patch.yml +482 -0
- package/cordis.yml +250 -0
- 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/activityPrefs.d.ts +63 -0
- package/lib/types/activityPrefs.d.ts.map +1 -0
- package/lib/types/activityPrefs.js +126 -0
- package/lib/types/adapter/channel/actions.d.ts +17 -0
- package/lib/types/adapter/channel/actions.d.ts.map +1 -0
- package/lib/types/adapter/channel/actions.js +28 -0
- package/lib/types/adapter/channel/consumer.d.ts +34 -0
- package/lib/types/adapter/channel/consumer.d.ts.map +1 -0
- package/lib/types/adapter/channel/consumer.js +87 -0
- package/lib/types/adapter/channel/features.d.ts +12 -0
- package/lib/types/adapter/channel/features.d.ts.map +1 -0
- package/lib/types/adapter/channel/features.js +41 -0
- package/lib/types/adapter/channel/host-registry.d.ts +40 -0
- package/lib/types/adapter/channel/host-registry.d.ts.map +1 -0
- package/lib/types/adapter/channel/host-registry.js +120 -0
- package/lib/types/adapter/channel/index.d.ts +22 -0
- package/lib/types/adapter/channel/index.d.ts.map +1 -0
- package/lib/types/adapter/channel/index.js +21 -0
- package/lib/types/adapter/channel/internal-token.d.ts +12 -0
- package/lib/types/adapter/channel/internal-token.d.ts.map +1 -0
- package/lib/types/adapter/channel/internal-token.js +11 -0
- package/lib/types/adapter/channel/plugins.d.ts +17 -0
- package/lib/types/adapter/channel/plugins.d.ts.map +1 -0
- package/lib/types/adapter/channel/plugins.js +47 -0
- package/lib/types/adapter/channel/projection.d.ts +15 -0
- package/lib/types/adapter/channel/projection.d.ts.map +1 -0
- package/lib/types/adapter/channel/projection.js +59 -0
- package/lib/types/adapter/channel/provider.d.ts +52 -0
- package/lib/types/adapter/channel/provider.d.ts.map +1 -0
- package/lib/types/adapter/channel/provider.js +231 -0
- package/lib/types/adapter/channel/read-view.d.ts +4 -0
- package/lib/types/adapter/channel/read-view.d.ts.map +1 -0
- package/lib/types/adapter/channel/read-view.js +132 -0
- package/lib/types/adapter/channel/session-projection.d.ts +56 -0
- package/lib/types/adapter/channel/session-projection.d.ts.map +1 -0
- package/lib/types/adapter/channel/session-projection.js +249 -0
- package/lib/types/adapter/channel/state.d.ts +11 -0
- package/lib/types/adapter/channel/state.d.ts.map +1 -0
- package/lib/types/adapter/channel/state.js +57 -0
- package/lib/types/adapter/channel/transcript.d.ts +15 -0
- package/lib/types/adapter/channel/transcript.d.ts.map +1 -0
- package/lib/types/adapter/channel/transcript.js +22 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +109 -0
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -0
- package/lib/types/adapter/channel/ui-policy.js +170 -0
- package/lib/types/adapter/channel/ui.d.ts +16 -0
- package/lib/types/adapter/channel/ui.d.ts.map +1 -0
- package/lib/types/adapter/channel/ui.js +173 -0
- package/lib/types/adapter/index.d.ts +20 -0
- package/lib/types/adapter/index.d.ts.map +1 -0
- package/lib/types/adapter/index.js +19 -0
- package/lib/types/adapter/kernel/contract-catalog.d.ts +12 -0
- package/lib/types/adapter/kernel/contract-catalog.d.ts.map +1 -0
- package/lib/types/adapter/kernel/contract-catalog.js +11 -0
- package/lib/types/adapter/kernel/diagnostics.d.ts +18 -0
- package/lib/types/adapter/kernel/diagnostics.d.ts.map +1 -0
- package/lib/types/adapter/kernel/diagnostics.js +16 -0
- package/lib/types/adapter/kernel/driver-types.d.ts +16 -0
- package/lib/types/adapter/kernel/driver-types.d.ts.map +1 -0
- package/lib/types/adapter/kernel/driver-types.js +8 -0
- package/lib/types/adapter/kernel/host-facade.d.ts +65 -0
- package/lib/types/adapter/kernel/host-facade.d.ts.map +1 -0
- package/lib/types/adapter/kernel/host-facade.js +216 -0
- package/lib/types/adapter/kernel/host-probe-access.d.ts +71 -0
- package/lib/types/adapter/kernel/host-probe-access.d.ts.map +1 -0
- package/lib/types/adapter/kernel/host-probe-access.js +121 -0
- package/lib/types/adapter/kernel/index.d.ts +20 -0
- package/lib/types/adapter/kernel/index.d.ts.map +1 -0
- package/lib/types/adapter/kernel/index.js +19 -0
- package/lib/types/adapter/kernel/kernel-runtime.d.ts +138 -0
- package/lib/types/adapter/kernel/kernel-runtime.d.ts.map +1 -0
- package/lib/types/adapter/kernel/kernel-runtime.js +572 -0
- package/lib/types/adapter/kernel/ledger.d.ts +55 -0
- package/lib/types/adapter/kernel/ledger.d.ts.map +1 -0
- package/lib/types/adapter/kernel/ledger.js +33 -0
- package/lib/types/adapter/kernel/legacy-facade.d.ts +22 -0
- package/lib/types/adapter/kernel/legacy-facade.d.ts.map +1 -0
- package/lib/types/adapter/kernel/legacy-facade.js +34 -0
- package/lib/types/adapter/kernel/lifecycle.d.ts +38 -0
- package/lib/types/adapter/kernel/lifecycle.d.ts.map +1 -0
- package/lib/types/adapter/kernel/lifecycle.js +53 -0
- package/lib/types/adapter/kernel/replay-isolation.d.ts +27 -0
- package/lib/types/adapter/kernel/replay-isolation.d.ts.map +1 -0
- package/lib/types/adapter/kernel/replay-isolation.js +45 -0
- package/lib/types/adapter/kernel/replay.d.ts +132 -0
- package/lib/types/adapter/kernel/replay.d.ts.map +1 -0
- package/lib/types/adapter/kernel/replay.js +428 -0
- package/lib/types/adapter/kernel/runtime-context.d.ts +15 -0
- package/lib/types/adapter/kernel/runtime-context.d.ts.map +1 -0
- package/lib/types/adapter/kernel/runtime-context.js +24 -0
- package/lib/types/adapter/kernel/runtime.d.ts +70 -0
- package/lib/types/adapter/kernel/runtime.d.ts.map +1 -0
- package/lib/types/adapter/kernel/runtime.js +327 -0
- package/lib/types/adapter/kernel/slices/channel.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/channel.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/channel.js +8 -0
- package/lib/types/adapter/kernel/slices/decisions.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/decisions.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/decisions.js +10 -0
- package/lib/types/adapter/kernel/slices/extensions.d.ts +8 -0
- package/lib/types/adapter/kernel/slices/extensions.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/extensions.js +43 -0
- package/lib/types/adapter/kernel/slices/index.d.ts +19 -0
- package/lib/types/adapter/kernel/slices/index.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/index.js +36 -0
- package/lib/types/adapter/kernel/slices/presentation.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/presentation.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/presentation.js +14 -0
- package/lib/types/adapter/kernel/slices/scenes.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/scenes.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/scenes.js +14 -0
- package/lib/types/adapter/kernel/slices/settings.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/settings.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/settings.js +12 -0
- package/lib/types/adapter/kernel/slices/types.d.ts +20 -0
- package/lib/types/adapter/kernel/slices/types.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/types.js +12 -0
- package/lib/types/adapter/kernel/slices/workspace.d.ts +3 -0
- package/lib/types/adapter/kernel/slices/workspace.d.ts.map +1 -0
- package/lib/types/adapter/kernel/slices/workspace.js +16 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts +90 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-catalog.js +2 -0
- package/lib/types/adapter/ports/channel-display.d.ts +90 -0
- package/lib/types/adapter/ports/channel-display.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-display.js +2 -0
- package/lib/types/adapter/ports/channel-session.d.ts +229 -0
- package/lib/types/adapter/ports/channel-session.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-session.js +2 -0
- package/lib/types/adapter/ports/channel-settings.d.ts +279 -0
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-settings.js +1 -0
- package/lib/types/adapter/ports/channel-ui.d.ts +593 -0
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-ui.js +1 -0
- package/lib/types/adapter/ports/channel-view.d.ts +663 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-view.js +2 -0
- package/lib/types/adapter/ports/channel-workspace.d.ts +68 -0
- package/lib/types/adapter/ports/channel-workspace.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel-workspace.js +2 -0
- package/lib/types/adapter/ports/channel.d.ts +148 -0
- package/lib/types/adapter/ports/channel.d.ts.map +1 -0
- package/lib/types/adapter/ports/channel.js +22 -0
- package/lib/types/adapter/ports/decisions.d.ts +18 -0
- package/lib/types/adapter/ports/decisions.d.ts.map +1 -0
- package/lib/types/adapter/ports/decisions.js +9 -0
- package/lib/types/adapter/ports/descriptor.d.ts +25 -0
- package/lib/types/adapter/ports/descriptor.d.ts.map +1 -0
- package/lib/types/adapter/ports/descriptor.js +11 -0
- package/lib/types/adapter/ports/extensions.d.ts +86 -0
- package/lib/types/adapter/ports/extensions.d.ts.map +1 -0
- package/lib/types/adapter/ports/extensions.js +9 -0
- package/lib/types/adapter/ports/index.d.ts +23 -0
- package/lib/types/adapter/ports/index.d.ts.map +1 -0
- package/lib/types/adapter/ports/index.js +14 -0
- package/lib/types/adapter/ports/owner.d.ts +19 -0
- package/lib/types/adapter/ports/owner.d.ts.map +1 -0
- package/lib/types/adapter/ports/owner.js +9 -0
- package/lib/types/adapter/ports/presentation.d.ts +81 -0
- package/lib/types/adapter/ports/presentation.d.ts.map +1 -0
- package/lib/types/adapter/ports/presentation.js +10 -0
- package/lib/types/adapter/ports/scenes.d.ts +24 -0
- package/lib/types/adapter/ports/scenes.d.ts.map +1 -0
- package/lib/types/adapter/ports/scenes.js +8 -0
- package/lib/types/adapter/ports/settings.d.ts +44 -0
- package/lib/types/adapter/ports/settings.d.ts.map +1 -0
- package/lib/types/adapter/ports/settings.js +9 -0
- package/lib/types/adapter/ports/workspace.d.ts +62 -0
- package/lib/types/adapter/ports/workspace.d.ts.map +1 -0
- package/lib/types/adapter/ports/workspace.js +8 -0
- package/lib/types/adapter/spec/index.d.ts +11 -0
- package/lib/types/adapter/spec/index.d.ts.map +1 -0
- package/lib/types/adapter/spec/index.js +10 -0
- package/lib/types/adapter/spec/profile.d.ts +10 -0
- package/lib/types/adapter/spec/profile.d.ts.map +1 -0
- package/lib/types/adapter/spec/profile.js +9 -0
- package/lib/types/adapter/spec/protocol-constants.d.ts +60 -0
- package/lib/types/adapter/spec/protocol-constants.d.ts.map +1 -0
- package/lib/types/adapter/spec/protocol-constants.js +129 -0
- package/lib/types/adapter/spec/tui-contributions.d.ts +18 -0
- package/lib/types/adapter/spec/tui-contributions.d.ts.map +1 -0
- package/lib/types/adapter/spec/tui-contributions.js +19 -0
- package/lib/types/adapter/standard/admission.d.ts +11 -0
- package/lib/types/adapter/standard/admission.d.ts.map +1 -0
- package/lib/types/adapter/standard/admission.js +10 -0
- package/lib/types/adapter/standard/descriptor.d.ts +74 -0
- package/lib/types/adapter/standard/descriptor.d.ts.map +1 -0
- package/lib/types/adapter/standard/descriptor.js +356 -0
- package/lib/types/adapter/standard/grants.d.ts +30 -0
- package/lib/types/adapter/standard/grants.d.ts.map +1 -0
- package/lib/types/adapter/standard/grants.js +219 -0
- package/lib/types/adapter/standard/index.d.ts +25 -0
- package/lib/types/adapter/standard/index.d.ts.map +1 -0
- package/lib/types/adapter/standard/index.js +24 -0
- package/lib/types/adapter/standard/negotiate.d.ts +11 -0
- package/lib/types/adapter/standard/negotiate.d.ts.map +1 -0
- package/lib/types/adapter/standard/negotiate.js +97 -0
- package/lib/types/adapter/standard/permission-scope.d.ts +27 -0
- package/lib/types/adapter/standard/permission-scope.d.ts.map +1 -0
- package/lib/types/adapter/standard/permission-scope.js +68 -0
- package/lib/types/adapter/standard/protocols.d.ts +12 -0
- package/lib/types/adapter/standard/protocols.d.ts.map +1 -0
- package/lib/types/adapter/standard/protocols.js +11 -0
- package/lib/types/adapter/standard/registry.d.ts +23 -0
- package/lib/types/adapter/standard/registry.d.ts.map +1 -0
- package/lib/types/adapter/standard/registry.js +240 -0
- package/lib/types/adapter/standard/schema-check.d.ts +17 -0
- package/lib/types/adapter/standard/schema-check.d.ts.map +1 -0
- package/lib/types/adapter/standard/schema-check.js +167 -0
- package/lib/types/adapter/standard/tui-extension.d.ts +25 -0
- package/lib/types/adapter/standard/tui-extension.d.ts.map +1 -0
- package/lib/types/adapter/standard/tui-extension.js +45 -0
- package/lib/types/adapter/standard/types.d.ts +108 -0
- package/lib/types/adapter/standard/types.d.ts.map +1 -0
- package/lib/types/adapter/standard/types.js +10 -0
- package/lib/types/adapter/standard/validate.d.ts +21 -0
- package/lib/types/adapter/standard/validate.d.ts.map +1 -0
- package/lib/types/adapter/standard/validate.js +139 -0
- package/lib/types/adapter/upstream/channel-driver.d.ts +22 -0
- package/lib/types/adapter/upstream/channel-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/channel-driver.js +424 -0
- package/lib/types/adapter/upstream/decisions-driver.d.ts +15 -0
- package/lib/types/adapter/upstream/decisions-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/decisions-driver.js +141 -0
- package/lib/types/adapter/upstream/detection.d.ts +26 -0
- package/lib/types/adapter/upstream/detection.d.ts.map +1 -0
- package/lib/types/adapter/upstream/detection.js +9 -0
- package/lib/types/adapter/upstream/driver.d.ts +50 -0
- package/lib/types/adapter/upstream/driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/driver.js +8 -0
- package/lib/types/adapter/upstream/extensions-driver.d.ts +24 -0
- package/lib/types/adapter/upstream/extensions-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/extensions-driver.js +697 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.d.ts +45 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/host-descriptor-driver.js +606 -0
- package/lib/types/adapter/upstream/index.d.ts +18 -0
- package/lib/types/adapter/upstream/index.d.ts.map +1 -0
- package/lib/types/adapter/upstream/index.js +15 -0
- package/lib/types/adapter/upstream/presentation-driver.d.ts +17 -0
- package/lib/types/adapter/upstream/presentation-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/presentation-driver.js +129 -0
- package/lib/types/adapter/upstream/scenes-driver.d.ts +18 -0
- package/lib/types/adapter/upstream/scenes-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/scenes-driver.js +170 -0
- package/lib/types/adapter/upstream/settings-driver.d.ts +20 -0
- package/lib/types/adapter/upstream/settings-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/settings-driver.js +173 -0
- package/lib/types/adapter/upstream/workspace-driver.d.ts +19 -0
- package/lib/types/adapter/upstream/workspace-driver.d.ts.map +1 -0
- package/lib/types/adapter/upstream/workspace-driver.js +198 -0
- package/lib/types/api.d.ts +7 -0
- package/lib/types/api.d.ts.map +1 -0
- package/lib/types/api.js +1 -0
- package/lib/types/bootstrap/state.d.ts +11 -0
- package/lib/types/bootstrap/state.d.ts.map +1 -0
- package/lib/types/bootstrap/state.js +10 -0
- package/lib/types/command-trees.d.ts +4 -0
- package/lib/types/command-trees.d.ts.map +1 -0
- package/lib/types/command-trees.js +4 -0
- package/lib/types/commands.d.ts +87 -0
- package/lib/types/commands.d.ts.map +1 -0
- package/lib/types/commands.js +218 -0
- package/lib/types/components/ActivityLine.d.ts +34 -0
- package/lib/types/components/ActivityLine.d.ts.map +1 -0
- package/lib/types/components/ActivityLine.js +39 -0
- package/lib/types/components/ActivityPicker.d.ts +16 -0
- package/lib/types/components/ActivityPicker.d.ts.map +1 -0
- package/lib/types/components/ActivityPicker.js +23 -0
- package/lib/types/components/AutoRecapRow.d.ts +23 -0
- package/lib/types/components/AutoRecapRow.d.ts.map +1 -0
- package/lib/types/components/AutoRecapRow.js +23 -0
- package/lib/types/components/BalanceReportRow.d.ts +24 -0
- package/lib/types/components/BalanceReportRow.d.ts.map +1 -0
- package/lib/types/components/BalanceReportRow.js +87 -0
- package/lib/types/components/BtwPanel.d.ts +16 -0
- package/lib/types/components/BtwPanel.d.ts.map +1 -0
- package/lib/types/components/BtwPanel.js +47 -0
- package/lib/types/components/Chat/JobCard.d.ts +23 -0
- package/lib/types/components/Chat/JobCard.d.ts.map +1 -0
- package/lib/types/components/Chat/JobCard.js +93 -0
- package/lib/types/components/Chat/SubagentMessage.d.ts +20 -0
- package/lib/types/components/Chat/SubagentMessage.d.ts.map +1 -0
- package/lib/types/components/Chat/SubagentMessage.js +83 -0
- package/lib/types/components/ColorPicker.d.ts +17 -0
- package/lib/types/components/ColorPicker.d.ts.map +1 -0
- package/lib/types/components/ColorPicker.js +20 -0
- package/lib/types/components/CommandSuggestions.d.ts +34 -0
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -0
- package/lib/types/components/CommandSuggestions.js +61 -0
- package/lib/types/components/ContextBarView.d.ts +41 -0
- package/lib/types/components/ContextBarView.d.ts.map +1 -0
- package/lib/types/components/ContextBarView.js +50 -0
- package/lib/types/components/EffortChargeGlyph.d.ts +26 -0
- package/lib/types/components/EffortChargeGlyph.d.ts.map +1 -0
- package/lib/types/components/EffortChargeGlyph.js +70 -0
- package/lib/types/components/EffortInputBorder.d.ts +47 -0
- package/lib/types/components/EffortInputBorder.d.ts.map +1 -0
- package/lib/types/components/EffortInputBorder.js +90 -0
- package/lib/types/components/EffortSlider.d.ts +18 -0
- package/lib/types/components/EffortSlider.d.ts.map +1 -0
- package/lib/types/components/EffortSlider.js +19 -0
- package/lib/types/components/EffortTierBadge.d.ts +26 -0
- package/lib/types/components/EffortTierBadge.d.ts.map +1 -0
- package/lib/types/components/EffortTierBadge.js +97 -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 +253 -0
- package/lib/types/components/FileActionsPanel.d.ts +22 -0
- package/lib/types/components/FileActionsPanel.d.ts.map +1 -0
- package/lib/types/components/FileActionsPanel.js +28 -0
- package/lib/types/components/FileSuggestions.d.ts +18 -0
- package/lib/types/components/FileSuggestions.d.ts.map +1 -0
- package/lib/types/components/FileSuggestions.js +78 -0
- package/lib/types/components/GoalTodoPanel.d.ts +38 -0
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -0
- package/lib/types/components/GoalTodoPanel.js +131 -0
- package/lib/types/components/HelpMenu.d.ts +29 -0
- package/lib/types/components/HelpMenu.d.ts.map +1 -0
- package/lib/types/components/HelpMenu.js +39 -0
- package/lib/types/components/HistorySearchDialog.d.ts +18 -0
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -0
- package/lib/types/components/HistorySearchDialog.js +47 -0
- package/lib/types/components/ImagePreviewOverlay.d.ts +51 -0
- package/lib/types/components/ImagePreviewOverlay.d.ts.map +1 -0
- package/lib/types/components/ImagePreviewOverlay.js +269 -0
- package/lib/types/components/JobsPanel.d.ts +17 -0
- package/lib/types/components/JobsPanel.d.ts.map +1 -0
- package/lib/types/components/JobsPanel.js +111 -0
- package/lib/types/components/LangPicker.d.ts +14 -0
- package/lib/types/components/LangPicker.d.ts.map +1 -0
- package/lib/types/components/LangPicker.js +17 -0
- package/lib/types/components/LoadedContextPanel.d.ts +20 -0
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -0
- package/lib/types/components/LoadedContextPanel.js +32 -0
- package/lib/types/components/LogoV2.d.ts +48 -0
- package/lib/types/components/LogoV2.d.ts.map +1 -0
- package/lib/types/components/LogoV2.js +239 -0
- package/lib/types/components/Markdown.d.ts +46 -0
- package/lib/types/components/Markdown.d.ts.map +1 -0
- package/lib/types/components/Markdown.js +178 -0
- package/lib/types/components/MarkdownTable.d.ts +13 -0
- package/lib/types/components/MarkdownTable.d.ts.map +1 -0
- package/lib/types/components/MarkdownTable.js +155 -0
- package/lib/types/components/MermaidDiagram.d.ts +13 -0
- package/lib/types/components/MermaidDiagram.d.ts.map +1 -0
- package/lib/types/components/MermaidDiagram.js +61 -0
- package/lib/types/components/MessageList.d.ts +144 -0
- package/lib/types/components/MessageList.d.ts.map +1 -0
- package/lib/types/components/MessageList.js +1170 -0
- package/lib/types/components/MigratePicker.d.ts +30 -0
- package/lib/types/components/MigratePicker.d.ts.map +1 -0
- package/lib/types/components/MigratePicker.js +38 -0
- package/lib/types/components/ModelPicker.d.ts +42 -0
- package/lib/types/components/ModelPicker.d.ts.map +1 -0
- package/lib/types/components/ModelPicker.js +51 -0
- package/lib/types/components/OverlayAbove.d.ts +48 -0
- package/lib/types/components/OverlayAbove.d.ts.map +1 -0
- package/lib/types/components/OverlayAbove.js +98 -0
- package/lib/types/components/PageMargin.d.ts +58 -0
- package/lib/types/components/PageMargin.d.ts.map +1 -0
- package/lib/types/components/PageMargin.js +38 -0
- package/lib/types/components/PermissionsPicker.d.ts +20 -0
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -0
- package/lib/types/components/PermissionsPicker.js +33 -0
- package/lib/types/components/PlanPicker.d.ts +15 -0
- package/lib/types/components/PlanPicker.d.ts.map +1 -0
- package/lib/types/components/PlanPicker.js +18 -0
- package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
- package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
- package/lib/types/components/PluginSceneBoundary.js +29 -0
- package/lib/types/components/PluginStatusViewBoundary.d.ts +26 -0
- package/lib/types/components/PluginStatusViewBoundary.d.ts.map +1 -0
- package/lib/types/components/PluginStatusViewBoundary.js +22 -0
- package/lib/types/components/PresetPicker.d.ts +20 -0
- package/lib/types/components/PresetPicker.d.ts.map +1 -0
- package/lib/types/components/PresetPicker.js +24 -0
- package/lib/types/components/PromptEditor.d.ts +48 -0
- package/lib/types/components/PromptEditor.d.ts.map +1 -0
- package/lib/types/components/PromptEditor.js +75 -0
- package/lib/types/components/PromptInput.d.ts +163 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -0
- package/lib/types/components/PromptInput.js +3503 -0
- package/lib/types/components/RecapPanel.d.ts +25 -0
- package/lib/types/components/RecapPanel.d.ts.map +1 -0
- package/lib/types/components/RecapPanel.js +55 -0
- package/lib/types/components/RewindPicker.d.ts +37 -0
- package/lib/types/components/RewindPicker.d.ts.map +1 -0
- package/lib/types/components/RewindPicker.js +66 -0
- package/lib/types/components/ScrollbarGutter.d.ts +43 -0
- package/lib/types/components/ScrollbarGutter.d.ts.map +1 -0
- package/lib/types/components/ScrollbarGutter.js +197 -0
- package/lib/types/components/SearchBox.d.ts +24 -0
- package/lib/types/components/SearchBox.d.ts.map +1 -0
- package/lib/types/components/SearchBox.js +132 -0
- package/lib/types/components/Select.d.ts +29 -0
- package/lib/types/components/Select.d.ts.map +1 -0
- package/lib/types/components/Select.js +21 -0
- package/lib/types/components/SkillsPicker.d.ts +21 -0
- package/lib/types/components/SkillsPicker.d.ts.map +1 -0
- package/lib/types/components/SkillsPicker.js +52 -0
- package/lib/types/components/Spinner/GlimmerMessage.d.ts +16 -0
- package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -0
- package/lib/types/components/Spinner/GlimmerMessage.js +57 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +33 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +168 -0
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts +16 -0
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts.map +1 -0
- package/lib/types/components/Spinner/SpinnerGlyph.js +36 -0
- package/lib/types/components/Spinner/spinnerMode.d.ts +2 -0
- package/lib/types/components/Spinner/spinnerMode.d.ts.map +1 -0
- package/lib/types/components/Spinner/spinnerMode.js +1 -0
- package/lib/types/components/Spinner/spinnerUtils.d.ts +36 -0
- package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -0
- package/lib/types/components/Spinner/spinnerUtils.js +94 -0
- package/lib/types/components/Spinner/useStalledAnimation.d.ts +16 -0
- package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -0
- package/lib/types/components/Spinner/useStalledAnimation.js +52 -0
- package/lib/types/components/SplitDiffView.d.ts +25 -0
- package/lib/types/components/SplitDiffView.d.ts.map +1 -0
- package/lib/types/components/SplitDiffView.js +279 -0
- package/lib/types/components/StreamingMarkdown.d.ts +6 -0
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -0
- package/lib/types/components/StreamingMarkdown.js +279 -0
- package/lib/types/components/SubagentCard.d.ts +10 -0
- package/lib/types/components/SubagentCard.d.ts.map +1 -0
- package/lib/types/components/SubagentCard.js +39 -0
- package/lib/types/components/SubagentDashboard.d.ts +17 -0
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -0
- package/lib/types/components/SubagentDashboard.js +58 -0
- package/lib/types/components/SubagentDetailScene.d.ts +16 -0
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -0
- package/lib/types/components/SubagentDetailScene.js +147 -0
- package/lib/types/components/SuggestionCard.d.ts +65 -0
- package/lib/types/components/SuggestionCard.d.ts.map +1 -0
- package/lib/types/components/SuggestionCard.js +77 -0
- package/lib/types/components/SyntaxText.d.ts +15 -0
- package/lib/types/components/SyntaxText.d.ts.map +1 -0
- package/lib/types/components/SyntaxText.js +34 -0
- package/lib/types/components/ThemePicker.d.ts +27 -0
- package/lib/types/components/ThemePicker.d.ts.map +1 -0
- package/lib/types/components/ThemePicker.js +55 -0
- package/lib/types/components/ThinkingToggle.d.ts +13 -0
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -0
- package/lib/types/components/ThinkingToggle.js +25 -0
- package/lib/types/components/TimelineRail.d.ts +53 -0
- package/lib/types/components/TimelineRail.d.ts.map +1 -0
- package/lib/types/components/TimelineRail.js +197 -0
- package/lib/types/components/TipsPanel.d.ts +14 -0
- package/lib/types/components/TipsPanel.d.ts.map +1 -0
- package/lib/types/components/TipsPanel.js +37 -0
- package/lib/types/components/ToolUseLoader.d.ts +18 -0
- package/lib/types/components/ToolUseLoader.d.ts.map +1 -0
- package/lib/types/components/ToolUseLoader.js +51 -0
- package/lib/types/components/Tooltip.d.ts +67 -0
- package/lib/types/components/Tooltip.d.ts.map +1 -0
- package/lib/types/components/Tooltip.js +266 -0
- package/lib/types/components/TurnInterruptedRow.d.ts +6 -0
- package/lib/types/components/TurnInterruptedRow.d.ts.map +1 -0
- package/lib/types/components/TurnInterruptedRow.js +9 -0
- package/lib/types/components/Whale.d.ts +42 -0
- package/lib/types/components/Whale.d.ts.map +1 -0
- package/lib/types/components/Whale.js +108 -0
- package/lib/types/components/WorkingSpinner.d.ts +26 -0
- package/lib/types/components/WorkingSpinner.d.ts.map +1 -0
- package/lib/types/components/WorkingSpinner.js +67 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts +20 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceFlowPicker.js +21 -0
- package/lib/types/components/WorkspaceMenuPicker.d.ts +19 -0
- package/lib/types/components/WorkspaceMenuPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceMenuPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +12 -0
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
- package/lib/types/components/WorkspacePicker.js +13 -0
- package/lib/types/components/activityFrames.d.ts +23 -0
- package/lib/types/components/activityFrames.d.ts.map +1 -0
- package/lib/types/components/activityFrames.js +31 -0
- package/lib/types/components/approvals/ApprovalPanel.d.ts +24 -0
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -0
- package/lib/types/components/approvals/ApprovalPanel.js +53 -0
- package/lib/types/components/bigfont.d.ts +28 -0
- package/lib/types/components/bigfont.d.ts.map +1 -0
- package/lib/types/components/bigfont.js +91 -0
- package/lib/types/components/design-system/Byline.d.ts +14 -0
- package/lib/types/components/design-system/Byline.d.ts.map +1 -0
- package/lib/types/components/design-system/Byline.js +17 -0
- package/lib/types/components/design-system/Divider.d.ts +61 -0
- package/lib/types/components/design-system/Divider.d.ts.map +1 -0
- package/lib/types/components/design-system/Divider.js +115 -0
- package/lib/types/components/design-system/HintLine.d.ts +11 -0
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
- package/lib/types/components/design-system/HintLine.js +14 -0
- package/lib/types/components/design-system/ListItem.d.ts +42 -0
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -0
- package/lib/types/components/design-system/ListItem.js +84 -0
- package/lib/types/components/design-system/LoadingState.d.ts +19 -0
- package/lib/types/components/design-system/LoadingState.d.ts.map +1 -0
- package/lib/types/components/design-system/LoadingState.js +22 -0
- package/lib/types/components/design-system/Pane.d.ts +17 -0
- package/lib/types/components/design-system/Pane.d.ts.map +1 -0
- package/lib/types/components/design-system/Pane.js +15 -0
- package/lib/types/components/design-system/ProgressBar.d.ts +21 -0
- package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -0
- package/lib/types/components/design-system/ProgressBar.js +26 -0
- package/lib/types/components/design-system/StatusIcon.d.ts +15 -0
- package/lib/types/components/design-system/StatusIcon.d.ts.map +1 -0
- package/lib/types/components/design-system/StatusIcon.js +20 -0
- package/lib/types/components/design-system/ThemeProvider.d.ts +21 -0
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemeProvider.js +256 -0
- package/lib/types/components/design-system/ThemedBox.d.ts +60 -0
- package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemedBox.js +29 -0
- package/lib/types/components/design-system/ThemedText.d.ts +61 -0
- package/lib/types/components/design-system/ThemedText.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemedText.js +42 -0
- package/lib/types/components/listWindow.d.ts +26 -0
- package/lib/types/components/listWindow.d.ts.map +1 -0
- package/lib/types/components/listWindow.js +47 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts +20 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantTextMessage.js +18 -0
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +40 -0
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantThinkingMessage.js +84 -0
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +72 -0
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantToolUseMessage.js +517 -0
- package/lib/types/components/messages/MessageMetadata.d.ts +14 -0
- package/lib/types/components/messages/MessageMetadata.d.ts.map +1 -0
- package/lib/types/components/messages/MessageMetadata.js +19 -0
- package/lib/types/components/messages/TranscriptImages.d.ts +21 -0
- package/lib/types/components/messages/TranscriptImages.d.ts.map +1 -0
- package/lib/types/components/messages/TranscriptImages.js +83 -0
- package/lib/types/components/messages/UserPromptMessage.d.ts +18 -0
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -0
- package/lib/types/components/messages/UserPromptMessage.js +28 -0
- package/lib/types/components/messages/imageInspection.d.ts +33 -0
- package/lib/types/components/messages/imageInspection.d.ts.map +1 -0
- package/lib/types/components/messages/imageInspection.js +107 -0
- package/lib/types/components/messages/originalImage.d.ts +5 -0
- package/lib/types/components/messages/originalImage.d.ts.map +1 -0
- package/lib/types/components/messages/originalImage.js +56 -0
- package/lib/types/components/messages/transcriptImageDecode.d.ts +9 -0
- package/lib/types/components/messages/transcriptImageDecode.d.ts.map +1 -0
- package/lib/types/components/messages/transcriptImageDecode.js +144 -0
- package/lib/types/components/messages/useImageInspection.d.ts +10 -0
- package/lib/types/components/messages/useImageInspection.d.ts.map +1 -0
- package/lib/types/components/messages/useImageInspection.js +91 -0
- package/lib/types/components/overlayBudget.d.ts +39 -0
- package/lib/types/components/overlayBudget.d.ts.map +1 -0
- package/lib/types/components/overlayBudget.js +43 -0
- package/lib/types/components/promptDraftCache.d.ts +102 -0
- package/lib/types/components/promptDraftCache.d.ts.map +1 -0
- package/lib/types/components/promptDraftCache.js +76 -0
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +94 -0
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -0
- package/lib/types/components/questions/AskUserQuestionPanel.js +527 -0
- package/lib/types/components/questions/PlanReviewPanel.d.ts +55 -0
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -0
- package/lib/types/components/questions/PlanReviewPanel.js +351 -0
- package/lib/types/components/questions/QuestionMinimizedBar.d.ts +12 -0
- package/lib/types/components/questions/QuestionMinimizedBar.d.ts.map +1 -0
- package/lib/types/components/questions/QuestionMinimizedBar.js +43 -0
- package/lib/types/components/sessions/SessionListRow.d.ts +58 -0
- package/lib/types/components/sessions/SessionListRow.d.ts.map +1 -0
- package/lib/types/components/sessions/SessionListRow.js +108 -0
- package/lib/types/components/sessions/SessionPreview.d.ts +25 -0
- package/lib/types/components/sessions/SessionPreview.d.ts.map +1 -0
- package/lib/types/components/sessions/SessionPreview.js +62 -0
- package/lib/types/components/sessions/WorkspaceListRow.d.ts +17 -0
- package/lib/types/components/sessions/WorkspaceListRow.d.ts.map +1 -0
- package/lib/types/components/sessions/WorkspaceListRow.js +27 -0
- package/lib/types/components/shimmer.d.ts +35 -0
- package/lib/types/components/shimmer.d.ts.map +1 -0
- package/lib/types/components/shimmer.js +43 -0
- package/lib/types/components/smoothReveal.d.ts +57 -0
- package/lib/types/components/smoothReveal.d.ts.map +1 -0
- package/lib/types/components/smoothReveal.js +305 -0
- package/lib/types/components/trajectory/HotspotView.d.ts +20 -0
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
- package/lib/types/components/trajectory/HotspotView.js +89 -0
- package/lib/types/components/trajectory/Inspector.d.ts +31 -0
- package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
- package/lib/types/components/trajectory/Inspector.js +67 -0
- package/lib/types/components/trajectory/Ledger.d.ts +28 -0
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
- package/lib/types/components/trajectory/Ledger.js +130 -0
- package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
- package/lib/types/components/trajectory/MiniWake.js +99 -0
- package/lib/types/components/trajectory/WaveBand.d.ts +42 -0
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
- package/lib/types/components/trajectory/WaveBand.js +150 -0
- package/lib/types/components/whaleFrames.d.ts +81 -0
- package/lib/types/components/whaleFrames.d.ts.map +1 -0
- package/lib/types/components/whaleFrames.js +768 -0
- package/lib/types/components/whaleIdle.d.ts +66 -0
- package/lib/types/components/whaleIdle.d.ts.map +1 -0
- package/lib/types/components/whaleIdle.js +174 -0
- package/lib/types/components/whaleLayers.d.ts +28 -0
- package/lib/types/components/whaleLayers.d.ts.map +1 -0
- package/lib/types/components/whaleLayers.js +90 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts +49 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.d.ts.map +1 -0
- package/lib/types/components/workspaces/HomeWorkspaceRow.js +50 -0
- package/lib/types/customTheme.d.ts +108 -0
- package/lib/types/customTheme.d.ts.map +1 -0
- package/lib/types/customTheme.js +281 -0
- package/lib/types/deepseekBalance.d.ts +19 -0
- package/lib/types/deepseekBalance.d.ts.map +1 -0
- package/lib/types/deepseekBalance.js +72 -0
- package/lib/types/deepseekPricing.d.ts +83 -0
- package/lib/types/deepseekPricing.d.ts.map +1 -0
- package/lib/types/deepseekPricing.js +140 -0
- package/lib/types/dsh-adapter/activity-store.d.ts +221 -0
- package/lib/types/dsh-adapter/activity-store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/activity-store.js +359 -0
- package/lib/types/dsh-adapter/agent-view.d.ts +66 -0
- package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -0
- package/lib/types/dsh-adapter/agent-view.js +153 -0
- package/lib/types/dsh-adapter/approvals.d.ts +225 -0
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
- package/lib/types/dsh-adapter/approvals.js +465 -0
- package/lib/types/dsh-adapter/bundled-presets.d.ts +10 -0
- package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/bundled-presets.js +80 -0
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/action-readiness.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/action-readiness.js +86 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts +64 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/agent-view-projection.js +312 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts +41 -0
- package/lib/types/dsh-adapter/channel/background-action.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/background-action.js +110 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +67 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.js +170 -0
- package/lib/types/dsh-adapter/channel/binding.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/binding.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/binding.js +287 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts +29 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/command-completions.js +94 -0
- package/lib/types/dsh-adapter/channel/commands.d.ts +8 -0
- package/lib/types/dsh-adapter/channel/commands.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/commands.js +9 -0
- package/lib/types/dsh-adapter/channel/compaction.d.ts +18 -0
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/compaction.js +114 -0
- package/lib/types/dsh-adapter/channel/composer-images.d.ts +62 -0
- package/lib/types/dsh-adapter/channel/composer-images.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/composer-images.js +316 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.d.ts +15 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/composer-mentions.js +200 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts +34 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/context-bookkeeping.js +31 -0
- package/lib/types/dsh-adapter/channel/decisions.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/decisions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/decisions.js +90 -0
- package/lib/types/dsh-adapter/channel/emitter.d.ts +10 -0
- package/lib/types/dsh-adapter/channel/emitter.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/emitter.js +71 -0
- package/lib/types/dsh-adapter/channel/external-commands.d.ts +31 -0
- package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/external-commands.js +187 -0
- package/lib/types/dsh-adapter/channel/file-actions.d.ts +20 -0
- package/lib/types/dsh-adapter/channel/file-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/file-actions.js +45 -0
- package/lib/types/dsh-adapter/channel/ide-selection.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/ide-selection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/ide-selection.js +226 -0
- package/lib/types/dsh-adapter/channel/input-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/input-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/input-actions.js +135 -0
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts +42 -0
- package/lib/types/dsh-adapter/channel/input-delivery.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/input-delivery.js +313 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts +28 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/job-projection.js +150 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts +9 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/lifetime-resources.js +33 -0
- package/lib/types/dsh-adapter/channel/loaded-context.d.ts +40 -0
- package/lib/types/dsh-adapter/channel/loaded-context.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/loaded-context.js +62 -0
- package/lib/types/dsh-adapter/channel/local-actions.d.ts +54 -0
- package/lib/types/dsh-adapter/channel/local-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/local-actions.js +109 -0
- package/lib/types/dsh-adapter/channel/mentions.d.ts +29 -0
- package/lib/types/dsh-adapter/channel/mentions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mentions.js +235 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts +30 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-actions.js +247 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +35 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +199 -0
- package/lib/types/dsh-adapter/channel/mode-permission.d.ts +58 -0
- package/lib/types/dsh-adapter/channel/mode-permission.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-permission.js +240 -0
- package/lib/types/dsh-adapter/channel/mode-roster.d.ts +51 -0
- package/lib/types/dsh-adapter/channel/mode-roster.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/mode-roster.js +119 -0
- package/lib/types/dsh-adapter/channel/model-actions.d.ts +49 -0
- package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/model-actions.js +351 -0
- package/lib/types/dsh-adapter/channel/model-switch.d.ts +31 -0
- package/lib/types/dsh-adapter/channel/model-switch.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/model-switch.js +116 -0
- package/lib/types/dsh-adapter/channel/notifications.d.ts +9 -0
- package/lib/types/dsh-adapter/channel/notifications.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/notifications.js +24 -0
- package/lib/types/dsh-adapter/channel/owner.d.ts +18 -0
- package/lib/types/dsh-adapter/channel/owner.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/owner.js +73 -0
- package/lib/types/dsh-adapter/channel/paths.d.ts +31 -0
- package/lib/types/dsh-adapter/channel/paths.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/paths.js +147 -0
- package/lib/types/dsh-adapter/channel/permissions.d.ts +40 -0
- package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/permissions.js +187 -0
- package/lib/types/dsh-adapter/channel/preferences.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/preferences.js +103 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/projection-helpers.js +63 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts +44 -0
- package/lib/types/dsh-adapter/channel/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/projection.js +1031 -0
- package/lib/types/dsh-adapter/channel/reports.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/reports.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/reports.js +163 -0
- package/lib/types/dsh-adapter/channel/session-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/session-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-actions.js +29 -0
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts +32 -0
- package/lib/types/dsh-adapter/channel/session-adoption.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-adoption.js +36 -0
- package/lib/types/dsh-adapter/channel/session-fork.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-fork.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-fork.js +109 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts +35 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-live-adoption.js +64 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts +91 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-metadata.js +220 -0
- package/lib/types/dsh-adapter/channel/session-reset.d.ts +11 -0
- package/lib/types/dsh-adapter/channel/session-reset.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-reset.js +43 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts +65 -0
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-resume.js +438 -0
- package/lib/types/dsh-adapter/channel/session-rewind.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-rewind.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-rewind.js +146 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts +19 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-tree-actions.js +154 -0
- package/lib/types/dsh-adapter/channel/session-tree.d.ts +10 -0
- package/lib/types/dsh-adapter/channel/session-tree.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/session-tree.js +503 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts +4 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/settings-host.js +257 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.d.ts +33 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/skill-catalog.js +215 -0
- package/lib/types/dsh-adapter/channel/state.d.ts +51 -0
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/state.js +31 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts +67 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/subagent-projection.js +307 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts +73 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/transcript.js +306 -0
- package/lib/types/dsh-adapter/channel/types.d.ts +167 -0
- package/lib/types/dsh-adapter/channel/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/types.js +1 -0
- package/lib/types/dsh-adapter/channel/usage.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/usage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/usage.js +48 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts +23 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel/workspace-actions.js +96 -0
- package/lib/types/dsh-adapter/channel-facade-actions.d.ts +25 -0
- package/lib/types/dsh-adapter/channel-facade-actions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-facade-actions.js +55 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.d.ts +6 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-scene-outlet.js +13 -0
- package/lib/types/dsh-adapter/channel-ui.d.ts +9 -0
- package/lib/types/dsh-adapter/channel-ui.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel-ui.js +128 -0
- package/lib/types/dsh-adapter/channel.d.ts +23 -0
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
- package/lib/types/dsh-adapter/channel.js +999 -0
- package/lib/types/dsh-adapter/childStderr.d.ts +63 -0
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
- package/lib/types/dsh-adapter/childStderr.js +180 -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 +34 -0
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-trees.js +111 -0
- package/lib/types/dsh-adapter/compat/index.d.ts +29 -0
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/index.js +28 -0
- package/lib/types/dsh-adapter/compat/liveSession.d.ts +79 -0
- package/lib/types/dsh-adapter/compat/liveSession.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/liveSession.js +223 -0
- package/lib/types/dsh-adapter/compat/messages.d.ts +15 -0
- package/lib/types/dsh-adapter/compat/messages.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/messages.js +15 -0
- package/lib/types/dsh-adapter/compat/persistence.d.ts +21 -0
- package/lib/types/dsh-adapter/compat/persistence.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/persistence.js +17 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +309 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/sessionLog.js +1177 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts +35 -0
- package/lib/types/dsh-adapter/compat/settings.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/settings.js +57 -0
- package/lib/types/dsh-adapter/compat/shell.d.ts +25 -0
- package/lib/types/dsh-adapter/compat/shell.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/shell.js +11 -0
- 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 +91 -0
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
- package/lib/types/dsh-adapter/contract.js +276 -0
- package/lib/types/dsh-adapter/credentialRefGuard.d.ts +40 -0
- package/lib/types/dsh-adapter/credentialRefGuard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/credentialRefGuard.js +43 -0
- package/lib/types/dsh-adapter/decision-guard.d.ts +128 -0
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/decision-guard.js +460 -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 +329 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts +96 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
- package/lib/types/dsh-adapter/effect-ledger.js +290 -0
- package/lib/types/dsh-adapter/extension-events.d.ts +186 -0
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extension-events.js +187 -0
- package/lib/types/dsh-adapter/extensions.d.ts +36 -0
- package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extensions.js +51 -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-grants.d.ts +23 -0
- package/lib/types/dsh-adapter/host-grants.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-grants.js +45 -0
- package/lib/types/dsh-adapter/ide-channel.d.ts +224 -0
- package/lib/types/dsh-adapter/ide-channel.d.ts.map +1 -0
- package/lib/types/dsh-adapter/ide-channel.js +556 -0
- package/lib/types/dsh-adapter/index.d.ts +151 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/index.js +119 -0
- package/lib/types/dsh-adapter/inject-channel.d.ts +108 -0
- package/lib/types/dsh-adapter/inject-channel.d.ts.map +1 -0
- package/lib/types/dsh-adapter/inject-channel.js +247 -0
- package/lib/types/dsh-adapter/invariant.d.ts +20 -0
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
- package/lib/types/dsh-adapter/invariant.js +26 -0
- package/lib/types/dsh-adapter/jobs.d.ts +101 -0
- package/lib/types/dsh-adapter/jobs.d.ts.map +1 -0
- package/lib/types/dsh-adapter/jobs.js +177 -0
- package/lib/types/dsh-adapter/message-observer.d.ts +186 -0
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
- package/lib/types/dsh-adapter/message-observer.js +682 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/claude-code.js +191 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/codex.js +133 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/grok-build.js +175 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/omp.js +132 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts +6 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/scan.js +38 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts +3 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/adapters/zcode.js +107 -0
- package/lib/types/dsh-adapter/migrate/bin-path.d.ts +6 -0
- package/lib/types/dsh-adapter/migrate/bin-path.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/bin-path.js +30 -0
- package/lib/types/dsh-adapter/migrate/cli.d.ts +9 -0
- package/lib/types/dsh-adapter/migrate/cli.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/cli.js +105 -0
- package/lib/types/dsh-adapter/migrate/index.d.ts +29 -0
- package/lib/types/dsh-adapter/migrate/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/index.js +108 -0
- package/lib/types/dsh-adapter/migrate/picker.d.ts +64 -0
- package/lib/types/dsh-adapter/migrate/picker.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/picker.js +86 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.d.ts +40 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/recent-agents.js +100 -0
- package/lib/types/dsh-adapter/migrate/sessionize.d.ts +19 -0
- package/lib/types/dsh-adapter/migrate/sessionize.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/sessionize.js +101 -0
- package/lib/types/dsh-adapter/migrate/types.d.ts +52 -0
- package/lib/types/dsh-adapter/migrate/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/types.js +11 -0
- package/lib/types/dsh-adapter/migrate/uuid.d.ts +7 -0
- package/lib/types/dsh-adapter/migrate/uuid.d.ts.map +1 -0
- package/lib/types/dsh-adapter/migrate/uuid.js +25 -0
- package/lib/types/dsh-adapter/packaged-presets.d.ts +22 -0
- package/lib/types/dsh-adapter/packaged-presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/packaged-presets.js +94 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts +205 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-host.js +762 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts +118 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-storage.js +536 -0
- package/lib/types/dsh-adapter/plugin.d.ts +70 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin.js +2140 -0
- 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 +293 -0
- package/lib/types/dsh-adapter/preset-resolution.d.ts +57 -0
- package/lib/types/dsh-adapter/preset-resolution.d.ts.map +1 -0
- package/lib/types/dsh-adapter/preset-resolution.js +52 -0
- package/lib/types/dsh-adapter/presets.d.ts +110 -0
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/presets.js +161 -0
- package/lib/types/dsh-adapter/promptDebug.d.ts +4 -0
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
- package/lib/types/dsh-adapter/promptDebug.js +163 -0
- package/lib/types/dsh-adapter/providerGuard.d.ts +75 -0
- package/lib/types/dsh-adapter/providerGuard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerGuard.js +104 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts +42 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.js +921 -0
- package/lib/types/dsh-adapter/questions-answerer.d.ts +51 -0
- package/lib/types/dsh-adapter/questions-answerer.d.ts.map +1 -0
- package/lib/types/dsh-adapter/questions-answerer.js +64 -0
- package/lib/types/dsh-adapter/questions.d.ts +130 -0
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/questions.js +282 -0
- package/lib/types/dsh-adapter/recap.d.ts +41 -0
- package/lib/types/dsh-adapter/recap.d.ts.map +1 -0
- package/lib/types/dsh-adapter/recap.js +111 -0
- package/lib/types/dsh-adapter/renderers.d.ts +58 -0
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
- package/lib/types/dsh-adapter/renderers.js +198 -0
- package/lib/types/dsh-adapter/sanitize.d.ts +45 -0
- package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sanitize.js +84 -0
- package/lib/types/dsh-adapter/scenes.d.ts +87 -0
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
- package/lib/types/dsh-adapter/scenes.js +223 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts +53 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.d.ts.map +1 -0
- package/lib/types/dsh-adapter/session-mount-heartbeat.js +100 -0
- package/lib/types/dsh-adapter/sessionTree.d.ts +232 -0
- package/lib/types/dsh-adapter/sessionTree.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessionTree.js +984 -0
- package/lib/types/dsh-adapter/sessions/digest.d.ts +54 -0
- package/lib/types/dsh-adapter/sessions/digest.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/digest.js +478 -0
- package/lib/types/dsh-adapter/sessions/frames.d.ts +103 -0
- package/lib/types/dsh-adapter/sessions/frames.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/frames.js +263 -0
- package/lib/types/dsh-adapter/sessions/header.d.ts +56 -0
- package/lib/types/dsh-adapter/sessions/header.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/header.js +85 -0
- package/lib/types/dsh-adapter/sessions/index.d.ts +17 -0
- package/lib/types/dsh-adapter/sessions/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/index.js +15 -0
- package/lib/types/dsh-adapter/sessions/list.d.ts +64 -0
- package/lib/types/dsh-adapter/sessions/list.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/list.js +331 -0
- package/lib/types/dsh-adapter/sessions/recovery.d.ts +17 -0
- package/lib/types/dsh-adapter/sessions/recovery.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/recovery.js +109 -0
- package/lib/types/dsh-adapter/sessions/store.d.ts +60 -0
- package/lib/types/dsh-adapter/sessions/store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/store.js +221 -0
- package/lib/types/dsh-adapter/sessions/types.d.ts +21 -0
- package/lib/types/dsh-adapter/sessions/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sessions/types.js +1 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts +48 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settings-sections.js +253 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts +100 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settingsEditor.js +238 -0
- package/lib/types/dsh-adapter/sharp.d.ts +10 -0
- package/lib/types/dsh-adapter/sharp.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sharp.js +59 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts +82 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
- package/lib/types/dsh-adapter/shortcuts.js +252 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts +36 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sideQuestion.js +59 -0
- package/lib/types/dsh-adapter/status.d.ts +148 -0
- package/lib/types/dsh-adapter/status.d.ts.map +1 -0
- package/lib/types/dsh-adapter/status.js +435 -0
- package/lib/types/dsh-adapter/subagents.d.ts +64 -0
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -0
- package/lib/types/dsh-adapter/subagents.js +366 -0
- package/lib/types/dsh-adapter/themes.d.ts +52 -0
- package/lib/types/dsh-adapter/themes.d.ts.map +1 -0
- package/lib/types/dsh-adapter/themes.js +307 -0
- package/lib/types/dsh-adapter/toast.d.ts +80 -0
- package/lib/types/dsh-adapter/toast.d.ts.map +1 -0
- package/lib/types/dsh-adapter/toast.js +171 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +47 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.js +208 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts +196 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/guards.js +273 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/index.js +15 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts +146 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/projection.js +710 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/types.js +70 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
- package/lib/types/dsh-adapter/transcript-images.d.ts +17 -0
- package/lib/types/dsh-adapter/transcript-images.d.ts.map +1 -0
- package/lib/types/dsh-adapter/transcript-images.js +96 -0
- package/lib/types/dsh-adapter/types.d.ts +23 -0
- package/lib/types/dsh-adapter/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/types.js +1 -0
- package/lib/types/dsh-adapter/workspace.d.ts +22 -0
- package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspace.js +16 -0
- package/lib/types/dsh-adapter/workspaces.d.ts +125 -0
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspaces.js +543 -0
- package/lib/types/effortPrefs.d.ts +48 -0
- package/lib/types/effortPrefs.d.ts.map +1 -0
- package/lib/types/effortPrefs.js +95 -0
- package/lib/types/extensions.d.ts +18 -0
- package/lib/types/extensions.d.ts.map +1 -0
- package/lib/types/extensions.js +27 -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/herdr.d.ts +28 -0
- package/lib/types/herdr.d.ts.map +1 -0
- package/lib/types/herdr.js +133 -0
- package/lib/types/history.d.ts +39 -0
- package/lib/types/history.d.ts.map +1 -0
- package/lib/types/history.js +177 -0
- package/lib/types/homePrefs.d.ts +15 -0
- package/lib/types/homePrefs.d.ts.map +1 -0
- package/lib/types/homePrefs.js +53 -0
- package/lib/types/hooks/useBlink.d.ts +10 -0
- package/lib/types/hooks/useBlink.d.ts.map +1 -0
- package/lib/types/hooks/useBlink.js +19 -0
- package/lib/types/hooks/useExternalVersion.d.ts +32 -0
- package/lib/types/hooks/useExternalVersion.d.ts.map +1 -0
- package/lib/types/hooks/useExternalVersion.js +53 -0
- package/lib/types/hooks/useRevealVersion.d.ts +21 -0
- package/lib/types/hooks/useRevealVersion.d.ts.map +1 -0
- package/lib/types/hooks/useRevealVersion.js +33 -0
- package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts +10 -0
- package/lib/types/hooks/useRuntimeThemeSnapshot.d.ts.map +1 -0
- package/lib/types/hooks/useRuntimeThemeSnapshot.js +32 -0
- package/lib/types/i18n.d.ts +4433 -0
- package/lib/types/i18n.d.ts.map +1 -0
- package/lib/types/i18n.js +1493 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +4 -0
- package/lib/types/ink/Ansi.d.ts +9 -0
- package/lib/types/ink/Ansi.d.ts.map +1 -0
- package/lib/types/ink/Ansi.js +45 -0
- package/lib/types/ink/bidi.d.ts +18 -0
- package/lib/types/ink/bidi.d.ts.map +1 -0
- package/lib/types/ink/bidi.js +119 -0
- package/lib/types/ink/clearTerminal.d.ts +22 -0
- package/lib/types/ink/clearTerminal.d.ts.map +1 -0
- package/lib/types/ink/clearTerminal.js +72 -0
- package/lib/types/ink/colorize.d.ts +43 -0
- package/lib/types/ink/colorize.d.ts.map +1 -0
- package/lib/types/ink/colorize.js +233 -0
- package/lib/types/ink/components/AlternateScreen.d.ts +8 -0
- package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -0
- package/lib/types/ink/components/AlternateScreen.js +29 -0
- package/lib/types/ink/components/App.d.ts +149 -0
- package/lib/types/ink/components/App.d.ts.map +1 -0
- package/lib/types/ink/components/App.js +1027 -0
- package/lib/types/ink/components/AppContext.d.ts +17 -0
- package/lib/types/ink/components/AppContext.d.ts.map +1 -0
- package/lib/types/ink/components/AppContext.js +12 -0
- package/lib/types/ink/components/Box.d.ts +85 -0
- package/lib/types/ink/components/Box.d.ts.map +1 -0
- package/lib/types/ink/components/Box.js +22 -0
- package/lib/types/ink/components/Button.d.ts +37 -0
- package/lib/types/ink/components/Button.d.ts.map +1 -0
- package/lib/types/ink/components/Button.js +23 -0
- package/lib/types/ink/components/ClockContext.d.ts +17 -0
- package/lib/types/ink/components/ClockContext.d.ts.map +1 -0
- package/lib/types/ink/components/ClockContext.js +99 -0
- package/lib/types/ink/components/CursorDeclarationContext.d.ts +30 -0
- package/lib/types/ink/components/CursorDeclarationContext.d.ts.map +1 -0
- package/lib/types/ink/components/CursorDeclarationContext.js +6 -0
- package/lib/types/ink/components/ErrorOverview.d.ts +7 -0
- package/lib/types/ink/components/ErrorOverview.d.ts.map +1 -0
- package/lib/types/ink/components/ErrorOverview.js +49 -0
- package/lib/types/ink/components/Image.d.ts +28 -0
- package/lib/types/ink/components/Image.d.ts.map +1 -0
- package/lib/types/ink/components/Image.js +44 -0
- package/lib/types/ink/components/Link.d.ts +8 -0
- package/lib/types/ink/components/Link.d.ts.map +1 -0
- package/lib/types/ink/components/Link.js +7 -0
- package/lib/types/ink/components/Newline.d.ts +7 -0
- package/lib/types/ink/components/Newline.d.ts.map +1 -0
- package/lib/types/ink/components/Newline.js +5 -0
- package/lib/types/ink/components/NoSelect.d.ts +9 -0
- package/lib/types/ink/components/NoSelect.d.ts.map +1 -0
- package/lib/types/ink/components/NoSelect.js +6 -0
- package/lib/types/ink/components/RawAnsi.d.ts +9 -0
- package/lib/types/ink/components/RawAnsi.d.ts.map +1 -0
- package/lib/types/ink/components/RawAnsi.js +7 -0
- package/lib/types/ink/components/ScrollBox.d.ts +78 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -0
- package/lib/types/ink/components/ScrollBox.js +309 -0
- package/lib/types/ink/components/Spacer.d.ts +4 -0
- package/lib/types/ink/components/Spacer.d.ts.map +1 -0
- package/lib/types/ink/components/Spacer.js +6 -0
- package/lib/types/ink/components/StdinContext.d.ts +32 -0
- package/lib/types/ink/components/StdinContext.d.ts.map +1 -0
- package/lib/types/ink/components/StdinContext.js +16 -0
- package/lib/types/ink/components/TerminalFocusContext.d.ts +11 -0
- package/lib/types/ink/components/TerminalFocusContext.d.ts.map +1 -0
- package/lib/types/ink/components/TerminalFocusContext.js +11 -0
- package/lib/types/ink/components/TerminalSizeContext.d.ts +6 -0
- package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -0
- package/lib/types/ink/components/TerminalSizeContext.js +2 -0
- package/lib/types/ink/components/Text.d.ts +64 -0
- package/lib/types/ink/components/Text.d.ts.map +1 -0
- package/lib/types/ink/components/Text.js +19 -0
- package/lib/types/ink/constants.d.ts +12 -0
- package/lib/types/ink/constants.d.ts.map +1 -0
- package/lib/types/ink/constants.js +11 -0
- package/lib/types/ink/cursor.d.ts +11 -0
- package/lib/types/ink/cursor.d.ts.map +1 -0
- package/lib/types/ink/cursor.js +1 -0
- package/lib/types/ink/devtools.d.ts +7 -0
- package/lib/types/ink/devtools.d.ts.map +1 -0
- package/lib/types/ink/devtools.js +1 -0
- package/lib/types/ink/dom.d.ts +194 -0
- package/lib/types/ink/dom.d.ts.map +1 -0
- package/lib/types/ink/dom.js +424 -0
- package/lib/types/ink/events/click-event.d.ts +23 -0
- package/lib/types/ink/events/click-event.d.ts.map +1 -0
- package/lib/types/ink/events/click-event.js +33 -0
- package/lib/types/ink/events/context-menu-event.d.ts +19 -0
- package/lib/types/ink/events/context-menu-event.d.ts.map +1 -0
- package/lib/types/ink/events/context-menu-event.js +20 -0
- package/lib/types/ink/events/dispatcher.d.ts +63 -0
- package/lib/types/ink/events/dispatcher.d.ts.map +1 -0
- package/lib/types/ink/events/dispatcher.js +194 -0
- package/lib/types/ink/events/drag-event.d.ts +44 -0
- package/lib/types/ink/events/drag-event.d.ts.map +1 -0
- package/lib/types/ink/events/drag-event.js +39 -0
- package/lib/types/ink/events/emitter.d.ts +20 -0
- package/lib/types/ink/events/emitter.d.ts.map +1 -0
- package/lib/types/ink/events/emitter.js +43 -0
- package/lib/types/ink/events/event-handlers.d.ts +65 -0
- package/lib/types/ink/events/event-handlers.d.ts.map +1 -0
- package/lib/types/ink/events/event-handlers.js +40 -0
- package/lib/types/ink/events/event.d.ts +19 -0
- package/lib/types/ink/events/event.d.ts.map +1 -0
- package/lib/types/ink/events/event.js +22 -0
- package/lib/types/ink/events/focus-event.d.ts +19 -0
- package/lib/types/ink/events/focus-event.d.ts.map +1 -0
- package/lib/types/ink/events/focus-event.js +21 -0
- package/lib/types/ink/events/input-event.d.ts +72 -0
- package/lib/types/ink/events/input-event.d.ts.map +1 -0
- package/lib/types/ink/events/input-event.js +185 -0
- package/lib/types/ink/events/keyboard-event.d.ts +40 -0
- package/lib/types/ink/events/keyboard-event.d.ts.map +1 -0
- package/lib/types/ink/events/keyboard-event.js +65 -0
- package/lib/types/ink/events/paste-event.d.ts +11 -0
- package/lib/types/ink/events/paste-event.d.ts.map +1 -0
- package/lib/types/ink/events/paste-event.js +13 -0
- package/lib/types/ink/events/pointer-event.d.ts +61 -0
- package/lib/types/ink/events/pointer-event.d.ts.map +1 -0
- package/lib/types/ink/events/pointer-event.js +61 -0
- package/lib/types/ink/events/resize-event.d.ts +13 -0
- package/lib/types/ink/events/resize-event.d.ts.map +1 -0
- package/lib/types/ink/events/resize-event.js +16 -0
- package/lib/types/ink/events/terminal-event.d.ts +112 -0
- package/lib/types/ink/events/terminal-event.d.ts.map +1 -0
- package/lib/types/ink/events/terminal-event.js +131 -0
- package/lib/types/ink/events/terminal-focus-event.d.ts +21 -0
- package/lib/types/ink/events/terminal-focus-event.d.ts.map +1 -0
- package/lib/types/ink/events/terminal-focus-event.js +18 -0
- package/lib/types/ink/events/wheel-event.d.ts +17 -0
- package/lib/types/ink/events/wheel-event.d.ts.map +1 -0
- package/lib/types/ink/events/wheel-event.js +20 -0
- package/lib/types/ink/flush-tick.d.ts +26 -0
- package/lib/types/ink/flush-tick.d.ts.map +1 -0
- package/lib/types/ink/flush-tick.js +31 -0
- package/lib/types/ink/focus.d.ts +74 -0
- package/lib/types/ink/focus.d.ts.map +1 -0
- package/lib/types/ink/focus.js +188 -0
- package/lib/types/ink/frame.d.ts +128 -0
- package/lib/types/ink/frame.d.ts.map +1 -0
- package/lib/types/ink/frame.js +43 -0
- package/lib/types/ink/geometry-trace.d.ts +51 -0
- package/lib/types/ink/geometry-trace.d.ts.map +1 -0
- package/lib/types/ink/geometry-trace.js +83 -0
- package/lib/types/ink/get-max-width.d.ts +12 -0
- package/lib/types/ink/get-max-width.d.ts.map +1 -0
- package/lib/types/ink/get-max-width.js +12 -0
- package/lib/types/ink/hit-test.d.ts +181 -0
- package/lib/types/ink/hit-test.d.ts.map +1 -0
- package/lib/types/ink/hit-test.js +540 -0
- package/lib/types/ink/hooks/use-animation-frame.d.ts +27 -0
- package/lib/types/ink/hooks/use-animation-frame.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-animation-frame.js +48 -0
- package/lib/types/ink/hooks/use-app.d.ts +7 -0
- package/lib/types/ink/hooks/use-app.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-app.js +7 -0
- package/lib/types/ink/hooks/use-copy-on-select.d.ts +26 -0
- package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-copy-on-select.js +54 -0
- package/lib/types/ink/hooks/use-declared-cursor.d.ts +31 -0
- package/lib/types/ink/hooks/use-declared-cursor.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-declared-cursor.js +65 -0
- package/lib/types/ink/hooks/use-input.d.ts +41 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-input.js +81 -0
- package/lib/types/ink/hooks/use-interval.d.ts +23 -0
- package/lib/types/ink/hooks/use-interval.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-interval.js +58 -0
- package/lib/types/ink/hooks/use-search-highlight.d.ts +34 -0
- package/lib/types/ink/hooks/use-search-highlight.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-search-highlight.js +35 -0
- package/lib/types/ink/hooks/use-selection.d.ts +44 -0
- package/lib/types/ink/hooks/use-selection.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-selection.js +64 -0
- package/lib/types/ink/hooks/use-stdin.d.ts +8 -0
- package/lib/types/ink/hooks/use-stdin.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-stdin.js +8 -0
- package/lib/types/ink/hooks/use-tab-status.d.ts +18 -0
- package/lib/types/ink/hooks/use-tab-status.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-tab-status.js +58 -0
- package/lib/types/ink/hooks/use-terminal-focus.d.ts +11 -0
- package/lib/types/ink/hooks/use-terminal-focus.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-focus.js +15 -0
- package/lib/types/ink/hooks/use-terminal-images.d.ts +14 -0
- package/lib/types/ink/hooks/use-terminal-images.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-images.js +22 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts +6 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-size.js +12 -0
- package/lib/types/ink/hooks/use-terminal-title.d.ts +14 -0
- package/lib/types/ink/hooks/use-terminal-title.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-title.js +30 -0
- package/lib/types/ink/hooks/use-terminal-viewport.d.ts +32 -0
- package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-viewport.js +79 -0
- package/lib/types/ink/ink.d.ts +571 -0
- package/lib/types/ink/ink.d.ts.map +1 -0
- package/lib/types/ink/ink.js +2818 -0
- package/lib/types/ink/input-suppression.d.ts +20 -0
- package/lib/types/ink/input-suppression.d.ts.map +1 -0
- package/lib/types/ink/input-suppression.js +26 -0
- package/lib/types/ink/instances.d.ts +10 -0
- package/lib/types/ink/instances.d.ts.map +1 -0
- package/lib/types/ink/instances.js +13 -0
- package/lib/types/ink/kitty-graphics.d.ts +41 -0
- package/lib/types/ink/kitty-graphics.d.ts.map +1 -0
- package/lib/types/ink/kitty-graphics.js +229 -0
- package/lib/types/ink/layout/engine.d.ts +7 -0
- package/lib/types/ink/layout/engine.d.ts.map +1 -0
- package/lib/types/ink/layout/engine.js +8 -0
- package/lib/types/ink/layout/geometry.d.ts +86 -0
- package/lib/types/ink/layout/geometry.d.ts.map +1 -0
- package/lib/types/ink/layout/geometry.js +95 -0
- package/lib/types/ink/layout/node.d.ts +153 -0
- package/lib/types/ink/layout/node.d.ts.map +1 -0
- package/lib/types/ink/layout/node.js +72 -0
- package/lib/types/ink/layout/yoga.d.ts +70 -0
- package/lib/types/ink/layout/yoga.d.ts.map +1 -0
- package/lib/types/ink/layout/yoga.js +252 -0
- package/lib/types/ink/line-width-cache.d.ts +9 -0
- package/lib/types/ink/line-width-cache.d.ts.map +1 -0
- package/lib/types/ink/line-width-cache.js +45 -0
- package/lib/types/ink/log-update.d.ts +57 -0
- package/lib/types/ink/log-update.d.ts.map +1 -0
- package/lib/types/ink/log-update.js +1000 -0
- package/lib/types/ink/measure-element.d.ts +19 -0
- package/lib/types/ink/measure-element.d.ts.map +1 -0
- package/lib/types/ink/measure-element.js +10 -0
- package/lib/types/ink/measure-text.d.ts +13 -0
- package/lib/types/ink/measure-text.d.ts.map +1 -0
- package/lib/types/ink/measure-text.js +38 -0
- package/lib/types/ink/node-cache.d.ts +54 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -0
- package/lib/types/ink/node-cache.js +45 -0
- package/lib/types/ink/optimizer.d.ts +18 -0
- package/lib/types/ink/optimizer.d.ts.map +1 -0
- package/lib/types/ink/optimizer.js +83 -0
- package/lib/types/ink/output.d.ts +300 -0
- package/lib/types/ink/output.d.ts.map +1 -0
- package/lib/types/ink/output.js +1205 -0
- package/lib/types/ink/parse-keypress.d.ts +217 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -0
- package/lib/types/ink/parse-keypress.js +1550 -0
- package/lib/types/ink/reconciler.d.ts +43 -0
- package/lib/types/ink/reconciler.d.ts.map +1 -0
- package/lib/types/ink/reconciler.js +414 -0
- package/lib/types/ink/render-border.d.ts +41 -0
- package/lib/types/ink/render-border.d.ts.map +1 -0
- package/lib/types/ink/render-border.js +159 -0
- package/lib/types/ink/render-node-to-output.d.ts +199 -0
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -0
- package/lib/types/ink/render-node-to-output.js +1758 -0
- package/lib/types/ink/render-to-screen.d.ts +65 -0
- package/lib/types/ink/render-to-screen.d.ts.map +1 -0
- package/lib/types/ink/render-to-screen.js +189 -0
- package/lib/types/ink/renderer.d.ts +34 -0
- package/lib/types/ink/renderer.d.ts.map +1 -0
- package/lib/types/ink/renderer.js +181 -0
- package/lib/types/ink/root.d.ts +109 -0
- package/lib/types/ink/root.d.ts.map +1 -0
- package/lib/types/ink/root.js +96 -0
- package/lib/types/ink/screen.d.ts +545 -0
- package/lib/types/ink/screen.d.ts.map +1 -0
- package/lib/types/ink/screen.js +1607 -0
- package/lib/types/ink/selection.d.ts +529 -0
- package/lib/types/ink/selection.d.ts.map +1 -0
- package/lib/types/ink/selection.js +1292 -0
- package/lib/types/ink/sixel-codec.d.ts +41 -0
- package/lib/types/ink/sixel-codec.d.ts.map +1 -0
- package/lib/types/ink/sixel-codec.js +128 -0
- package/lib/types/ink/sixel-graphics.d.ts +74 -0
- package/lib/types/ink/sixel-graphics.d.ts.map +1 -0
- package/lib/types/ink/sixel-graphics.js +498 -0
- package/lib/types/ink/sixel-worker.d.ts +2 -0
- package/lib/types/ink/sixel-worker.d.ts.map +1 -0
- package/lib/types/ink/sixel-worker.js +12 -0
- package/lib/types/ink/squash-text-nodes.d.ts +30 -0
- package/lib/types/ink/squash-text-nodes.d.ts.map +1 -0
- package/lib/types/ink/squash-text-nodes.js +63 -0
- package/lib/types/ink/stringWidth.d.ts +3 -0
- package/lib/types/ink/stringWidth.d.ts.map +1 -0
- package/lib/types/ink/stringWidth.js +248 -0
- package/lib/types/ink/styles.d.ts +346 -0
- package/lib/types/ink/styles.d.ts.map +1 -0
- package/lib/types/ink/styles.js +307 -0
- package/lib/types/ink/supports-hyperlinks.d.ts +20 -0
- package/lib/types/ink/supports-hyperlinks.d.ts.map +1 -0
- package/lib/types/ink/supports-hyperlinks.js +44 -0
- package/lib/types/ink/tabstops.d.ts +10 -0
- package/lib/types/ink/tabstops.d.ts.map +1 -0
- package/lib/types/ink/tabstops.js +47 -0
- package/lib/types/ink/terminal-focus-state.d.ts +35 -0
- package/lib/types/ink/terminal-focus-state.d.ts.map +1 -0
- package/lib/types/ink/terminal-focus-state.js +57 -0
- package/lib/types/ink/terminal-image-protocol.d.ts +4 -0
- package/lib/types/ink/terminal-image-protocol.d.ts.map +1 -0
- package/lib/types/ink/terminal-image-protocol.js +8 -0
- package/lib/types/ink/terminal-image.d.ts +102 -0
- package/lib/types/ink/terminal-image.d.ts.map +1 -0
- package/lib/types/ink/terminal-image.js +223 -0
- package/lib/types/ink/terminal-querier.d.ts +203 -0
- package/lib/types/ink/terminal-querier.d.ts.map +1 -0
- package/lib/types/ink/terminal-querier.js +286 -0
- package/lib/types/ink/terminal.d.ts +192 -0
- package/lib/types/ink/terminal.d.ts.map +1 -0
- package/lib/types/ink/terminal.js +436 -0
- package/lib/types/ink/termio/ansi.d.ts +75 -0
- package/lib/types/ink/termio/ansi.d.ts.map +1 -0
- package/lib/types/ink/termio/ansi.js +79 -0
- package/lib/types/ink/termio/csi.d.ts +263 -0
- package/lib/types/ink/termio/csi.d.ts.map +1 -0
- package/lib/types/ink/termio/csi.js +367 -0
- package/lib/types/ink/termio/dec.d.ts +61 -0
- package/lib/types/ink/termio/dec.d.ts.map +1 -0
- package/lib/types/ink/termio/dec.js +76 -0
- package/lib/types/ink/termio/esc.d.ts +15 -0
- package/lib/types/ink/termio/esc.d.ts.map +1 -0
- package/lib/types/ink/termio/esc.js +57 -0
- package/lib/types/ink/termio/osc.d.ts +198 -0
- package/lib/types/ink/termio/osc.d.ts.map +1 -0
- package/lib/types/ink/termio/osc.js +475 -0
- package/lib/types/ink/termio/parser.d.ts +46 -0
- package/lib/types/ink/termio/parser.d.ts.map +1 -0
- package/lib/types/ink/termio/parser.js +366 -0
- package/lib/types/ink/termio/sgr.d.ts +17 -0
- package/lib/types/ink/termio/sgr.d.ts.map +1 -0
- package/lib/types/ink/termio/sgr.js +300 -0
- package/lib/types/ink/termio/tokenize.d.ts +56 -0
- package/lib/types/ink/termio/tokenize.d.ts.map +1 -0
- package/lib/types/ink/termio/tokenize.js +290 -0
- package/lib/types/ink/termio/types.d.ts +211 -0
- package/lib/types/ink/termio/types.d.ts.map +1 -0
- package/lib/types/ink/termio/types.js +68 -0
- package/lib/types/ink/termio.d.ts +25 -0
- package/lib/types/ink/termio.d.ts.map +1 -0
- package/lib/types/ink/termio.js +24 -0
- package/lib/types/ink/timeline-rail.d.ts +134 -0
- package/lib/types/ink/timeline-rail.d.ts.map +1 -0
- package/lib/types/ink/timeline-rail.js +175 -0
- package/lib/types/ink/transcript-highlight.d.ts +25 -0
- package/lib/types/ink/transcript-highlight.d.ts.map +1 -0
- package/lib/types/ink/transcript-highlight.js +82 -0
- package/lib/types/ink/truncateToWidth.d.ts +7 -0
- package/lib/types/ink/truncateToWidth.d.ts.map +1 -0
- package/lib/types/ink/truncateToWidth.js +18 -0
- package/lib/types/ink/update-overflow-guard.d.ts +62 -0
- package/lib/types/ink/update-overflow-guard.d.ts.map +1 -0
- package/lib/types/ink/update-overflow-guard.js +164 -0
- package/lib/types/ink/useTerminalNotification.d.ts +45 -0
- package/lib/types/ink/useTerminalNotification.d.ts.map +1 -0
- package/lib/types/ink/useTerminalNotification.js +70 -0
- package/lib/types/ink/warn.d.ts +7 -0
- package/lib/types/ink/warn.d.ts.map +1 -0
- package/lib/types/ink/warn.js +15 -0
- package/lib/types/ink/widest-line.d.ts +7 -0
- package/lib/types/ink/widest-line.d.ts.map +1 -0
- package/lib/types/ink/widest-line.js +19 -0
- package/lib/types/ink/wrap-text.d.ts +10 -0
- package/lib/types/ink/wrap-text.d.ts.map +1 -0
- package/lib/types/ink/wrap-text.js +103 -0
- package/lib/types/ink/wrapAnsi.d.ts +17 -0
- package/lib/types/ink/wrapAnsi.d.ts.map +1 -0
- package/lib/types/ink/wrapAnsi.js +38 -0
- package/lib/types/jsx-runtime.d.ts +2 -0
- package/lib/types/jsx-runtime.d.ts.map +1 -0
- package/lib/types/jsx-runtime.js +13 -0
- package/lib/types/migrationPrefs.d.ts +60 -0
- package/lib/types/migrationPrefs.d.ts.map +1 -0
- package/lib/types/migrationPrefs.js +97 -0
- package/lib/types/minimalMode.d.ts +13 -0
- package/lib/types/minimalMode.d.ts.map +1 -0
- package/lib/types/minimalMode.js +17 -0
- package/lib/types/modelGroups.d.ts +72 -0
- package/lib/types/modelGroups.d.ts.map +1 -0
- package/lib/types/modelGroups.js +97 -0
- package/lib/types/modelPrefs.d.ts +37 -0
- package/lib/types/modelPrefs.d.ts.map +1 -0
- package/lib/types/modelPrefs.js +66 -0
- package/lib/types/modelRecents.d.ts +39 -0
- package/lib/types/modelRecents.d.ts.map +1 -0
- package/lib/types/modelRecents.js +97 -0
- package/lib/types/modelRoute.d.ts +87 -0
- package/lib/types/modelRoute.d.ts.map +1 -0
- package/lib/types/modelRoute.js +125 -0
- package/lib/types/native-ts/yoga-layout/enums.d.ts +183 -0
- package/lib/types/native-ts/yoga-layout/enums.d.ts.map +1 -0
- package/lib/types/native-ts/yoga-layout/enums.js +150 -0
- package/lib/types/native-ts/yoga-layout/index.d.ts +804 -0
- package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -0
- package/lib/types/native-ts/yoga-layout/index.js +2614 -0
- package/lib/types/oauth.d.ts +15 -0
- package/lib/types/oauth.d.ts.map +1 -0
- package/lib/types/oauth.js +14 -0
- package/lib/types/plugin-host.d.ts +14 -0
- package/lib/types/plugin-host.d.ts.map +1 -0
- package/lib/types/plugin-host.js +19 -0
- package/lib/types/presetPrefs.d.ts +30 -0
- package/lib/types/presetPrefs.d.ts.map +1 -0
- package/lib/types/presetPrefs.js +66 -0
- package/lib/types/reload.d.ts +109 -0
- package/lib/types/reload.d.ts.map +1 -0
- package/lib/types/reload.js +118 -0
- package/lib/types/scenes.d.ts +4 -0
- package/lib/types/scenes.d.ts.map +1 -0
- package/lib/types/scenes.js +4 -0
- package/lib/types/screens/Chat.d.ts +82 -0
- package/lib/types/screens/Chat.d.ts.map +1 -0
- package/lib/types/screens/Chat.js +4299 -0
- package/lib/types/screens/SessionSupervisor.d.ts +84 -0
- package/lib/types/screens/SessionSupervisor.d.ts.map +1 -0
- package/lib/types/screens/SessionSupervisor.js +350 -0
- package/lib/types/screens/SessionTree.d.ts +27 -0
- package/lib/types/screens/SessionTree.d.ts.map +1 -0
- package/lib/types/screens/SessionTree.js +583 -0
- package/lib/types/screens/Settings.d.ts +22 -0
- package/lib/types/screens/Settings.d.ts.map +1 -0
- package/lib/types/screens/Settings.js +592 -0
- package/lib/types/screens/StatusLine.d.ts +48 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -0
- package/lib/types/screens/StatusLine.js +453 -0
- package/lib/types/screens/StatusMetrics.d.ts +176 -0
- package/lib/types/screens/StatusMetrics.d.ts.map +1 -0
- package/lib/types/screens/StatusMetrics.js +372 -0
- package/lib/types/screens/TrajectoryScene.d.ts +16 -0
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
- package/lib/types/screens/TrajectoryScene.js +374 -0
- package/lib/types/screens/chatOverlay.d.ts +267 -0
- package/lib/types/screens/chatOverlay.d.ts.map +1 -0
- package/lib/types/screens/chatOverlay.js +132 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts +83 -0
- package/lib/types/screens/sessionSupervisor/model.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/model.js +69 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts +120 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.d.ts.map +1 -0
- package/lib/types/screens/sessionSupervisor/useSessionSupervisor.js +639 -0
- package/lib/types/sessionHistory.d.ts +59 -0
- package/lib/types/sessionHistory.d.ts.map +1 -0
- package/lib/types/sessionHistory.js +223 -0
- package/lib/types/sessionModes.d.ts +83 -0
- package/lib/types/sessionModes.d.ts.map +1 -0
- package/lib/types/sessionModes.js +141 -0
- package/lib/types/sessionMounts.d.ts +272 -0
- package/lib/types/sessionMounts.d.ts.map +1 -0
- package/lib/types/sessionMounts.js +706 -0
- package/lib/types/sessionPins.d.ts +33 -0
- package/lib/types/sessionPins.d.ts.map +1 -0
- package/lib/types/sessionPins.js +181 -0
- package/lib/types/sessions/format.d.ts +125 -0
- package/lib/types/sessions/format.d.ts.map +1 -0
- package/lib/types/sessions/format.js +276 -0
- package/lib/types/sessions/resumeFailure.d.ts +38 -0
- package/lib/types/sessions/resumeFailure.d.ts.map +1 -0
- package/lib/types/sessions/resumeFailure.js +58 -0
- package/lib/types/sessions/view.d.ts +162 -0
- package/lib/types/sessions/view.d.ts.map +1 -0
- package/lib/types/sessions/view.js +350 -0
- package/lib/types/settings-sections.d.ts +4 -0
- package/lib/types/settings-sections.d.ts.map +1 -0
- package/lib/types/settings-sections.js +4 -0
- package/lib/types/terminal-utils/cliHighlight.d.ts +20 -0
- package/lib/types/terminal-utils/cliHighlight.d.ts.map +1 -0
- package/lib/types/terminal-utils/cliHighlight.js +53 -0
- package/lib/types/terminal-utils/figures.d.ts +26 -0
- package/lib/types/terminal-utils/figures.d.ts.map +1 -0
- package/lib/types/terminal-utils/figures.js +36 -0
- package/lib/types/terminal-utils/format.d.ts +35 -0
- package/lib/types/terminal-utils/format.d.ts.map +1 -0
- package/lib/types/terminal-utils/format.js +63 -0
- package/lib/types/terminal-utils/hash.d.ts +25 -0
- package/lib/types/terminal-utils/hash.d.ts.map +1 -0
- package/lib/types/terminal-utils/hash.js +41 -0
- package/lib/types/terminal-utils/hyperlink.d.ts +27 -0
- package/lib/types/terminal-utils/hyperlink.d.ts.map +1 -0
- package/lib/types/terminal-utils/hyperlink.js +70 -0
- package/lib/types/terminal-utils/markdown.d.ts +58 -0
- package/lib/types/terminal-utils/markdown.d.ts.map +1 -0
- package/lib/types/terminal-utils/markdown.js +441 -0
- package/lib/types/terminal-utils/mermaid.d.ts +44 -0
- package/lib/types/terminal-utils/mermaid.d.ts.map +1 -0
- package/lib/types/terminal-utils/mermaid.js +83 -0
- package/lib/types/terminal-utils/sessionColors.d.ts +27 -0
- package/lib/types/terminal-utils/sessionColors.d.ts.map +1 -0
- package/lib/types/terminal-utils/sessionColors.js +39 -0
- package/lib/types/terminal-utils/spinnerVerbs.d.ts +3 -0
- package/lib/types/terminal-utils/spinnerVerbs.d.ts.map +1 -0
- package/lib/types/terminal-utils/spinnerVerbs.js +21 -0
- package/lib/types/terminal-utils/syntaxRuns.d.ts +16 -0
- package/lib/types/terminal-utils/syntaxRuns.d.ts.map +1 -0
- package/lib/types/terminal-utils/syntaxRuns.js +79 -0
- package/lib/types/terminal-utils/syntaxTheme.d.ts +12 -0
- package/lib/types/terminal-utils/syntaxTheme.d.ts.map +1 -0
- package/lib/types/terminal-utils/syntaxTheme.js +76 -0
- package/lib/types/theme.d.ts +201 -0
- package/lib/types/theme.d.ts.map +1 -0
- package/lib/types/theme.js +525 -0
- package/lib/types/themeCatalog.d.ts +36 -0
- package/lib/types/themeCatalog.d.ts.map +1 -0
- package/lib/types/themeCatalog.js +159 -0
- package/lib/types/themePrefs.d.ts +28 -0
- package/lib/types/themePrefs.d.ts.map +1 -0
- package/lib/types/themePrefs.js +59 -0
- package/lib/types/tips.d.ts +30 -0
- package/lib/types/tips.d.ts.map +1 -0
- package/lib/types/tips.js +899 -0
- package/lib/types/trajectory/effortIgnition.d.ts +66 -0
- package/lib/types/trajectory/effortIgnition.d.ts.map +1 -0
- package/lib/types/trajectory/effortIgnition.js +142 -0
- package/lib/types/trajectory/format.d.ts +100 -0
- package/lib/types/trajectory/format.d.ts.map +1 -0
- package/lib/types/trajectory/format.js +213 -0
- package/lib/types/trajectory/motion.d.ts +99 -0
- package/lib/types/trajectory/motion.d.ts.map +1 -0
- package/lib/types/trajectory/motion.js +143 -0
- package/lib/types/trajectory/query.d.ts +83 -0
- package/lib/types/trajectory/query.d.ts.map +1 -0
- package/lib/types/trajectory/query.js +187 -0
- package/lib/types/trajectoryPrefs.d.ts +36 -0
- package/lib/types/trajectoryPrefs.d.ts.map +1 -0
- package/lib/types/trajectoryPrefs.js +65 -0
- package/lib/types/tuiDisplayPrefs.d.ts +49 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
- package/lib/types/tuiDisplayPrefs.js +168 -0
- package/lib/types/ui.d.ts +29 -0
- package/lib/types/ui.d.ts.map +1 -0
- package/lib/types/ui.js +25 -0
- package/lib/types/update.d.ts +550 -0
- package/lib/types/update.d.ts.map +1 -0
- package/lib/types/update.js +1751 -0
- package/lib/types/utils/clipboard.d.ts +122 -0
- package/lib/types/utils/clipboard.d.ts.map +1 -0
- package/lib/types/utils/clipboard.js +577 -0
- package/lib/types/utils/credentials.d.ts +13 -0
- package/lib/types/utils/credentials.d.ts.map +1 -0
- package/lib/types/utils/credentials.js +41 -0
- package/lib/types/utils/debug.d.ts +18 -0
- package/lib/types/utils/debug.d.ts.map +1 -0
- package/lib/types/utils/debug.js +37 -0
- package/lib/types/utils/earlyInput.d.ts +6 -0
- package/lib/types/utils/earlyInput.d.ts.map +1 -0
- package/lib/types/utils/earlyInput.js +5 -0
- package/lib/types/utils/env.d.ts +8 -0
- package/lib/types/utils/env.d.ts.map +1 -0
- package/lib/types/utils/env.js +7 -0
- package/lib/types/utils/envUtils.d.ts +8 -0
- package/lib/types/utils/envUtils.d.ts.map +1 -0
- package/lib/types/utils/envUtils.js +13 -0
- package/lib/types/utils/execFileNoThrow.d.ts +17 -0
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -0
- package/lib/types/utils/execFileNoThrow.js +65 -0
- package/lib/types/utils/externalEditor.d.ts +116 -0
- package/lib/types/utils/externalEditor.d.ts.map +1 -0
- package/lib/types/utils/externalEditor.js +270 -0
- package/lib/types/utils/fileSuggestions.d.ts +12 -0
- package/lib/types/utils/fileSuggestions.d.ts.map +1 -0
- package/lib/types/utils/fileSuggestions.js +40 -0
- package/lib/types/utils/fileTarget.d.ts +46 -0
- package/lib/types/utils/fileTarget.d.ts.map +1 -0
- package/lib/types/utils/fileTarget.js +178 -0
- package/lib/types/utils/fold-long-lines.d.ts +38 -0
- package/lib/types/utils/fold-long-lines.d.ts.map +1 -0
- package/lib/types/utils/fold-long-lines.js +91 -0
- package/lib/types/utils/fullscreen.d.ts +7 -0
- package/lib/types/utils/fullscreen.d.ts.map +1 -0
- package/lib/types/utils/fullscreen.js +9 -0
- package/lib/types/utils/imageResize.d.ts +90 -0
- package/lib/types/utils/imageResize.d.ts.map +1 -0
- package/lib/types/utils/imageResize.js +272 -0
- package/lib/types/utils/intl.d.ts +7 -0
- package/lib/types/utils/intl.d.ts.map +1 -0
- package/lib/types/utils/intl.js +9 -0
- package/lib/types/utils/keymap.d.ts +138 -0
- package/lib/types/utils/keymap.d.ts.map +1 -0
- package/lib/types/utils/keymap.js +351 -0
- package/lib/types/utils/loaded-context.d.ts +25 -0
- package/lib/types/utils/loaded-context.d.ts.map +1 -0
- package/lib/types/utils/loaded-context.js +72 -0
- package/lib/types/utils/log.d.ts +7 -0
- package/lib/types/utils/log.d.ts.map +1 -0
- package/lib/types/utils/log.js +9 -0
- package/lib/types/utils/mentions.d.ts +53 -0
- package/lib/types/utils/mentions.d.ts.map +1 -0
- package/lib/types/utils/mentions.js +133 -0
- package/lib/types/utils/modifiers.d.ts +43 -0
- package/lib/types/utils/modifiers.d.ts.map +1 -0
- package/lib/types/utils/modifiers.js +45 -0
- package/lib/types/utils/narration.d.ts +11 -0
- package/lib/types/utils/narration.d.ts.map +1 -0
- package/lib/types/utils/narration.js +16 -0
- package/lib/types/utils/openExternal.d.ts +50 -0
- package/lib/types/utils/openExternal.d.ts.map +1 -0
- package/lib/types/utils/openExternal.js +170 -0
- package/lib/types/utils/pastedImagePath.d.ts +51 -0
- package/lib/types/utils/pastedImagePath.d.ts.map +1 -0
- package/lib/types/utils/pastedImagePath.js +194 -0
- package/lib/types/utils/paths.d.ts +16 -0
- package/lib/types/utils/paths.d.ts.map +1 -0
- package/lib/types/utils/paths.js +19 -0
- package/lib/types/utils/semver.d.ts +9 -0
- package/lib/types/utils/semver.d.ts.map +1 -0
- package/lib/types/utils/semver.js +24 -0
- package/lib/types/utils/shellQuote.d.ts +14 -0
- package/lib/types/utils/shellQuote.d.ts.map +1 -0
- package/lib/types/utils/shellQuote.js +39 -0
- package/lib/types/utils/sliceAnsi.d.ts +12 -0
- package/lib/types/utils/sliceAnsi.d.ts.map +1 -0
- package/lib/types/utils/sliceAnsi.js +79 -0
- package/lib/types/utils/truncateMiddle.d.ts +9 -0
- package/lib/types/utils/truncateMiddle.d.ts.map +1 -0
- package/lib/types/utils/truncateMiddle.js +28 -0
- package/lib/types/utils/urlGuard.d.ts +28 -0
- package/lib/types/utils/urlGuard.d.ts.map +1 -0
- package/lib/types/utils/urlGuard.js +21 -0
- package/lib/types/utils/workspaceRoot.d.ts +21 -0
- package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
- package/lib/types/utils/workspaceRoot.js +47 -0
- package/lib/types/working-activity.d.ts +32 -0
- package/lib/types/working-activity.d.ts.map +1 -0
- package/lib/types/working-activity.js +38 -0
- package/lib/types/workspaces.d.ts +5 -0
- package/lib/types/workspaces.d.ts.map +1 -0
- package/lib/types/workspaces.js +4 -0
- package/node_modules/@askdkc/dsh-auth/LICENSE +21 -0
- package/node_modules/@askdkc/dsh-auth/README.ja.md +164 -0
- package/node_modules/@askdkc/dsh-auth/README.md +163 -0
- package/node_modules/@askdkc/dsh-auth/cordis.patch.yml +11 -0
- package/node_modules/@askdkc/dsh-auth/dsh-plugin.json +44 -0
- package/node_modules/@askdkc/dsh-auth/lib/command.d.ts +14 -0
- package/node_modules/@askdkc/dsh-auth/lib/command.js +70 -0
- package/node_modules/@askdkc/dsh-auth/lib/credentials.d.ts +63 -0
- package/node_modules/@askdkc/dsh-auth/lib/credentials.js +204 -0
- package/node_modules/@askdkc/dsh-auth/lib/custom-profiles.d.ts +26 -0
- package/node_modules/@askdkc/dsh-auth/lib/custom-profiles.js +142 -0
- package/node_modules/@askdkc/dsh-auth/lib/index.d.ts +96 -0
- package/node_modules/@askdkc/dsh-auth/lib/index.js +263 -0
- package/node_modules/@askdkc/dsh-auth/lib/interaction.d.ts +68 -0
- package/node_modules/@askdkc/dsh-auth/lib/interaction.js +193 -0
- package/node_modules/@askdkc/dsh-auth/lib/nous-oauth.d.ts +5 -0
- package/node_modules/@askdkc/dsh-auth/lib/nous-oauth.js +112 -0
- package/node_modules/@askdkc/dsh-auth/lib/opener.d.ts +32 -0
- package/node_modules/@askdkc/dsh-auth/lib/opener.js +101 -0
- package/node_modules/@askdkc/dsh-auth/lib/pi-ai.d.ts +23 -0
- package/node_modules/@askdkc/dsh-auth/lib/pi-ai.js +27 -0
- package/node_modules/@askdkc/dsh-auth/lib/profiles.d.ts +45 -0
- package/node_modules/@askdkc/dsh-auth/lib/profiles.js +110 -0
- package/node_modules/@askdkc/dsh-auth/lib/service.d.ts +80 -0
- package/node_modules/@askdkc/dsh-auth/lib/service.js +224 -0
- package/node_modules/@askdkc/dsh-auth/package.json +70 -0
- 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 +492 -0
- package/presets/liangshen/.dsh-tui-managed.json +5 -0
- package/presets/liangshen/agent.cordis.yml +425 -0
- package/presets/liangshen/compaction-epoch.mjs +83 -0
- package/presets/liangshen/custom-bash.mjs +301 -0
- package/presets/liangshen/instruction-hint.mjs +190 -0
- package/presets/liangshen/preset.yml +3 -0
- package/presets/liangshen/session-events.mjs +8 -0
- package/presets/liangshen/skill-search.mjs +141 -0
- package/presets/liangshen/tool-bootstrap.mjs +300 -0
- 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
|
@@ -0,0 +1,2818 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import autoBind from 'auto-bind';
|
|
3
|
+
import { closeSync, constants as fsConstants, openSync, readSync, writeSync } from 'fs';
|
|
4
|
+
import noop from 'lodash-es/noop.js';
|
|
5
|
+
import throttle from 'lodash-es/throttle.js';
|
|
6
|
+
import { ConcurrentRoot } from 'react-reconciler/constants.js';
|
|
7
|
+
import { onExit } from 'signal-exit';
|
|
8
|
+
import { flushInteractionTime } from '../bootstrap/state.js';
|
|
9
|
+
import { getYogaCounters } from '../native-ts/yoga-layout/index.js';
|
|
10
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
11
|
+
import { logError } from '../utils/log.js';
|
|
12
|
+
import { isEnvTruthy } from '../utils/envUtils.js';
|
|
13
|
+
import { format } from 'util';
|
|
14
|
+
import { colorize } from './colorize.js';
|
|
15
|
+
import App from './components/App.js';
|
|
16
|
+
import { FRAME_INTERVAL_MS, PTY_BACKLOG_BYTES } from './constants.js';
|
|
17
|
+
import * as dom from './dom.js';
|
|
18
|
+
import { beginGeometryFrame, endGeometryFrame, GEOMETRY_TRACE_ENABLED, noteFrameCause } from './geometry-trace.js';
|
|
19
|
+
import { callWithUpdateOverflowGuard, installNestedUpdateOverflowProcessGuard } from './update-overflow-guard.js';
|
|
20
|
+
import { KeyboardEvent } from './events/keyboard-event.js';
|
|
21
|
+
import { FocusManager } from './focus.js';
|
|
22
|
+
import { emptyFrame } from './frame.js';
|
|
23
|
+
import { dispatchClick, dispatchContextMenu, dispatchDragEvent as bubbleDragEvent, dispatchHover, dispatchWheel, findDragTarget, clearHovered, invalidateNoInterestRect } from './hit-test.js';
|
|
24
|
+
import { logMouseDebug } from '../utils/debug.js';
|
|
25
|
+
import { noteTerminalFlush } from './flush-tick.js';
|
|
26
|
+
import instances from './instances.js';
|
|
27
|
+
import { suppressInputFor } from './input-suppression.js';
|
|
28
|
+
import { LogUpdate } from './log-update.js';
|
|
29
|
+
import { KittyGraphicsManager } from './kitty-graphics.js';
|
|
30
|
+
import { SixelGraphicsManager } from './sixel-graphics.js';
|
|
31
|
+
import { selectTerminalImageProtocol } from './terminal-image-protocol.js';
|
|
32
|
+
import { nodeCache } from './node-cache.js';
|
|
33
|
+
import { optimize } from './optimizer.js';
|
|
34
|
+
import Output from './output.js';
|
|
35
|
+
import reconciler, { dispatcher, getLastCommitMs, getLastYogaMs, isDebugRepaintsEnabled, recordYogaMs, resetProfileCounters } from './reconciler.js';
|
|
36
|
+
import renderNodeToOutput, { consumeFollowScroll, consumeViewportResizes, didLayoutShift } from './render-node-to-output.js';
|
|
37
|
+
import { applyPositionedHighlight, scanPositions } from './render-to-screen.js';
|
|
38
|
+
import createRenderer from './renderer.js';
|
|
39
|
+
import { CharPool, cellAt, createScreen, HyperlinkPool, isEmptyCellAt, migrateScreenPools, StylePool } from './screen.js';
|
|
40
|
+
import { applySearchHighlight } from './transcript-highlight.js';
|
|
41
|
+
import { applySelectionOverlay, captureScrolledRows, clearSelection, createSelectionState, extendSelection, findPlainTextUrlAt, getSelectedText, hasSelection, moveFocus, pickFollowForSelection, refreshSelectionFingerprint, selectLineAt, selectWordAt, shiftSelection, shiftSelectionForFollow, shiftSelectionForViewportResize, shiftSelectionForViewportTranslation, startSelection, updateSelection } from './selection.js';
|
|
42
|
+
import { isDecstbmSafe, SYNC_OUTPUT_SUPPORTED, serializeDiff, supportsDecrqmProbe, supportsExtendedKeys, supportsWin32InputMode, writeDiffToTerminal } from './terminal.js';
|
|
43
|
+
import { CURSOR_HOME, cursorMove, cursorPosition, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE, ENABLE_KITTY_KEYBOARD, ENABLE_MODIFY_OTHER_KEYS, ENABLE_WIN32_INPUT_MODE, ERASE_SCREEN, ERASE_SCROLLBACK, SGR_RESET } from './termio/csi.js';
|
|
44
|
+
import { DBP, DFE, DISABLE_MOUSE_TRACKING, ENABLE_MOUSE_TRACKING, ENTER_ALT_SCREEN, EXIT_ALT_SCREEN, SHOW_CURSOR } from './termio/dec.js';
|
|
45
|
+
import { CLEAR_ITERM2_PROGRESS, CLEAR_TAB_STATUS, setClipboard, supportsTabStatus, wrapForMultiplexer } from './termio/osc.js';
|
|
46
|
+
import { decrqm, kittyGraphics, terminalCellSizePixels, terminalWindowSizePixels } from './terminal-querier.js';
|
|
47
|
+
import { TerminalWriteProvider } from './useTerminalNotification.js';
|
|
48
|
+
import { TerminalImagesContext } from './hooks/use-terminal-images.js';
|
|
49
|
+
import { DEFAULT_TERMINAL_CELL_SIZE, resolveTerminalCellSize } from './terminal-image.js';
|
|
50
|
+
// Alt-screen: renderer.ts sets cursor.visible = !isTTY || screen.height===0,
|
|
51
|
+
// which is always false in alt-screen (TTY + content fills screen).
|
|
52
|
+
// Reusing a frozen object saves 1 allocation per frame.
|
|
53
|
+
const ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
|
|
54
|
+
x: 0,
|
|
55
|
+
y: 0,
|
|
56
|
+
visible: false
|
|
57
|
+
});
|
|
58
|
+
const CURSOR_HOME_PATCH = Object.freeze({
|
|
59
|
+
type: 'stdout',
|
|
60
|
+
content: CURSOR_HOME
|
|
61
|
+
});
|
|
62
|
+
const ERASE_THEN_HOME_PATCH = Object.freeze({
|
|
63
|
+
type: 'stdout',
|
|
64
|
+
content: ERASE_SCREEN + CURSOR_HOME
|
|
65
|
+
});
|
|
66
|
+
const TERMINAL_REPLY_QUARANTINE_MS = 120;
|
|
67
|
+
// Cached per-Ink-instance, invalidated on resize. frame.cursor.y for
|
|
68
|
+
// alt-screen is always terminalRows - 1 (renderer.ts).
|
|
69
|
+
function makeAltScreenParkPatch(terminalRows) {
|
|
70
|
+
return Object.freeze({
|
|
71
|
+
type: 'stdout',
|
|
72
|
+
content: cursorPosition(terminalRows, 1)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export default class Ink {
|
|
76
|
+
options;
|
|
77
|
+
log;
|
|
78
|
+
terminal;
|
|
79
|
+
kittyGraphicsManager = new KittyGraphicsManager();
|
|
80
|
+
sixelGraphicsManager = new SixelGraphicsManager(() => {
|
|
81
|
+
if (this.isUnmounted || this.isPaused || this.terminalQueriesSuspended || !this.altScreenActive)
|
|
82
|
+
return;
|
|
83
|
+
dom.markTreeDirty(this.rootNode);
|
|
84
|
+
this.scheduleRender();
|
|
85
|
+
});
|
|
86
|
+
sixelGraphicsSupported = false;
|
|
87
|
+
kittyGraphicsSupported = false;
|
|
88
|
+
kittyGraphicsProbeStarted = false;
|
|
89
|
+
terminalImageRequests = 0;
|
|
90
|
+
measuredImageCellSize;
|
|
91
|
+
terminalImageListeners = new Set();
|
|
92
|
+
terminalImages = {
|
|
93
|
+
subscribe: (listener) => {
|
|
94
|
+
this.terminalImageListeners.add(listener);
|
|
95
|
+
return () => { this.terminalImageListeners.delete(listener); };
|
|
96
|
+
},
|
|
97
|
+
getSnapshot: () => this.altScreenActive && (this.kittyGraphicsSupported || this.sixelGraphicsSupported) &&
|
|
98
|
+
!this.isPaused && !this.terminalQueriesSuspended && !this.isUnmounted,
|
|
99
|
+
getCellSize: () => this.measuredImageCellSize,
|
|
100
|
+
request: () => {
|
|
101
|
+
if (this.isUnmounted)
|
|
102
|
+
return noop;
|
|
103
|
+
this.terminalImageRequests += 1;
|
|
104
|
+
this.maybeProbeKittyGraphics([]);
|
|
105
|
+
return () => { this.terminalImageRequests -= 1; };
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
terminalCellMetricsInFlight = false;
|
|
109
|
+
terminalCellMetricsRefreshPending = false;
|
|
110
|
+
terminalQueryResumeTimer = null;
|
|
111
|
+
app = null;
|
|
112
|
+
scheduleRender;
|
|
113
|
+
// Ignore last render after unmounting a tree to prevent empty output before exit
|
|
114
|
+
isUnmounted = false;
|
|
115
|
+
isPaused = false;
|
|
116
|
+
container;
|
|
117
|
+
rootNode;
|
|
118
|
+
focusManager;
|
|
119
|
+
renderer;
|
|
120
|
+
stylePool;
|
|
121
|
+
charPool;
|
|
122
|
+
hyperlinkPool;
|
|
123
|
+
exitPromise;
|
|
124
|
+
restoreConsole;
|
|
125
|
+
restoreStderr;
|
|
126
|
+
unsubscribeTTYHandlers;
|
|
127
|
+
terminalColumns;
|
|
128
|
+
terminalRows;
|
|
129
|
+
currentNode = null;
|
|
130
|
+
frontFrame;
|
|
131
|
+
backFrame;
|
|
132
|
+
lastPoolResetTime = performance.now();
|
|
133
|
+
drainTimer = null;
|
|
134
|
+
// Every scheduled microtask carries the generation that created it. Immediate
|
|
135
|
+
// renders invalidate older trailing work before it can append an old frame.
|
|
136
|
+
renderGeneration = 0;
|
|
137
|
+
pendingRenderGeneration = null;
|
|
138
|
+
lastYogaCounters = {
|
|
139
|
+
ms: 0,
|
|
140
|
+
visited: 0,
|
|
141
|
+
measured: 0,
|
|
142
|
+
cacheHits: 0,
|
|
143
|
+
live: 0
|
|
144
|
+
};
|
|
145
|
+
altScreenParkPatch;
|
|
146
|
+
// Text selection state (alt-screen only). Owned here so the overlay
|
|
147
|
+
// pass in onRender can read it and App.tsx can update it from mouse
|
|
148
|
+
// events. Public so instances.get() callers can access.
|
|
149
|
+
selection = createSelectionState();
|
|
150
|
+
// Search highlight query (alt-screen only). Setter below triggers
|
|
151
|
+
// scheduleRender; applySearchHighlight in onRender inverts matching cells.
|
|
152
|
+
searchHighlightQuery = '';
|
|
153
|
+
// Position-based highlight. VML scans positions ONCE (via
|
|
154
|
+
// scanElementSubtree, when the target message is mounted), stores them
|
|
155
|
+
// message-relative, sets this for every-frame apply. rowOffset =
|
|
156
|
+
// message's current screen-top. currentIdx = which position is
|
|
157
|
+
// "current" (yellow). null clears. Positions are known upfront —
|
|
158
|
+
// navigation is index arithmetic, no scan-feedback loop.
|
|
159
|
+
searchPositions = null;
|
|
160
|
+
// React-land subscribers for selection state changes (useHasSelection).
|
|
161
|
+
// Fired alongside the terminal repaint whenever the selection mutates
|
|
162
|
+
// so UI (e.g. footer hints) can react to selection appearing/clearing.
|
|
163
|
+
selectionListeners = new Set();
|
|
164
|
+
// DOM nodes currently under the pointer (mode-1003 motion). Held here
|
|
165
|
+
// so App.tsx's handleMouseEvent is stateless — dispatchHover diffs
|
|
166
|
+
// against this set and mutates it in place.
|
|
167
|
+
hoveredNodes = new Set();
|
|
168
|
+
// Set by <AlternateScreen> via setAltScreenActive(). Controls the
|
|
169
|
+
// renderer's cursor.y clamping (keeps cursor in-viewport to avoid
|
|
170
|
+
// LF-induced scroll when screen.height === terminalRows) and gates
|
|
171
|
+
// alt-screen-aware SIGCONT/resize/unmount handling.
|
|
172
|
+
altScreenActive = false;
|
|
173
|
+
// Set alongside altScreenActive so SIGCONT resume knows whether to
|
|
174
|
+
// re-enable mouse tracking (not all <AlternateScreen> uses want it).
|
|
175
|
+
altScreenMouseTracking = false;
|
|
176
|
+
// DEC 1049 preserves the physical main screen and cursor. Keep the matching
|
|
177
|
+
// renderer state while an inline full-screen view is active so its exit can
|
|
178
|
+
// diff from what the terminal actually restores instead of printing a full
|
|
179
|
+
// duplicate frame into main-screen scrollback.
|
|
180
|
+
mainScreenFrameState = null;
|
|
181
|
+
// True when the previous frame's screen buffer cannot be trusted for
|
|
182
|
+
// blit — selection overlay mutated it, resetFramesForAltScreen()
|
|
183
|
+
// replaced it with blanks, or forceRedraw() reset it to 0×0. Forces
|
|
184
|
+
// one full-render frame; steady-state frames after clear it and regain
|
|
185
|
+
// the blit + narrow-damage fast path.
|
|
186
|
+
prevFrameContaminated = false;
|
|
187
|
+
// A ConPTY resize may discard terminal cells without changing the grid.
|
|
188
|
+
// Consume once at the next scheduled paint, not once per resize event.
|
|
189
|
+
needsSurfaceRepaint = false;
|
|
190
|
+
// Set by handleResize: prepend ERASE_SCREEN to the next onRender's patches
|
|
191
|
+
// INSIDE the BSU/ESU block so clear+paint is atomic. Writing ERASE_SCREEN
|
|
192
|
+
// synchronously in handleResize would leave the screen blank for the ~80ms
|
|
193
|
+
// render() takes; deferring into the atomic block means old content stays
|
|
194
|
+
// visible until the new frame is fully ready.
|
|
195
|
+
needsEraseBeforePaint = false;
|
|
196
|
+
// Native cursor positioning: a component (via useDeclaredCursor) declares
|
|
197
|
+
// where the terminal cursor should be parked after each frame. Terminal
|
|
198
|
+
// emulators render IME preedit text at the physical cursor position, and
|
|
199
|
+
// screen readers / screen magnifiers track it — so parking at the text
|
|
200
|
+
// input's caret makes CJK input appear inline and lets a11y tools follow.
|
|
201
|
+
cursorDeclaration = null;
|
|
202
|
+
// Main-screen: physical cursor position after the declared-cursor move,
|
|
203
|
+
// tracked separately from frame.cursor (which must stay at content-bottom
|
|
204
|
+
// for log-update's relative-move invariants). Alt-screen doesn't need
|
|
205
|
+
// this — every frame begins with CSI H. null = no move emitted last frame.
|
|
206
|
+
displayCursor = null;
|
|
207
|
+
handleStdinError(error) {
|
|
208
|
+
if (this.isUnmounted && error.code === 'EIO') {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
constructor(options) {
|
|
214
|
+
this.options = options;
|
|
215
|
+
autoBind(this);
|
|
216
|
+
if (options.stdin.isTTY) {
|
|
217
|
+
// Keep this listener through teardown: a pending libuv TTY read can
|
|
218
|
+
// report EIO only after raw mode and React have already been released.
|
|
219
|
+
options.stdin.on('error', this.handleStdinError);
|
|
220
|
+
}
|
|
221
|
+
if (this.options.patchConsole) {
|
|
222
|
+
this.restoreConsole = this.patchConsole();
|
|
223
|
+
this.restoreStderr = this.patchStderr();
|
|
224
|
+
}
|
|
225
|
+
this.terminal = {
|
|
226
|
+
stdout: options.stdout,
|
|
227
|
+
stderr: options.stderr
|
|
228
|
+
};
|
|
229
|
+
this.terminalColumns = options.stdout.columns || 80;
|
|
230
|
+
this.terminalRows = options.stdout.rows || 24;
|
|
231
|
+
this.altScreenParkPatch = makeAltScreenParkPatch(this.terminalRows);
|
|
232
|
+
this.stylePool = new StylePool();
|
|
233
|
+
this.charPool = new CharPool();
|
|
234
|
+
this.hyperlinkPool = new HyperlinkPool();
|
|
235
|
+
this.frontFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
236
|
+
this.backFrame = emptyFrame(this.terminalRows, this.terminalColumns, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
237
|
+
this.log = new LogUpdate({
|
|
238
|
+
isTTY: options.stdout.isTTY || false,
|
|
239
|
+
stylePool: this.stylePool
|
|
240
|
+
});
|
|
241
|
+
// scheduleRender is called from the reconciler's resetAfterCommit, which
|
|
242
|
+
// runs BEFORE React's layout phase (ref attach + useLayoutEffect). Any
|
|
243
|
+
// state set in layout effects — notably the cursorDeclaration from
|
|
244
|
+
// useDeclaredCursor — would lag one commit behind if we rendered
|
|
245
|
+
// synchronously. Deferring to a microtask runs onRender after layout
|
|
246
|
+
// effects have committed, so the native cursor tracks the caret without
|
|
247
|
+
// a one-keystroke lag. Same event-loop tick, so throughput is unchanged.
|
|
248
|
+
// Test env uses onImmediateRender (direct onRender, no throttle) so
|
|
249
|
+
// existing synchronous lastFrame() tests are unaffected. Keep a
|
|
250
|
+
// generation on the microtask: an immediate render may supersede the
|
|
251
|
+
// leading frame before its deferred callback runs.
|
|
252
|
+
const deferredRender = () => {
|
|
253
|
+
const generation = ++this.renderGeneration;
|
|
254
|
+
this.pendingRenderGeneration = generation;
|
|
255
|
+
queueMicrotask(() => {
|
|
256
|
+
if (this.pendingRenderGeneration !== generation || this.renderGeneration !== generation)
|
|
257
|
+
return;
|
|
258
|
+
this.pendingRenderGeneration = null;
|
|
259
|
+
this.onRender();
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
this.scheduleRender = throttle(deferredRender, FRAME_INTERVAL_MS, {
|
|
263
|
+
leading: true,
|
|
264
|
+
trailing: true
|
|
265
|
+
});
|
|
266
|
+
// Ignore last render after unmounting a tree to prevent empty output before exit
|
|
267
|
+
this.isUnmounted = false;
|
|
268
|
+
// Unmount when process exits
|
|
269
|
+
this.unsubscribeExit = onExit(this.unmount, {
|
|
270
|
+
alwaysLast: false
|
|
271
|
+
});
|
|
272
|
+
if (options.stdout.isTTY) {
|
|
273
|
+
options.stdout.on('resize', this.handleResize);
|
|
274
|
+
process.on('SIGCONT', this.handleResume);
|
|
275
|
+
this.unsubscribeTTYHandlers = () => {
|
|
276
|
+
options.stdout.off('resize', this.handleResize);
|
|
277
|
+
process.off('SIGCONT', this.handleResume);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
this.rootNode = dom.createNode('ink-root');
|
|
281
|
+
this.focusManager = new FocusManager((target, event) => dispatcher.dispatchDiscrete(target, event));
|
|
282
|
+
this.rootNode.focusManager = this.focusManager;
|
|
283
|
+
this.renderer = createRenderer(this.rootNode, this.stylePool);
|
|
284
|
+
this.rootNode.onRender = this.scheduleRender;
|
|
285
|
+
this.rootNode.onImmediateRender = this.renderNow;
|
|
286
|
+
this.rootNode.onComputeLayout = () => {
|
|
287
|
+
// Hover no-interest cache (hit-test.ts) is strictly per-frame: every
|
|
288
|
+
// React commit may attach or detach hover handlers, so drop the cache
|
|
289
|
+
// at the COMMIT boundary. The renderer also invalidates at the top of
|
|
290
|
+
// each render pass, but that runs up to a frame later (throttled
|
|
291
|
+
// scheduleRender) — invalidating here closes the gap so a motion
|
|
292
|
+
// event inside that window re-hit-tests against the fresh tree.
|
|
293
|
+
invalidateNoInterestRect();
|
|
294
|
+
// Calculate layout during React's commit phase so useLayoutEffect hooks
|
|
295
|
+
// have access to fresh layout data
|
|
296
|
+
// Guard against accessing freed Yoga nodes after unmount
|
|
297
|
+
if (this.isUnmounted) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (this.rootNode.yogaNode) {
|
|
301
|
+
const t0 = performance.now();
|
|
302
|
+
this.rootNode.yogaNode.setWidth(this.terminalColumns);
|
|
303
|
+
this.rootNode.yogaNode.calculateLayout(this.terminalColumns);
|
|
304
|
+
const ms = performance.now() - t0;
|
|
305
|
+
recordYogaMs(ms);
|
|
306
|
+
const c = getYogaCounters();
|
|
307
|
+
this.lastYogaCounters = {
|
|
308
|
+
ms,
|
|
309
|
+
...c
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
// @ts-ignore -- runtime/type-definition mismatch: @types/react-reconciler@0.32.3 declares 11 args with transitionCallbacks,
|
|
314
|
+
// but react-reconciler 0.33.0 source only accepts 10 args (no transitionCallbacks)
|
|
315
|
+
this.container = reconciler.createContainer(this.rootNode, ConcurrentRoot, null, false, null, 'id', noop,
|
|
316
|
+
// onUncaughtError
|
|
317
|
+
noop,
|
|
318
|
+
// onCaughtError
|
|
319
|
+
noop,
|
|
320
|
+
// onRecoverableError
|
|
321
|
+
noop // onDefaultTransitionIndicator
|
|
322
|
+
);
|
|
323
|
+
// #185 process backstop: the nested-update overflow can surface from any
|
|
324
|
+
// timer dispatch (not only the guarded hotspots), which would kill the
|
|
325
|
+
// process. React resets the counter before throwing, so absorbing the
|
|
326
|
+
// error class process-wide is safe — see update-overflow-guard.ts.
|
|
327
|
+
installNestedUpdateOverflowProcessGuard();
|
|
328
|
+
if (process.env.NODE_ENV === 'development') {
|
|
329
|
+
reconciler.injectIntoDevTools({
|
|
330
|
+
bundleType: 0,
|
|
331
|
+
// Reporting React DOM's version, not Ink's
|
|
332
|
+
// See https://github.com/facebook/react/issues/16666#issuecomment-532639905
|
|
333
|
+
version: '16.13.1',
|
|
334
|
+
rendererPackageName: 'ink'
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
handleResume = () => {
|
|
339
|
+
if (!this.options.stdout.isTTY) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
// Alt screen: after SIGCONT, content is stale (shell may have written
|
|
343
|
+
// to main screen, switching focus away) and mouse tracking was
|
|
344
|
+
// disabled by handleSuspend.
|
|
345
|
+
if (this.altScreenActive) {
|
|
346
|
+
this.reenterAltScreen();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
// Main screen: start fresh to prevent clobbering terminal content
|
|
350
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
351
|
+
this.backFrame = emptyFrame(this.backFrame.viewport.height, this.backFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
352
|
+
this.log.reset();
|
|
353
|
+
// Physical cursor position is unknown after the shell took over during
|
|
354
|
+
// suspend. Clear displayCursor so the next frame's cursor preamble
|
|
355
|
+
// doesn't emit a relative move from a stale park position.
|
|
356
|
+
this.displayCursor = null;
|
|
357
|
+
};
|
|
358
|
+
// NOT debounced. A debounce opens a window where stdout.columns is NEW
|
|
359
|
+
// but this.terminalColumns/Yoga are OLD — any scheduleRender during that
|
|
360
|
+
// window (spinner, clock) makes log-update detect a width change and
|
|
361
|
+
// clear the screen, then the debounce fires and clears again (double
|
|
362
|
+
// blank→paint flicker). useVirtualScroll's height scaling already bounds
|
|
363
|
+
// the per-resize cost; synchronous handling keeps dimensions consistent.
|
|
364
|
+
handleResize = () => {
|
|
365
|
+
const cols = this.options.stdout.columns || 80;
|
|
366
|
+
const rows = this.options.stdout.rows || 24;
|
|
367
|
+
// Duplicate resize events normally leave both layout and surface intact.
|
|
368
|
+
// ConPTY can rebuild the alt buffer during maximize with the SAME grid,
|
|
369
|
+
// though: the cached frame then hides lost static cells forever (#891).
|
|
370
|
+
if (cols === this.terminalColumns && rows === this.terminalRows) {
|
|
371
|
+
// A font zoom or DPI move can change cell pixels without changing the
|
|
372
|
+
// row/column grid. The in-flight guard coalesces duplicate events.
|
|
373
|
+
this.refreshTerminalCellMetrics();
|
|
374
|
+
if ((process.platform === 'win32' || !!process.env.WT_SESSION) &&
|
|
375
|
+
this.altScreenActive && this.options.stdout.isTTY &&
|
|
376
|
+
!this.isPaused && !this.isUnmounted && !this.needsSurfaceRepaint) {
|
|
377
|
+
this.needsSurfaceRepaint = true;
|
|
378
|
+
this.scheduleRender();
|
|
379
|
+
}
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
noteFrameCause('resize');
|
|
383
|
+
this.terminalColumns = cols;
|
|
384
|
+
this.terminalRows = rows;
|
|
385
|
+
this.refreshTerminalCellMetrics();
|
|
386
|
+
this.altScreenParkPatch = makeAltScreenParkPatch(this.terminalRows);
|
|
387
|
+
// Reflow moved every rect the pointer state was tracking: hover sets
|
|
388
|
+
// and the multi-click chain reference pre-resize geometry. Fire the
|
|
389
|
+
// leave handlers FIRST — a bare clear() strands the crossed rows'
|
|
390
|
+
// hovered=true React state forever (stuck highlights) — then drop the
|
|
391
|
+
// set so a post-resize click is a fresh single click and hover re-fires
|
|
392
|
+
// from scratch. (Coordinates in in-flight events are clamped at the
|
|
393
|
+
// App boundary against the new dimensions.)
|
|
394
|
+
clearHovered(this.hoveredNodes);
|
|
395
|
+
this.app?.resetPointerState();
|
|
396
|
+
// Same geometry wholesale-change: the cached no-interest hover rect
|
|
397
|
+
// (hit-test.ts) was computed against pre-resize rects — drop it.
|
|
398
|
+
invalidateNoInterestRect();
|
|
399
|
+
// Invalidate every render that was scheduled against the OLD size: a
|
|
400
|
+
// queued microtask generation or a scroll-drain timer would otherwise
|
|
401
|
+
// fire after this resize completes and paint a frame computed for the
|
|
402
|
+
// pre-resize layout (mixed-width rows, off-by-reflow writes). The
|
|
403
|
+
// re-render below schedules fresh work at the new dimensions.
|
|
404
|
+
this.renderGeneration++;
|
|
405
|
+
this.pendingRenderGeneration = null;
|
|
406
|
+
this.scheduleRender.cancel?.();
|
|
407
|
+
if (this.drainTimer !== null) {
|
|
408
|
+
clearTimeout(this.drainTimer);
|
|
409
|
+
this.drainTimer = null;
|
|
410
|
+
}
|
|
411
|
+
// Every cached measurement in the tree was taken against a width that no
|
|
412
|
+
// longer exists. Nothing here is "dirty" in the reconciler's sense — no
|
|
413
|
+
// props changed — so without an explicit sweep the text nodes keep
|
|
414
|
+
// answering with the sizes they computed for the old terminal, and the
|
|
415
|
+
// rows that depend on flex arbitration come out assembled from two
|
|
416
|
+
// different layouts. Setting the root's width alone does not reach them:
|
|
417
|
+
// markDirty walks upward from a changed node, and here the change is the
|
|
418
|
+
// constraint every node was measured against.
|
|
419
|
+
dom.markTreeDirty(this.rootNode);
|
|
420
|
+
// Alt screen: reset frame buffers so the next render repaints from
|
|
421
|
+
// scratch (prevFrameContaminated → every cell written, wrapped in
|
|
422
|
+
// BSU/ESU — old content stays visible until the new frame swaps
|
|
423
|
+
// atomically). Re-assert mouse tracking (some emulators reset it on
|
|
424
|
+
// resize). Do NOT write ENTER_ALT_SCREEN: iTerm2 treats ?1049h as a
|
|
425
|
+
// buffer clear even when already in alt — that's the blank flicker.
|
|
426
|
+
// Self-healing re-entry (if something kicked us out of alt) is handled
|
|
427
|
+
// by handleResume (SIGCONT) and the sleep-wake detector; resize itself
|
|
428
|
+
// doesn't exit alt-screen. Do NOT write ERASE_SCREEN: render() below
|
|
429
|
+
// can take ~80ms; erasing first leaves the screen blank that whole time.
|
|
430
|
+
if (this.altScreenActive && !this.isPaused && this.options.stdout.isTTY) {
|
|
431
|
+
// Blind mouse re-assert + 1049 probe: conpty resets modes on resize
|
|
432
|
+
// too, and a dropped 1049 means every subsequent frame paints onto
|
|
433
|
+
// the MAIN screen (looks like the app spontaneously exited
|
|
434
|
+
// fullscreen). The probe's re-entry is gated on a positive DECRPM
|
|
435
|
+
// "reset" answer, so this stays inert on healthy terminals.
|
|
436
|
+
this.probeAltScreenHealth();
|
|
437
|
+
this.resetFramesForAltScreen();
|
|
438
|
+
this.needsEraseBeforePaint = true;
|
|
439
|
+
}
|
|
440
|
+
// Re-render the React tree with updated props so the context value changes.
|
|
441
|
+
// React's commit phase will call onComputeLayout() to recalculate yoga layout
|
|
442
|
+
// with the new dimensions, then call onRender() to render the updated frame.
|
|
443
|
+
// We don't call scheduleRender() here because that would render before the
|
|
444
|
+
// layout is updated, causing a mismatch between viewport and content dimensions.
|
|
445
|
+
if (this.currentNode !== null) {
|
|
446
|
+
this.render(this.currentNode);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
resolveExitPromise = () => { };
|
|
450
|
+
rejectExitPromise = () => { };
|
|
451
|
+
unsubscribeExit = () => { };
|
|
452
|
+
/**
|
|
453
|
+
* Pause Ink and hand the terminal over to an external TUI (e.g. git
|
|
454
|
+
* commit editor). In non-fullscreen mode this enters the alt screen;
|
|
455
|
+
* in fullscreen mode we're already in alt so we just clear it.
|
|
456
|
+
* Call `exitAlternateScreen()` when done to restore Ink.
|
|
457
|
+
*/
|
|
458
|
+
enterAlternateScreen() {
|
|
459
|
+
this.pause();
|
|
460
|
+
this.app?.querier.suspend();
|
|
461
|
+
if (this.terminalQueryResumeTimer !== null) {
|
|
462
|
+
clearTimeout(this.terminalQueryResumeTimer);
|
|
463
|
+
this.terminalQueryResumeTimer = null;
|
|
464
|
+
}
|
|
465
|
+
// Replies cannot be routed while the child owns stdin. Release every
|
|
466
|
+
// query hold before cooked mode is restored; an interrupted first Kitty
|
|
467
|
+
// probe may be attempted again after the handoff.
|
|
468
|
+
if (!this.kittyGraphicsSupported && !this.sixelGraphicsSupported)
|
|
469
|
+
this.kittyGraphicsProbeStarted = false;
|
|
470
|
+
this.suspendStdin();
|
|
471
|
+
// Kitty placements are independent of the terminal cell grid: clearing
|
|
472
|
+
// the screen for an external editor does not remove them. Delete every
|
|
473
|
+
// renderer-owned image before handing the buffer over, otherwise a
|
|
474
|
+
// negative-z preview can remain visible through the editor's default-
|
|
475
|
+
// background cells. deleteAll() also forgets the ids so the restore pass
|
|
476
|
+
// uploads fresh data after resetFramesForAltScreen().
|
|
477
|
+
const deleteImages = this.kittyGraphicsManager.deleteAll() + this.sixelGraphicsManager.clear();
|
|
478
|
+
this.options.stdout.write(deleteImages +
|
|
479
|
+
// Disable extended key reporting first — editors that don't speak
|
|
480
|
+
// CSI-u (e.g. nano) show "Unknown sequence" for every Ctrl-<key> if
|
|
481
|
+
// kitty/modifyOtherKeys stays active. exitAlternateScreen re-enables.
|
|
482
|
+
// win32-input-mode (native Windows) likewise must not leak into the
|
|
483
|
+
// editor — it would turn every key into INPUT_RECORD sequences.
|
|
484
|
+
DISABLE_WIN32_INPUT_MODE + DISABLE_KITTY_KEYBOARD + DISABLE_MODIFY_OTHER_KEYS + (this.altScreenMouseTracking ? DISABLE_MOUSE_TRACKING : '') + (
|
|
485
|
+
// disable mouse (no-op if off)
|
|
486
|
+
this.altScreenActive ? '' : '\x1b[?1049h') +
|
|
487
|
+
// enter alt (already in alt if fullscreen)
|
|
488
|
+
'\x1b[?1004l' +
|
|
489
|
+
// disable focus reporting
|
|
490
|
+
'\x1b[0m' +
|
|
491
|
+
// reset attributes
|
|
492
|
+
'\x1b[?25h' +
|
|
493
|
+
// show cursor
|
|
494
|
+
'\x1b[2J' +
|
|
495
|
+
// clear screen
|
|
496
|
+
'\x1b[H' // cursor home
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Resume Ink after an external TUI handoff with a full repaint.
|
|
501
|
+
* In non-fullscreen mode this exits the alt screen back to main;
|
|
502
|
+
* in fullscreen mode we re-enter alt and clear + repaint.
|
|
503
|
+
*
|
|
504
|
+
* The re-enter matters: terminal editors (vim, nano, less) write
|
|
505
|
+
* smcup/rmcup (?1049h/?1049l), so even though we started in alt,
|
|
506
|
+
* the editor's rmcup on exit drops us to main screen. Without
|
|
507
|
+
* re-entering, the 2J below wipes the user's main-screen scrollback
|
|
508
|
+
* and subsequent renders land in main — native terminal scroll
|
|
509
|
+
* returns, fullscreen scroll is dead.
|
|
510
|
+
*/
|
|
511
|
+
exitAlternateScreen() {
|
|
512
|
+
if (this.altScreenActive) {
|
|
513
|
+
// Fullscreen: re-enter alt FIRST — terminal editors (vim, nano, less)
|
|
514
|
+
// write smcup/rmcup, so the editor's rmcup on exit dropped us to the
|
|
515
|
+
// main screen; without re-entering, the 2J below would wipe the
|
|
516
|
+
// user's main-screen scrollback and later renders would land in main
|
|
517
|
+
// (native scroll returns, fullscreen scroll dies).
|
|
518
|
+
this.options.stdout.write(ENTER_ALT_SCREEN +
|
|
519
|
+
'\x1b[2J' +
|
|
520
|
+
// clear screen
|
|
521
|
+
'\x1b[H' + (
|
|
522
|
+
// cursor home
|
|
523
|
+
this.altScreenMouseTracking ? ENABLE_MOUSE_TRACKING : '') +
|
|
524
|
+
// Restore mouse tracking when enabled for the alternate screen.
|
|
525
|
+
'\x1b[?25l' // hide cursor (Ink manages)
|
|
526
|
+
);
|
|
527
|
+
this.resumeStdin();
|
|
528
|
+
// Swallow the terminal's post-restore chatter (async CPR/DECRPM
|
|
529
|
+
// replies, mouse fragments): resumeStdin's drain only covers bytes
|
|
530
|
+
// already buffered, and a stray ESC would clear a non-empty prompt
|
|
531
|
+
// (issue #123 field report).
|
|
532
|
+
suppressInputFor(TERMINAL_REPLY_QUARANTINE_MS);
|
|
533
|
+
this.resetFramesForAltScreen();
|
|
534
|
+
this.resume();
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// Inline: pop alt FIRST (a no-op when the editor's rmcup already did
|
|
538
|
+
// it), THEN clear+home the main screen and force a full redraw from
|
|
539
|
+
// home — the same proven sequence as forceRedraw()/Ctrl+L. The
|
|
540
|
+
// previous order (2J before 1049l, plain repaint(), no contamination
|
|
541
|
+
// flag) erased the alt buffer or left the blit fast path copying
|
|
542
|
+
// from an empty frontFrame: the transcript stayed blank until the
|
|
543
|
+
// next message, and the desynced log-update cursor duplicated the
|
|
544
|
+
// frame below (issue #123 field report).
|
|
545
|
+
this.options.stdout.write('\x1b[?1049l' +
|
|
546
|
+
// exit alt before touching the main screen
|
|
547
|
+
SGR_RESET + ERASE_SCREEN + CURSOR_HOME +
|
|
548
|
+
// BCE-safe clear from home, cursor parked top-left for the redraw
|
|
549
|
+
'\x1b[?25l' // hide cursor (Ink manages)
|
|
550
|
+
);
|
|
551
|
+
this.resumeStdin();
|
|
552
|
+
suppressInputFor(TERMINAL_REPLY_QUARANTINE_MS);
|
|
553
|
+
this.repaint();
|
|
554
|
+
// repaint()'s fresh empty frontFrame would let the blit fast path
|
|
555
|
+
// copy blanks and diff to nothing — same flag forceRedraw() sets.
|
|
556
|
+
this.prevFrameContaminated = true;
|
|
557
|
+
this.resume();
|
|
558
|
+
}
|
|
559
|
+
// Re-enable focus reporting and extended key reporting — terminal
|
|
560
|
+
// editors (vim, nano, etc.) write their own modifyOtherKeys level on
|
|
561
|
+
// entry and reset it on exit, leaving us unable to distinguish
|
|
562
|
+
// ctrl+shift+<letter> from ctrl+<letter>. Pop-before-push keeps the
|
|
563
|
+
// Kitty stack balanced (a well-behaved editor restores our entry, so
|
|
564
|
+
// without the pop we'd accumulate depth on each editor round-trip).
|
|
565
|
+
this.options.stdout.write('\x1b[?1004h' + (supportsWin32InputMode() ? ENABLE_WIN32_INPUT_MODE : supportsExtendedKeys() ? DISABLE_KITTY_KEYBOARD + ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS : ''));
|
|
566
|
+
this.resumeTerminalQueriesAfterHandoff();
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* One-shot viewport re-anchor for the NEXT main-screen frame: repaint the
|
|
570
|
+
* visible viewport in place instead of diffing. Exposed for callers that
|
|
571
|
+
* know a layout flip just rewrote the whole frame (Ctrl+O transcript
|
|
572
|
+
* toggle): the ordinary scroll-based diff pushes rows into terminal
|
|
573
|
+
* scrollback on every expand and nothing removes them on collapse — rapid
|
|
574
|
+
* toggles drift the virtual↔scrollback mapping until writes misland.
|
|
575
|
+
* In-place repaint adds nothing to scrollback. No-op in alt-screen
|
|
576
|
+
* (already CSI H-anchored every frame). ONLY sets the flag: the caller's
|
|
577
|
+
* own state change (setExpanded) drives the render that consumes it —
|
|
578
|
+
* forcing an extra render here would paint the OLD layout once more and
|
|
579
|
+
* burn the flag before the real frame lands.
|
|
580
|
+
*/
|
|
581
|
+
reanchorViewport() {
|
|
582
|
+
if (this.altScreenActive)
|
|
583
|
+
return;
|
|
584
|
+
noteFrameCause('reanchor');
|
|
585
|
+
this.log.requestViewportReanchor();
|
|
586
|
+
}
|
|
587
|
+
/** Render synchronously and invalidate older trailing/drain callbacks. */
|
|
588
|
+
renderNow() {
|
|
589
|
+
noteFrameCause('immediate');
|
|
590
|
+
this.renderGeneration++;
|
|
591
|
+
this.pendingRenderGeneration = null;
|
|
592
|
+
this.scheduleRender.cancel?.();
|
|
593
|
+
if (this.drainTimer !== null) {
|
|
594
|
+
clearTimeout(this.drainTimer);
|
|
595
|
+
this.drainTimer = null;
|
|
596
|
+
}
|
|
597
|
+
this.onRender();
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Drain scrolling at quarter-frame cadence while keeping queued output
|
|
601
|
+
* bounded on slow terminals. React-driven updates retain their normal
|
|
602
|
+
* throttle, so typing and streaming do not wait behind a scroll backlog.
|
|
603
|
+
*/
|
|
604
|
+
scheduleDrain() {
|
|
605
|
+
if (this.drainTimer !== null)
|
|
606
|
+
return;
|
|
607
|
+
const stdout = this.options.stdout;
|
|
608
|
+
const backlog = typeof stdout.writableLength === 'number'
|
|
609
|
+
? stdout.writableLength
|
|
610
|
+
: 0;
|
|
611
|
+
if (backlog > PTY_BACKLOG_BYTES) {
|
|
612
|
+
this.drainTimer = setTimeout(() => {
|
|
613
|
+
this.drainTimer = null;
|
|
614
|
+
this.scheduleDrain();
|
|
615
|
+
}, FRAME_INTERVAL_MS >> 2);
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
this.drainTimer = setTimeout(this.renderNow, FRAME_INTERVAL_MS >> 2);
|
|
619
|
+
}
|
|
620
|
+
onRender() {
|
|
621
|
+
if (this.isUnmounted || this.isPaused) {
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
if (this.needsSurfaceRepaint) {
|
|
625
|
+
this.needsSurfaceRepaint = false;
|
|
626
|
+
if (this.altScreenActive) {
|
|
627
|
+
noteFrameCause('resize');
|
|
628
|
+
// Repaint from an empty diff baseline without an early erase or
|
|
629
|
+
// DECSET 1049: neither may interrupt an external-editor handoff.
|
|
630
|
+
this.resetFramesForAltScreen();
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (GEOMETRY_TRACE_ENABLED)
|
|
634
|
+
beginGeometryFrame(this.renderGeneration);
|
|
635
|
+
// Entering a render cancels any pending drain tick — this render will
|
|
636
|
+
// handle the drain (and re-schedule below if needed). Prevents a
|
|
637
|
+
// wheel-event-triggered render AND a drain-timer render both firing.
|
|
638
|
+
if (this.drainTimer !== null) {
|
|
639
|
+
clearTimeout(this.drainTimer);
|
|
640
|
+
this.drainTimer = null;
|
|
641
|
+
}
|
|
642
|
+
// Flush deferred interaction-time update before rendering so we call
|
|
643
|
+
// Date.now() at most once per frame instead of once per keypress.
|
|
644
|
+
// Done before the render to avoid dirtying state that would trigger
|
|
645
|
+
// an extra React re-render cycle.
|
|
646
|
+
flushInteractionTime();
|
|
647
|
+
// Dimension consistency: onComputeLayout laid the tree out against
|
|
648
|
+
// this.terminalColumns/Rows (the cached values handleResize owns), so
|
|
649
|
+
// the renderer and the diff engine MUST paint that same size. Reading
|
|
650
|
+
// the live stdout size here mixed the two when a resize event had not
|
|
651
|
+
// fired yet (Windows Terminal emits 'resize' after columns already
|
|
652
|
+
// changed): Yoga laid out for the old width while log-update wrapped
|
|
653
|
+
// and diffed at the new one — rows painted off by the reflow delta.
|
|
654
|
+
// On drift, route through the resize path (cache sync + markTreeDirty
|
|
655
|
+
// + re-render) and bail: the render handleResize schedules paints the
|
|
656
|
+
// correctly-laid-out frame.
|
|
657
|
+
const liveColumns = this.options.stdout.columns || 80;
|
|
658
|
+
const liveRows = this.options.stdout.rows || 24;
|
|
659
|
+
if (this.options.stdout.isTTY && (liveColumns !== this.terminalColumns || liveRows !== this.terminalRows)) {
|
|
660
|
+
this.handleResize();
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const renderStart = performance.now();
|
|
664
|
+
const terminalWidth = this.terminalColumns;
|
|
665
|
+
const terminalRows = this.terminalRows;
|
|
666
|
+
const sixelActive = this.altScreenActive && this.sixelGraphicsSupported;
|
|
667
|
+
this.sixelGraphicsManager.beginFrame(terminalWidth, terminalRows);
|
|
668
|
+
const frame = this.renderer({
|
|
669
|
+
frontFrame: this.frontFrame,
|
|
670
|
+
backFrame: this.backFrame,
|
|
671
|
+
isTTY: this.options.stdout.isTTY,
|
|
672
|
+
terminalWidth,
|
|
673
|
+
terminalRows,
|
|
674
|
+
altScreen: this.altScreenActive,
|
|
675
|
+
terminalImages: this.altScreenActive && (this.kittyGraphicsSupported || this.sixelGraphicsSupported),
|
|
676
|
+
imageReady: sixelActive ? this.sixelGraphicsManager.prepare : undefined,
|
|
677
|
+
// Sixel paints rasters over the cells: an image's own cells must then
|
|
678
|
+
// carry the surface background instead of terminal-default blanks.
|
|
679
|
+
opaqueImageBacking: sixelActive,
|
|
680
|
+
prevFrameContaminated: this.prevFrameContaminated
|
|
681
|
+
});
|
|
682
|
+
const rendererMs = performance.now() - renderStart;
|
|
683
|
+
// Whether THIS frame ran a selection-coordinate translation (viewport
|
|
684
|
+
// resize/follow-shift). A covered-rows fingerprint change in such a
|
|
685
|
+
// frame is the coordinated kind — content moved WITH the highlight.
|
|
686
|
+
// An UNcoordinated change means the rows under a stationary highlight
|
|
687
|
+
// were replaced in place (streaming transcript overwrite), and the
|
|
688
|
+
// selection is marked stale so commit-time copy refuses (see
|
|
689
|
+
// refreshSelectionFingerprint below the overlay block).
|
|
690
|
+
let selectionCoordinated = false;
|
|
691
|
+
this.maybeProbeKittyGraphics(frame.images ?? []);
|
|
692
|
+
// Viewport-shrink translation (companion to the follow block below):
|
|
693
|
+
// chrome mounting around a ScrollBox (the new-messages pill, the sticky
|
|
694
|
+
// prompt header, the working spinner, prompt growth) moves the viewport
|
|
695
|
+
// edges with NO scroll delta, so no followScroll event fires and the
|
|
696
|
+
// block below never sees it. The selection endpoints are screen-buffer
|
|
697
|
+
// rows; unhandled, the anchor strands BELOW the shrunken viewport —
|
|
698
|
+
// pickFollowForSelection then rejects every follow event (anchor
|
|
699
|
+
// outside the viewport) and wheel tracking silently dies, leaving the
|
|
700
|
+
// highlight pinned to the chrome row: copy-on-select grabs the chrome
|
|
701
|
+
// text itself (the "↓ 回到底部" pill leaking into bottom-to-top copies)
|
|
702
|
+
// and the rows that scrolled under the dead highlight never reach the
|
|
703
|
+
// scrolledOff accumulators. Capture the covered band from the PREVIOUS
|
|
704
|
+
// frame's screen (frontFrame — the swap is below) and re-clamp the
|
|
705
|
+
// endpoints BEFORE the follow pick, so the clamped anchor is in-viewport
|
|
706
|
+
// and this frame's wheel drain translates normally.
|
|
707
|
+
const viewportResizes = consumeViewportResizes();
|
|
708
|
+
if (viewportResizes.length > 0 && this.selection.anchor) {
|
|
709
|
+
const resize = pickFollowForSelection(viewportResizes, this.selection.anchor.row);
|
|
710
|
+
// Terminal resize rebuilds the screen at new dimensions; the
|
|
711
|
+
// selection's screen-buffer coords are stale against the previous
|
|
712
|
+
// frame's buffer and band capture would read garbage. Chrome-mount
|
|
713
|
+
// resizes (the target case) never change the terminal size.
|
|
714
|
+
if (resize &&
|
|
715
|
+
this.frontFrame.screen.width === terminalWidth &&
|
|
716
|
+
this.frontFrame.screen.height === terminalRows) {
|
|
717
|
+
const hadSelection = hasSelection(this.selection);
|
|
718
|
+
if (resize.kind === 'translate') {
|
|
719
|
+
const cleared = shiftSelectionForViewportTranslation(this.selection, resize.rowDelta, resize.prevTop, resize.prevBottom, resize.top, resize.bottom);
|
|
720
|
+
selectionCoordinated = true;
|
|
721
|
+
if (cleared)
|
|
722
|
+
for (const cb of this.selectionListeners)
|
|
723
|
+
cb();
|
|
724
|
+
}
|
|
725
|
+
else {
|
|
726
|
+
shiftSelectionForViewportResize(this.selection, this.frontFrame.screen, resize.prevTop, resize.prevBottom, resize.top, resize.bottom);
|
|
727
|
+
selectionCoordinated = true;
|
|
728
|
+
// Both-ends-covered clear must notify React-land so useHasSelection
|
|
729
|
+
// re-renders and the footer copy/escape hint disappears — direct
|
|
730
|
+
// listener fire (notifySelectionChange would re-enter onRender).
|
|
731
|
+
if (hadSelection && !hasSelection(this.selection)) {
|
|
732
|
+
for (const cb of this.selectionListeners)
|
|
733
|
+
cb();
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
// Sticky/auto-follow or wheel-drain scrolled one or more ScrollBoxes
|
|
739
|
+
// this frame. Translate the selection by the same delta so the highlight
|
|
740
|
+
// stays anchored to the TEXT (native terminal behavior — the
|
|
741
|
+
// selection walks up the screen as content scrolls, eventually
|
|
742
|
+
// clipping at the top). frontFrame
|
|
743
|
+
// still holds the PREVIOUS frame's screen (swap is at ~500 below), so
|
|
744
|
+
// captureScrolledRows reads the rows that are about to scroll out
|
|
745
|
+
// before they're overwritten — the text stays copyable until the
|
|
746
|
+
// selection scrolls entirely off. During drag, focus tracks the mouse
|
|
747
|
+
// (screen-local) so only anchor shifts — selection grows toward the
|
|
748
|
+
// mouse as the anchor walks up. After release, both ends are text-
|
|
749
|
+
// anchored and move as a block.
|
|
750
|
+
const follow = pickFollowForSelection(consumeFollowScroll(), this.selection.anchor?.row ?? null);
|
|
751
|
+
// pickFollowForSelection already checked anchor-in-viewport (that IS
|
|
752
|
+
// the "selection is on scrollbox content" guard — footer/prompt
|
|
753
|
+
// selections on static text match no viewport and follow nothing).
|
|
754
|
+
// Innermost-viewport wins attributes correctly when several boxes
|
|
755
|
+
// scrolled this frame (transcript draining while an overlay panel's
|
|
756
|
+
// box scrolls): panels render on top, so overlap-row selections
|
|
757
|
+
// belong to the panel, not the covered transcript.
|
|
758
|
+
if (follow && this.selection.anchor) {
|
|
759
|
+
const { delta, viewportTop, viewportBottom } = follow;
|
|
760
|
+
// Signed delta: >0 = content moved up (at-bottom follow or
|
|
761
|
+
// wheel-down drain); <0 = content moved down (wheel-up drain, #438).
|
|
762
|
+
// The capture window is the viewport-edge rows about to scroll out
|
|
763
|
+
// (top edge when content moves up, bottom edge when it moves down),
|
|
764
|
+
// and the shift re-anchors the endpoints by the same amount in the
|
|
765
|
+
// OPPOSITE direction so they track the text, not the screen.
|
|
766
|
+
const rows = Math.abs(delta);
|
|
767
|
+
const up = delta > 0;
|
|
768
|
+
const firstRow = up ? viewportTop : viewportBottom - rows + 1;
|
|
769
|
+
const lastRow = up ? viewportTop + rows - 1 : viewportBottom;
|
|
770
|
+
const side = up ? 'above' : 'below';
|
|
771
|
+
const shift = up ? -rows : rows;
|
|
772
|
+
// captureScrolledRows and shift* are a pair: capture grabs rows about
|
|
773
|
+
// to scroll off, shift moves the selection endpoint so the same rows
|
|
774
|
+
// won't intersect again next frame. Capturing without shifting leaves
|
|
775
|
+
// the endpoint in place, so the SAME viewport rows re-intersect every
|
|
776
|
+
// frame and scrolledOffAbove grows without bound — getSelectedText
|
|
777
|
+
// then returns ever-growing text on each re-copy. Keep capture inside
|
|
778
|
+
// each shift branch so the pairing can't be broken by a new guard.
|
|
779
|
+
if (this.selection.isDragging) {
|
|
780
|
+
if (hasSelection(this.selection)) {
|
|
781
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, firstRow, lastRow, side, follow.screenRowOffset);
|
|
782
|
+
// Record the viewport bounds for finishSelection's deferred
|
|
783
|
+
// commit-time check: the in-flight drag never clears (a wheel
|
|
784
|
+
// must not kill the gesture), so a drag that wheeled fully
|
|
785
|
+
// off-edge is dropped when it ENDS, not while it is running.
|
|
786
|
+
this.selection.dragBounds = { top: viewportTop, bottom: viewportBottom };
|
|
787
|
+
}
|
|
788
|
+
// allowClear=false: both ends clamp to the edge; the ghost guard
|
|
789
|
+
// runs at release via dragBounds above.
|
|
790
|
+
shiftSelectionForFollow(this.selection, shift, viewportTop, viewportBottom, false);
|
|
791
|
+
selectionCoordinated = true;
|
|
792
|
+
}
|
|
793
|
+
else if (
|
|
794
|
+
// Flag-3 guard: the anchor check above only proves ONE endpoint is
|
|
795
|
+
// on scrollbox content. A drag from row 3 (scrollbox) into the
|
|
796
|
+
// footer at row 6, then release, leaves focus outside the viewport
|
|
797
|
+
// — shiftSelectionForFollow would clamp it to viewportBottom,
|
|
798
|
+
// teleporting the highlight from static footer into the scrollbox.
|
|
799
|
+
// Symmetric check: require BOTH ends inside to translate. A
|
|
800
|
+
// straddling selection falls through to NEITHER shift NOR capture:
|
|
801
|
+
// the footer endpoint pins the selection, text scrolls away under
|
|
802
|
+
// the highlight, and getSelectedText reads the CURRENT screen
|
|
803
|
+
// contents — no accumulation. Both endpoints are text-anchored in
|
|
804
|
+
// the active drag branch too, so a wheel cannot leave focus on the
|
|
805
|
+
// old screen row.
|
|
806
|
+
!this.selection.focus || this.selection.focus.row >= viewportTop && this.selection.focus.row <= viewportBottom) {
|
|
807
|
+
if (hasSelection(this.selection)) {
|
|
808
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, firstRow, lastRow, side, follow.screenRowOffset);
|
|
809
|
+
}
|
|
810
|
+
const cleared = shiftSelectionForFollow(this.selection, shift, viewportTop, viewportBottom);
|
|
811
|
+
selectionCoordinated = true;
|
|
812
|
+
// Auto-clear (both ends overshot an edge — off the top via
|
|
813
|
+
// follow/wheel-down, off the bottom via wheel-up) must notify
|
|
814
|
+
// React-land so useHasSelection re-renders and the footer
|
|
815
|
+
// copy/escape hint disappears. notifySelectionChange() would
|
|
816
|
+
// recurse into onRender; fire the listeners directly — they
|
|
817
|
+
// schedule a React update for LATER, they don't re-enter this
|
|
818
|
+
// frame. (#185 self-heal guard: same as selection.notify.)
|
|
819
|
+
if (cleared)
|
|
820
|
+
for (const cb of this.selectionListeners)
|
|
821
|
+
callWithUpdateOverflowGuard('selection.notify', cb);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
// Selection overlay: invert cell styles in the screen buffer itself,
|
|
825
|
+
// so the diff picks up selection as ordinary cell changes and
|
|
826
|
+
// LogUpdate remains a pure diff engine.
|
|
827
|
+
//
|
|
828
|
+
// Full-screen damage (PR #20120) is a correctness backstop for the
|
|
829
|
+
// sibling-resize bleed: when flexbox siblings resize between frames
|
|
830
|
+
// (spinner appears → bottom grows → scrollbox shrinks), the
|
|
831
|
+
// cached-clear + clip-and-cull + setCellAt damage union can miss
|
|
832
|
+
// transition cells at the boundary. But that only happens when layout
|
|
833
|
+
// actually SHIFTS — didLayoutShift() tracks exactly this (any node's
|
|
834
|
+
// cached yoga position/size differs from current, or a child was
|
|
835
|
+
// removed). Steady-state frames (spinner rotate, clock tick, text
|
|
836
|
+
// stream into fixed-height box) don't shift layout, so normal damage
|
|
837
|
+
// bounds are correct and diffEach only compares the damaged region.
|
|
838
|
+
//
|
|
839
|
+
// Selection also requires full damage: overlay writes via setCellStyleId
|
|
840
|
+
// which doesn't track damage, and prev-frame overlay cells need to be
|
|
841
|
+
// compared when selection moves/clears. prevFrameContaminated covers
|
|
842
|
+
// the frame-after-selection-clears case.
|
|
843
|
+
let selActive = false;
|
|
844
|
+
let hlActive = false;
|
|
845
|
+
if (this.altScreenActive) {
|
|
846
|
+
selActive = hasSelection(this.selection);
|
|
847
|
+
if (selActive) {
|
|
848
|
+
applySelectionOverlay(frame.screen, this.selection, this.stylePool);
|
|
849
|
+
}
|
|
850
|
+
// Commit-consistency guard: hash the rows under the highlight on the
|
|
851
|
+
// frame the copy would actually read. An uncoordinated change since
|
|
852
|
+
// the previous frame latches selection.stale; copySelectionNoClear
|
|
853
|
+
// then refuses rather than shipping whatever text now occupies the
|
|
854
|
+
// highlight coordinates. Runs on frame.screen (post-render, pre-swap)
|
|
855
|
+
// with this frame's coordinated selection coordinates.
|
|
856
|
+
refreshSelectionFingerprint(this.selection, frame.screen, selectionCoordinated);
|
|
857
|
+
// Scan-highlight: inverse on ALL visible matches (less/vim style).
|
|
858
|
+
// Position-highlight (below) overlays CURRENT (yellow) on top.
|
|
859
|
+
hlActive = applySearchHighlight(frame.screen, this.searchHighlightQuery, this.stylePool);
|
|
860
|
+
// Position-based CURRENT: write yellow at positions[currentIdx] +
|
|
861
|
+
// rowOffset. No scanning — positions came from a prior scan when
|
|
862
|
+
// the message first mounted. Message-relative + rowOffset = screen.
|
|
863
|
+
if (this.searchPositions) {
|
|
864
|
+
const sp = this.searchPositions;
|
|
865
|
+
const posApplied = applyPositionedHighlight(frame.screen, this.stylePool, sp.positions, sp.rowOffset, sp.currentIdx);
|
|
866
|
+
hlActive = hlActive || posApplied;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
// Full-damage backstop: applies on BOTH alt-screen and main-screen.
|
|
870
|
+
// Layout shifts (spinner appears, status line resizes) can leave stale
|
|
871
|
+
// cells at sibling boundaries that per-node damage tracking misses.
|
|
872
|
+
// Selection/highlight overlays write via setCellStyleId which doesn't
|
|
873
|
+
// track damage. prevFrameContaminated covers the cleanup frame.
|
|
874
|
+
if (didLayoutShift() || selActive || hlActive || this.prevFrameContaminated) {
|
|
875
|
+
frame.screen.damage = {
|
|
876
|
+
x: 0,
|
|
877
|
+
y: 0,
|
|
878
|
+
width: frame.screen.width,
|
|
879
|
+
height: frame.screen.height
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
// Alt-screen: anchor the physical cursor to (0,0) before every diff.
|
|
883
|
+
// All cursor moves in log-update are RELATIVE to prev.cursor; if tmux
|
|
884
|
+
// (or any emulator) perturbs the physical cursor out-of-band (status
|
|
885
|
+
// bar refresh, pane redraw, Cmd+K wipe), the relative moves drift and
|
|
886
|
+
// content creeps up 1 row/frame. CSI H resets the physical cursor;
|
|
887
|
+
// passing prev.cursor=(0,0) makes the diff compute from the same spot.
|
|
888
|
+
// Self-healing against any external cursor manipulation. Main-screen
|
|
889
|
+
// can't do this — cursor.y tracks scrollback rows CSI H can't reach.
|
|
890
|
+
// The CSI H write is deferred until after the diff is computed so we
|
|
891
|
+
// can skip it for empty diffs (no writes → physical cursor unused).
|
|
892
|
+
let prevFrame = this.frontFrame;
|
|
893
|
+
const sixelFrame = sixelActive
|
|
894
|
+
? this.sixelGraphicsManager.reconcile(frame.screen, prevFrame.screen, frame.images)
|
|
895
|
+
: { erase: '', baseline: prevFrame.screen };
|
|
896
|
+
if (sixelFrame.baseline !== prevFrame.screen)
|
|
897
|
+
prevFrame = { ...prevFrame, screen: sixelFrame.baseline };
|
|
898
|
+
if (this.altScreenActive) {
|
|
899
|
+
prevFrame = {
|
|
900
|
+
...prevFrame,
|
|
901
|
+
cursor: ALT_SCREEN_ANCHOR_CURSOR
|
|
902
|
+
};
|
|
903
|
+
}
|
|
904
|
+
const tDiff = performance.now();
|
|
905
|
+
const diff = this.log.render(prevFrame, frame, this.altScreenActive,
|
|
906
|
+
// DECSTBM needs BSU/ESU atomicity — without it the outer terminal
|
|
907
|
+
// renders the scrolled-but-not-yet-repainted intermediate state.
|
|
908
|
+
// tmux is the main case (re-emits DECSTBM with its own timing and
|
|
909
|
+
// doesn't implement DEC 2026, so SYNC_OUTPUT_SUPPORTED is false).
|
|
910
|
+
// JediTerm is separately excluded in isDecstbmSafe(): its DECSTBM
|
|
911
|
+
// implementation deviates from xterm and garbles scrolling content.
|
|
912
|
+
isDecstbmSafe() && !(sixelActive && (this.sixelGraphicsManager.hasImage || sixelFrame.erase !== '')));
|
|
913
|
+
const diffMs = performance.now() - tDiff;
|
|
914
|
+
// Swap buffers
|
|
915
|
+
this.backFrame = this.frontFrame;
|
|
916
|
+
this.frontFrame = frame;
|
|
917
|
+
// Periodically reset char/hyperlink pools to prevent unbounded growth
|
|
918
|
+
// during long sessions. 5 minutes is infrequent enough that the O(cells)
|
|
919
|
+
// migration cost is negligible. Reuses renderStart to avoid extra clock call.
|
|
920
|
+
if (renderStart - this.lastPoolResetTime > 5 * 60 * 1000) {
|
|
921
|
+
this.resetPools();
|
|
922
|
+
this.lastPoolResetTime = renderStart;
|
|
923
|
+
}
|
|
924
|
+
const flickers = [];
|
|
925
|
+
for (const patch of diff) {
|
|
926
|
+
if (patch.type === 'clearTerminal') {
|
|
927
|
+
flickers.push({
|
|
928
|
+
desiredHeight: frame.screen.height,
|
|
929
|
+
availableHeight: frame.viewport.height,
|
|
930
|
+
reason: patch.reason
|
|
931
|
+
});
|
|
932
|
+
if (isDebugRepaintsEnabled() && patch.debug) {
|
|
933
|
+
const chain = dom.findOwnerChainAtRow(this.rootNode, patch.debug.triggerY);
|
|
934
|
+
logForDebugging(`[REPAINT] full reset · ${patch.reason} · row ${patch.debug.triggerY}\n` + ` prev: "${patch.debug.prevLine}"\n` + ` next: "${patch.debug.nextLine}"\n` + ` culprit: ${chain.length ? chain.join(' < ') : '(no owner chain captured)'}`, {
|
|
935
|
+
level: 'warn'
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
const tOptimize = performance.now();
|
|
941
|
+
if (flickers.length > 0 || this.needsEraseBeforePaint) {
|
|
942
|
+
this.kittyGraphicsManager.invalidateAll();
|
|
943
|
+
this.sixelGraphicsManager.invalidateAll();
|
|
944
|
+
}
|
|
945
|
+
const optimized = optimize(diff);
|
|
946
|
+
const optimizeMs = performance.now() - tOptimize;
|
|
947
|
+
const graphicsOutput = this.altScreenActive && this.kittyGraphicsSupported
|
|
948
|
+
? this.kittyGraphicsManager.reconcile(frame.images ?? [])
|
|
949
|
+
: sixelActive ? this.sixelGraphicsManager.paint(optimized) : '';
|
|
950
|
+
const hasDiff = optimized.length > 0 || graphicsOutput !== '' || sixelFrame.erase !== '';
|
|
951
|
+
if (this.altScreenActive && hasDiff) {
|
|
952
|
+
// Prepend CSI H to anchor the physical cursor to (0,0) so
|
|
953
|
+
// log-update's relative moves compute from a known spot (self-healing
|
|
954
|
+
// against out-of-band cursor drift, see the ALT_SCREEN_ANCHOR_CURSOR
|
|
955
|
+
// comment above). Append CSI row;1 H to park the cursor at the bottom
|
|
956
|
+
// row (where the prompt input is) — without this, the cursor ends
|
|
957
|
+
// wherever the last diff write landed (a different row every frame),
|
|
958
|
+
// making iTerm2's cursor guide flicker as it chases the cursor.
|
|
959
|
+
// BSU/ESU protects content atomicity but iTerm2's guide tracks cursor
|
|
960
|
+
// position independently. Parking at bottom (not 0,0) keeps the guide
|
|
961
|
+
// where the user's attention is.
|
|
962
|
+
//
|
|
963
|
+
// After resize, prepend ERASE_SCREEN too. The diff only writes cells
|
|
964
|
+
// that changed; cells where new=blank and prev-buffer=blank get skipped
|
|
965
|
+
// — but the physical terminal still has stale content there (shorter
|
|
966
|
+
// lines at new width leave old-width text tails visible). ERASE inside
|
|
967
|
+
// BSU/ESU is atomic: old content stays visible until the whole
|
|
968
|
+
// erase+paint lands, then swaps in one go. Writing ERASE_SCREEN
|
|
969
|
+
// synchronously in handleResize would blank the screen for the ~80ms
|
|
970
|
+
// render() takes.
|
|
971
|
+
if (this.needsEraseBeforePaint) {
|
|
972
|
+
this.needsEraseBeforePaint = false;
|
|
973
|
+
optimized.unshift(ERASE_THEN_HOME_PATCH);
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
optimized.unshift(CURSOR_HOME_PATCH);
|
|
977
|
+
}
|
|
978
|
+
if (sixelFrame.erase !== '')
|
|
979
|
+
optimized.unshift({ type: 'stdout', content: sixelFrame.erase });
|
|
980
|
+
if (graphicsOutput !== '') {
|
|
981
|
+
optimized.push({ type: 'stdout', content: graphicsOutput });
|
|
982
|
+
}
|
|
983
|
+
optimized.push(this.altScreenParkPatch);
|
|
984
|
+
}
|
|
985
|
+
// Native cursor positioning: park the terminal cursor at the declared
|
|
986
|
+
// position so IME preedit text renders inline and screen readers /
|
|
987
|
+
// magnifiers can follow the input. nodeCache holds the absolute screen
|
|
988
|
+
// rect populated by renderNodeToOutput this frame (including scrollTop
|
|
989
|
+
// translation) — if the declared node didn't render (stale declaration
|
|
990
|
+
// after remount, or scrolled out of view), it won't be in the cache
|
|
991
|
+
// and no move is emitted.
|
|
992
|
+
const decl = this.cursorDeclaration;
|
|
993
|
+
const rect = decl !== null ? nodeCache.get(decl.node) : undefined;
|
|
994
|
+
// Keep the declared target in the same full-frame coordinate system as
|
|
995
|
+
// frame.cursor and displayCursor. Main-screen cursor moves are relative:
|
|
996
|
+
// subtracting the scrollback height from target alone makes the physical
|
|
997
|
+
// cursor climb that height on every park/preamble cycle, so later streaming
|
|
998
|
+
// diffs overwrite thinking, tool, and assistant rows. The terminal maps the
|
|
999
|
+
// full-frame relative move onto its viewport/scrollback position itself.
|
|
1000
|
+
const target = decl !== null && rect !== undefined ? {
|
|
1001
|
+
x: rect.x + decl.relativeX,
|
|
1002
|
+
y: rect.y + decl.relativeY
|
|
1003
|
+
} : null;
|
|
1004
|
+
const parked = this.displayCursor;
|
|
1005
|
+
// Diagnostics: the resolved park target per frame (DSH_TUI_DEBUG only).
|
|
1006
|
+
// ConPTY's readback drops trailing cursor moves, so pty probes can't
|
|
1007
|
+
// observe the park position — this trace is the ground truth of where
|
|
1008
|
+
// the native cursor is being told to go.
|
|
1009
|
+
logForDebugging(`park target=${target !== null ? target.x + ',' + target.y : 'null'} decl=${decl !== null} rect=${rect !== undefined} moved=${target !== null && (parked === null || parked.x !== target.x || parked.y !== target.y)}`);
|
|
1010
|
+
// Preserve the empty-diff zero-write fast path: skip all cursor writes
|
|
1011
|
+
// when nothing rendered AND the park target is unchanged.
|
|
1012
|
+
const targetMoved = target !== null && (parked === null || parked.x !== target.x || parked.y !== target.y);
|
|
1013
|
+
if (hasDiff || targetMoved || target === null && parked !== null) {
|
|
1014
|
+
// Main-screen preamble: log-update's relative moves assume the
|
|
1015
|
+
// physical cursor is at prevFrame.cursor. If last frame parked it
|
|
1016
|
+
// elsewhere, move back before the diff runs. Alt-screen's CSI H
|
|
1017
|
+
// already resets to (0,0) so no preamble needed.
|
|
1018
|
+
if (parked !== null && !this.altScreenActive && hasDiff) {
|
|
1019
|
+
const pdx = prevFrame.cursor.x - parked.x;
|
|
1020
|
+
const pdy = prevFrame.cursor.y - parked.y;
|
|
1021
|
+
if (pdx !== 0 || pdy !== 0) {
|
|
1022
|
+
optimized.unshift({
|
|
1023
|
+
type: 'stdout',
|
|
1024
|
+
content: cursorMove(pdx, pdy)
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
if (target !== null) {
|
|
1029
|
+
if (this.altScreenActive) {
|
|
1030
|
+
// Absolute CUP (1-indexed); next frame's CSI H resets regardless.
|
|
1031
|
+
// Emitted after altScreenParkPatch so the declared position wins.
|
|
1032
|
+
const row = Math.min(Math.max(target.y + 1, 1), terminalRows);
|
|
1033
|
+
const col = Math.min(Math.max(target.x + 1, 1), terminalWidth);
|
|
1034
|
+
optimized.push({
|
|
1035
|
+
type: 'stdout',
|
|
1036
|
+
content: cursorPosition(row, col)
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
// After the diff (or preamble), cursor is at frame.cursor. If no
|
|
1041
|
+
// diff AND previously parked, it's still at the old park position
|
|
1042
|
+
// (log-update wrote nothing). Otherwise it's at frame.cursor.
|
|
1043
|
+
const from = !hasDiff && parked !== null ? parked : {
|
|
1044
|
+
x: frame.cursor.x,
|
|
1045
|
+
y: frame.cursor.y
|
|
1046
|
+
};
|
|
1047
|
+
const dx = target.x - from.x;
|
|
1048
|
+
const dy = target.y - from.y;
|
|
1049
|
+
if (dx !== 0 || dy !== 0) {
|
|
1050
|
+
optimized.push({
|
|
1051
|
+
type: 'stdout',
|
|
1052
|
+
content: cursorMove(dx, dy)
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
this.displayCursor = target;
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
// Declaration cleared (input blur, unmount). Restore physical cursor
|
|
1060
|
+
// to frame.cursor before forgetting the park position — otherwise
|
|
1061
|
+
// displayCursor=null lies about where the cursor is, and the NEXT
|
|
1062
|
+
// frame's preamble (or log-update's relative moves) computes from a
|
|
1063
|
+
// wrong spot. The preamble above handles hasDiff; this handles
|
|
1064
|
+
// !hasDiff (e.g. accessibility mode where blur doesn't change
|
|
1065
|
+
// renderedValue since invert is identity).
|
|
1066
|
+
if (parked !== null && !this.altScreenActive && !hasDiff) {
|
|
1067
|
+
const rdx = frame.cursor.x - parked.x;
|
|
1068
|
+
const rdy = frame.cursor.y - parked.y;
|
|
1069
|
+
if (rdx !== 0 || rdy !== 0) {
|
|
1070
|
+
optimized.push({
|
|
1071
|
+
type: 'stdout',
|
|
1072
|
+
content: cursorMove(rdx, rdy)
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
this.displayCursor = null;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
const tWrite = performance.now();
|
|
1080
|
+
writeDiffToTerminal(this.terminal, optimized, this.altScreenActive && !SYNC_OUTPUT_SUPPORTED);
|
|
1081
|
+
const writeMs = performance.now() - tWrite;
|
|
1082
|
+
// One frame reached the terminal. Components holding a widened mount
|
|
1083
|
+
// window until its content is actually flushed (MessageList's paint
|
|
1084
|
+
// expansion hold) key off this tick — a commit can be superseded before
|
|
1085
|
+
// its frame flushes, so "mounted" alone must never unlock tightening.
|
|
1086
|
+
noteTerminalFlush();
|
|
1087
|
+
// Update blit safety for the NEXT frame. The frame just rendered
|
|
1088
|
+
// becomes frontFrame (= next frame's prevScreen). If we applied the
|
|
1089
|
+
// selection overlay, that buffer has inverted cells. selActive/hlActive
|
|
1090
|
+
// are only ever true in alt-screen; in main-screen this is false→false.
|
|
1091
|
+
// poisonNextFrame: an absolute overlay shrank/moved this frame and its
|
|
1092
|
+
// vacated cells were blitted stale — the next frame must render without
|
|
1093
|
+
// prevScreen to re-derive them from the tree.
|
|
1094
|
+
this.prevFrameContaminated = selActive || hlActive || frame.poisonNextFrame === true;
|
|
1095
|
+
// A ScrollBox has pendingScrollDelta left to drain — schedule the next
|
|
1096
|
+
// frame via scheduleDrain (cadence + pty backpressure gate, see there).
|
|
1097
|
+
// MUST NOT call this.scheduleRender() here: we're inside a trailing-edge
|
|
1098
|
+
// throttle invocation, timerId is undefined, and lodash's debounce sees
|
|
1099
|
+
// timeSinceLastCall >= wait (last call was at the start of this window)
|
|
1100
|
+
// → leadingEdge fires IMMEDIATELY → double render ~0.1ms apart → jank.
|
|
1101
|
+
// If a wheel event or immediate render arrives first, renderNow cancels
|
|
1102
|
+
// this timer — no double.
|
|
1103
|
+
if (frame.scrollDrainPending || frame.poisonNextFrame === true) {
|
|
1104
|
+
noteFrameCause(frame.scrollDrainPending ? 'scroll-drain' : 'overlay-shrink');
|
|
1105
|
+
this.scheduleDrain();
|
|
1106
|
+
}
|
|
1107
|
+
const yogaMs = getLastYogaMs();
|
|
1108
|
+
const commitMs = getLastCommitMs();
|
|
1109
|
+
const yc = this.lastYogaCounters;
|
|
1110
|
+
// Reset so drain-only frames (no React commit) don't repeat stale values.
|
|
1111
|
+
resetProfileCounters();
|
|
1112
|
+
this.lastYogaCounters = {
|
|
1113
|
+
ms: 0,
|
|
1114
|
+
visited: 0,
|
|
1115
|
+
measured: 0,
|
|
1116
|
+
cacheHits: 0,
|
|
1117
|
+
live: 0
|
|
1118
|
+
};
|
|
1119
|
+
endGeometryFrame(performance.now() - renderStart);
|
|
1120
|
+
this.options.onFrame?.({
|
|
1121
|
+
durationMs: performance.now() - renderStart,
|
|
1122
|
+
phases: {
|
|
1123
|
+
renderer: rendererMs,
|
|
1124
|
+
diff: diffMs,
|
|
1125
|
+
optimize: optimizeMs,
|
|
1126
|
+
write: writeMs,
|
|
1127
|
+
patches: diff.length,
|
|
1128
|
+
yoga: yogaMs,
|
|
1129
|
+
commit: commitMs,
|
|
1130
|
+
yogaVisited: yc.visited,
|
|
1131
|
+
yogaMeasured: yc.measured,
|
|
1132
|
+
yogaCacheHits: yc.cacheHits,
|
|
1133
|
+
yogaLive: yc.live
|
|
1134
|
+
},
|
|
1135
|
+
flickers
|
|
1136
|
+
});
|
|
1137
|
+
}
|
|
1138
|
+
pause() {
|
|
1139
|
+
// Flush pending React updates and render before pausing.
|
|
1140
|
+
// @ts-ignore -- runtime/type-definition mismatch: flushSyncFromReconciler exists in react-reconciler 0.31 but not in @types/react-reconciler
|
|
1141
|
+
reconciler.flushSyncFromReconciler();
|
|
1142
|
+
this.renderNow();
|
|
1143
|
+
this.isPaused = true;
|
|
1144
|
+
this.notifyTerminalImagesChange();
|
|
1145
|
+
}
|
|
1146
|
+
resume() {
|
|
1147
|
+
this.isPaused = false;
|
|
1148
|
+
this.notifyTerminalImagesChange();
|
|
1149
|
+
this.renderNow();
|
|
1150
|
+
if (this.terminalCellMetricsRefreshPending &&
|
|
1151
|
+
!this.terminalCellMetricsInFlight &&
|
|
1152
|
+
!this.terminalQueriesSuspended) {
|
|
1153
|
+
this.terminalCellMetricsRefreshPending = false;
|
|
1154
|
+
this.refreshTerminalCellMetrics();
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Reset frame buffers so the next render writes the full screen from scratch.
|
|
1159
|
+
* Call this before resume() when the terminal content has been corrupted by
|
|
1160
|
+
* an external process (e.g. tmux, shell, full-screen TUI).
|
|
1161
|
+
*/
|
|
1162
|
+
repaint() {
|
|
1163
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
1164
|
+
this.backFrame = emptyFrame(this.backFrame.viewport.height, this.backFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
1165
|
+
this.log.reset();
|
|
1166
|
+
// Physical cursor position is unknown after external terminal corruption.
|
|
1167
|
+
// Clear displayCursor so the cursor preamble doesn't emit a stale
|
|
1168
|
+
// relative move from where we last parked it.
|
|
1169
|
+
this.displayCursor = null;
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Clear the physical terminal and force a full redraw.
|
|
1173
|
+
*
|
|
1174
|
+
* The traditional readline ctrl+l — clears the visible screen and
|
|
1175
|
+
* redraws the current content. Also the recovery path when the terminal
|
|
1176
|
+
* was cleared externally (macOS Cmd+K) and Ink's diff engine thinks
|
|
1177
|
+
* unchanged cells don't need repainting. Scrollback is preserved.
|
|
1178
|
+
*/
|
|
1179
|
+
forceRedraw() {
|
|
1180
|
+
if (!this.options.stdout.isTTY || this.isUnmounted || this.isPaused)
|
|
1181
|
+
return;
|
|
1182
|
+
// SGR reset first — ERASE_SCREEN fills with the current background
|
|
1183
|
+
// (BCE); ctrl+l is exactly the recovery a user reaches for when the
|
|
1184
|
+
// screen is already wrecked (e.g. a stuck colored SGR after a torn
|
|
1185
|
+
// frame), so the clear must not repaint the wreckage color.
|
|
1186
|
+
this.options.stdout.write(SGR_RESET + ERASE_SCREEN + CURSOR_HOME);
|
|
1187
|
+
if (this.altScreenActive) {
|
|
1188
|
+
this.resetFramesForAltScreen();
|
|
1189
|
+
}
|
|
1190
|
+
else {
|
|
1191
|
+
this.repaint();
|
|
1192
|
+
// repaint() resets frontFrame to 0×0. Without this flag the next
|
|
1193
|
+
// frame's blit optimization copies from that empty screen and the
|
|
1194
|
+
// diff sees no content. onRender resets the flag at frame end.
|
|
1195
|
+
this.prevFrameContaminated = true;
|
|
1196
|
+
}
|
|
1197
|
+
this.renderNow();
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Establish a genuinely fresh terminal page: clear both the visible screen
|
|
1201
|
+
* and native scrollback, reset frame correspondence, then redraw the current
|
|
1202
|
+
* React tree. This is intentionally stronger than Ctrl+L/forceRedraw(),
|
|
1203
|
+
* which preserves history; use it only at a destructive UI boundary such as
|
|
1204
|
+
* `/new`, where showing the previous conversation above the new session is
|
|
1205
|
+
* misleading.
|
|
1206
|
+
*/
|
|
1207
|
+
clearScrollbackAndRedraw() {
|
|
1208
|
+
if (!this.options.stdout.isTTY || this.isUnmounted || this.isPaused)
|
|
1209
|
+
return;
|
|
1210
|
+
// Keep 3J outside synchronized output. Windows Terminal can relocate the
|
|
1211
|
+
// viewport when erase-buffer commands execute inside BSU/ESU.
|
|
1212
|
+
this.options.stdout.write(SGR_RESET + ERASE_SCROLLBACK + ERASE_SCREEN + CURSOR_HOME);
|
|
1213
|
+
if (this.altScreenActive) {
|
|
1214
|
+
this.resetFramesForAltScreen();
|
|
1215
|
+
}
|
|
1216
|
+
else {
|
|
1217
|
+
this.repaint();
|
|
1218
|
+
this.prevFrameContaminated = true;
|
|
1219
|
+
}
|
|
1220
|
+
this.renderNow();
|
|
1221
|
+
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Mark the previous frame as untrustworthy for blit, forcing the next
|
|
1224
|
+
* render to do a full-damage diff instead of the per-node fast path.
|
|
1225
|
+
*
|
|
1226
|
+
* Lighter than forceRedraw() — no screen clear, no extra write. Call
|
|
1227
|
+
* from a useLayoutEffect cleanup when unmounting a tall overlay: the
|
|
1228
|
+
* blit fast path can copy stale cells from the overlay frame into rows
|
|
1229
|
+
* the shrunken layout no longer reaches, leaving a ghost title/divider.
|
|
1230
|
+
* onRender resets the flag at frame end so it's one-shot.
|
|
1231
|
+
*/
|
|
1232
|
+
invalidatePrevFrame() {
|
|
1233
|
+
this.prevFrameContaminated = true;
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Called by the <AlternateScreen> component on mount/unmount.
|
|
1237
|
+
* Controls cursor.y clamping in the renderer and gates alt-screen-aware
|
|
1238
|
+
* behavior in SIGCONT/resize/unmount handlers. The first alt-screen frame
|
|
1239
|
+
* redraws from blank; exit restores the saved main frame for a physical-
|
|
1240
|
+
* screen-matched diff, with repaint as the resize fallback.
|
|
1241
|
+
*/
|
|
1242
|
+
setAltScreenActive(active, mouseTracking = false) {
|
|
1243
|
+
if (this.altScreenActive === active)
|
|
1244
|
+
return;
|
|
1245
|
+
const resetOldPointerContext = () => {
|
|
1246
|
+
// Fire leave handlers before dropping the set — a bare clear strands
|
|
1247
|
+
// old rows with hovered=true. resetPointerState also emits dragend for
|
|
1248
|
+
// a captured drag before its geometry disappears.
|
|
1249
|
+
clearHovered(this.hoveredNodes);
|
|
1250
|
+
this.app?.resetPointerState();
|
|
1251
|
+
invalidateNoInterestRect();
|
|
1252
|
+
};
|
|
1253
|
+
// Leaving must settle dragend WHILE the dispatch gate is still active;
|
|
1254
|
+
// flipping altScreenActive first would silently drop the cleanup event.
|
|
1255
|
+
if (!active) {
|
|
1256
|
+
resetOldPointerContext();
|
|
1257
|
+
const deleteImages = this.kittyGraphicsManager.deleteAll() + this.sixelGraphicsManager.clear();
|
|
1258
|
+
if (deleteImages !== '')
|
|
1259
|
+
this.options.stdout.write(deleteImages);
|
|
1260
|
+
}
|
|
1261
|
+
this.altScreenActive = active;
|
|
1262
|
+
this.notifyTerminalImagesChange();
|
|
1263
|
+
this.altScreenMouseTracking = active && mouseTracking;
|
|
1264
|
+
// Entering has no old alt-screen drag to notify, but the main-screen
|
|
1265
|
+
// hover/click geometry still needs to be cleared after the gate flips.
|
|
1266
|
+
if (active)
|
|
1267
|
+
resetOldPointerContext();
|
|
1268
|
+
if (active) {
|
|
1269
|
+
this.mainScreenFrameState = {
|
|
1270
|
+
frontFrame: this.frontFrame,
|
|
1271
|
+
displayCursor: this.displayCursor,
|
|
1272
|
+
columns: this.terminalColumns,
|
|
1273
|
+
rows: this.terminalRows
|
|
1274
|
+
};
|
|
1275
|
+
this.resetFramesForAltScreen();
|
|
1276
|
+
// Alt-screen reactivation is a safe boundary: the component just
|
|
1277
|
+
// remounted, so no gesture can be in flight. Drain any deferred
|
|
1278
|
+
// re-entry confirmed while the alt screen was inactive.
|
|
1279
|
+
this.drainAltScreenReentry();
|
|
1280
|
+
}
|
|
1281
|
+
else {
|
|
1282
|
+
const saved = this.mainScreenFrameState;
|
|
1283
|
+
this.mainScreenFrameState = null;
|
|
1284
|
+
if (saved && saved.columns === this.terminalColumns && saved.rows === this.terminalRows) {
|
|
1285
|
+
this.frontFrame = saved.frontFrame;
|
|
1286
|
+
this.displayCursor = saved.displayCursor;
|
|
1287
|
+
this.log.reset();
|
|
1288
|
+
// The main React subtree may have changed while the alternate screen
|
|
1289
|
+
// was mounted. Disable blitting once, but keep the restored frame as
|
|
1290
|
+
// the diff baseline that matches the terminal's physical contents.
|
|
1291
|
+
this.prevFrameContaminated = true;
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
// A resize reflows the terminal's saved main buffer, so the old frame
|
|
1295
|
+
// is no longer a trustworthy physical baseline.
|
|
1296
|
+
this.repaint();
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
get isAltScreenActive() {
|
|
1301
|
+
return this.altScreenActive;
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Re-assert terminal modes after a gap (>5s stdin silence or event-loop
|
|
1305
|
+
* stall). Catches tmux detach→attach, ssh reconnect, and laptop
|
|
1306
|
+
* sleep/wake — none of which send SIGCONT. The terminal may reset DEC
|
|
1307
|
+
* private modes on reconnect; this method restores them.
|
|
1308
|
+
*
|
|
1309
|
+
* Always re-asserts extended key reporting and mouse tracking. Mouse
|
|
1310
|
+
* tracking is idempotent (DEC private mode set-when-set is a no-op). The
|
|
1311
|
+
* Kitty keyboard protocol is NOT — CSI >1u is a stack push, so we pop
|
|
1312
|
+
* first to keep depth balanced (pop on empty stack is a no-op per spec,
|
|
1313
|
+
* so after a terminal reset this still restores depth 0→1). Without the
|
|
1314
|
+
* pop, each >5s idle gap adds a stack entry, and the single pop on exit
|
|
1315
|
+
* or suspend can't drain them — the shell is left in CSI u mode where
|
|
1316
|
+
* Ctrl+C/Ctrl+D leak as escape sequences. The alt-screen
|
|
1317
|
+
* re-entry (ERASE_SCREEN + frame reset) is NOT idempotent — it blanks the
|
|
1318
|
+
* screen — so it's opt-in via includeAltScreen. The stdin-gap caller fires
|
|
1319
|
+
* on ordinary >5s idle + keypress and must not erase; the event-loop stall
|
|
1320
|
+
* detector fires on genuine sleep/wake and opts in. tmux attach / ssh
|
|
1321
|
+
* reconnect typically send a resize, which already covers alt-screen via
|
|
1322
|
+
* handleResize.
|
|
1323
|
+
*/
|
|
1324
|
+
reassertTerminalModes = (includeAltScreen = false) => {
|
|
1325
|
+
if (!this.options.stdout.isTTY)
|
|
1326
|
+
return;
|
|
1327
|
+
// Shutdown latch: the >5s idle-gap trigger (or an event-loop stall
|
|
1328
|
+
// detector firing during the dispose window) must not re-assert mouse
|
|
1329
|
+
// tracking after the exit cleanup disabled it (issue #522).
|
|
1330
|
+
if (this.isUnmounted)
|
|
1331
|
+
return;
|
|
1332
|
+
// Don't touch the terminal during an editor handoff — re-enabling kitty
|
|
1333
|
+
// keyboard here would undo enterAlternateScreen's disable and nano would
|
|
1334
|
+
// start seeing CSI-u sequences again.
|
|
1335
|
+
if (this.isPaused)
|
|
1336
|
+
return;
|
|
1337
|
+
// Extended keys — re-assert if enabled (App.tsx enables these on
|
|
1338
|
+
// allowlisted terminals at raw-mode entry; a terminal reset clears them).
|
|
1339
|
+
// Pop-before-push keeps Kitty stack depth at 1 instead of accumulating
|
|
1340
|
+
// on each call. win32-input-mode is a plain DEC private mode (no stack),
|
|
1341
|
+
// so a bare re-set suffices.
|
|
1342
|
+
if (supportsWin32InputMode()) {
|
|
1343
|
+
this.options.stdout.write(ENABLE_WIN32_INPUT_MODE);
|
|
1344
|
+
}
|
|
1345
|
+
else if (supportsExtendedKeys()) {
|
|
1346
|
+
this.options.stdout.write(DISABLE_KITTY_KEYBOARD + ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS);
|
|
1347
|
+
}
|
|
1348
|
+
if (!this.altScreenActive) {
|
|
1349
|
+
// Main-screen self-heal: alt-screen re-anchors the cursor with CSI H
|
|
1350
|
+
// every frame, but inline diffs are purely relative — a third-party
|
|
1351
|
+
// tty write during the idle gap (an MCP subprocess's stderr, issue
|
|
1352
|
+
// #17) shifts every subsequent write by N rows and nothing detects
|
|
1353
|
+
// it after the fact (see requestViewportReanchor). The same
|
|
1354
|
+
// gap-then-keypress signal that re-asserts DEC modes is the natural
|
|
1355
|
+
// moment to blindly re-sync: repaint the viewport from the physical
|
|
1356
|
+
// cursor position. Idempotent when nothing drifted — the user sees
|
|
1357
|
+
// no change, at O(viewport) bytes once per >5s idle gap.
|
|
1358
|
+
this.log.requestViewportReanchor();
|
|
1359
|
+
this.renderNow();
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
// Mouse tracking + alt-screen health — the probe re-asserts mouse
|
|
1363
|
+
// blindly (idempotent) and re-enters alt only if the terminal answers
|
|
1364
|
+
// DECRPM with "1049 reset".
|
|
1365
|
+
this.probeAltScreenHealth();
|
|
1366
|
+
// Drain any deferred re-entry: a >5s stdin gap is a safe boundary (no
|
|
1367
|
+
// button can be held — the terminal would have sent motion events), and
|
|
1368
|
+
// resume is exactly the moment a confirmed 1049 loss should heal.
|
|
1369
|
+
this.drainAltScreenReentry();
|
|
1370
|
+
// Alt-screen re-entry — destructive (ERASE_SCREEN). Only for callers that
|
|
1371
|
+
// have a strong signal the terminal actually dropped mode 1049.
|
|
1372
|
+
if (includeAltScreen) {
|
|
1373
|
+
this.reenterAltScreen();
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
/**
|
|
1377
|
+
* Mark this instance as unmounted so future unmount() calls early-return.
|
|
1378
|
+
* Called by gracefulShutdown's cleanupTerminalModes() after it has sent
|
|
1379
|
+
* EXIT_ALT_SCREEN but before the remaining terminal-reset sequences.
|
|
1380
|
+
* Without this, signal-exit's deferred ink.unmount() (triggered by
|
|
1381
|
+
* process.exit()) runs the full unmount path: onRender() + writeSync
|
|
1382
|
+
* cleanup block + updateContainerSync → AlternateScreen unmount cleanup.
|
|
1383
|
+
* The result is 2-3 redundant EXIT_ALT_SCREEN sequences landing on the
|
|
1384
|
+
* main screen AFTER printResumeHint(), which tmux (at least) interprets
|
|
1385
|
+
* as restoring the saved cursor position — clobbering the resume hint.
|
|
1386
|
+
*/
|
|
1387
|
+
detachForShutdown() {
|
|
1388
|
+
this.isUnmounted = true;
|
|
1389
|
+
this.terminalImageListeners.clear();
|
|
1390
|
+
// Cancel any pending throttled render so it doesn't fire between
|
|
1391
|
+
// cleanupTerminalModes() and process.exit() and write to main screen.
|
|
1392
|
+
this.scheduleRender.cancel?.();
|
|
1393
|
+
if (this.drainTimer !== null) {
|
|
1394
|
+
clearTimeout(this.drainTimer);
|
|
1395
|
+
this.drainTimer = null;
|
|
1396
|
+
}
|
|
1397
|
+
if (this.terminalQueryResumeTimer !== null) {
|
|
1398
|
+
clearTimeout(this.terminalQueryResumeTimer);
|
|
1399
|
+
this.terminalQueryResumeTimer = null;
|
|
1400
|
+
}
|
|
1401
|
+
// Delete Kitty placements before terminal mode cleanup. This write uses
|
|
1402
|
+
// the renderer's own ordered stream, matching the rest of this shutdown
|
|
1403
|
+
// path and leaving unmount's synchronous cleanup safely idempotent.
|
|
1404
|
+
const deleteImages = this.kittyGraphicsManager.deleteAll() + this.sixelGraphicsManager.dispose();
|
|
1405
|
+
if (deleteImages !== '' && this.options.stdout.isTTY) {
|
|
1406
|
+
this.options.stdout.write(deleteImages);
|
|
1407
|
+
}
|
|
1408
|
+
this.app?.detachForShutdown();
|
|
1409
|
+
// Shutdown bypasses the normal unmount path, so release the process and
|
|
1410
|
+
// stdout listeners here as well. Otherwise a SIGCONT or resize arriving
|
|
1411
|
+
// while an updater is running can re-enter the alternate screen or render
|
|
1412
|
+
// through this detached instance after terminal cleanup has completed.
|
|
1413
|
+
this.unsubscribeTTYHandlers?.();
|
|
1414
|
+
this.unsubscribeExit();
|
|
1415
|
+
// unmount() early-returns on isUnmounted above, so its instances.delete
|
|
1416
|
+
// never runs — a detached instance would stay in the map and a later
|
|
1417
|
+
// instances.get(stdout) lookup (Chat's reanchorViewport plumbing) could
|
|
1418
|
+
// hand out a dead renderer. Remove the mapping here too.
|
|
1419
|
+
instances.delete(this.options.stdout);
|
|
1420
|
+
// `detachForShutdown()` deliberately makes later `unmount()` calls a
|
|
1421
|
+
// no-op, so release process-level output patches here rather than relying
|
|
1422
|
+
// on unmount() to do it. The shutdown continuation may run an updater
|
|
1423
|
+
// (or report its failure) after this point; leaving stderr intercepted
|
|
1424
|
+
// would silently route those messages to the debug log instead of the
|
|
1425
|
+
// terminal.
|
|
1426
|
+
if (typeof this.restoreConsole === 'function') {
|
|
1427
|
+
this.restoreConsole();
|
|
1428
|
+
}
|
|
1429
|
+
this.restoreStderr?.();
|
|
1430
|
+
// Restore stdin from raw mode. unmount() used to do this via React
|
|
1431
|
+
// unmount (App.componentWillUnmount → handleSetRawMode(false)) but we're
|
|
1432
|
+
// short-circuiting that path. Must use this.options.stdin — NOT
|
|
1433
|
+
// process.stdin — because getStdinOverride() may have opened /dev/tty
|
|
1434
|
+
// when stdin is piped.
|
|
1435
|
+
const stdin = this.options.stdin;
|
|
1436
|
+
this.drainStdin();
|
|
1437
|
+
if (stdin.isTTY && stdin.isRaw && stdin.setRawMode) {
|
|
1438
|
+
try {
|
|
1439
|
+
stdin.setRawMode(false);
|
|
1440
|
+
}
|
|
1441
|
+
catch {
|
|
1442
|
+
// The TTY may have been revoked (for example after an SSH
|
|
1443
|
+
// disconnect). Shutdown must continue even if raw-mode restoration
|
|
1444
|
+
// is no longer possible.
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* Fully detach stdin before handing the terminal to a child process that
|
|
1450
|
+
* inherits it (the /update restart). `detachForShutdown()` restores
|
|
1451
|
+
* cooked mode but leaves the App's 'readable' pump attached — ordinary
|
|
1452
|
+
* exits don't care because the process dies right after, but a parent
|
|
1453
|
+
* that lingers waiting on the child keeps a libuv read pending on the
|
|
1454
|
+
* console and races the child for every keypress: the restarted TUI
|
|
1455
|
+
* sees dropped or entirely swallowed input (issues #284/#307). Remove
|
|
1456
|
+
* the listeners and pause the pump so the child is the sole reader.
|
|
1457
|
+
*/
|
|
1458
|
+
detachStdinForHandoff() {
|
|
1459
|
+
const stdin = this.options.stdin;
|
|
1460
|
+
try {
|
|
1461
|
+
this.drainStdin();
|
|
1462
|
+
}
|
|
1463
|
+
catch {
|
|
1464
|
+
// A destroyed stream must not block the handoff.
|
|
1465
|
+
}
|
|
1466
|
+
stdin.removeAllListeners('readable');
|
|
1467
|
+
stdin.removeAllListeners('data');
|
|
1468
|
+
try {
|
|
1469
|
+
stdin.pause();
|
|
1470
|
+
}
|
|
1471
|
+
catch {
|
|
1472
|
+
// Same destroyed-stream tolerance as above.
|
|
1473
|
+
}
|
|
1474
|
+
try {
|
|
1475
|
+
stdin.unref();
|
|
1476
|
+
}
|
|
1477
|
+
catch {
|
|
1478
|
+
// unref on a closed stream can throw on some Node versions.
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
/** @see drainStdin */
|
|
1482
|
+
drainStdin() {
|
|
1483
|
+
drainStdin(this.options.stdin);
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Self-heal after a terminal-side mode reset. Windows conpty drops DEC
|
|
1487
|
+
* private modes on DPI changes, window moves between monitors and renderer
|
|
1488
|
+
* restarts — the user sees the app "exit fullscreen" with a dead mouse
|
|
1489
|
+
* while altScreenActive still claims we are in alt. Two layers:
|
|
1490
|
+
*
|
|
1491
|
+
* 1. Blind, idempotent mouse-tracking re-assert (covers the mode reset
|
|
1492
|
+
* without a round trip; ~30 bytes).
|
|
1493
|
+
* 2. DECRQM probe of mode 1049. Re-entry (destructive: ERASE) happens
|
|
1494
|
+
* ONLY on a positive "reset" answer, so iTerm2's
|
|
1495
|
+
* enter-clears-when-already-in-alt quirk can never fire on a healthy
|
|
1496
|
+
* screen, and terminals that ignore DECRQM stay inert.
|
|
1497
|
+
*
|
|
1498
|
+
* Called from every interaction dispatch (click/hover/wheel/key) plus the
|
|
1499
|
+
* focus/resize/stdin-gap triggers. The 250ms throttle keeps the round
|
|
1500
|
+
* trip bounded while active use is going on — a dropped 1049 heals on
|
|
1501
|
+
* the FIRST interaction after the drop instead of waiting for a focus
|
|
1502
|
+
* event or a >5s idle gap (mouse motion keeps lastStdinTime fresh, so
|
|
1503
|
+
* the gap path never fires during active use — the exact pattern that
|
|
1504
|
+
* left the app broken until the user gave up).
|
|
1505
|
+
*/
|
|
1506
|
+
lastHealthProbeAt = 0;
|
|
1507
|
+
/**
|
|
1508
|
+
* True while a mouse button is held (press seen, no release/reset yet).
|
|
1509
|
+
* Set by App via setPointerGestureActive. The health probe must not write
|
|
1510
|
+
* while a gesture is in flight: the blind ENABLE_MOUSE_TRACKING re-assert
|
|
1511
|
+
* mid-drag resets button tracking on some emulators (WezTerm, xterm.js
|
|
1512
|
+
* family), silently killing the gesture's motion stream, and a DECRQM
|
|
1513
|
+
* "1049 reset" reply resolving mid-drag would erase the screen under the
|
|
1514
|
+
* user's pointer.
|
|
1515
|
+
*/
|
|
1516
|
+
pointerGestureActive = false;
|
|
1517
|
+
/**
|
|
1518
|
+
* Protocol-candidate latch: an SGR mouse prefix is in flight (parser hold
|
|
1519
|
+
* or tokenizer incomplete buffer). Cleared by App on any complete event
|
|
1520
|
+
* (mouse or key), ordinary text, paste/response boundary, or the 1s hold
|
|
1521
|
+
* deadline. Distinct from pointerGestureActive: a split wheel report
|
|
1522
|
+
* resolves to a ParsedKey (no physical button), and a stale candidate
|
|
1523
|
+
* must not leave the probe permanently blocked.
|
|
1524
|
+
*/
|
|
1525
|
+
protocolCandidateActive = false;
|
|
1526
|
+
/**
|
|
1527
|
+
* Set when a DECRPM reply confirmed "1049 reset" while a gesture was
|
|
1528
|
+
* latched. The re-entry (ENTER_ALT_SCREEN + ERASE_SCREEN + mouse
|
|
1529
|
+
* re-assert) is destructive mid-drag — it erases the screen under the
|
|
1530
|
+
* user's pointer and resets button tracking — so it is deferred to the
|
|
1531
|
+
* gesture's end and drained by setPointerGestureActive(false).
|
|
1532
|
+
*/
|
|
1533
|
+
pendingAltScreenReentry = false;
|
|
1534
|
+
/**
|
|
1535
|
+
* Set when probeAltScreenHealth was blocked by an active gesture. The
|
|
1536
|
+
* probe is retried at the release tail (drainAltScreenReentry) with the
|
|
1537
|
+
* original caller's skipMouseReassert semantics.
|
|
1538
|
+
*/
|
|
1539
|
+
pendingProbeRequest = undefined;
|
|
1540
|
+
setPointerGestureActive = (active) => {
|
|
1541
|
+
this.pointerGestureActive = active;
|
|
1542
|
+
// Do NOT drain pendingAltScreenReentry here: the gesture latch clears at
|
|
1543
|
+
// the START of release handling, but the destructive re-entry must wait
|
|
1544
|
+
// until the full release/click/drag tail completes (dispatchClick reads
|
|
1545
|
+
// frontFrame for cellIsBlank / getHyperlinkAt — reenterAltScreen resets
|
|
1546
|
+
// those frames synchronously). App calls drainAltScreenReentry() after
|
|
1547
|
+
// the release tail instead.
|
|
1548
|
+
};
|
|
1549
|
+
setProtocolCandidateActive = (active) => {
|
|
1550
|
+
this.protocolCandidateActive = active;
|
|
1551
|
+
};
|
|
1552
|
+
/**
|
|
1553
|
+
* Execute a deferred alt-screen re-entry, if one was confirmed while a
|
|
1554
|
+
* gesture was latched. Called by App after the release tail completes.
|
|
1555
|
+
* Only clears the pending flag when the re-entry actually runs — a pause
|
|
1556
|
+
* or alt-screen exit during the gesture keeps the recovery signal alive
|
|
1557
|
+
* for the next safe boundary (resume, focus, or a later release).
|
|
1558
|
+
*/
|
|
1559
|
+
drainAltScreenReentry = () => {
|
|
1560
|
+
if (!this.pendingAltScreenReentry)
|
|
1561
|
+
return;
|
|
1562
|
+
if (this.isUnmounted || this.isPaused || !this.altScreenActive)
|
|
1563
|
+
return;
|
|
1564
|
+
// Dual latch: never re-enter while a physical button is held OR while a
|
|
1565
|
+
// protocol candidate (split SGR prefix) is in flight. The destructive
|
|
1566
|
+
// re-entry (1049h + 2J + mouse DECSET) would erase the screen under the
|
|
1567
|
+
// user's pointer and reset button tracking mid-drag, or corrupt a
|
|
1568
|
+
// half-parsed report.
|
|
1569
|
+
if (this.pointerGestureActive || this.protocolCandidateActive)
|
|
1570
|
+
return;
|
|
1571
|
+
this.pendingAltScreenReentry = false;
|
|
1572
|
+
this.reenterAltScreen();
|
|
1573
|
+
};
|
|
1574
|
+
/**
|
|
1575
|
+
* Retry a health probe that was blocked by an active gesture. Called by
|
|
1576
|
+
* App after the release tail completes, with the original caller's
|
|
1577
|
+
* skipMouseReassert semantics preserved. The request is cleared ONLY
|
|
1578
|
+
* after the probe actually writes — a throttle hit keeps it pending and
|
|
1579
|
+
* schedules a retry once the 250ms window expires.
|
|
1580
|
+
*/
|
|
1581
|
+
drainPendingProbe = () => {
|
|
1582
|
+
const req = this.pendingProbeRequest;
|
|
1583
|
+
if (!req)
|
|
1584
|
+
return;
|
|
1585
|
+
// Dual latch: never probe while a physical button is held OR while a
|
|
1586
|
+
// protocol candidate is in flight — the probe's DECSET/DECRQM writes
|
|
1587
|
+
// would corrupt the stream.
|
|
1588
|
+
if (this.pointerGestureActive || this.protocolCandidateActive)
|
|
1589
|
+
return;
|
|
1590
|
+
const now = Date.now();
|
|
1591
|
+
const throttleLeft = 250 - (now - this.lastHealthProbeAt);
|
|
1592
|
+
if (throttleLeft > 0) {
|
|
1593
|
+
// Still inside the throttle window: keep the request pending and
|
|
1594
|
+
// schedule the retry for when the window closes. The timer is
|
|
1595
|
+
// best-effort — a later drain (focus, release, resume) may fire
|
|
1596
|
+
// first; the guard inside probeAltScreenHealth makes a duplicate
|
|
1597
|
+
// harmless.
|
|
1598
|
+
setTimeout(() => this.drainPendingProbe(), throttleLeft);
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
this.pendingProbeRequest = undefined;
|
|
1602
|
+
this.probeAltScreenHealth(req);
|
|
1603
|
+
};
|
|
1604
|
+
/**
|
|
1605
|
+
* Combined drain for the release tail: re-entry first (destructive),
|
|
1606
|
+
* then the blocked probe retry (may discover a new 1049 loss and
|
|
1607
|
+
* schedule the NEXT re-entry).
|
|
1608
|
+
*/
|
|
1609
|
+
drainReleaseTail = () => {
|
|
1610
|
+
this.drainAltScreenReentry();
|
|
1611
|
+
this.drainPendingProbe();
|
|
1612
|
+
};
|
|
1613
|
+
probeAltScreenHealth = (options) => {
|
|
1614
|
+
// Shutdown latch: during the dispose window after detachForShutdown
|
|
1615
|
+
// (up to the 5s fallback exit) stray input, focus, resize or a pending
|
|
1616
|
+
// DECRPM reply would otherwise re-write ENABLE_MOUSE_TRACKING AFTER the
|
|
1617
|
+
// exit cleanup's DISABLE_MOUSE_TRACKING — the mouse-reporting residue
|
|
1618
|
+
// the shell then echoes as SGR garbage (issue #522). isUnmounted is set
|
|
1619
|
+
// by detachForShutdown() before any cleanup sequence is written.
|
|
1620
|
+
if (this.isUnmounted)
|
|
1621
|
+
return;
|
|
1622
|
+
// Dual latch: never write while a physical button is held OR while a
|
|
1623
|
+
// protocol candidate (split SGR prefix) is in flight. The physical latch
|
|
1624
|
+
// covers press→release; the candidate latch covers the window between
|
|
1625
|
+
// the first byte of a report and its completion — a DECSET re-assert
|
|
1626
|
+
// there corrupts the stream mid-parse.
|
|
1627
|
+
if (this.pointerGestureActive || this.protocolCandidateActive) {
|
|
1628
|
+
this.pendingProbeRequest = { ...options };
|
|
1629
|
+
return;
|
|
1630
|
+
}
|
|
1631
|
+
const now = Date.now();
|
|
1632
|
+
if (now - this.lastHealthProbeAt < 250)
|
|
1633
|
+
return;
|
|
1634
|
+
this.lastHealthProbeAt = now;
|
|
1635
|
+
if (!this.options.stdout.isTTY || this.isPaused || !this.altScreenActive)
|
|
1636
|
+
return;
|
|
1637
|
+
// Mouse-driven callers pass skipMouseReassert: the event that triggered
|
|
1638
|
+
// the probe already proves tracking is alive, so the blind DECSET
|
|
1639
|
+
// re-assert is pure risk near gestures — only the 1049 query below is
|
|
1640
|
+
// worth sending (conpty can drop 1049 while mouse tracking survives;
|
|
1641
|
+
// without a mouse-path probe a mouse-only user never recovers, since
|
|
1642
|
+
// mouse input keeps lastStdinTime fresh and starves the >5s gap path).
|
|
1643
|
+
if (this.altScreenMouseTracking && !options?.skipMouseReassert) {
|
|
1644
|
+
this.options.stdout.write(ENABLE_MOUSE_TRACKING);
|
|
1645
|
+
}
|
|
1646
|
+
const querier = this.app?.querier;
|
|
1647
|
+
if (querier === undefined)
|
|
1648
|
+
return;
|
|
1649
|
+
// macOS Terminal.app prints the trailing `p` of `CSI ? 1049 $ p` as
|
|
1650
|
+
// literal text instead of ignoring the unsupported query, leaking a
|
|
1651
|
+
// visible character at the cursor on every probe. The blind
|
|
1652
|
+
// mouse-tracking re-assert above still runs there — only the round trip
|
|
1653
|
+
// is skipped, which costs nothing: Terminal.app never answered it.
|
|
1654
|
+
if (!supportsDecrqmProbe())
|
|
1655
|
+
return;
|
|
1656
|
+
void Promise.all([querier.send(decrqm(1049)), querier.flush()]).then(([reply]) => {
|
|
1657
|
+
if (this.isUnmounted || this.isPaused || this.terminalQueriesSuspended)
|
|
1658
|
+
return;
|
|
1659
|
+
// DECRPM status: 1/3 = set, 2/4 = reset, 0/undefined = unknown.
|
|
1660
|
+
// Heal only on a POSITIVE reset — an unanswered probe must not
|
|
1661
|
+
// trigger the destructive re-entry.
|
|
1662
|
+
if (reply === undefined || (reply.status !== 2 && reply.status !== 4))
|
|
1663
|
+
return;
|
|
1664
|
+
// The reply resolves asynchronously: focus/keyboard/resize issued the
|
|
1665
|
+
// query, but a mouse press may have latched a gesture since (or a
|
|
1666
|
+
// protocol candidate may be in flight). Re-entering now would erase
|
|
1667
|
+
// the screen under the user's pointer and reset button tracking
|
|
1668
|
+
// mid-drag — defer to the gesture's end instead.
|
|
1669
|
+
if (this.pointerGestureActive || this.protocolCandidateActive) {
|
|
1670
|
+
this.pendingAltScreenReentry = true;
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
// Same re-check for the wider world: the probe ran with alt-screen
|
|
1674
|
+
// active, but an exit or editor handoff may have landed meanwhile.
|
|
1675
|
+
if (this.isUnmounted || this.isPaused || !this.altScreenActive)
|
|
1676
|
+
return;
|
|
1677
|
+
this.reenterAltScreen();
|
|
1678
|
+
}).catch(() => {
|
|
1679
|
+
/* probe is best-effort; the next trigger retries */
|
|
1680
|
+
});
|
|
1681
|
+
};
|
|
1682
|
+
/** Refocus = first observable moment after a conpty-side mode reset. */
|
|
1683
|
+
handleTerminalFocusProbe = (focused) => {
|
|
1684
|
+
if (focused) {
|
|
1685
|
+
this.probeAltScreenHealth();
|
|
1686
|
+
// Refocus is a safe boundary: the OS delivered the focus event, so no
|
|
1687
|
+
// button can be held (a held button would have generated motion or a
|
|
1688
|
+
// release first). Drain any deferred re-entry confirmed while the
|
|
1689
|
+
// window was unfocused.
|
|
1690
|
+
this.drainAltScreenReentry();
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
notifyTerminalImagesChange() {
|
|
1694
|
+
// AlternateScreen changes modes in an insertion effect. Notify React
|
|
1695
|
+
// after that commit, when scheduling a subscriber update is safe.
|
|
1696
|
+
queueMicrotask(() => {
|
|
1697
|
+
for (const listener of this.terminalImageListeners)
|
|
1698
|
+
listener();
|
|
1699
|
+
});
|
|
1700
|
+
}
|
|
1701
|
+
/** Probe on image demand, before lazy consumers need to decode a source. */
|
|
1702
|
+
maybeProbeKittyGraphics(placements) {
|
|
1703
|
+
if ((placements.length === 0 && this.terminalImageRequests === 0) ||
|
|
1704
|
+
this.isUnmounted ||
|
|
1705
|
+
this.kittyGraphicsProbeStarted ||
|
|
1706
|
+
this.options.terminalImages === false ||
|
|
1707
|
+
!this.altScreenActive ||
|
|
1708
|
+
this.isPaused ||
|
|
1709
|
+
this.terminalQueriesSuspended ||
|
|
1710
|
+
!this.options.stdout.isTTY ||
|
|
1711
|
+
process.env.TMUX !== undefined ||
|
|
1712
|
+
process.env.STY !== undefined ||
|
|
1713
|
+
isEnvTruthy(process.env.DSH_TUI_ACCESSIBILITY) ||
|
|
1714
|
+
isEnvTruthy(process.env.DSH_TUI_DISABLE_TERMINAL_IMAGES)
|
|
1715
|
+
|| process.env.DSH_TUI_IMAGE_PROTOCOL === 'none') {
|
|
1716
|
+
return;
|
|
1717
|
+
}
|
|
1718
|
+
const querier = this.app?.querier;
|
|
1719
|
+
if (querier === undefined)
|
|
1720
|
+
return;
|
|
1721
|
+
this.kittyGraphicsProbeStarted = true;
|
|
1722
|
+
const queryId = 31;
|
|
1723
|
+
const columns = this.terminalColumns;
|
|
1724
|
+
const rows = this.terminalRows;
|
|
1725
|
+
void Promise.all([
|
|
1726
|
+
querier.send(kittyGraphics(queryId)),
|
|
1727
|
+
querier.send(terminalCellSizePixels()),
|
|
1728
|
+
querier.send(terminalWindowSizePixels()),
|
|
1729
|
+
querier.flush({ attributes: true }),
|
|
1730
|
+
])
|
|
1731
|
+
.then(async ([reply, cellPixels, windowPixels, attributes]) => {
|
|
1732
|
+
if (this.isUnmounted || this.isPaused || this.terminalQueriesSuspended) {
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
const protocol = selectTerminalImageProtocol(reply?.status, attributes?.params, process.env.DSH_TUI_IMAGE_PROTOCOL);
|
|
1736
|
+
if (protocol === 'none')
|
|
1737
|
+
return;
|
|
1738
|
+
if (protocol === 'sixel') {
|
|
1739
|
+
const [mode] = await Promise.all([querier.send(decrqm(80)), querier.flush()]);
|
|
1740
|
+
if (this.isUnmounted || this.isPaused || this.terminalQueriesSuspended)
|
|
1741
|
+
return;
|
|
1742
|
+
// A permanently set display mode cannot place a preview at CUP.
|
|
1743
|
+
if (mode?.status === 3)
|
|
1744
|
+
return;
|
|
1745
|
+
this.sixelGraphicsManager.setDisplayMode(mode?.status === 1);
|
|
1746
|
+
}
|
|
1747
|
+
this.kittyGraphicsSupported = protocol === 'kitty';
|
|
1748
|
+
this.sixelGraphicsSupported = protocol === 'sixel';
|
|
1749
|
+
this.notifyTerminalImagesChange();
|
|
1750
|
+
if (columns === this.terminalColumns &&
|
|
1751
|
+
rows === this.terminalRows) {
|
|
1752
|
+
this.measuredImageCellSize = resolveTerminalCellSize(cellPixels, windowPixels, columns, rows);
|
|
1753
|
+
this.kittyGraphicsManager.setCellSize(this.measuredImageCellSize ??
|
|
1754
|
+
DEFAULT_TERMINAL_CELL_SIZE);
|
|
1755
|
+
this.sixelGraphicsManager.setCellSize(this.measuredImageCellSize ?? DEFAULT_TERMINAL_CELL_SIZE);
|
|
1756
|
+
}
|
|
1757
|
+
else {
|
|
1758
|
+
// The capability result is still valid, but its geometry snapshot
|
|
1759
|
+
// is not. Start one fresh metrics batch after this sentinel.
|
|
1760
|
+
this.refreshTerminalCellMetrics();
|
|
1761
|
+
}
|
|
1762
|
+
if (!this.altScreenActive)
|
|
1763
|
+
return;
|
|
1764
|
+
// The preceding frame painted text fallback cells. Force one complete
|
|
1765
|
+
// paint so image nodes replace those cells with blank backing before
|
|
1766
|
+
// their graphics placements are uploaded.
|
|
1767
|
+
dom.markTreeDirty(this.rootNode);
|
|
1768
|
+
this.prevFrameContaminated = true;
|
|
1769
|
+
this.scheduleRender();
|
|
1770
|
+
})
|
|
1771
|
+
.catch(() => {
|
|
1772
|
+
/* Capability detection is best-effort; fallback remains visible. */
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
/** Refresh image pixel geometry after a resize, coalescing resize bursts. */
|
|
1776
|
+
refreshTerminalCellMetrics() {
|
|
1777
|
+
if ((!this.kittyGraphicsSupported && !this.sixelGraphicsSupported) ||
|
|
1778
|
+
this.isUnmounted ||
|
|
1779
|
+
!this.options.stdout.isTTY) {
|
|
1780
|
+
return;
|
|
1781
|
+
}
|
|
1782
|
+
if (this.isPaused || this.terminalQueriesSuspended) {
|
|
1783
|
+
this.terminalCellMetricsRefreshPending = true;
|
|
1784
|
+
return;
|
|
1785
|
+
}
|
|
1786
|
+
const querier = this.app?.querier;
|
|
1787
|
+
if (querier === undefined)
|
|
1788
|
+
return;
|
|
1789
|
+
if (this.terminalCellMetricsInFlight) {
|
|
1790
|
+
this.terminalCellMetricsRefreshPending = true;
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
this.terminalCellMetricsInFlight = true;
|
|
1794
|
+
this.terminalCellMetricsRefreshPending = false;
|
|
1795
|
+
const columns = this.terminalColumns;
|
|
1796
|
+
const rows = this.terminalRows;
|
|
1797
|
+
void Promise.all([
|
|
1798
|
+
querier.send(terminalCellSizePixels()),
|
|
1799
|
+
querier.send(terminalWindowSizePixels()),
|
|
1800
|
+
querier.flush(),
|
|
1801
|
+
])
|
|
1802
|
+
.then(([cellPixels, windowPixels]) => {
|
|
1803
|
+
if (this.isUnmounted)
|
|
1804
|
+
return;
|
|
1805
|
+
if (this.isPaused || this.terminalQueriesSuspended) {
|
|
1806
|
+
this.terminalCellMetricsRefreshPending = true;
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
if (columns !== this.terminalColumns ||
|
|
1810
|
+
rows !== this.terminalRows) {
|
|
1811
|
+
this.terminalCellMetricsRefreshPending = true;
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
const cellSize = resolveTerminalCellSize(cellPixels, windowPixels, columns, rows);
|
|
1815
|
+
if (cellSize === undefined)
|
|
1816
|
+
return;
|
|
1817
|
+
if (this.measuredImageCellSize?.width !== cellSize.width || this.measuredImageCellSize?.height !== cellSize.height) {
|
|
1818
|
+
this.measuredImageCellSize = cellSize;
|
|
1819
|
+
this.notifyTerminalImagesChange();
|
|
1820
|
+
}
|
|
1821
|
+
const changed = this.kittyGraphicsManager.setCellSize(cellSize);
|
|
1822
|
+
const sixelChanged = this.sixelGraphicsManager.setCellSize(cellSize);
|
|
1823
|
+
if ((changed || sixelChanged) && this.altScreenActive) {
|
|
1824
|
+
dom.markTreeDirty(this.rootNode);
|
|
1825
|
+
this.scheduleRender();
|
|
1826
|
+
}
|
|
1827
|
+
})
|
|
1828
|
+
.catch(() => {
|
|
1829
|
+
/* Pixel geometry is best-effort; retain the last known value. */
|
|
1830
|
+
})
|
|
1831
|
+
.finally(() => {
|
|
1832
|
+
this.terminalCellMetricsInFlight = false;
|
|
1833
|
+
if (this.terminalCellMetricsRefreshPending &&
|
|
1834
|
+
!this.isPaused &&
|
|
1835
|
+
!this.terminalQueriesSuspended) {
|
|
1836
|
+
this.terminalCellMetricsRefreshPending = false;
|
|
1837
|
+
this.refreshTerminalCellMetrics();
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
}
|
|
1841
|
+
/** Reopen terminal queries only after late handoff replies are quarantined. */
|
|
1842
|
+
resumeTerminalQueriesAfterHandoff() {
|
|
1843
|
+
if (this.terminalQueryResumeTimer !== null) {
|
|
1844
|
+
clearTimeout(this.terminalQueryResumeTimer);
|
|
1845
|
+
}
|
|
1846
|
+
this.terminalQueryResumeTimer = setTimeout(() => {
|
|
1847
|
+
this.terminalQueryResumeTimer = null;
|
|
1848
|
+
if (this.isUnmounted)
|
|
1849
|
+
return;
|
|
1850
|
+
this.app?.querier.resume();
|
|
1851
|
+
this.notifyTerminalImagesChange();
|
|
1852
|
+
this.app?.scheduleXtversionProbe();
|
|
1853
|
+
if (this.terminalCellMetricsRefreshPending &&
|
|
1854
|
+
!this.terminalCellMetricsInFlight) {
|
|
1855
|
+
this.terminalCellMetricsRefreshPending = false;
|
|
1856
|
+
this.refreshTerminalCellMetrics();
|
|
1857
|
+
}
|
|
1858
|
+
else if (!this.kittyGraphicsSupported && !this.sixelGraphicsSupported) {
|
|
1859
|
+
this.scheduleRender();
|
|
1860
|
+
}
|
|
1861
|
+
}, TERMINAL_REPLY_QUARANTINE_MS);
|
|
1862
|
+
}
|
|
1863
|
+
get terminalQueriesSuspended() {
|
|
1864
|
+
return this.app?.querier.isSuspended ?? false;
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Re-enter alt-screen, clear, home, re-enable mouse tracking, and reset
|
|
1868
|
+
* frame buffers so the next render repaints from scratch. Self-heal for
|
|
1869
|
+
* SIGCONT, resize, and stdin-gap/event-loop-stall (sleep/wake) — any of
|
|
1870
|
+
* which can leave the terminal in main-screen mode while altScreenActive
|
|
1871
|
+
* stays true. ENTER_ALT_SCREEN is a terminal-side no-op if already in alt.
|
|
1872
|
+
*/
|
|
1873
|
+
reenterAltScreen() {
|
|
1874
|
+
// Same shutdown latch as probeAltScreenHealth: a DECRPM reply resolving
|
|
1875
|
+
// after detachForShutdown (or a SIGCONT racing unmount) must not re-enter
|
|
1876
|
+
// the alt screen or re-enable mouse tracking past the exit cleanup
|
|
1877
|
+
// (issue #522).
|
|
1878
|
+
if (this.isUnmounted)
|
|
1879
|
+
return;
|
|
1880
|
+
this.options.stdout.write(ENTER_ALT_SCREEN + ERASE_SCREEN + CURSOR_HOME + (this.altScreenMouseTracking ? ENABLE_MOUSE_TRACKING : ''));
|
|
1881
|
+
this.resetFramesForAltScreen();
|
|
1882
|
+
}
|
|
1883
|
+
/**
|
|
1884
|
+
* Seed prev/back frames with full-size BLANK screens (rows×cols of empty
|
|
1885
|
+
* cells, not 0×0). In alt-screen mode, next.screen.height is always
|
|
1886
|
+
* terminalRows; if prev.screen.height is 0 (emptyFrame's default),
|
|
1887
|
+
* log-update sees heightDelta > 0 ('growing') and calls renderFrameSlice,
|
|
1888
|
+
* whose trailing per-row CR+LF at the last row scrolls the alt screen,
|
|
1889
|
+
* permanently desyncing the virtual and physical cursors by 1 row.
|
|
1890
|
+
*
|
|
1891
|
+
* With a rows×cols blank prev, heightDelta === 0 → standard diffEach
|
|
1892
|
+
* → moveCursorTo (CSI cursorMove, no LF, no scroll).
|
|
1893
|
+
*
|
|
1894
|
+
* viewport.height = rows + 1 matches the renderer's alt-screen output,
|
|
1895
|
+
* preventing a spurious resize trigger on the first frame. cursor.y = 0
|
|
1896
|
+
* matches the physical cursor after ENTER_ALT_SCREEN + CSI H (home).
|
|
1897
|
+
*/
|
|
1898
|
+
resetFramesForAltScreen() {
|
|
1899
|
+
this.needsSurfaceRepaint = false;
|
|
1900
|
+
const rows = this.terminalRows;
|
|
1901
|
+
const cols = this.terminalColumns;
|
|
1902
|
+
const blank = () => ({
|
|
1903
|
+
screen: createScreen(cols, rows, this.stylePool, this.charPool, this.hyperlinkPool),
|
|
1904
|
+
viewport: {
|
|
1905
|
+
width: cols,
|
|
1906
|
+
height: rows + 1
|
|
1907
|
+
},
|
|
1908
|
+
cursor: {
|
|
1909
|
+
x: 0,
|
|
1910
|
+
y: 0,
|
|
1911
|
+
visible: true
|
|
1912
|
+
}
|
|
1913
|
+
});
|
|
1914
|
+
this.frontFrame = blank();
|
|
1915
|
+
this.backFrame = blank();
|
|
1916
|
+
this.log.reset();
|
|
1917
|
+
this.kittyGraphicsManager.invalidateAll();
|
|
1918
|
+
this.sixelGraphicsManager.invalidateAll();
|
|
1919
|
+
// Defense-in-depth: alt-screen skips the cursor preamble anyway (CSI H
|
|
1920
|
+
// resets), but a stale displayCursor would be misleading if we later
|
|
1921
|
+
// exit to main-screen without an intervening render.
|
|
1922
|
+
this.displayCursor = null;
|
|
1923
|
+
// Fresh frontFrame is blank rows×cols — blitting from it would copy
|
|
1924
|
+
// blanks over content. Next alt-screen frame must full-render.
|
|
1925
|
+
this.prevFrameContaminated = true;
|
|
1926
|
+
}
|
|
1927
|
+
/**
|
|
1928
|
+
* Copy the current selection to the clipboard without clearing the
|
|
1929
|
+
* highlight. Matches iTerm2's copy-on-select behavior where the selected
|
|
1930
|
+
* region stays visible after the automatic copy.
|
|
1931
|
+
*/
|
|
1932
|
+
copySelectionNoClear() {
|
|
1933
|
+
if (!hasSelection(this.selection))
|
|
1934
|
+
return '';
|
|
1935
|
+
// Commit-consistency guard: the rows under the highlight changed
|
|
1936
|
+
// without follow coordination during the selection's lifetime, so
|
|
1937
|
+
// these coordinates now hold text the user never highlighted.
|
|
1938
|
+
// Shipping it would copy visibly wrong content (the "mojibake-looking"
|
|
1939
|
+
// paste of another line); refuse, clear the stale highlight, and let
|
|
1940
|
+
// the caller surface it (React callers enter through copySelection /
|
|
1941
|
+
// useCopyOnSelect's onRefused — the direct no-clear entry must not
|
|
1942
|
+
// leave the misleading highlight up either).
|
|
1943
|
+
if (this.selection.stale) {
|
|
1944
|
+
clearSelection(this.selection);
|
|
1945
|
+
this.notifySelectionChange();
|
|
1946
|
+
return '';
|
|
1947
|
+
}
|
|
1948
|
+
const text = getSelectedText(this.selection, this.frontFrame.screen);
|
|
1949
|
+
if (text) {
|
|
1950
|
+
// Raw OSC 52, or DCS-passthrough-wrapped OSC 52 inside tmux (tmux
|
|
1951
|
+
// drops it silently unless allow-passthrough is on — no regression).
|
|
1952
|
+
void setClipboard(text).then(raw => {
|
|
1953
|
+
if (raw)
|
|
1954
|
+
this.writeRaw(raw);
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
return text;
|
|
1958
|
+
}
|
|
1959
|
+
/**
|
|
1960
|
+
* Copy the current text selection to the system clipboard via OSC 52
|
|
1961
|
+
* and clear the selection. Returns the copied text (empty if no selection).
|
|
1962
|
+
*/
|
|
1963
|
+
copySelection() {
|
|
1964
|
+
if (!hasSelection(this.selection))
|
|
1965
|
+
return '';
|
|
1966
|
+
const text = this.copySelectionNoClear();
|
|
1967
|
+
clearSelection(this.selection);
|
|
1968
|
+
this.notifySelectionChange();
|
|
1969
|
+
return text;
|
|
1970
|
+
}
|
|
1971
|
+
/** Clear the current text selection without copying. */
|
|
1972
|
+
clearTextSelection() {
|
|
1973
|
+
if (!hasSelection(this.selection))
|
|
1974
|
+
return;
|
|
1975
|
+
clearSelection(this.selection);
|
|
1976
|
+
this.notifySelectionChange();
|
|
1977
|
+
}
|
|
1978
|
+
/**
|
|
1979
|
+
* Set the search highlight query. Non-empty → all visible occurrences
|
|
1980
|
+
* are inverted (SGR 7) on the next frame; first one also underlined.
|
|
1981
|
+
* Empty → clears (prevFrameContaminated handles the frame after). Same
|
|
1982
|
+
* damage-tracking machinery as selection — setCellStyleId doesn't track
|
|
1983
|
+
* damage, so the overlay forces full-frame damage while active.
|
|
1984
|
+
*/
|
|
1985
|
+
setSearchHighlight(query) {
|
|
1986
|
+
if (this.searchHighlightQuery === query)
|
|
1987
|
+
return;
|
|
1988
|
+
this.searchHighlightQuery = query;
|
|
1989
|
+
this.scheduleRender();
|
|
1990
|
+
}
|
|
1991
|
+
/** Paint an EXISTING DOM subtree to a fresh Screen at its natural
|
|
1992
|
+
* height, scan for query. Returns positions relative to the element's
|
|
1993
|
+
* bounding box (row 0 = element top).
|
|
1994
|
+
*
|
|
1995
|
+
* The element comes from the MAIN tree — built with all real
|
|
1996
|
+
* providers, yoga already computed. We paint it to a fresh buffer
|
|
1997
|
+
* with offsets so it lands at (0,0). Same paint path as the main
|
|
1998
|
+
* render. Zero drift. No second React root, no context bridge.
|
|
1999
|
+
*
|
|
2000
|
+
* ~1-2ms (paint only, no reconcile — the DOM is already built). */
|
|
2001
|
+
scanElementSubtree(el) {
|
|
2002
|
+
if (!this.searchHighlightQuery || !el.yogaNode)
|
|
2003
|
+
return [];
|
|
2004
|
+
const width = Math.ceil(el.yogaNode.getComputedWidth());
|
|
2005
|
+
const height = Math.ceil(el.yogaNode.getComputedHeight());
|
|
2006
|
+
if (width <= 0 || height <= 0)
|
|
2007
|
+
return [];
|
|
2008
|
+
// renderNodeToOutput adds el's OWN computedLeft/Top to offsetX/Y.
|
|
2009
|
+
// Passing -elLeft/-elTop nets to 0 → paints at (0,0) in our buffer.
|
|
2010
|
+
const elLeft = el.yogaNode.getComputedLeft();
|
|
2011
|
+
const elTop = el.yogaNode.getComputedTop();
|
|
2012
|
+
const screen = createScreen(width, height, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
2013
|
+
const output = new Output({
|
|
2014
|
+
width,
|
|
2015
|
+
height,
|
|
2016
|
+
stylePool: this.stylePool,
|
|
2017
|
+
screen
|
|
2018
|
+
});
|
|
2019
|
+
renderNodeToOutput(el, output, {
|
|
2020
|
+
offsetX: -elLeft,
|
|
2021
|
+
offsetY: -elTop,
|
|
2022
|
+
prevScreen: undefined
|
|
2023
|
+
});
|
|
2024
|
+
const rendered = output.get();
|
|
2025
|
+
// renderNodeToOutput wrote our offset positions to nodeCache —
|
|
2026
|
+
// corrupts the main render (it'd blit from wrong coords). Mark the
|
|
2027
|
+
// subtree dirty so the next main render repaints + re-caches
|
|
2028
|
+
// correctly. One extra paint of this message, but correct > fast.
|
|
2029
|
+
dom.markDirty(el);
|
|
2030
|
+
const positions = scanPositions(rendered, this.searchHighlightQuery);
|
|
2031
|
+
logForDebugging(`scanElementSubtree: q='${this.searchHighlightQuery}' ` + `el=${width}x${height}@(${elLeft},${elTop}) n=${positions.length} ` + `[${positions.slice(0, 10).map(p => `${p.row}:${p.col}`).join(',')}` + `${positions.length > 10 ? ',…' : ''}]`);
|
|
2032
|
+
return positions;
|
|
2033
|
+
}
|
|
2034
|
+
/** Set the position-based highlight state. Every frame, writes CURRENT
|
|
2035
|
+
* style at positions[currentIdx] + rowOffset. null clears. The scan-
|
|
2036
|
+
* highlight (inverse on all matches) still runs — this overlays yellow
|
|
2037
|
+
* on top. rowOffset changes as the user scrolls (= message's current
|
|
2038
|
+
* screen-top); positions stay stable (message-relative). */
|
|
2039
|
+
setSearchPositions(state) {
|
|
2040
|
+
this.searchPositions = state;
|
|
2041
|
+
this.scheduleRender();
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* Set the selection highlight background color. Replaces the per-cell
|
|
2045
|
+
* SGR-7 inverse with a solid theme-aware bg (matches native terminal
|
|
2046
|
+
* selection). Accepts the same color formats as Text backgroundColor
|
|
2047
|
+
* (rgb(), ansi:name, #hex, ansi256()) — colorize() routes through
|
|
2048
|
+
* chalk so the tmux/xterm.js level clamps in colorize.ts apply and
|
|
2049
|
+
* the emitted SGR is correct for the current terminal.
|
|
2050
|
+
*
|
|
2051
|
+
* Called by React-land once theme is known (ScrollKeybindingHandler's
|
|
2052
|
+
* useEffect watching useTheme). Before that call, withSelectionBg
|
|
2053
|
+
* falls back to withInverse so selection still renders on the first
|
|
2054
|
+
* frame; the effect fires before any mouse input so the fallback is
|
|
2055
|
+
* unobservable in practice.
|
|
2056
|
+
*/
|
|
2057
|
+
/**
|
|
2058
|
+
* The colour a backdrop shade (`<Box backdrop="dim">`) fades explicit
|
|
2059
|
+
* colours toward — the terminal background from OSC 11, or black/white
|
|
2060
|
+
* by theme lightness when unknown. See StylePool.setShadeTarget.
|
|
2061
|
+
*/
|
|
2062
|
+
setShadeTarget(rgb) {
|
|
2063
|
+
this.stylePool.setShadeTarget(rgb);
|
|
2064
|
+
}
|
|
2065
|
+
setSelectionBgColor(color) {
|
|
2066
|
+
// Wrap a NUL marker, then split on it to extract the open/close SGR.
|
|
2067
|
+
// colorize returns the input unchanged if the color string is bad —
|
|
2068
|
+
// no NUL-split then, so fall through to null (inverse fallback).
|
|
2069
|
+
const wrapped = colorize('\0', color, 'background');
|
|
2070
|
+
const nul = wrapped.indexOf('\0');
|
|
2071
|
+
if (nul <= 0 || nul === wrapped.length - 1) {
|
|
2072
|
+
this.stylePool.setSelectionBg(null);
|
|
2073
|
+
return;
|
|
2074
|
+
}
|
|
2075
|
+
this.stylePool.setSelectionBg({
|
|
2076
|
+
type: 'ansi',
|
|
2077
|
+
code: wrapped.slice(0, nul),
|
|
2078
|
+
endCode: wrapped.slice(nul + 1) // always \x1b[49m for bg
|
|
2079
|
+
});
|
|
2080
|
+
// No scheduleRender: this is called from a React effect that already
|
|
2081
|
+
// runs inside the render cycle, and the bg only matters once a
|
|
2082
|
+
// selection exists (which itself triggers a full-damage frame).
|
|
2083
|
+
}
|
|
2084
|
+
/**
|
|
2085
|
+
* Capture text from rows about to scroll out of the viewport during
|
|
2086
|
+
* drag-to-scroll. Must be called BEFORE the ScrollBox scrolls so the
|
|
2087
|
+
* screen buffer still holds the outgoing content. Accumulated into
|
|
2088
|
+
* the selection state and joined back in by getSelectedText.
|
|
2089
|
+
*/
|
|
2090
|
+
captureScrolledRows(firstRow, lastRow, side) {
|
|
2091
|
+
captureScrolledRows(this.selection, this.frontFrame.screen, firstRow, lastRow, side);
|
|
2092
|
+
}
|
|
2093
|
+
/**
|
|
2094
|
+
* Shift anchor AND focus by dRow, clamped to [minRow, maxRow]. Used by
|
|
2095
|
+
* keyboard scroll handlers (PgUp/PgDn etc.) so the highlight tracks the
|
|
2096
|
+
* content instead of disappearing. Unlike shiftAnchor (drag-to-scroll),
|
|
2097
|
+
* this moves BOTH endpoints — the user isn't holding the mouse at one
|
|
2098
|
+
* edge. Supplies screen.width for the col-reset-on-clamp boundary.
|
|
2099
|
+
*/
|
|
2100
|
+
shiftSelectionForScroll(dRow, minRow, maxRow) {
|
|
2101
|
+
const hadSel = hasSelection(this.selection);
|
|
2102
|
+
shiftSelection(this.selection, dRow, minRow, maxRow, this.frontFrame.screen.width);
|
|
2103
|
+
// shiftSelection clears when both endpoints overshoot the same edge
|
|
2104
|
+
// (Home/g/End/G page-jump past the selection). Notify subscribers so
|
|
2105
|
+
// useHasSelection updates. Safe to call notifySelectionChange here —
|
|
2106
|
+
// this runs from keyboard handlers, not inside onRender().
|
|
2107
|
+
if (hadSel && !hasSelection(this.selection)) {
|
|
2108
|
+
this.notifySelectionChange();
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
/**
|
|
2112
|
+
* Keyboard selection extension (shift+arrow/home/end). Moves focus;
|
|
2113
|
+
* anchor stays fixed so the highlight grows or shrinks relative to it.
|
|
2114
|
+
* Left/right wrap across row boundaries — native macOS text-edit
|
|
2115
|
+
* behavior: shift+left at col 0 wraps to end of the previous row.
|
|
2116
|
+
* Up/down clamp at viewport edges (no scroll-to-extend yet). Drops to
|
|
2117
|
+
* char mode. No-op outside alt-screen or without an active selection.
|
|
2118
|
+
*/
|
|
2119
|
+
moveSelectionFocus(move) {
|
|
2120
|
+
if (!this.altScreenActive)
|
|
2121
|
+
return;
|
|
2122
|
+
const { focus } = this.selection;
|
|
2123
|
+
if (!focus)
|
|
2124
|
+
return;
|
|
2125
|
+
const { width, height } = this.frontFrame.screen;
|
|
2126
|
+
const maxCol = width - 1;
|
|
2127
|
+
const maxRow = height - 1;
|
|
2128
|
+
let { col, row } = focus;
|
|
2129
|
+
switch (move) {
|
|
2130
|
+
case 'left':
|
|
2131
|
+
if (col > 0)
|
|
2132
|
+
col--;
|
|
2133
|
+
else if (row > 0) {
|
|
2134
|
+
col = maxCol;
|
|
2135
|
+
row--;
|
|
2136
|
+
}
|
|
2137
|
+
break;
|
|
2138
|
+
case 'right':
|
|
2139
|
+
if (col < maxCol)
|
|
2140
|
+
col++;
|
|
2141
|
+
else if (row < maxRow) {
|
|
2142
|
+
col = 0;
|
|
2143
|
+
row++;
|
|
2144
|
+
}
|
|
2145
|
+
break;
|
|
2146
|
+
case 'up':
|
|
2147
|
+
if (row > 0)
|
|
2148
|
+
row--;
|
|
2149
|
+
break;
|
|
2150
|
+
case 'down':
|
|
2151
|
+
if (row < maxRow)
|
|
2152
|
+
row++;
|
|
2153
|
+
break;
|
|
2154
|
+
case 'lineStart':
|
|
2155
|
+
col = 0;
|
|
2156
|
+
break;
|
|
2157
|
+
case 'lineEnd':
|
|
2158
|
+
col = maxCol;
|
|
2159
|
+
break;
|
|
2160
|
+
}
|
|
2161
|
+
if (col === focus.col && row === focus.row)
|
|
2162
|
+
return;
|
|
2163
|
+
moveFocus(this.selection, col, row);
|
|
2164
|
+
this.notifySelectionChange();
|
|
2165
|
+
}
|
|
2166
|
+
/** Whether there is an active text selection. */
|
|
2167
|
+
hasTextSelection() {
|
|
2168
|
+
return hasSelection(this.selection);
|
|
2169
|
+
}
|
|
2170
|
+
/**
|
|
2171
|
+
* Subscribe to selection state changes. Fires whenever the selection
|
|
2172
|
+
* is started, updated, cleared, or copied. Returns an unsubscribe fn.
|
|
2173
|
+
*/
|
|
2174
|
+
subscribeToSelectionChange(cb) {
|
|
2175
|
+
this.selectionListeners.add(cb);
|
|
2176
|
+
return () => this.selectionListeners.delete(cb);
|
|
2177
|
+
}
|
|
2178
|
+
notifySelectionChange() {
|
|
2179
|
+
this.renderNow();
|
|
2180
|
+
// #185 self-heal: selection listeners drive React state; an overflow
|
|
2181
|
+
// throw resets React's nested counter, so absorb and keep the rest.
|
|
2182
|
+
for (const cb of this.selectionListeners) {
|
|
2183
|
+
callWithUpdateOverflowGuard('selection.notify', cb);
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
/**
|
|
2187
|
+
* Hit-test the rendered DOM tree at (col, row) and bubble a ClickEvent
|
|
2188
|
+
* from the deepest hit node up through ancestors with onClick handlers.
|
|
2189
|
+
* Returns true if a DOM handler consumed the click. Gated on
|
|
2190
|
+
* altScreenActive — clicks only make sense with a fixed viewport where
|
|
2191
|
+
* nodeCache rects map 1:1 to terminal cells (no scrollback offset).
|
|
2192
|
+
* The button byte is the raw SGR release code; its modifier bits land
|
|
2193
|
+
* on ClickEvent.shift/alt/ctrl.
|
|
2194
|
+
*/
|
|
2195
|
+
/** Batch-tail probe for release-path clicks that deferred via deferProbe. */
|
|
2196
|
+
clickProbeAtBatchTail = () => {
|
|
2197
|
+
this.probeAltScreenHealth({ skipMouseReassert: true });
|
|
2198
|
+
};
|
|
2199
|
+
dispatchClick(col, row, button = 0, deferProbe = false) {
|
|
2200
|
+
// Safe-boundary probe: clicks are dispatched from the RELEASE tail,
|
|
2201
|
+
// after App cleared the gesture latch — no button is held here. A
|
|
2202
|
+
// received mouse report proves tracking is alive but says nothing about
|
|
2203
|
+
// mode 1049 (conpty drops them independently), and mouse input keeps
|
|
2204
|
+
// lastStdinTime fresh so the >5s stdin-gap path never fires for a
|
|
2205
|
+
// mouse-only user — without a mouse-path probe, a silently dropped
|
|
2206
|
+
// alt-screen would never recover. skipMouseReassert: the arriving event
|
|
2207
|
+
// already proves tracking, so only the DECRQM 1049 query is sent.
|
|
2208
|
+
// deferProbe: release-path clicks defer the probe to the batch tail — a
|
|
2209
|
+
// single stdin chunk can carry `release → next press`, and the probe
|
|
2210
|
+
// must not write before the next press latch is established.
|
|
2211
|
+
if (!deferProbe) {
|
|
2212
|
+
this.probeAltScreenHealth({ skipMouseReassert: true });
|
|
2213
|
+
}
|
|
2214
|
+
if (!this.altScreenActive) {
|
|
2215
|
+
logMouseDebug('dispatchClick skipped — alt screen inactive', { col, row });
|
|
2216
|
+
return false;
|
|
2217
|
+
}
|
|
2218
|
+
const blank = isEmptyCellAt(this.frontFrame.screen, col, row);
|
|
2219
|
+
const handled = dispatchClick(this.rootNode, col, row, blank, button);
|
|
2220
|
+
logMouseDebug('dispatchClick', { col, row, handled });
|
|
2221
|
+
return handled;
|
|
2222
|
+
}
|
|
2223
|
+
/**
|
|
2224
|
+
* Hit-test the rendered DOM tree at (col, row) and bubble a
|
|
2225
|
+
* ContextMenuEvent from the deepest hit node up through ancestors with
|
|
2226
|
+
* onContextMenu handlers. Returns true if a DOM handler consumed it.
|
|
2227
|
+
* Gated on altScreenActive like dispatchClick. The button byte is the
|
|
2228
|
+
* raw SGR press code; its low bits are 2 for the right button and the
|
|
2229
|
+
* modifier bits land on ContextMenuEvent.shift/alt/ctrl.
|
|
2230
|
+
*/
|
|
2231
|
+
dispatchContextMenu(col, row, button = 0) {
|
|
2232
|
+
// No probe: this runs at right-PRESS time, inside the gesture window
|
|
2233
|
+
// (App latches before dispatching) — the probe would be latch-blocked
|
|
2234
|
+
// here anyway. Recovery lives at the safe boundaries (click release,
|
|
2235
|
+
// hover, wheel — see dispatchClick).
|
|
2236
|
+
if (!this.altScreenActive) {
|
|
2237
|
+
logMouseDebug('dispatchContextMenu skipped — alt screen inactive', { col, row });
|
|
2238
|
+
return false;
|
|
2239
|
+
}
|
|
2240
|
+
const handled = dispatchContextMenu(this.rootNode, col, row, button);
|
|
2241
|
+
logMouseDebug('dispatchContextMenu', { col, row, handled });
|
|
2242
|
+
return handled;
|
|
2243
|
+
}
|
|
2244
|
+
/**
|
|
2245
|
+
* Route a wheel event to the ScrollBox (any onWheel handler) under the
|
|
2246
|
+
* pointer. Returns true when a handler consumed it, so App can skip the
|
|
2247
|
+
* legacy global wheel-key path and exactly one layer scrolls. Gated on
|
|
2248
|
+
* altScreenActive like dispatchClick — without mouse tracking there are
|
|
2249
|
+
* no wheel coordinates to route by.
|
|
2250
|
+
*/
|
|
2251
|
+
dispatchWheelAt(col, row, deltaY, deltaX = 0, button = 0) {
|
|
2252
|
+
// Safe-boundary probe (skipMouseReassert — see dispatchClick). Wheel is
|
|
2253
|
+
// the recovery entry for mouse-only users on mode-1002-only terminals,
|
|
2254
|
+
// where no-button hover motion never arrives: SGR wheel reports carry
|
|
2255
|
+
// no held-button state and never engage the gesture latch.
|
|
2256
|
+
this.probeAltScreenHealth({ skipMouseReassert: true });
|
|
2257
|
+
if (!this.altScreenActive)
|
|
2258
|
+
return false;
|
|
2259
|
+
const handled = dispatchWheel(this.rootNode, col, row, deltaY, deltaX, button);
|
|
2260
|
+
if (handled) {
|
|
2261
|
+
logMouseDebug('dispatchWheelAt consumed', { col, row, deltaY, deltaX });
|
|
2262
|
+
}
|
|
2263
|
+
return handled;
|
|
2264
|
+
}
|
|
2265
|
+
dispatchHover(col, row) {
|
|
2266
|
+
// Safe-boundary probe (skipMouseReassert — see dispatchClick). Hover is
|
|
2267
|
+
// no-button motion; App already cleared the gesture latch before routing
|
|
2268
|
+
// here, so no button can be held.
|
|
2269
|
+
this.probeAltScreenHealth({ skipMouseReassert: true });
|
|
2270
|
+
if (!this.altScreenActive)
|
|
2271
|
+
return;
|
|
2272
|
+
dispatchHover(this.rootNode, col, row, this.hoveredNodes);
|
|
2273
|
+
}
|
|
2274
|
+
/**
|
|
2275
|
+
* Drag protocol entry: find the drag target at an unmodified left
|
|
2276
|
+
* press — the deepest node at (col, row) whose ancestor chain carries
|
|
2277
|
+
* an onDragStart handler. Gated on altScreenActive like dispatchClick
|
|
2278
|
+
* (drag needs mouse tracking + a fixed viewport). Returns null when no
|
|
2279
|
+
* drag target is under the pointer, in which case App keeps the
|
|
2280
|
+
* baseline selection/click path untouched.
|
|
2281
|
+
*/
|
|
2282
|
+
findDragTargetAt(col, row) {
|
|
2283
|
+
// No probe: this runs AT PRESS TIME, inside the gesture window — a
|
|
2284
|
+
// probe here writes the blind ENABLE_MOUSE_TRACKING re-assert + DECRQM
|
|
2285
|
+
// query while the user is holding the button, and some emulators
|
|
2286
|
+
// (WezTerm, xterm.js family) reset button tracking on DECSET re-assert,
|
|
2287
|
+
// killing the drag's motion stream mid-gesture (field-confirmed: drags
|
|
2288
|
+
// intermittently produced zero motion events). Recovery lives at the
|
|
2289
|
+
// safe boundaries (see dispatchClick).
|
|
2290
|
+
if (!this.altScreenActive)
|
|
2291
|
+
return null;
|
|
2292
|
+
const target = findDragTarget(this.rootNode, col, row);
|
|
2293
|
+
logMouseDebug('findDragTargetAt', { col, row, found: Boolean(target) });
|
|
2294
|
+
return target;
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Dispatch a drag event to the drag session target captured at press
|
|
2298
|
+
* time (bubbles through its ancestors). Gated on altScreenActive like
|
|
2299
|
+
* dispatchClick.
|
|
2300
|
+
*/
|
|
2301
|
+
dispatchDrag(target, event) {
|
|
2302
|
+
// No probe: dragmove IS mid-gesture by definition (gesture latched) —
|
|
2303
|
+
// a re-assert write here kills the very motion stream that feeds it
|
|
2304
|
+
// (see dispatchClick for the safe-boundary probes).
|
|
2305
|
+
if (!this.altScreenActive)
|
|
2306
|
+
return;
|
|
2307
|
+
logMouseDebug('dispatchDrag', { type: event.type, col: event.col, row: event.row });
|
|
2308
|
+
bubbleDragEvent(target, event);
|
|
2309
|
+
}
|
|
2310
|
+
dispatchKeyboardEvent(parsedKey) {
|
|
2311
|
+
this.probeAltScreenHealth();
|
|
2312
|
+
const target = this.focusManager.activeElement ?? this.rootNode;
|
|
2313
|
+
const event = new KeyboardEvent(parsedKey);
|
|
2314
|
+
dispatcher.dispatchDiscrete(target, event);
|
|
2315
|
+
// Tab cycling is the default action — only fires if no handler
|
|
2316
|
+
// called preventDefault(). Mirrors browser behavior.
|
|
2317
|
+
if (!event.defaultPrevented && parsedKey.name === 'tab' && !parsedKey.ctrl && !parsedKey.meta) {
|
|
2318
|
+
if (parsedKey.shift) {
|
|
2319
|
+
this.focusManager.focusPrevious(this.rootNode);
|
|
2320
|
+
}
|
|
2321
|
+
else {
|
|
2322
|
+
this.focusManager.focusNext(this.rootNode);
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
/**
|
|
2327
|
+
* Look up the URL at (col, row) in the current front frame. Checks for
|
|
2328
|
+
* an OSC 8 hyperlink first, then falls back to scanning the row for a
|
|
2329
|
+
* plain-text URL (mouse tracking intercepts the terminal's native
|
|
2330
|
+
* Cmd+Click URL detection, so we replicate it). This is a pure lookup
|
|
2331
|
+
* with no side effects — call it synchronously at click time so the
|
|
2332
|
+
* result reflects the screen the user actually clicked on, then defer
|
|
2333
|
+
* the browser-open action via a timer.
|
|
2334
|
+
*/
|
|
2335
|
+
getHyperlinkAt(col, row) {
|
|
2336
|
+
if (!this.altScreenActive)
|
|
2337
|
+
return undefined;
|
|
2338
|
+
const screen = this.frontFrame.screen;
|
|
2339
|
+
const cell = cellAt(screen, col, row);
|
|
2340
|
+
let url = cell?.hyperlink;
|
|
2341
|
+
// SpacerTail cells (right half of wide/CJK/emoji chars) store the
|
|
2342
|
+
// hyperlink on the head cell at col-1.
|
|
2343
|
+
if (!url && cell?.width === 2 /* CellWidth.SpacerTail */ && col > 0) {
|
|
2344
|
+
url = cellAt(screen, col - 1, row)?.hyperlink;
|
|
2345
|
+
}
|
|
2346
|
+
return url ?? findPlainTextUrlAt(screen, col, row);
|
|
2347
|
+
}
|
|
2348
|
+
/**
|
|
2349
|
+
* Optional callback fired when clicking an OSC 8 hyperlink in fullscreen
|
|
2350
|
+
* mode. Set by FullscreenLayout via useLayoutEffect.
|
|
2351
|
+
*/
|
|
2352
|
+
onHyperlinkClick;
|
|
2353
|
+
/**
|
|
2354
|
+
* Stable prototype wrapper for onHyperlinkClick. Passed to <App> as
|
|
2355
|
+
* onOpenHyperlink so the prop is a bound method (autoBind'd) that reads
|
|
2356
|
+
* the mutable field at call time — not the undefined-at-render value.
|
|
2357
|
+
*/
|
|
2358
|
+
openHyperlink(url) {
|
|
2359
|
+
this.onHyperlinkClick?.(url);
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* Handle a double- or triple-click at (col, row): select the word or
|
|
2363
|
+
* line under the cursor by reading the current screen buffer. Called on
|
|
2364
|
+
* PRESS (not release) so the highlight appears immediately and drag can
|
|
2365
|
+
* extend the selection word-by-word / line-by-line. Falls back to
|
|
2366
|
+
* char-mode startSelection if the click lands on a noSelect cell.
|
|
2367
|
+
*/
|
|
2368
|
+
handleMultiClick(col, row, count) {
|
|
2369
|
+
if (!this.altScreenActive)
|
|
2370
|
+
return;
|
|
2371
|
+
const screen = this.frontFrame.screen;
|
|
2372
|
+
// selectWordAt/selectLineAt no-op on noSelect/out-of-bounds. Seed with
|
|
2373
|
+
// a char-mode selection so the press still starts a drag even if the
|
|
2374
|
+
// word/line scan finds nothing selectable.
|
|
2375
|
+
startSelection(this.selection, col, row);
|
|
2376
|
+
if (count === 2)
|
|
2377
|
+
selectWordAt(this.selection, screen, col, row);
|
|
2378
|
+
else
|
|
2379
|
+
selectLineAt(this.selection, screen, row);
|
|
2380
|
+
// Ensure hasSelection is true so release doesn't re-dispatch onClickAt.
|
|
2381
|
+
// selectWordAt no-ops on noSelect; selectLineAt no-ops out-of-bounds.
|
|
2382
|
+
if (!this.selection.focus)
|
|
2383
|
+
this.selection.focus = this.selection.anchor;
|
|
2384
|
+
this.notifySelectionChange();
|
|
2385
|
+
}
|
|
2386
|
+
/**
|
|
2387
|
+
* Handle a drag-motion at (col, row). In char mode updates focus to the
|
|
2388
|
+
* exact cell. In word/line mode snaps to word/line boundaries so the
|
|
2389
|
+
* selection extends by word/line like native macOS. Gated on
|
|
2390
|
+
* altScreenActive for the same reason as dispatchClick.
|
|
2391
|
+
*/
|
|
2392
|
+
handleSelectionDrag(col, row) {
|
|
2393
|
+
if (!this.altScreenActive)
|
|
2394
|
+
return;
|
|
2395
|
+
const sel = this.selection;
|
|
2396
|
+
if (sel.anchorSpan) {
|
|
2397
|
+
extendSelection(sel, this.frontFrame.screen, col, row);
|
|
2398
|
+
}
|
|
2399
|
+
else {
|
|
2400
|
+
updateSelection(sel, col, row);
|
|
2401
|
+
}
|
|
2402
|
+
this.notifySelectionChange();
|
|
2403
|
+
}
|
|
2404
|
+
// Methods to properly suspend stdin for external editor usage
|
|
2405
|
+
// This is needed to prevent Ink from swallowing keystrokes when an external editor is active
|
|
2406
|
+
stdinListeners = [];
|
|
2407
|
+
wasRawMode = false;
|
|
2408
|
+
suspendStdin() {
|
|
2409
|
+
const stdin = this.options.stdin;
|
|
2410
|
+
if (!stdin.isTTY) {
|
|
2411
|
+
return;
|
|
2412
|
+
}
|
|
2413
|
+
// Store and remove all 'readable' event listeners temporarily
|
|
2414
|
+
// This prevents Ink from consuming stdin while the editor is active
|
|
2415
|
+
const readableListeners = stdin.listeners('readable');
|
|
2416
|
+
logForDebugging(`[stdin] suspendStdin: removing ${readableListeners.length} readable listener(s), wasRawMode=${stdin.isRaw ?? false}`);
|
|
2417
|
+
readableListeners.forEach(listener => {
|
|
2418
|
+
this.stdinListeners.push({
|
|
2419
|
+
event: 'readable',
|
|
2420
|
+
listener: listener
|
|
2421
|
+
});
|
|
2422
|
+
stdin.removeListener('readable', listener);
|
|
2423
|
+
});
|
|
2424
|
+
// If raw mode is enabled, disable it temporarily
|
|
2425
|
+
const stdinWithRaw = stdin;
|
|
2426
|
+
if (stdinWithRaw.isRaw && stdinWithRaw.setRawMode) {
|
|
2427
|
+
stdinWithRaw.setRawMode(false);
|
|
2428
|
+
this.wasRawMode = true;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
resumeStdin() {
|
|
2432
|
+
const stdin = this.options.stdin;
|
|
2433
|
+
if (!stdin.isTTY) {
|
|
2434
|
+
return;
|
|
2435
|
+
}
|
|
2436
|
+
// Re-attach all the stored listeners
|
|
2437
|
+
if (this.stdinListeners.length === 0 && !this.wasRawMode) {
|
|
2438
|
+
logForDebugging('[stdin] resumeStdin: called with no stored listeners and wasRawMode=false (possible desync)', {
|
|
2439
|
+
level: 'warn'
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
// Raw mode FIRST: the editor restored the tty to canonical mode on
|
|
2443
|
+
// exit, so keystrokes typed during the handoff window are sitting in
|
|
2444
|
+
// the kernel line buffer; setRawMode(true) makes them readable.
|
|
2445
|
+
if (this.wasRawMode) {
|
|
2446
|
+
const stdinWithRaw = stdin;
|
|
2447
|
+
if (stdinWithRaw.setRawMode) {
|
|
2448
|
+
stdinWithRaw.setRawMode(true);
|
|
2449
|
+
}
|
|
2450
|
+
this.wasRawMode = false;
|
|
2451
|
+
}
|
|
2452
|
+
// Drain every already-buffered byte BEFORE the listeners come back:
|
|
2453
|
+
// line-buffer leftovers, editor exit-sequence replies (CPR/DECRPM),
|
|
2454
|
+
// mouse-event fragments. Parsed as input they are destructive — a
|
|
2455
|
+
// stray ESC clears a non-empty prompt, the rest lands as text garbage
|
|
2456
|
+
// (issue #123 field report). Bytes arriving LATE (async terminal
|
|
2457
|
+
// replies) are covered by the suppression window in
|
|
2458
|
+
// exitAlternateScreen.
|
|
2459
|
+
let chunk;
|
|
2460
|
+
while ((chunk = stdin.read()) !== null) {
|
|
2461
|
+
void chunk;
|
|
2462
|
+
}
|
|
2463
|
+
logForDebugging(`[stdin] resumeStdin: re-attaching ${this.stdinListeners.length} listener(s)`);
|
|
2464
|
+
this.stdinListeners.forEach(({ event, listener }) => {
|
|
2465
|
+
stdin.addListener(event, listener);
|
|
2466
|
+
});
|
|
2467
|
+
this.stdinListeners = [];
|
|
2468
|
+
}
|
|
2469
|
+
// Stable identity for TerminalWriteContext. An inline arrow here would
|
|
2470
|
+
// change on every render() call (initial mount + each resize), which
|
|
2471
|
+
// cascades through useContext → <AlternateScreen>'s useLayoutEffect dep
|
|
2472
|
+
// array → spurious exit+re-enter of the alt screen on every SIGWINCH.
|
|
2473
|
+
writeRaw(data) {
|
|
2474
|
+
if (data.includes('\x1b[?1049')) {
|
|
2475
|
+
logMouseDebug('stdout:1049', { len: data.length, head: data.slice(0, 60) });
|
|
2476
|
+
}
|
|
2477
|
+
this.options.stdout.write(data);
|
|
2478
|
+
}
|
|
2479
|
+
setCursorDeclaration = (decl, clearIfNode) => {
|
|
2480
|
+
if (decl === null && clearIfNode !== undefined && this.cursorDeclaration?.node !== clearIfNode) {
|
|
2481
|
+
return;
|
|
2482
|
+
}
|
|
2483
|
+
this.cursorDeclaration = decl;
|
|
2484
|
+
};
|
|
2485
|
+
setAppRef(app) {
|
|
2486
|
+
this.app = app;
|
|
2487
|
+
}
|
|
2488
|
+
render(node) {
|
|
2489
|
+
this.currentNode = node;
|
|
2490
|
+
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, onContextMenuAt: this.dispatchContextMenu, onHoverAt: this.dispatchHover, onWheelAt: this.dispatchWheelAt, getHyperlinkAt: this.getHyperlinkAt, onOpenHyperlink: this.openHyperlink, onMultiClick: this.handleMultiClick, onSelectionDrag: this.handleSelectionDrag, onDragTargetAt: this.findDragTargetAt, onDragDispatch: this.dispatchDrag, onPointerGestureChange: this.setPointerGestureActive, onProtocolCandidateChange: this.setProtocolCandidateActive, onReleaseTail: this.drainReleaseTail, onClickProbe: this.clickProbeAtBatchTail, onStdinResume: this.reassertTerminalModes, onTerminalFocus: this.handleTerminalFocusProbe, onCursorDeclaration: this.setCursorDeclaration, dispatchKeyboardEvent: this.dispatchKeyboardEvent, children: _jsx(TerminalWriteProvider, { value: this.writeRaw, children: _jsx(TerminalImagesContext.Provider, { value: this.terminalImages, children: node }) }) });
|
|
2491
|
+
// @ts-ignore -- runtime/type-definition mismatch: updateContainerSync exists in react-reconciler but not in @types/react-reconciler
|
|
2492
|
+
reconciler.updateContainerSync(tree, this.container, null, noop);
|
|
2493
|
+
// @ts-ignore -- runtime/type-definition mismatch: flushSyncWork exists in react-reconciler but not in @types/react-reconciler
|
|
2494
|
+
reconciler.flushSyncWork();
|
|
2495
|
+
}
|
|
2496
|
+
unmount(error) {
|
|
2497
|
+
if (this.isUnmounted) {
|
|
2498
|
+
return;
|
|
2499
|
+
}
|
|
2500
|
+
// The final frame render is best-effort: a mid-state React commit can
|
|
2501
|
+
// throw (agent still working at the exact exit moment). It must NOT
|
|
2502
|
+
// skip the synchronous cleanup block below — a skipped DISABLE_*
|
|
2503
|
+
// leaves mouse reporting on past process exit, and the shell echoes
|
|
2504
|
+
// SGR garbage for every click/drag/wheel (issue #522).
|
|
2505
|
+
try {
|
|
2506
|
+
this.renderNow();
|
|
2507
|
+
}
|
|
2508
|
+
catch (renderError) {
|
|
2509
|
+
logError(renderError instanceof Error ? renderError : new Error(String(renderError)));
|
|
2510
|
+
}
|
|
2511
|
+
this.unsubscribeExit();
|
|
2512
|
+
if (typeof this.restoreConsole === 'function') {
|
|
2513
|
+
this.restoreConsole();
|
|
2514
|
+
}
|
|
2515
|
+
this.restoreStderr?.();
|
|
2516
|
+
this.unsubscribeTTYHandlers?.();
|
|
2517
|
+
// Non-TTY environments don't handle erasing ansi escapes well, so it's better to
|
|
2518
|
+
// only render last frame of non-static output
|
|
2519
|
+
const diff = this.log.renderPreviousOutput_DEPRECATED(this.frontFrame);
|
|
2520
|
+
const lastFrame = serializeDiff(this.terminal, optimize(diff));
|
|
2521
|
+
const sixelCleanup = this.sixelGraphicsManager.dispose();
|
|
2522
|
+
// Clean up terminal modes synchronously before process exit.
|
|
2523
|
+
// React's componentWillUnmount won't run in time when process.exit() is called,
|
|
2524
|
+
// so we must reset terminal modes here to prevent escape sequence leakage.
|
|
2525
|
+
// Use writeSync to the stdout stream's own fd (not a hard-coded 1 — a
|
|
2526
|
+
// host that runs the TUI on a non-1 TTY would drop every sequence while
|
|
2527
|
+
// the enable writes still reach the TTY, issue #522) to ensure writes
|
|
2528
|
+
// complete before exit. We unconditionally send all disable sequences
|
|
2529
|
+
// because terminal detection may not work correctly (e.g., in tmux,
|
|
2530
|
+
// screen) and these are no-ops on terminals that don't support them.
|
|
2531
|
+
/* eslint-disable custom-rules/no-sync-fs -- process exiting; async writes would be dropped */
|
|
2532
|
+
if (this.options.stdout.isTTY) {
|
|
2533
|
+
// Node's TTY WriteStream exposes .fd; the NodeJS.WriteStream interface
|
|
2534
|
+
// doesn't declare it, hence the local intersection cast.
|
|
2535
|
+
const stdoutWithFd = this.options.stdout;
|
|
2536
|
+
const stdoutFd = typeof stdoutWithFd.fd === 'number' ? stdoutWithFd.fd : 1;
|
|
2537
|
+
// The last frame must land on the ALT screen while it is still up:
|
|
2538
|
+
// writing it through the async stream would race the synchronous
|
|
2539
|
+
// EXIT_ALT_SCREEN below and the frame bytes would arrive AFTER the
|
|
2540
|
+
// switch to the main screen, painting misplaced residue over the
|
|
2541
|
+
// shell (issue #522).
|
|
2542
|
+
if (lastFrame !== '') {
|
|
2543
|
+
writeSync(stdoutFd, lastFrame);
|
|
2544
|
+
}
|
|
2545
|
+
const deleteImages = this.kittyGraphicsManager.deleteAll() + sixelCleanup;
|
|
2546
|
+
if (deleteImages !== '') {
|
|
2547
|
+
writeSync(stdoutFd, deleteImages);
|
|
2548
|
+
}
|
|
2549
|
+
if (this.altScreenActive) {
|
|
2550
|
+
// <AlternateScreen>'s unmount effect won't run during signal-exit.
|
|
2551
|
+
// Exit alt screen FIRST so other cleanup sequences go to the main screen.
|
|
2552
|
+
writeSync(stdoutFd, EXIT_ALT_SCREEN);
|
|
2553
|
+
}
|
|
2554
|
+
// Disable mouse tracking — unconditional because altScreenActive can be
|
|
2555
|
+
// stale if AlternateScreen's unmount (which flips the flag) raced a
|
|
2556
|
+
// blocked event loop + SIGINT. No-op if tracking was never enabled.
|
|
2557
|
+
writeSync(stdoutFd, DISABLE_MOUSE_TRACKING);
|
|
2558
|
+
// Drain stdin so in-flight mouse events don't leak to the shell
|
|
2559
|
+
this.drainStdin();
|
|
2560
|
+
// Disable extended key reporting (both kitty and modifyOtherKeys)
|
|
2561
|
+
writeSync(stdoutFd, DISABLE_MODIFY_OTHER_KEYS);
|
|
2562
|
+
writeSync(stdoutFd, DISABLE_KITTY_KEYBOARD);
|
|
2563
|
+
// Disable win32-input-mode (no-op where never enabled)
|
|
2564
|
+
writeSync(stdoutFd, DISABLE_WIN32_INPUT_MODE);
|
|
2565
|
+
// Disable focus events (DECSET 1004)
|
|
2566
|
+
writeSync(stdoutFd, DFE);
|
|
2567
|
+
// Disable bracketed paste mode
|
|
2568
|
+
writeSync(stdoutFd, DBP);
|
|
2569
|
+
// Show cursor
|
|
2570
|
+
writeSync(stdoutFd, SHOW_CURSOR);
|
|
2571
|
+
// Clear iTerm2 progress bar
|
|
2572
|
+
writeSync(stdoutFd, CLEAR_ITERM2_PROGRESS);
|
|
2573
|
+
// Clear tab status (OSC 21337) so a stale dot doesn't linger
|
|
2574
|
+
if (supportsTabStatus())
|
|
2575
|
+
writeSync(stdoutFd, wrapForMultiplexer(CLEAR_TAB_STATUS));
|
|
2576
|
+
}
|
|
2577
|
+
/* eslint-enable custom-rules/no-sync-fs */
|
|
2578
|
+
this.isUnmounted = true;
|
|
2579
|
+
this.terminalImageListeners.clear();
|
|
2580
|
+
// Cancel any pending throttled renders to prevent accessing freed Yoga nodes
|
|
2581
|
+
this.scheduleRender.cancel?.();
|
|
2582
|
+
if (this.drainTimer !== null) {
|
|
2583
|
+
clearTimeout(this.drainTimer);
|
|
2584
|
+
this.drainTimer = null;
|
|
2585
|
+
}
|
|
2586
|
+
if (this.terminalQueryResumeTimer !== null) {
|
|
2587
|
+
clearTimeout(this.terminalQueryResumeTimer);
|
|
2588
|
+
this.terminalQueryResumeTimer = null;
|
|
2589
|
+
}
|
|
2590
|
+
// @ts-ignore -- runtime/type-definition mismatch: updateContainerSync exists in react-reconciler but not in @types/react-reconciler
|
|
2591
|
+
reconciler.updateContainerSync(null, this.container, null, noop);
|
|
2592
|
+
// @ts-ignore -- runtime/type-definition mismatch: flushSyncWork exists in react-reconciler but not in @types/react-reconciler
|
|
2593
|
+
reconciler.flushSyncWork();
|
|
2594
|
+
instances.delete(this.options.stdout);
|
|
2595
|
+
// Free the root yoga node, then clear its reference. Children are already
|
|
2596
|
+
// freed by the reconciler's removeChildFromContainer; using .free() (not
|
|
2597
|
+
// .freeRecursive()) avoids double-freeing them.
|
|
2598
|
+
this.rootNode.yogaNode?.free();
|
|
2599
|
+
this.rootNode.yogaNode = undefined;
|
|
2600
|
+
if (error instanceof Error) {
|
|
2601
|
+
this.rejectExitPromise(error);
|
|
2602
|
+
}
|
|
2603
|
+
else {
|
|
2604
|
+
this.resolveExitPromise();
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
async waitUntilExit() {
|
|
2608
|
+
this.exitPromise ||= new Promise((resolve, reject) => {
|
|
2609
|
+
this.resolveExitPromise = resolve;
|
|
2610
|
+
this.rejectExitPromise = reject;
|
|
2611
|
+
});
|
|
2612
|
+
return this.exitPromise;
|
|
2613
|
+
}
|
|
2614
|
+
resetLineCount() {
|
|
2615
|
+
if (this.options.stdout.isTTY) {
|
|
2616
|
+
// Swap so old front becomes back (for screen reuse), then reset front
|
|
2617
|
+
this.backFrame = this.frontFrame;
|
|
2618
|
+
this.frontFrame = emptyFrame(this.frontFrame.viewport.height, this.frontFrame.viewport.width, this.stylePool, this.charPool, this.hyperlinkPool);
|
|
2619
|
+
this.log.reset();
|
|
2620
|
+
// frontFrame is reset, so frame.cursor on the next render is (0,0).
|
|
2621
|
+
// Clear displayCursor so the preamble doesn't compute a stale delta.
|
|
2622
|
+
this.displayCursor = null;
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
/**
|
|
2626
|
+
* Replace char/hyperlink pools with fresh instances to prevent unbounded
|
|
2627
|
+
* growth during long sessions. Migrates the front frame's screen IDs into
|
|
2628
|
+
* the new pools so diffing remains correct. The back frame doesn't need
|
|
2629
|
+
* migration — resetScreen zeros it before any reads.
|
|
2630
|
+
*
|
|
2631
|
+
* Call between conversation turns or periodically.
|
|
2632
|
+
*/
|
|
2633
|
+
resetPools() {
|
|
2634
|
+
this.charPool = new CharPool();
|
|
2635
|
+
this.hyperlinkPool = new HyperlinkPool();
|
|
2636
|
+
migrateScreenPools(this.frontFrame.screen, this.charPool, this.hyperlinkPool);
|
|
2637
|
+
// Back frame's data is zeroed by resetScreen before reads, but its pool
|
|
2638
|
+
// references are used by the renderer to intern new characters. Point
|
|
2639
|
+
// them at the new pools so the next frame's IDs are comparable.
|
|
2640
|
+
this.backFrame.screen.charPool = this.charPool;
|
|
2641
|
+
this.backFrame.screen.hyperlinkPool = this.hyperlinkPool;
|
|
2642
|
+
if (this.mainScreenFrameState) {
|
|
2643
|
+
migrateScreenPools(this.mainScreenFrameState.frontFrame.screen, this.charPool, this.hyperlinkPool);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
patchConsole() {
|
|
2647
|
+
// biome-ignore lint/suspicious/noConsole: intentionally patching global console
|
|
2648
|
+
const con = console;
|
|
2649
|
+
const originals = {};
|
|
2650
|
+
const toDebug = (...args) => logForDebugging(`console.log: ${format(...args)}`);
|
|
2651
|
+
const toError = (...args) => logError(new Error(`console.error: ${format(...args)}`));
|
|
2652
|
+
for (const m of CONSOLE_STDOUT_METHODS) {
|
|
2653
|
+
originals[m] = con[m];
|
|
2654
|
+
con[m] = toDebug;
|
|
2655
|
+
}
|
|
2656
|
+
for (const m of CONSOLE_STDERR_METHODS) {
|
|
2657
|
+
originals[m] = con[m];
|
|
2658
|
+
con[m] = toError;
|
|
2659
|
+
}
|
|
2660
|
+
originals.assert = con.assert;
|
|
2661
|
+
con.assert = (condition, ...args) => {
|
|
2662
|
+
if (!condition)
|
|
2663
|
+
toError(...args);
|
|
2664
|
+
};
|
|
2665
|
+
return () => Object.assign(con, originals);
|
|
2666
|
+
}
|
|
2667
|
+
/**
|
|
2668
|
+
* Intercept process.stderr.write so stray writes (config.ts, hooks.ts,
|
|
2669
|
+
* third-party deps) don't corrupt the alt-screen buffer. patchConsole only
|
|
2670
|
+
* hooks console.* methods — direct stderr writes bypass it, land at the
|
|
2671
|
+
* parked cursor, scroll the alt-screen, and desync frontFrame from the
|
|
2672
|
+
* physical terminal. Next diff writes only changed-in-React cells at
|
|
2673
|
+
* absolute coords → interleaved garbage.
|
|
2674
|
+
*
|
|
2675
|
+
* Swallows the write (routes text to the debug log) and, in alt-screen,
|
|
2676
|
+
* forces a full-damage repaint as a defensive recovery. Not patching
|
|
2677
|
+
* process.stdout — Ink itself writes there.
|
|
2678
|
+
*/
|
|
2679
|
+
patchStderr() {
|
|
2680
|
+
const stderr = process.stderr;
|
|
2681
|
+
const originalWrite = stderr.write;
|
|
2682
|
+
let reentered = false;
|
|
2683
|
+
const intercept = (chunk, encodingOrCb, cb) => {
|
|
2684
|
+
const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
|
|
2685
|
+
// Reentrancy guard: logForDebugging → writeToStderr → here. Pass
|
|
2686
|
+
// through to the original so --debug-to-stderr still works and we
|
|
2687
|
+
// don't stack-overflow.
|
|
2688
|
+
if (reentered) {
|
|
2689
|
+
const encoding = typeof encodingOrCb === 'string' ? encodingOrCb : undefined;
|
|
2690
|
+
return originalWrite.call(stderr, chunk, encoding, callback);
|
|
2691
|
+
}
|
|
2692
|
+
reentered = true;
|
|
2693
|
+
try {
|
|
2694
|
+
const text = typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString('utf8');
|
|
2695
|
+
logForDebugging(`[stderr] ${text}`, {
|
|
2696
|
+
level: 'warn'
|
|
2697
|
+
});
|
|
2698
|
+
if (!this.isUnmounted && !this.isPaused) {
|
|
2699
|
+
if (this.altScreenActive) {
|
|
2700
|
+
this.prevFrameContaminated = true;
|
|
2701
|
+
this.scheduleRender();
|
|
2702
|
+
}
|
|
2703
|
+
else {
|
|
2704
|
+
// Main-screen (inline): the diff engine's moves are purely
|
|
2705
|
+
// relative to the physical cursor, so ANY unobserved tty write
|
|
2706
|
+
// (one that slipped through before this patch existed, or via
|
|
2707
|
+
// a path it can't intercept — a snapshotted ESM writer) shifts
|
|
2708
|
+
// every later write by N rows with nothing to detect it after
|
|
2709
|
+
// the fact. The stdin-gap reassert covers slow leaks; this
|
|
2710
|
+
// per-write defensive net closes the fast ones: blind
|
|
2711
|
+
// idempotent viewport repaint from the physical cursor. When
|
|
2712
|
+
// nothing drifted (the usual case — the write was swallowed)
|
|
2713
|
+
// it paints the same pixels again at O(viewport) bytes.
|
|
2714
|
+
this.log.requestViewportReanchor();
|
|
2715
|
+
this.scheduleRender();
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
finally {
|
|
2720
|
+
reentered = false;
|
|
2721
|
+
callback?.();
|
|
2722
|
+
}
|
|
2723
|
+
return true;
|
|
2724
|
+
};
|
|
2725
|
+
stderr.write = intercept;
|
|
2726
|
+
return () => {
|
|
2727
|
+
if (stderr.write === intercept) {
|
|
2728
|
+
stderr.write = originalWrite;
|
|
2729
|
+
}
|
|
2730
|
+
};
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
/**
|
|
2734
|
+
* Discard pending stdin bytes so in-flight escape sequences (mouse tracking
|
|
2735
|
+
* reports, bracketed-paste markers) don't leak to the shell after exit.
|
|
2736
|
+
*
|
|
2737
|
+
* Two layers of trickiness:
|
|
2738
|
+
*
|
|
2739
|
+
* 1. setRawMode is termios, not fcntl — the stdin fd stays blocking, so
|
|
2740
|
+
* readSync on it would hang forever. Node doesn't expose fcntl, so we
|
|
2741
|
+
* open /dev/tty fresh with O_NONBLOCK (all fds to the controlling
|
|
2742
|
+
* terminal share one line-discipline input queue).
|
|
2743
|
+
*
|
|
2744
|
+
* 2. By the time forceExit calls this, detachForShutdown has already put
|
|
2745
|
+
* the TTY back in cooked (canonical) mode. Canonical mode line-buffers
|
|
2746
|
+
* input until newline, so O_NONBLOCK reads return EAGAIN even when
|
|
2747
|
+
* mouse bytes are sitting in the buffer. We briefly re-enter raw mode
|
|
2748
|
+
* so reads return any available bytes, then restore cooked mode.
|
|
2749
|
+
*
|
|
2750
|
+
* Safe to call multiple times. Call as LATE as possible in the exit path:
|
|
2751
|
+
* DISABLE_MOUSE_TRACKING has terminal round-trip latency, so events can
|
|
2752
|
+
* arrive for a few ms after it's written.
|
|
2753
|
+
*/
|
|
2754
|
+
/* eslint-disable custom-rules/no-sync-fs -- must be sync; called from signal handler / unmount */
|
|
2755
|
+
export function drainStdin(stdin = process.stdin) {
|
|
2756
|
+
if (!stdin.isTTY)
|
|
2757
|
+
return;
|
|
2758
|
+
// Drain Node's stream buffer (bytes libuv already pulled in). read()
|
|
2759
|
+
// returns null when empty — never blocks.
|
|
2760
|
+
try {
|
|
2761
|
+
while (stdin.read() !== null) {
|
|
2762
|
+
/* discard */
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
catch {
|
|
2766
|
+
/* stream may be destroyed */
|
|
2767
|
+
}
|
|
2768
|
+
// No /dev/tty on Windows; CONIN$ doesn't support O_NONBLOCK semantics.
|
|
2769
|
+
// Windows Terminal also doesn't buffer mouse reports the same way.
|
|
2770
|
+
if (process.platform === 'win32')
|
|
2771
|
+
return;
|
|
2772
|
+
// termios is per-device: flip stdin to raw so canonical-mode line
|
|
2773
|
+
// buffering doesn't hide partial input from the non-blocking read.
|
|
2774
|
+
// Restored in the finally block.
|
|
2775
|
+
const tty = stdin;
|
|
2776
|
+
const wasRaw = tty.isRaw === true;
|
|
2777
|
+
// Drain the kernel TTY buffer via a fresh O_NONBLOCK fd. Bounded at 64
|
|
2778
|
+
// reads (64KB) — a real mouse burst is a few hundred bytes; the cap
|
|
2779
|
+
// guards against a terminal that ignores O_NONBLOCK.
|
|
2780
|
+
let fd = -1;
|
|
2781
|
+
try {
|
|
2782
|
+
// setRawMode inside try: on revoked TTY (SIGHUP/SSH disconnect) the
|
|
2783
|
+
// ioctl throws EBADF — same recovery path as openSync/readSync below.
|
|
2784
|
+
if (!wasRaw)
|
|
2785
|
+
tty.setRawMode?.(true);
|
|
2786
|
+
fd = openSync('/dev/tty', fsConstants.O_RDONLY | fsConstants.O_NONBLOCK);
|
|
2787
|
+
const buf = Buffer.alloc(1024);
|
|
2788
|
+
for (let i = 0; i < 64; i++) {
|
|
2789
|
+
if (readSync(fd, buf, 0, buf.length, null) <= 0)
|
|
2790
|
+
break;
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
catch {
|
|
2794
|
+
// EAGAIN (buffer empty — expected), ENXIO/ENOENT (no controlling tty),
|
|
2795
|
+
// EBADF/EIO (TTY revoked — SIGHUP, SSH disconnect)
|
|
2796
|
+
}
|
|
2797
|
+
finally {
|
|
2798
|
+
if (fd >= 0) {
|
|
2799
|
+
try {
|
|
2800
|
+
closeSync(fd);
|
|
2801
|
+
}
|
|
2802
|
+
catch {
|
|
2803
|
+
/* ignore */
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
if (!wasRaw) {
|
|
2807
|
+
try {
|
|
2808
|
+
tty.setRawMode?.(false);
|
|
2809
|
+
}
|
|
2810
|
+
catch {
|
|
2811
|
+
/* TTY may be gone */
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
/* eslint-enable custom-rules/no-sync-fs */
|
|
2817
|
+
const CONSOLE_STDOUT_METHODS = ['log', 'info', 'debug', 'dir', 'dirxml', 'count', 'countReset', 'group', 'groupCollapsed', 'groupEnd', 'table', 'time', 'timeEnd', 'timeLog'];
|
|
2818
|
+
const CONSOLE_STDERR_METHODS = ['warn', 'error', 'trace'];
|