@timurproko/a1 0.2.6 → 0.2.7-dev.1222
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -3
- package/bin/automatic-update.js +7 -0
- package/bin/cli.js +4 -0
- package/bin/guardian.js +5 -0
- package/bin/tab-launch-context.d.ts +27 -0
- package/bin/tab-launch-context.js +94 -0
- package/bin/ui.js +107 -59
- package/dist/app/session-shell/clipboard-diagnostics.js +1 -1
- package/dist/app/session-shell/dialog-coordinator.d.ts +42 -0
- package/dist/app/session-shell/dialog-coordinator.js +133 -0
- package/dist/app/session-shell/dock-chrome.d.ts +34 -0
- package/dist/app/session-shell/dock-chrome.js +109 -0
- package/dist/app/session-shell/exit-notice.d.ts +1 -1
- package/dist/app/session-shell/exit-notice.js +1 -1
- package/dist/app/session-shell/extension-surface.d.ts +30 -0
- package/dist/app/session-shell/extension-surface.js +105 -0
- package/dist/app/session-shell/helper-pool.d.ts +3 -5
- package/dist/app/session-shell/helper-pool.js +3 -5
- package/dist/app/session-shell/input-surface-switch.d.ts +36 -0
- package/dist/app/session-shell/input-surface-switch.js +85 -0
- package/dist/app/session-shell/login-interaction.d.ts +27 -0
- package/dist/app/session-shell/login-interaction.js +91 -0
- package/dist/app/session-shell/prompt-submission.d.ts +48 -0
- package/dist/app/session-shell/prompt-submission.js +276 -0
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +38 -0
- package/dist/app/session-shell/resident-tab-coordinator.js +77 -0
- package/dist/app/session-shell/response-copy-helper.js +21 -6
- package/dist/app/session-shell/response-copy-protocol.d.ts +1 -1
- package/dist/app/session-shell/response-copy-transport.d.ts +16 -6
- package/dist/app/session-shell/response-copy-transport.js +69 -17
- package/dist/app/session-shell/session-concern.d.ts +22 -0
- package/dist/app/session-shell/session-concern.js +29 -0
- package/dist/app/session-shell/session-lifecycle.d.ts +29 -0
- package/dist/app/session-shell/session-lifecycle.js +49 -0
- package/dist/app/session-shell/session-shell-root.d.ts +42 -6
- package/dist/app/session-shell/session-shell-root.js +197 -908
- package/dist/app/session-shell/session-shell.d.ts +3 -8
- package/dist/app/session-shell/session-shell.js +327 -835
- package/dist/app/session-shell/session-viewport-controller.d.ts +2 -1
- package/dist/app/session-shell/session-viewport-controller.js +41 -38
- package/dist/app/session-shell/settings-bindings.d.ts +17 -0
- package/dist/app/session-shell/settings-bindings.js +91 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +27 -0
- package/dist/app/session-shell/shell-editor-factory.js +105 -0
- package/dist/app/session-shell/shell-host.d.ts +6 -0
- package/dist/app/session-shell/shell-host.js +34 -7
- package/dist/app/session-shell/shell-layout.d.ts +64 -0
- package/dist/app/session-shell/shell-layout.js +18 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +25 -0
- package/dist/app/session-shell/suggestion-surface.js +63 -0
- package/dist/app/session-shell/transcript-document.d.ts +78 -0
- package/dist/app/session-shell/transcript-document.js +365 -0
- package/dist/app/session-shell/viewport-layout.d.ts +31 -0
- package/dist/app/session-shell/viewport-layout.js +160 -0
- package/dist/app/session-shell/workflow-output.d.ts +33 -0
- package/dist/app/session-shell/workflow-output.js +174 -0
- package/dist/app/session-shell/workflow-router.d.ts +25 -0
- package/dist/app/session-shell/workflow-router.js +39 -0
- package/dist/cli/dispatch.d.ts +11 -1
- package/dist/cli/dispatch.js +79 -5
- package/dist/cli/tabs-request.d.ts +7 -0
- package/dist/cli/tabs-request.js +1 -0
- package/dist/cli/tabs.d.ts +14 -0
- package/dist/cli/tabs.js +151 -0
- package/dist/cli/version-stats.js +38 -3
- package/dist/composition/owned-settings.d.ts +12 -0
- package/dist/composition/owned-settings.js +36 -0
- package/dist/composition/owned-ui.d.ts +27 -28
- package/dist/composition/owned-ui.js +207 -153
- package/dist/composition/reference-selection-options.d.ts +3 -0
- package/dist/composition/reference-selection-options.js +16 -0
- package/dist/composition/resident-tab-bridge.d.ts +25 -0
- package/dist/composition/resident-tab-bridge.js +180 -0
- package/dist/composition/session-backend.d.ts +19 -0
- package/dist/composition/session-backend.js +1 -0
- package/dist/composition/session-runtime-registry.d.ts +20 -0
- package/dist/composition/session-runtime-registry.js +85 -0
- package/dist/composition/settings-route-host.d.ts +16 -2
- package/dist/composition/settings-route-host.js +42 -17
- package/dist/composition/settings-search-input.d.ts +9 -0
- package/dist/composition/settings-search-input.js +61 -0
- package/dist/composition/startup-route.d.ts +32 -0
- package/dist/composition/startup-route.js +72 -0
- package/dist/composition/utility-tab.d.ts +28 -0
- package/dist/composition/utility-tab.js +244 -0
- package/dist/contracts/owned-ui/index.d.ts +1 -1
- package/dist/contracts/owned-ui/model.d.ts +3 -0
- package/dist/contracts/owned-ui/session-backend.d.ts +3 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +11 -4
- package/dist/contracts/presentation/index.d.ts +11 -0
- package/dist/contracts/presentation/index.js +12 -0
- package/dist/features/launch/development-launch.js +6 -0
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/intent.d.ts +3 -1
- package/dist/features/launch/intent.js +7 -4
- package/dist/features/launch/profile-paths.js +4 -0
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +22 -0
- package/dist/features/owned-ui/plus-menu-dialog.js +84 -0
- package/dist/features/owned-ui/project-trust-dialog.d.ts +1 -1
- package/dist/features/owned-ui/project-trust-dialog.js +6 -8
- package/dist/features/owned-ui/project-trust-prompt.d.ts +1 -0
- package/dist/features/owned-ui/project-trust-prompt.js +7 -3
- package/dist/features/owned-ui/reference-document-selection.d.ts +30 -0
- package/dist/features/owned-ui/reference-document-selection.js +179 -0
- package/dist/features/owned-ui/reference-screen-app.d.ts +6 -1
- package/dist/features/owned-ui/reference-screen-app.js +51 -10
- package/dist/features/owned-ui/settings-app.d.ts +13 -2
- package/dist/features/owned-ui/settings-app.js +136 -97
- package/dist/features/owned-ui/settings-search-input.d.ts +29 -0
- package/dist/features/owned-ui/settings-search-input.js +1 -0
- package/dist/features/prompt-history/index.d.ts +1 -1
- package/dist/features/prompt-history/paths.d.ts +2 -1
- package/dist/features/prompt-history/paths.js +10 -2
- package/dist/features/prompt-history/service.d.ts +5 -0
- package/dist/features/prompt-history/service.js +1 -1
- package/dist/features/resident-tab/auto-name.d.ts +11 -0
- package/dist/features/resident-tab/auto-name.js +44 -0
- package/dist/features/resident-tab/index.d.ts +5 -0
- package/dist/features/resident-tab/index.js +7 -0
- package/dist/features/resident-tab/shortcut-bindings-file.d.ts +8 -0
- package/dist/features/resident-tab/shortcut-bindings-file.js +40 -0
- package/dist/features/resident-tab/shortcut-declarations.d.ts +13 -0
- package/dist/features/resident-tab/shortcut-declarations.js +26 -0
- package/dist/features/resident-tab/shortcut-projection.d.ts +29 -0
- package/dist/features/resident-tab/shortcut-projection.js +64 -0
- package/dist/features/resident-tab/status-deriver.d.ts +10 -0
- package/dist/features/resident-tab/status-deriver.js +12 -0
- package/dist/foundation/launch-context/index.d.ts +12 -0
- package/dist/foundation/launch-context/index.js +26 -0
- package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
- package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
- package/dist/foundation/launch-guardian/main.d.ts +7 -1
- package/dist/foundation/launch-guardian/main.js +60 -7
- package/dist/foundation/lifecycle/session-repository-context.js +16 -2
- package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
- package/dist/foundation/process-containment/addon-containment.js +139 -0
- package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
- package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
- package/dist/foundation/process-containment/addon.d.ts +42 -0
- package/dist/foundation/process-containment/addon.js +57 -0
- package/dist/foundation/process-containment/artifact.d.ts +1 -1
- package/dist/foundation/process-containment/artifact.js +6 -5
- package/dist/foundation/process-containment/contracts.d.ts +2 -0
- package/dist/foundation/process-containment/index.d.ts +4 -4
- package/dist/foundation/process-containment/index.js +3 -3
- package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
- package/dist/foundation/process-containment/native-process-inspector.js +10 -10
- package/dist/foundation/release/automatic-update.d.ts +37 -0
- package/dist/foundation/release/automatic-update.js +265 -0
- package/dist/foundation/release/bootstrap.d.ts +7 -9
- package/dist/foundation/release/bootstrap.js +107 -24
- package/dist/foundation/release/cohort-state.d.ts +1 -1
- package/dist/foundation/release/cohort-state.js +1 -1
- package/dist/foundation/release/dependency-certification.js +54 -19
- package/dist/foundation/release/early-accent.d.ts +12 -0
- package/dist/foundation/release/early-accent.js +59 -0
- package/dist/foundation/release/index.d.ts +2 -2
- package/dist/foundation/release/index.js +2 -2
- package/dist/foundation/release/latest-release.d.ts +24 -2
- package/dist/foundation/release/latest-release.js +51 -1
- package/dist/foundation/release/progress-palette.generated.d.ts +137 -3
- package/dist/foundation/release/progress-palette.generated.js +137 -3
- package/dist/foundation/release/release-gc.d.ts +3 -0
- package/dist/foundation/release/release-gc.js +59 -8
- package/dist/foundation/release/release-store.d.ts +12 -0
- package/dist/foundation/release/release-store.js +124 -2
- package/dist/foundation/release/update-execution-lease.d.ts +48 -0
- package/dist/foundation/release/update-execution-lease.js +161 -0
- package/dist/foundation/release/update.d.ts +12 -7
- package/dist/foundation/release/update.js +281 -196
- package/dist/foundation/resident-tabs/bounded-host-command.d.ts +18 -0
- package/dist/foundation/resident-tabs/bounded-host-command.js +39 -0
- package/dist/foundation/resident-tabs/bridge-client.d.ts +70 -0
- package/dist/foundation/resident-tabs/bridge-client.js +321 -0
- package/dist/foundation/resident-tabs/doctor.d.ts +28 -0
- package/dist/foundation/resident-tabs/doctor.js +166 -0
- package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +27 -0
- package/dist/foundation/resident-tabs/draft-checkpoint.js +145 -0
- package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +36 -0
- package/dist/foundation/resident-tabs/ensure-terminal-host.js +151 -0
- package/dist/foundation/resident-tabs/fault-injection.d.ts +8 -0
- package/dist/foundation/resident-tabs/fault-injection.js +26 -0
- package/dist/foundation/resident-tabs/fixture-control.d.ts +7 -0
- package/dist/foundation/resident-tabs/fixture-control.js +35 -0
- package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
- package/dist/foundation/resident-tabs/host-entry.js +17 -0
- package/dist/foundation/resident-tabs/index.d.ts +12 -0
- package/dist/foundation/resident-tabs/index.js +6 -0
- package/dist/foundation/resident-tabs/maintenance.d.ts +39 -0
- package/dist/foundation/resident-tabs/maintenance.js +75 -0
- package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +34 -0
- package/dist/foundation/resident-tabs/progress-observation-schema.js +1 -0
- package/dist/foundation/resident-tabs/progress-observation.d.ts +4 -0
- package/dist/foundation/resident-tabs/progress-observation.js +150 -0
- package/dist/foundation/resident-tabs/prompt-journal.d.ts +63 -0
- package/dist/foundation/resident-tabs/prompt-journal.js +213 -0
- package/dist/foundation/resident-tabs/protocol.d.ts +12 -0
- package/dist/foundation/resident-tabs/protocol.js +195 -0
- package/dist/foundation/resident-tabs/recovery.d.ts +26 -0
- package/dist/foundation/resident-tabs/recovery.js +205 -0
- package/dist/foundation/resident-tabs/release-holds.d.ts +28 -0
- package/dist/foundation/resident-tabs/release-holds.js +75 -0
- package/dist/foundation/resident-tabs/routes.d.ts +5 -0
- package/dist/foundation/resident-tabs/routes.js +5 -0
- package/dist/foundation/resident-tabs/routing.d.ts +11 -0
- package/dist/foundation/resident-tabs/routing.js +10 -0
- package/dist/foundation/resident-tabs/session-sync.d.ts +14 -0
- package/dist/foundation/resident-tabs/session-sync.js +37 -0
- package/dist/foundation/resident-tabs/settings.d.ts +12 -0
- package/dist/foundation/resident-tabs/settings.js +58 -0
- package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +14 -0
- package/dist/foundation/resident-tabs/terminal-host-artifact.js +78 -0
- package/dist/foundation/resident-tabs/zip-archive.d.ts +9 -0
- package/dist/foundation/resident-tabs/zip-archive.js +56 -0
- package/dist/foundation/session-writer-lock/index.d.ts +30 -0
- package/dist/foundation/session-writer-lock/index.js +203 -0
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/foundation/terminal-cleanup/index.d.ts +1 -1
- package/dist/foundation/terminal-cleanup/index.js +1 -1
- package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +6 -0
- package/dist/foundation/terminal-cleanup/terminal-reset.js +6 -0
- package/dist/integrations/pi/components/editor-interaction.d.ts +2 -0
- package/dist/integrations/pi/components/modal-frame.d.ts +17 -1
- package/dist/integrations/pi/components/modal-frame.js +48 -9
- package/dist/integrations/pi/components/models-dialog.js +4 -52
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +6 -1
- package/dist/integrations/pi/components/owned-editor-ux.js +138 -11
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +4 -4
- package/dist/integrations/pi/components/resources/builtin-themes.js +4 -4
- package/dist/integrations/pi/components/share-operation-dialog.d.ts +2 -0
- package/dist/integrations/pi/components/share-operation-dialog.js +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +58 -36
- package/dist/integrations/pi/components/shell-extension-ui.js +79 -60
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +21 -5
- package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +5 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +18 -4
- package/dist/integrations/pi/components/shell-presenters-transcript.js +4 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +5 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +12 -1
- package/dist/integrations/pi/components/skills-dialog.js +2 -2
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +17 -4
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +8 -6
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +16 -9
- package/dist/integrations/pi/components/upstream/components/pi-logo.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +4 -4
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.js +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +31 -25
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +8 -7
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +3 -3
- package/dist/integrations/pi/components/upstream/components/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +8 -7
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +10 -9
- package/dist/integrations/pi/components/upstream/components/tool-execution.d.ts +2 -6
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +103 -101
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +9 -9
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +13 -21
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/history/editor-core.js +7 -5
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/program-status-reporter.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.d.ts +5 -0
- package/dist/integrations/pi/components/upstream/theme/theme.js +29 -2
- package/dist/integrations/pi/engine/adapter.d.ts +5 -77
- package/dist/integrations/pi/engine/adapter.js +95 -394
- package/dist/integrations/pi/engine/command-dispatch.d.ts +13 -0
- package/dist/integrations/pi/engine/command-dispatch.js +57 -0
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/offline-settings-port.d.ts +23 -0
- package/dist/integrations/pi/engine/offline-settings-port.js +53 -0
- package/dist/integrations/pi/engine/pi-settings-metadata.json +14 -2
- package/dist/integrations/pi/engine/ports.d.ts +56 -0
- package/dist/integrations/pi/engine/ports.js +93 -0
- package/dist/integrations/pi/engine/prompt-suggestions.d.ts +1 -0
- package/dist/integrations/pi/engine/prompt-suggestions.js +40 -0
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/runtime-integration.js +102 -29
- package/dist/integrations/pi/engine/session-runtime.d.ts +0 -6
- package/dist/integrations/pi/engine/session-runtime.js +13 -5
- package/dist/integrations/pi/engine/session-selection.d.ts +3 -0
- package/dist/integrations/pi/engine/session-selection.js +45 -9
- package/dist/integrations/pi/engine/settings-bridge.d.ts +5 -0
- package/dist/integrations/pi/engine/settings-bridge.js +15 -0
- package/dist/integrations/pi/engine/settings-port.js +11 -15
- package/dist/integrations/pi/engine/view-state.d.ts +42 -0
- package/dist/integrations/pi/engine/view-state.js +126 -0
- package/dist/integrations/pi/engine/workflow-contexts.js +10 -1
- package/dist/integrations/pi/engine/workflow-runner.js +74 -5
- package/dist/integrations/pi/engine/workflow-support.d.ts +12 -0
- package/dist/integrations/pi/engine/workflow-support.js +36 -0
- package/dist/integrations/pi/engine/workflows.d.ts +3 -1
- package/dist/integrations/pi/engine/workflows.js +1 -0
- package/dist/integrations/pi/startup-public.js +257 -310
- package/dist/integrations/pi/startup-public.manifest.json +564 -440
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
- package/dist/integrations/pi/tui-runtime/adapter.js +32 -1
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +12 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +31 -2
- package/dist/native/darwin-arm64/manifest.json +10 -7
- package/dist/native/darwin-arm64/process-guardian.node +0 -0
- package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +10500 -0
- package/dist/native/darwin-arm64/terminal-host.manifest.json +46 -0
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +23 -0
- package/dist/native/darwin-x64/process-guardian.node +0 -0
- package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10737 -0
- package/dist/native/darwin-x64/terminal-host.manifest.json +46 -0
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +10 -7
- package/dist/native/linux-x64/process-guardian.node +0 -0
- package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +11226 -0
- package/dist/native/linux-x64/terminal-host.manifest.json +46 -0
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +10 -7
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +10757 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +46 -0
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/product-identity.d.ts +3 -3
- package/dist/product-identity.js +4 -4
- package/dist/product-identity.json +16 -2
- package/dist/runtime-payload-inventory.json +6330 -6677
- package/dist/ui/apps/host.d.ts +2 -0
- package/dist/ui/apps/host.js +7 -1
- package/dist/ui/components/dialog-panel.d.ts +17 -8
- package/dist/ui/components/dialog-panel.js +117 -41
- package/dist/ui/components/index.d.ts +5 -5
- package/dist/ui/components/index.js +4 -4
- package/dist/ui/components/line-input.d.ts +4 -1
- package/dist/ui/components/line-input.js +3 -1
- package/dist/ui/components/prompt-input.d.ts +11 -8
- package/dist/ui/components/prompt-input.js +15 -13
- package/dist/ui/components/scrollbar.d.ts +1 -1
- package/dist/ui/components/scrollbar.js +1 -1
- package/dist/ui/components/selection-copy.d.ts +3 -3
- package/dist/ui/components/selection-copy.js +16 -1
- package/dist/ui/components/spans.js +2 -2
- package/dist/ui/components/submitted-prompt.d.ts +9 -6
- package/dist/ui/components/submitted-prompt.js +20 -12
- package/dist/ui/components/surface.js +4 -2
- package/dist/ui/components/text-selection.d.ts +1 -2
- package/dist/ui/components/text-selection.js +5 -2
- package/dist/ui/components/text.d.ts +3 -6
- package/dist/ui/components/text.js +6 -8
- package/dist/ui/components/transcript-viewport.d.ts +9 -2
- package/dist/ui/components/transcript-viewport.js +179 -58
- package/dist/ui/settings/declarations.d.ts +90 -16
- package/dist/ui/settings/declarations.js +67 -14
- package/dist/ui/settings/early-accent.d.ts +81 -0
- package/dist/ui/settings/early-accent.js +50 -0
- package/dist/ui/settings/index.d.ts +4 -2
- package/dist/ui/settings/index.js +2 -1
- package/dist/ui/settings/manager.d.ts +16 -3
- package/dist/ui/settings/manager.js +122 -33
- package/dist/ui/settings/migrations.d.ts +6 -0
- package/dist/ui/settings/migrations.js +73 -0
- package/dist/ui/settings/profile-document.d.ts +26 -0
- package/dist/ui/settings/profile-document.js +164 -0
- package/dist/ui/settings/progress-palette.generated.d.ts +139 -0
- package/dist/ui/settings/progress-palette.generated.js +139 -0
- package/dist/ui/settings/sections.d.ts +4 -0
- package/dist/ui/settings/sections.js +9 -3
- package/docs/architecture/boundaries.md +24 -9
- package/docs/architecture/evidence/resident-tabs/linux-x64.md +37 -0
- package/docs/architecture/evidence/resident-tabs/macos-arm64.md +36 -0
- package/docs/architecture/evidence/resident-tabs/macos-x64.md +35 -0
- package/docs/architecture/evidence/resident-tabs/windows-x64.md +36 -0
- package/docs/architecture/internal-naming.md +3 -1
- package/docs/architecture/process-guardian-provenance.md +18 -10
- package/docs/architecture/project-structure.md +8 -0
- package/docs/architecture/resident-tabs-requirements.md +18 -0
- package/docs/architecture/resident-tabs.md +649 -0
- package/docs/architecture/response-copy-delivery.md +1 -1
- package/docs/architecture/terminal-host-proof-gate.md +2 -0
- package/docs/architecture/terminal-host-provenance.md +16 -4
- package/docs/architecture/tool-image-presentation.md +2 -1
- package/docs/architecture/toolchain.md +11 -9
- package/docs/ci-release-runbook.md +14 -7
- package/docs/features/launch-profiles.md +11 -8
- package/docs/features/prompt-history.md +41 -20
- package/docs/manual-resident-tabs-acceptance.md +51 -0
- package/docs/openspec-archive-automation.md +49 -22
- package/docs/validation.md +49 -9
- package/package.json +19 -6
- package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
- package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
- package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
- package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
- package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
- package/dist/native/darwin-arm64/process-guardian +0 -0
- package/dist/native/linux-x64/process-guardian +0 -0
- package/dist/native/win32-x64/process-guardian.exe +0 -0
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import { displayWidth, truncateToWidth } from "./text.js";
|
|
2
|
-
/**
|
|
3
|
-
export
|
|
4
|
-
const TIMESTAMP_MARGIN = 3;
|
|
5
|
-
const MIN_USEFUL_CONTENT_WIDTH = 8;
|
|
6
|
-
/** Formats transcript metadata, never render time, as local 24-hour HH:mm. */
|
|
7
|
-
export function formatSubmittedPromptTime(source) {
|
|
2
|
+
/** Deterministic local hour/minute presentation shared by A1-owned time labels. */
|
|
3
|
+
export function formatLocalTime(source, format = "8:00 PM") {
|
|
8
4
|
const date = source instanceof Date ? source : new Date(source);
|
|
9
5
|
if (!Number.isFinite(date.getTime()))
|
|
10
6
|
return null;
|
|
11
|
-
|
|
7
|
+
const hour = date.getHours();
|
|
8
|
+
const minute = String(date.getMinutes()).padStart(2, "0");
|
|
9
|
+
if (format === "20:00")
|
|
10
|
+
return `${String(hour).padStart(2, "0")}:${minute}`;
|
|
11
|
+
return `${hour % 12 || 12}:${minute} ${hour < 12 ? "AM" : "PM"}`;
|
|
12
|
+
}
|
|
13
|
+
/** Visible width of the submitted-prompt prefix (` ❯ `). */
|
|
14
|
+
export const SUBMITTED_PROMPT_PREFIX_WIDTH = 3;
|
|
15
|
+
const TIMESTAMP_MARGIN = 3;
|
|
16
|
+
const MIN_USEFUL_CONTENT_WIDTH = 8;
|
|
17
|
+
/** Formats transcript metadata, never render time, in the active A1 time format. */
|
|
18
|
+
export function formatSubmittedPromptTime(source, format = "8:00 PM") {
|
|
19
|
+
return formatLocalTime(source, format);
|
|
12
20
|
}
|
|
13
21
|
/**
|
|
14
22
|
* Computes the width at which the prompt's Markdown body must be rendered.
|
|
15
23
|
* The timestamp is omitted rather than allowing it to crowd useful content.
|
|
16
24
|
*/
|
|
17
|
-
export function submittedPromptLayout(width, source) {
|
|
25
|
+
export function submittedPromptLayout(width, source, format = "8:00 PM") {
|
|
18
26
|
const boundedWidth = Math.max(1, width);
|
|
19
|
-
const timestamp = source === undefined || source === null ? null : formatSubmittedPromptTime(source);
|
|
27
|
+
const timestamp = source === undefined || source === null ? null : formatSubmittedPromptTime(source, format);
|
|
20
28
|
const timestampReserve = timestamp === null ? 0 : displayWidth(timestamp) + TIMESTAMP_MARGIN;
|
|
21
29
|
const canShowTimestamp = timestamp !== null
|
|
22
30
|
&& boundedWidth - SUBMITTED_PROMPT_PREFIX_WIDTH - timestampReserve >= MIN_USEFUL_CONTENT_WIDTH;
|
|
@@ -30,11 +38,11 @@ export function submittedPromptLayout(width, source) {
|
|
|
30
38
|
* Continuations align below the content, not below the prefix, and no row can
|
|
31
39
|
* exceed the supplied terminal width even when the content renderer misbehaves.
|
|
32
40
|
*/
|
|
33
|
-
export function composeSubmittedPromptRows(contentRows, width, source, style = {}) {
|
|
41
|
+
export function composeSubmittedPromptRows(contentRows, width, source, style = {}, format = "8:00 PM") {
|
|
34
42
|
if (width <= 0)
|
|
35
43
|
return [];
|
|
36
|
-
const layout = submittedPromptLayout(width, source);
|
|
37
|
-
const prefix = (style.prefix ?? identity)("❯ ");
|
|
44
|
+
const layout = submittedPromptLayout(width, source, format);
|
|
45
|
+
const prefix = (style.prefix ?? identity)(" ❯ ");
|
|
38
46
|
const rows = (contentRows.length === 0 ? [""] : contentRows).map((row, index) => {
|
|
39
47
|
const content = truncateToWidth(row, layout.contentWidth);
|
|
40
48
|
return `${index === 0 ? prefix : " ".repeat(SUBMITTED_PROMPT_PREFIX_WIDTH)}${content}`;
|
|
@@ -29,10 +29,12 @@ export function withScrollbarRail(lines, geometry, contentWidth, theme, options
|
|
|
29
29
|
*/
|
|
30
30
|
export function renderEmptyState(message, mark, height, width, theme) {
|
|
31
31
|
const middle = Math.floor(height / 2);
|
|
32
|
+
const messageRow = Math.min(Math.max(0, height - 1), middle + 1);
|
|
33
|
+
const markRow = messageRow - 1;
|
|
32
34
|
return Array.from({ length: Math.max(0, height) }, (_line, index) => {
|
|
33
|
-
if (index ===
|
|
35
|
+
if (index === markRow)
|
|
34
36
|
return centre(theme.fg("muted", mark), mark, width);
|
|
35
|
-
return index ===
|
|
37
|
+
return index === messageRow ? centre(theme.fg("muted", message), message, width) : "";
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
function centre(painted, raw, width) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** A reported pointer cell plus its grapheme-aligned zero-based boundaries. */
|
|
2
1
|
export interface TextSelectionPoint {
|
|
3
2
|
readonly line: number;
|
|
4
3
|
readonly column: number;
|
|
@@ -28,7 +27,6 @@ export interface TextSelectionLineContent {
|
|
|
28
27
|
readonly to?: number;
|
|
29
28
|
readonly selectable?: boolean;
|
|
30
29
|
}
|
|
31
|
-
/** Ordered zero-based, half-open display-column boundaries. */
|
|
32
30
|
export interface OrderedTextSelection {
|
|
33
31
|
readonly start: TextSelectionPoint;
|
|
34
32
|
readonly end: TextSelectionPoint;
|
|
@@ -45,6 +43,7 @@ export interface TextSelectionPressInput {
|
|
|
45
43
|
readonly now?: number;
|
|
46
44
|
}
|
|
47
45
|
export declare const TEXT_SELECTION_MULTI_CLICK_MS = 500;
|
|
46
|
+
export declare function paintTextSelection(line: string, from: number, to: number, widthOf?: (text: string) => number, clearInverse?: boolean): string;
|
|
48
47
|
export declare function orderedTextSelection(selection: TextSelection | undefined): OrderedTextSelection | undefined;
|
|
49
48
|
export declare function pressTextSelection(input: TextSelectionPressInput): {
|
|
50
49
|
readonly selection?: TextSelection;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { backgroundSgrSpan } from "./spans.js";
|
|
1
2
|
import { displayWidth, stripAnsi } from "./text.js";
|
|
2
3
|
const GRAPHEMES = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
3
4
|
export const TEXT_SELECTION_MULTI_CLICK_MS = 500;
|
|
5
|
+
const TEXT_SELECTION_BACKGROUND = "\u001b[48;2;38;79;120m";
|
|
6
|
+
export function paintTextSelection(line, from, to, widthOf = displayWidth, clearInverse = false) {
|
|
7
|
+
return backgroundSgrSpan(line, from, to, `${clearInverse ? "\u001b[27m" : ""}${TEXT_SELECTION_BACKGROUND}`, "\u001b[49m", widthOf);
|
|
8
|
+
}
|
|
4
9
|
export function orderedTextSelection(selection) {
|
|
5
10
|
if (selection === undefined)
|
|
6
11
|
return undefined;
|
|
@@ -17,8 +22,6 @@ export function orderedTextSelection(selection) {
|
|
|
17
22
|
}
|
|
18
23
|
if (!selection.cell && selection.dragged !== true)
|
|
19
24
|
return undefined;
|
|
20
|
-
// Invariant: an accepted drag includes both endpoint graphemes, even after returning
|
|
21
|
-
// to its anchor. Only an unextended point press is empty; paint and copy stay half-open.
|
|
22
25
|
const anchorFirst = comparePoints(anchor, head) <= 0;
|
|
23
26
|
const first = anchorFirst ? anchor : head;
|
|
24
27
|
const last = anchorFirst ? head : anchor;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display-width text handling. Terminals lay out by column, not by code unit,
|
|
3
|
-
* so measuring with `String.length` mis-sizes CJK, emoji, and combining marks,
|
|
4
|
-
* and counting styling escapes as visible width breaks every layout that uses
|
|
5
|
-
* colour.
|
|
6
|
-
*/
|
|
1
|
+
/** Terminal-column geometry: preserve graphemes, Unicode cell widths and ANSI styling. */
|
|
7
2
|
/** Removes styling sequences so only visible characters remain. */
|
|
8
3
|
export declare function stripAnsi(text: string): string;
|
|
4
|
+
/** Width of one grapheme cluster: two for emoji, else the widest code point it contains. */
|
|
5
|
+
export declare function graphemeWidth(grapheme: string): number;
|
|
9
6
|
export interface DisplayColumnRange {
|
|
10
7
|
readonly from: number;
|
|
11
8
|
readonly to: number;
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Display-width text handling. Terminals lay out by column, not by code unit,
|
|
3
|
-
* so measuring with `String.length` mis-sizes CJK, emoji, and combining marks,
|
|
4
|
-
* and counting styling escapes as visible width breaks every layout that uses
|
|
5
|
-
* colour.
|
|
6
|
-
*/
|
|
1
|
+
/** Terminal-column geometry: preserve graphemes, Unicode cell widths and ANSI styling. */
|
|
7
2
|
const ANSI_PATTERN = /\[[0-9;:?]*[ -/]*[@-~]|[\]_][^]*(?:|\\)|[@-Z\\-_]/g;
|
|
8
3
|
const SEGMENTER = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
9
4
|
const WORD_SEGMENTER = new Intl.Segmenter(undefined, { granularity: "word" });
|
|
@@ -76,7 +71,7 @@ function couldBeEmoji(grapheme) {
|
|
|
76
71
|
grapheme.length > 1);
|
|
77
72
|
}
|
|
78
73
|
/** Width of one grapheme cluster: two for emoji, else the widest code point it contains. */
|
|
79
|
-
function graphemeWidth(grapheme) {
|
|
74
|
+
export function graphemeWidth(grapheme) {
|
|
80
75
|
if (couldBeEmoji(grapheme) && RGI_EMOJI_PATTERN.test(grapheme))
|
|
81
76
|
return 2;
|
|
82
77
|
let width = 0;
|
|
@@ -126,8 +121,11 @@ export function displayColumnSlice(text, requestedFrom, requestedTo) {
|
|
|
126
121
|
}
|
|
127
122
|
/** Columns this text occupies once styling is removed. */
|
|
128
123
|
export function displayWidth(text) {
|
|
124
|
+
const plain = stripAnsi(text);
|
|
125
|
+
if (!/[^\x20-\x7e]/u.test(plain))
|
|
126
|
+
return plain.length;
|
|
129
127
|
let width = 0;
|
|
130
|
-
for (const { segment } of SEGMENTER.segment(
|
|
128
|
+
for (const { segment } of SEGMENTER.segment(plain))
|
|
131
129
|
width += graphemeWidth(segment);
|
|
132
130
|
return width;
|
|
133
131
|
}
|
|
@@ -6,6 +6,8 @@ export interface TranscriptPromptAnchor {
|
|
|
6
6
|
readonly lastRow: number;
|
|
7
7
|
/** The source first row, including its submitted-prompt styling and timestamp. */
|
|
8
8
|
readonly sourceRow: string;
|
|
9
|
+
/** Right-edge metadata cells omitted from semantic prompt copies. */
|
|
10
|
+
readonly copySuffixWidth?: number;
|
|
9
11
|
/** Optional source-styled row used only while prominent and not hovered. */
|
|
10
12
|
readonly prominentSourceRow?: string;
|
|
11
13
|
}
|
|
@@ -36,6 +38,11 @@ export interface TranscriptViewportFrameInput {
|
|
|
36
38
|
/** Final transient rows to bottom-align with unused viewport space while content fits. */
|
|
37
39
|
readonly bottomAlignedTailRowCount?: number;
|
|
38
40
|
readonly dockRows: readonly string[];
|
|
41
|
+
/** Zero-based dock rows admitted to frame copying, classified before dock composition. */
|
|
42
|
+
readonly copyableDockRows?: readonly {
|
|
43
|
+
readonly row: number;
|
|
44
|
+
readonly prompt?: "first" | "continuation";
|
|
45
|
+
}[];
|
|
39
46
|
readonly promptAnchors: readonly TranscriptPromptAnchor[];
|
|
40
47
|
readonly width: number;
|
|
41
48
|
readonly height: number;
|
|
@@ -171,7 +178,7 @@ export declare class TranscriptViewport {
|
|
|
171
178
|
releaseSelection(): boolean;
|
|
172
179
|
clearSelection(): boolean;
|
|
173
180
|
selectedText(): string | null;
|
|
174
|
-
/** Captures
|
|
181
|
+
/** Captures selected text, including document rows of a visible selection scrolled off-screen. */
|
|
175
182
|
captureSelectedText(): SelectionCopySnapshot | null;
|
|
176
183
|
scrollBy(lines: number, now?: number): boolean;
|
|
177
184
|
scrollTo(position: number, now?: number): boolean;
|
|
@@ -184,6 +191,6 @@ export declare class TranscriptViewport {
|
|
|
184
191
|
clearTransient(): void;
|
|
185
192
|
compose(input: TranscriptViewportFrameInput): TranscriptViewportFrame;
|
|
186
193
|
/** Reuses an established transcript frame when only same-height dock rows changed. */
|
|
187
|
-
composeDockOnly(dockRows: readonly string[], width: number, height: number): TranscriptViewportFrame | null;
|
|
194
|
+
composeDockOnly(dockRows: readonly string[], width: number, height: number, copyableDockRows?: TranscriptViewportFrameInput["copyableDockRows"]): TranscriptViewportFrame | null;
|
|
188
195
|
}
|
|
189
196
|
export declare function assertTranscriptViewportFrameDescriptor(descriptor: TranscriptViewportFrameDescriptor): void;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { MAX_COPY_SOURCE_UNITS, selectionCopyLineContent } from "./selection-copy.js";
|
|
2
2
|
import { isThumbRow, scrollbarGeometry, scrollbarPresentation, } from "./scrollbar.js";
|
|
3
|
-
import {
|
|
3
|
+
import { overlaySpan } from "./spans.js";
|
|
4
4
|
import { faint, truncateToWidth, displayWidth, stripAnsi } from "./text.js";
|
|
5
|
-
import { extendTextSelection, orderedTextSelection, pressTextSelection, releaseTextSelection, textSelectionLineExtendColumn, textSelectionPointAt, textSelectionText, usefulTextLineContent, } from "./text-selection.js";
|
|
5
|
+
import { extendTextSelection, orderedTextSelection, paintTextSelection, pressTextSelection, releaseTextSelection, textSelectionLineExtendColumn, textSelectionPointAt, textSelectionText, usefulTextLineContent, } from "./text-selection.js";
|
|
6
6
|
const CONTROL_STYLE_RESET = "\u001b]8;;\u001b\\\u001b[0m";
|
|
7
|
+
// Protocol: upstream OSC 133 zones are layout annotations, not fullscreen cursor commands.
|
|
8
|
+
// Styling/padding can move them away from the row prefix Pi strips; 133;A then advances a real
|
|
9
|
+
// terminal parser to a fresh line. The custom viewport owns prompt anchors separately.
|
|
10
|
+
const VIEWPORT_PROMPT_ZONES = /\u001b\]133;[ABC](?:\u0007|\u001b\\)/gu;
|
|
7
11
|
// Invariant: scrollbar chrome closes source links and decoration without clearing
|
|
8
12
|
// the row surface painted beneath its dedicated, non-semantic gutter.
|
|
9
13
|
const GUTTER_DECORATION_RESET = "\u001b]8;;\u001b\\\u001b[22;23;24;25;27;28;29;39;54;55m";
|
|
@@ -11,6 +15,19 @@ const IDENTITY_ROW = (row) => row;
|
|
|
11
15
|
function documentSelectionAnchor(row, source, liveFromBottom) {
|
|
12
16
|
return { kind: "document", row, source, identity: stripAnsi(source).trimEnd(), liveFromBottom };
|
|
13
17
|
}
|
|
18
|
+
function sameSelectionRowAnchor(left, right) {
|
|
19
|
+
if (left.kind !== right.kind)
|
|
20
|
+
return false;
|
|
21
|
+
if (left.kind === "document" && right.kind === "document") {
|
|
22
|
+
return left.row === right.row && left.source === right.source && left.liveFromBottom === right.liveFromBottom;
|
|
23
|
+
}
|
|
24
|
+
if (left.kind === "screen" && right.kind === "screen") {
|
|
25
|
+
return left.row === right.row && left.source === right.source;
|
|
26
|
+
}
|
|
27
|
+
if (left.kind === "transient" && right.kind === "transient")
|
|
28
|
+
return left.fromBottom === right.fromBottom;
|
|
29
|
+
return left.kind === "dock" && right.kind === "dock" && left.fromBottom === right.fromBottom;
|
|
30
|
+
}
|
|
14
31
|
function viewportSelectionAnchor(row, source, selectableDocumentRowCount, documentRowCount) {
|
|
15
32
|
return row < selectableDocumentRowCount
|
|
16
33
|
? documentSelectionAnchor(row, source)
|
|
@@ -26,7 +43,7 @@ const PLAIN_THEME = {
|
|
|
26
43
|
sticky: (text, hovered) => hovered ? `\u001b[7m${text}\u001b[27m` : text,
|
|
27
44
|
quietSticky: faint,
|
|
28
45
|
bottomControl: (text, hovered) => hovered ? `\u001b[7m${text}\u001b[27m` : `\u001b[7m${text}\u001b[27m`,
|
|
29
|
-
selection:
|
|
46
|
+
selection: paintTextSelection,
|
|
30
47
|
};
|
|
31
48
|
/**
|
|
32
49
|
* A1-owned viewport state. It knows only rows and semantic prompt anchors; Pi
|
|
@@ -63,6 +80,7 @@ export class TranscriptViewport {
|
|
|
63
80
|
#contentWidth = 0;
|
|
64
81
|
#selectionWidth = 0;
|
|
65
82
|
#viewportHeight = 0;
|
|
83
|
+
#copyableDockRows = new Map();
|
|
66
84
|
#firstSelectableRow = 0;
|
|
67
85
|
#selectionRowAnchors = [];
|
|
68
86
|
#frameId = 0;
|
|
@@ -135,7 +153,12 @@ export class TranscriptViewport {
|
|
|
135
153
|
this.scrollBy(1, now);
|
|
136
154
|
else if (autoScroll && frameRow <= 1 && this.#scrollTop > 0)
|
|
137
155
|
this.scrollBy(-1, now);
|
|
138
|
-
const
|
|
156
|
+
const pointerLine = clamp(frameRow - 1, 0, this.#selectionRows.length - 1);
|
|
157
|
+
// Invariant: a pinned prompt alias is chrome; an upward drag reaching it keeps the pointer
|
|
158
|
+
// column on the first visible content row.
|
|
159
|
+
const line = pointerLine < this.#firstSelectableRow && pointerLine < selection.anchor.line
|
|
160
|
+
? this.#firstSelectableRow
|
|
161
|
+
: pointerLine;
|
|
139
162
|
const selectionWidth = line < (this.#frame?.hits.viewportHeight ?? 0)
|
|
140
163
|
? this.#contentWidth
|
|
141
164
|
: this.#selectionWidth;
|
|
@@ -146,12 +169,13 @@ export class TranscriptViewport {
|
|
|
146
169
|
? { line, column: targetColumn }
|
|
147
170
|
: textSelectionPointAt(line, targetColumn, this.#selectionRows[line] ?? "");
|
|
148
171
|
const next = extendTextSelection(selection, point);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
172
|
+
const headAnchor = this.#selectionAnchorAt(line);
|
|
173
|
+
if (headAnchor === undefined || this.#selectionAnchors === undefined) {
|
|
174
|
+
this.clearSelection();
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
// Invariant: edge auto-scroll changes the document row under a still pointer; that advances the head.
|
|
178
|
+
if (next !== selection || !sameSelectionRowAnchor(this.#selectionAnchors.head, headAnchor)) {
|
|
155
179
|
this.#selection = next;
|
|
156
180
|
this.#selectionAnchors = { ...this.#selectionAnchors, head: headAnchor };
|
|
157
181
|
this.#selectionRevision += 1;
|
|
@@ -179,35 +203,80 @@ export class TranscriptViewport {
|
|
|
179
203
|
return true;
|
|
180
204
|
}
|
|
181
205
|
selectedText() {
|
|
182
|
-
const
|
|
183
|
-
if (
|
|
206
|
+
const visible = this.#visibleSelection();
|
|
207
|
+
if (visible === undefined)
|
|
184
208
|
return null;
|
|
185
|
-
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
|
|
209
|
+
const offscreen = offscreenSelectionRows(this.#selection, this.#selectionAnchors, this.#scrollTop, this.#firstSelectableRow, this.#viewportHeight, this.#documentRows.length);
|
|
210
|
+
// Rationale: edge auto-scroll grows a drag beyond one screen. Paint stays clipped to the
|
|
211
|
+
// frame, while copy reads the selected document rows past either viewport edge and beneath
|
|
212
|
+
// the floating bottom control.
|
|
213
|
+
const selectionRows = [];
|
|
214
|
+
const rowAnchors = [];
|
|
215
|
+
const controlLine = (this.#frame?.hits.bottom?.row ?? 0) - 1;
|
|
216
|
+
const pushDocumentRow = (row) => {
|
|
217
|
+
const source = this.#documentRows[row] ?? "";
|
|
218
|
+
selectionRows.push(truncateToWidth(source, this.#contentWidth));
|
|
219
|
+
rowAnchors.push(documentSelectionAnchor(row, source));
|
|
220
|
+
};
|
|
221
|
+
const pushBelow = () => {
|
|
222
|
+
for (let row = offscreen.below?.from ?? 0; row <= (offscreen.below?.to ?? -1); row += 1)
|
|
223
|
+
pushDocumentRow(row);
|
|
224
|
+
};
|
|
225
|
+
for (let row = offscreen.above?.from ?? 0; row <= (offscreen.above?.to ?? -1); row += 1)
|
|
226
|
+
pushDocumentRow(row);
|
|
227
|
+
if (offscreen.belowFirst)
|
|
228
|
+
pushBelow();
|
|
229
|
+
for (let line = visible.start.line; line <= visible.end.line; line += 1) {
|
|
189
230
|
const anchor = this.#selectionRowAnchors[line];
|
|
190
|
-
|
|
231
|
+
if (line === controlLine && anchor?.kind === "document")
|
|
232
|
+
pushDocumentRow(anchor.row);
|
|
233
|
+
else {
|
|
234
|
+
selectionRows.push(this.#selectionRows[line] ?? "");
|
|
235
|
+
rowAnchors.push(anchor);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (!offscreen.belowFirst)
|
|
239
|
+
pushBelow();
|
|
240
|
+
const offscreenStart = offscreen.above !== undefined || offscreen.belowFirst === true;
|
|
241
|
+
const offscreenEnd = offscreen.below !== undefined && !offscreen.belowFirst;
|
|
242
|
+
const selection = {
|
|
243
|
+
...visible,
|
|
244
|
+
start: { line: 0, column: offscreenStart ? offscreen.startColumn ?? 0 : visible.start.column },
|
|
245
|
+
end: {
|
|
246
|
+
line: selectionRows.length - 1,
|
|
247
|
+
column: offscreenEnd ? offscreen.endColumn ?? Number.MAX_SAFE_INTEGER : visible.end.column,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
const copiedLines = Array.from({ length: Math.max(0, selection.end.line - selection.start.line + 1) }, (_value, index) => selection.start.line + index).filter(line => {
|
|
251
|
+
const anchor = rowAnchors[line];
|
|
252
|
+
return anchor?.kind === "document" && anchor.row < this.#selectableDocumentRowCount
|
|
253
|
+
|| anchor?.kind === "dock" && this.#copyableDockRows.has(anchor.fromBottom);
|
|
191
254
|
});
|
|
192
255
|
if (copiedLines.length === 0)
|
|
193
256
|
return null;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const anchor = this.#selectionRowAnchors[line];
|
|
257
|
+
const transcriptLines = copiedLines.filter(line => rowAnchors[line]?.kind === "document");
|
|
258
|
+
const prompt = transcriptLines.length === 0 ? undefined : this.#promptAnchors.find(candidate => transcriptLines.every(line => {
|
|
259
|
+
const anchor = rowAnchors[line];
|
|
198
260
|
return anchor?.kind === "document" && anchor.row >= candidate.firstRow && anchor.row <= candidate.lastRow;
|
|
199
261
|
}));
|
|
200
262
|
const included = new Set(copiedLines);
|
|
201
|
-
const text = textSelectionText(selection,
|
|
202
|
-
const row =
|
|
203
|
-
const anchor =
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
263
|
+
const text = textSelectionText(selection, selectionRows, line => {
|
|
264
|
+
const row = selectionRows[line] ?? "";
|
|
265
|
+
const anchor = rowAnchors[line];
|
|
266
|
+
const dock = anchor?.kind === "dock" ? this.#copyableDockRows.get(anchor.fromBottom) : undefined;
|
|
267
|
+
if (prompt !== undefined && anchor?.kind === "document") {
|
|
268
|
+
const first = anchor.row === prompt.firstRow;
|
|
269
|
+
const copyRow = first && (prompt.copySuffixWidth ?? 0) > 0
|
|
270
|
+
? truncateToWidth(row, Math.max(0, displayWidth(row) - (prompt.copySuffixWidth ?? 0)))
|
|
271
|
+
: row;
|
|
272
|
+
return selectionCopyLineContent(copyRow, first ? "first" : "continuation");
|
|
273
|
+
}
|
|
274
|
+
// Invariant: the dock editor has no prefix; transcript prompts still carry chrome.
|
|
275
|
+
return dock?.prompt !== undefined ? usefulTextLineContent(row, 1) : usefulTextLineContent(row);
|
|
207
276
|
}, line => included.has(line));
|
|
208
277
|
return text.length === 0 ? null : text;
|
|
209
278
|
}
|
|
210
|
-
/** Captures
|
|
279
|
+
/** Captures selected text, including document rows of a visible selection scrolled off-screen. */
|
|
211
280
|
captureSelectedText() {
|
|
212
281
|
if (!this.#copyableSelection)
|
|
213
282
|
return null;
|
|
@@ -315,6 +384,7 @@ export class TranscriptViewport {
|
|
|
315
384
|
this.#contentWidth = 0;
|
|
316
385
|
this.#selectionWidth = 0;
|
|
317
386
|
this.#viewportHeight = 0;
|
|
387
|
+
this.#copyableDockRows.clear();
|
|
318
388
|
this.clearTransient();
|
|
319
389
|
this.#frame = null;
|
|
320
390
|
}
|
|
@@ -330,6 +400,7 @@ export class TranscriptViewport {
|
|
|
330
400
|
const theme = input.theme ?? PLAIN_THEME;
|
|
331
401
|
const previousDescriptor = this.#frame?.descriptor ?? null;
|
|
332
402
|
const dock = input.dockRows.length > height ? input.dockRows.slice(-height) : [...input.dockRows];
|
|
403
|
+
this.#copyableDockRows = copyableDockRowsBySuffix(input.dockRows, input.copyableDockRows);
|
|
333
404
|
const viewportHeight = Math.max(0, height - dock.length);
|
|
334
405
|
const bottomAlignedTailRowCount = clamp(input.bottomAlignedTailRowCount ?? 0, 0, input.documentRows.length);
|
|
335
406
|
const transientAlignmentGapRows = bottomAlignedTailRowCount > 0
|
|
@@ -356,7 +427,7 @@ export class TranscriptViewport {
|
|
|
356
427
|
contentLength: documentRows.length,
|
|
357
428
|
viewportHeight,
|
|
358
429
|
scroll: this.#scrollTop,
|
|
359
|
-
//
|
|
430
|
+
// Invariant: the rail keeps its top gap; the shell owns the spacing above the dock.
|
|
360
431
|
trackHeight: Math.max(0, viewportHeight - 1),
|
|
361
432
|
});
|
|
362
433
|
const presentation = scrollbarPresentation({
|
|
@@ -414,8 +485,6 @@ export class TranscriptViewport {
|
|
|
414
485
|
visible[0] = quiet && !this.#stickyHovered ? theme.quietSticky(sticky) : sticky;
|
|
415
486
|
visibleSource[0] = sourceRow;
|
|
416
487
|
}
|
|
417
|
-
// Invariant: selection uses exact visible source rows within the rendered
|
|
418
|
-
// content boundary; paint-only guards and the rail gutter stay presentation-only.
|
|
419
488
|
this.#selectionRows = [
|
|
420
489
|
...visibleSource.map(row => truncateToWidth(row, contentWidth)),
|
|
421
490
|
...dock,
|
|
@@ -426,7 +495,6 @@ export class TranscriptViewport {
|
|
|
426
495
|
? viewportSelectionAnchor(documentRow, documentRows[documentRow] ?? "", this.#selectableDocumentRowCount, documentRows.length)
|
|
427
496
|
: { kind: "screen", row, source: this.#selectionRows[row] ?? "" };
|
|
428
497
|
});
|
|
429
|
-
// Invariant: a pinned prompt is chrome over its hidden source row, which clips like off-screen rows.
|
|
430
498
|
this.#firstSelectableRow = stickyActive && viewportHeight > 0 ? 1 : 0;
|
|
431
499
|
this.#selectionRowAnchors = [
|
|
432
500
|
...visibleAnchors,
|
|
@@ -463,7 +531,7 @@ export class TranscriptViewport {
|
|
|
463
531
|
const bottomHovered = pointer !== undefined && pointer.row === bottomHit.row
|
|
464
532
|
&& pointer.column >= bottomHit.columnStart && pointer.column <= bottomHit.columnEnd;
|
|
465
533
|
control = { row, left, text: `${CONTROL_STYLE_RESET}${theme.bottomControl(label, bottomHovered)}` };
|
|
466
|
-
// Invariant: the control floats above selection;
|
|
534
|
+
// Invariant: the control floats above selection; copy restores the text beneath it.
|
|
467
535
|
selectionRows[row] = overlaySpan(padRowPreservingBackground(selectionRows[row] ?? "", width), left, left + labelWidth, " ".repeat(labelWidth));
|
|
468
536
|
}
|
|
469
537
|
}
|
|
@@ -501,7 +569,7 @@ export class TranscriptViewport {
|
|
|
501
569
|
// Invariant: paint the rail after selection over the gutter's continued row
|
|
502
570
|
// background. Source content and selection still end at the preceding cell.
|
|
503
571
|
let railCell = "";
|
|
504
|
-
if (row < viewportHeight && presentation.visible && geometry !== null
|
|
572
|
+
if (row > 0 && row < viewportHeight && presentation.visible && geometry !== null) {
|
|
505
573
|
const trackRow = row - 1;
|
|
506
574
|
const thumb = isThumbRow(geometry, trackRow);
|
|
507
575
|
const glyph = thumb ? presentation.thumbGlyph : presentation.trackGlyph;
|
|
@@ -523,7 +591,7 @@ export class TranscriptViewport {
|
|
|
523
591
|
return overlayWidth === 0 ? withControl : overlaySpan(padRowPreservingBackground(withControl, width), overlayLimit - overlayWidth, overlayLimit, `${GUTTER_DECORATION_RESET}${overlayText}`, { inheritStartStyle: true });
|
|
524
592
|
});
|
|
525
593
|
rowRecomputed ||= !final.reused;
|
|
526
|
-
frameRows[row] = final.value;
|
|
594
|
+
frameRows[row] = final.value.replace(VIEWPORT_PROMPT_ZONES, "");
|
|
527
595
|
(rowRecomputed ? recomputedRows : reusedRows).push(row + 1);
|
|
528
596
|
const state = `${width}\u0000${row}\u0000${painted}\u0000${rangeKey}\u0000${range === null ? "" : selectionPainterId}\u0000${railCell}\u0000${overlayText}\u0000${rowControl?.text ?? ""}`;
|
|
529
597
|
visibleStates.push(state);
|
|
@@ -609,7 +677,7 @@ export class TranscriptViewport {
|
|
|
609
677
|
return frame;
|
|
610
678
|
}
|
|
611
679
|
/** Reuses an established transcript frame when only same-height dock rows changed. */
|
|
612
|
-
composeDockOnly(dockRows, width, height) {
|
|
680
|
+
composeDockOnly(dockRows, width, height, copyableDockRows = []) {
|
|
613
681
|
const previous = this.#frame;
|
|
614
682
|
const boundedWidth = Math.max(1, width);
|
|
615
683
|
const boundedHeight = Math.max(0, height);
|
|
@@ -624,19 +692,10 @@ export class TranscriptViewport {
|
|
|
624
692
|
|| !sameRectangle(previous.descriptor.transcript, expectedTranscript))
|
|
625
693
|
return null;
|
|
626
694
|
const descriptor = {
|
|
695
|
+
...previous.descriptor,
|
|
627
696
|
frameId: ++this.#frameId,
|
|
628
|
-
width: boundedWidth,
|
|
629
|
-
height: boundedHeight,
|
|
630
|
-
transcript: expectedTranscript,
|
|
631
|
-
dock: expectedDock,
|
|
632
697
|
previousDocumentRange: previous.descriptor.nextDocumentRange,
|
|
633
|
-
nextDocumentRange: previous.descriptor.nextDocumentRange,
|
|
634
698
|
previousFollowingEnd: previous.followingEnd,
|
|
635
|
-
followingEnd: previous.followingEnd,
|
|
636
|
-
transientRowCount: previous.descriptor.transientRowCount,
|
|
637
|
-
transientAlignmentGapRows: previous.descriptor.transientAlignmentGapRows,
|
|
638
|
-
bottomAlignedTailRowCount: previous.descriptor.bottomAlignedTailRowCount,
|
|
639
|
-
liveTailRows: previous.descriptor.liveTailRows,
|
|
640
699
|
verticalShiftRows: 0,
|
|
641
700
|
safeVerticalShift: false,
|
|
642
701
|
selectionRevision: this.#selectionRevision,
|
|
@@ -645,13 +704,10 @@ export class TranscriptViewport {
|
|
|
645
704
|
};
|
|
646
705
|
assertTranscriptViewportFrameDescriptor(descriptor);
|
|
647
706
|
this.#selectionRows = [...this.#selectionRows.slice(0, viewportHeight), ...dock].slice(0, boundedHeight);
|
|
707
|
+
this.#copyableDockRows = copyableDockRowsBySuffix(dockRows, copyableDockRows);
|
|
648
708
|
const frame = {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
scrollTop: previous.scrollTop,
|
|
652
|
-
maxScroll: previous.maxScroll,
|
|
653
|
-
followingEnd: previous.followingEnd,
|
|
654
|
-
hits: previous.hits,
|
|
709
|
+
...previous,
|
|
710
|
+
rows: [...previous.rows.slice(0, viewportHeight), ...dock.map(row => row.replace(VIEWPORT_PROMPT_ZONES, ""))].slice(0, boundedHeight),
|
|
655
711
|
descriptor,
|
|
656
712
|
selectionDamage: {
|
|
657
713
|
revision: this.#selectionRevision,
|
|
@@ -706,7 +762,7 @@ export class TranscriptViewport {
|
|
|
706
762
|
const anchors = this.#selectionAnchors;
|
|
707
763
|
if (selection === undefined || anchors === undefined)
|
|
708
764
|
return;
|
|
709
|
-
const project = (anchor) => {
|
|
765
|
+
const project = (anchor, moving) => {
|
|
710
766
|
if (anchor.kind === "dock") {
|
|
711
767
|
const dockIndex = dockRows.length - anchor.fromBottom - 1;
|
|
712
768
|
return dockIndex < 0 || dockIndex >= dockRows.length
|
|
@@ -748,7 +804,7 @@ export class TranscriptViewport {
|
|
|
748
804
|
// Concurrency: a streaming chunk may replace or reflow the pointer's current live-tail
|
|
749
805
|
// row before the next motion report. During the held gesture only, retain its distance
|
|
750
806
|
// from the persistent tail; release restores identity-only projection.
|
|
751
|
-
if (selection.selecting && anchor.liveFromBottom !== undefined && this.#liveTailStartRow !== undefined) {
|
|
807
|
+
if (selection.selecting && moving && anchor.liveFromBottom !== undefined && this.#liveTailStartRow !== undefined) {
|
|
752
808
|
const documentRow = this.#selectableDocumentRowCount - anchor.liveFromBottom - 1;
|
|
753
809
|
if (documentRow >= this.#liveTailStartRow && documentRow < this.#selectableDocumentRowCount) {
|
|
754
810
|
const visible = this.#selectionRowAnchors.findIndex(candidate => candidate?.kind === "document" && candidate.row === documentRow);
|
|
@@ -760,10 +816,18 @@ export class TranscriptViewport {
|
|
|
760
816
|
}
|
|
761
817
|
}
|
|
762
818
|
}
|
|
819
|
+
// Concurrency: streaming may restyle a held endpoint's row; it keeps its document index.
|
|
820
|
+
// Following the tail would drag the press row toward the newest output.
|
|
821
|
+
if (selection.selecting && anchor.row >= 0 && anchor.row < documentRows.length) {
|
|
822
|
+
return {
|
|
823
|
+
line: anchor.row - this.#scrollTop,
|
|
824
|
+
anchor: documentSelectionAnchor(anchor.row, documentRows[anchor.row] ?? "", anchor.liveFromBottom),
|
|
825
|
+
};
|
|
826
|
+
}
|
|
763
827
|
return undefined;
|
|
764
828
|
};
|
|
765
|
-
const projectedAnchor = project(anchors.anchor);
|
|
766
|
-
const projectedHead = project(anchors.head);
|
|
829
|
+
const projectedAnchor = project(anchors.anchor, false);
|
|
830
|
+
const projectedHead = project(anchors.head, true);
|
|
767
831
|
if (projectedAnchor === undefined || projectedHead === undefined) {
|
|
768
832
|
this.clearSelection();
|
|
769
833
|
return;
|
|
@@ -783,11 +847,59 @@ export class TranscriptViewport {
|
|
|
783
847
|
// Invariant: mixed viewport/dock ranges project across the same complete frame regardless
|
|
784
848
|
// of origin. Document-only ranges remain clipped to the scrollable viewport when off-screen.
|
|
785
849
|
const rows = crossesDock ? this.#selectionRows.length : this.#viewportHeight;
|
|
786
|
-
|
|
850
|
+
const ordered = orderedTextSelection(dockOrderedSelection(this.#selection, anchors, this.#viewportHeight));
|
|
851
|
+
return visibleTextSelection(ordered, rows, this.#firstSelectableRow);
|
|
787
852
|
}
|
|
788
853
|
#updateCopyableSelection() {
|
|
789
|
-
|
|
854
|
+
// Performance: off-screen rows count as copyable by range alone; capture trims whitespace later.
|
|
855
|
+
const offscreen = offscreenSelectionRows(this.#selection, this.#selectionAnchors, this.#scrollTop, this.#firstSelectableRow, this.#viewportHeight, this.#documentRows.length);
|
|
856
|
+
const selectable = [offscreen.above, offscreen.below]
|
|
857
|
+
.some(range => range !== undefined && range.from < this.#selectableDocumentRowCount);
|
|
858
|
+
this.#copyableSelection = selectable && this.#visibleSelection() !== undefined || this.selectedText() !== null;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Invariant: dock rows follow the whole transcript, so a document endpoint scrolled below the
|
|
863
|
+
* viewport orders before every dock row instead of at its numeric frame line among them.
|
|
864
|
+
*/
|
|
865
|
+
function dockOrderedSelection(selection, anchors, viewportHeight) {
|
|
866
|
+
if (selection === undefined || anchors === undefined || anchors.anchor.kind !== "dock" && anchors.head.kind !== "dock") {
|
|
867
|
+
return selection;
|
|
790
868
|
}
|
|
869
|
+
const place = (point, kind) => kind === "document" && point.line >= viewportHeight ? { line: viewportHeight, column: 1, from: 0, to: 0 } : point;
|
|
870
|
+
return { ...selection, anchor: place(selection.anchor, anchors.anchor.kind), head: place(selection.head, anchors.head.kind) };
|
|
871
|
+
}
|
|
872
|
+
/** Document rows of a selection whose endpoints lie beyond the visible viewport edges. */
|
|
873
|
+
function offscreenSelectionRows(selection, anchors, scrollTop, firstSelectableRow, viewportHeight, documentRowCount) {
|
|
874
|
+
const ordered = orderedTextSelection(dockOrderedSelection(selection, anchors, viewportHeight));
|
|
875
|
+
if (selection === undefined || ordered === undefined || anchors === undefined)
|
|
876
|
+
return {};
|
|
877
|
+
const placed = dockOrderedSelection(selection, anchors, viewportHeight);
|
|
878
|
+
const anchorFirst = placed.anchor.line < placed.head.line
|
|
879
|
+
|| placed.anchor.line === placed.head.line && placed.anchor.column <= placed.head.column;
|
|
880
|
+
const top = anchorFirst ? anchors.anchor : anchors.head;
|
|
881
|
+
const bottom = anchorFirst ? anchors.head : anchors.anchor;
|
|
882
|
+
const topPoint = anchorFirst ? selection.anchor : selection.head;
|
|
883
|
+
const bottomPoint = anchorFirst ? selection.head : selection.anchor;
|
|
884
|
+
const firstVisibleRow = scrollTop + firstSelectableRow;
|
|
885
|
+
const pastVisibleRow = scrollTop + viewportHeight;
|
|
886
|
+
const columns = {
|
|
887
|
+
startColumn: selection.fullRow ? 0 : topPoint.from ?? Math.max(0, topPoint.column - 1),
|
|
888
|
+
endColumn: selection.fullRow ? Number.MAX_SAFE_INTEGER : bottomPoint.to ?? bottomPoint.column,
|
|
889
|
+
};
|
|
890
|
+
if (top.kind === "document" && bottom.kind === "dock" && top.row >= pastVisibleRow) {
|
|
891
|
+
return { ...columns, below: { from: top.row, to: documentRowCount - 1 }, belowFirst: true };
|
|
892
|
+
}
|
|
893
|
+
return {
|
|
894
|
+
...columns,
|
|
895
|
+
...(top.kind === "document" && top.row < firstVisibleRow && ordered.start.line < firstSelectableRow
|
|
896
|
+
? { above: { from: top.row, to: firstVisibleRow - 1 } }
|
|
897
|
+
: {}),
|
|
898
|
+
...(top.kind === "document" && bottom.kind === "document" && bottom.row >= pastVisibleRow
|
|
899
|
+
&& ordered.end.line >= viewportHeight
|
|
900
|
+
? { below: { from: pastVisibleRow, to: bottom.row } }
|
|
901
|
+
: {}),
|
|
902
|
+
};
|
|
791
903
|
}
|
|
792
904
|
function visibleTextSelection(selection, rowCount, firstRow) {
|
|
793
905
|
if (selection === undefined || rowCount <= firstRow || selection.end.line < firstRow || selection.start.line >= rowCount)
|
|
@@ -963,6 +1075,15 @@ function assertDocumentRange(range, label) {
|
|
|
963
1075
|
function sameRectangle(left, right) {
|
|
964
1076
|
return left === null ? right === null : right !== null && left.rowStart === right.rowStart && left.rowEnd === right.rowEnd;
|
|
965
1077
|
}
|
|
1078
|
+
function copyableDockRowsBySuffix(dockRows, declarations) {
|
|
1079
|
+
const result = new Map();
|
|
1080
|
+
for (const declaration of declarations ?? []) {
|
|
1081
|
+
if (!Number.isSafeInteger(declaration.row) || declaration.row < 0 || declaration.row >= dockRows.length)
|
|
1082
|
+
continue;
|
|
1083
|
+
result.set(dockRows.length - declaration.row - 1, declaration.prompt === undefined ? {} : { prompt: declaration.prompt });
|
|
1084
|
+
}
|
|
1085
|
+
return result;
|
|
1086
|
+
}
|
|
966
1087
|
function clamp(value, minimum, maximum) {
|
|
967
1088
|
return Math.min(Math.max(value, minimum), maximum);
|
|
968
1089
|
}
|