@timurproko/a1 0.2.6 → 0.2.7-dev.1221
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 +196 -908
- package/dist/app/session-shell/session-shell.d.ts +3 -8
- package/dist/app/session-shell/session-shell.js +324 -835
- package/dist/app/session-shell/session-viewport-controller.d.ts +2 -2
- package/dist/app/session-shell/session-viewport-controller.js +29 -15
- 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 +102 -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 +205 -153
- 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 -1
- package/dist/composition/settings-route-host.js +29 -10
- package/dist/composition/settings-search-input.d.ts +9 -0
- package/dist/composition/settings-search-input.js +58 -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 +242 -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 +76 -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-screen-app.d.ts +2 -0
- package/dist/features/owned-ui/reference-screen-app.js +12 -2
- package/dist/features/owned-ui/settings-app.d.ts +12 -2
- package/dist/features/owned-ui/settings-app.js +116 -81
- 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 +90 -6
- 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 +73 -4
- 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.js +35 -30
- package/dist/ui/components/index.d.ts +2 -2
- package/dist/ui/components/index.js +1 -1
- 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/selection-copy.d.ts +2 -0
- package/dist/ui/components/selection-copy.js +13 -0
- 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.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 +176 -55
- 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 +648 -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,7 +1,7 @@
|
|
|
1
1
|
import type { PiTuiPointerSurface } from "../../integrations/pi/tui-runtime/contracts.js";
|
|
2
2
|
import type { OwnedUiViewportSettings } from "../../contracts/owned-ui/index.js";
|
|
3
3
|
import { type TranscriptViewportFrame, type TranscriptViewportFrameInput } from "../../ui/components/transcript-viewport.js";
|
|
4
|
-
import type
|
|
4
|
+
import { type SelectionCopySnapshot } from "../../ui/components/selection-copy.js";
|
|
5
5
|
import type { PiShellEditorPort } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
6
6
|
import type { PasteEvent } from "./paste-protocol.js";
|
|
7
7
|
export interface SessionViewportControllerOptions {
|
|
@@ -64,7 +64,7 @@ export declare class SessionViewportController {
|
|
|
64
64
|
setOverlaySurfaces(surfaces: readonly PiTuiPointerSurface[] | null): void;
|
|
65
65
|
get inputGeometryReady(): boolean;
|
|
66
66
|
compose(input: Omit<TranscriptViewportFrameInput, "pointerPosition">): TranscriptViewportFrame;
|
|
67
|
-
composeDockOnly(dockRows: readonly string[], width: number, height: number): TranscriptViewportFrame | null;
|
|
67
|
+
composeDockOnly(dockRows: readonly string[], width: number, height: number, copyableDockRows?: TranscriptViewportFrameInput["copyableDockRows"]): TranscriptViewportFrame | null;
|
|
68
68
|
/** Returns true when document wrapping may have changed. */
|
|
69
69
|
setConfig(config: OwnedUiViewportSettings): boolean;
|
|
70
70
|
resumeFollowing(): void;
|
|
@@ -3,6 +3,7 @@ import { TranscriptViewport } from "../../ui/components/transcript-viewport.js";
|
|
|
3
3
|
import { readVisibleHyperlinks } from "../../ui/components/visible-hyperlinks.js";
|
|
4
4
|
import { routeMouseInput } from "../../ui/components/mouse.js";
|
|
5
5
|
import { scrollForTrackPage, scrollForThumbRow, scrollbarSelectionRows, scrollbarWheelRows } from "../../ui/components/scrollbar.js";
|
|
6
|
+
import { literalSelectionCopySnapshot } from "../../ui/components/selection-copy.js";
|
|
6
7
|
function withinTailControl(region, column, row) {
|
|
7
8
|
return row >= region.rowStart && row <= region.rowEnd && column >= region.columnStart && column <= region.columnEnd;
|
|
8
9
|
}
|
|
@@ -22,6 +23,7 @@ export class SessionViewportController {
|
|
|
22
23
|
#pasteDiagnosticRequest = 0;
|
|
23
24
|
#viewport = new TranscriptViewport();
|
|
24
25
|
#config = {
|
|
26
|
+
timeFormat: "8:00 PM",
|
|
25
27
|
scrollbarAppearance: "auto",
|
|
26
28
|
scrollbarStyle: "thin",
|
|
27
29
|
scrollbarSpeed: "normal",
|
|
@@ -165,16 +167,18 @@ export class SessionViewportController {
|
|
|
165
167
|
}
|
|
166
168
|
return frame;
|
|
167
169
|
}
|
|
168
|
-
composeDockOnly(dockRows, width, height) {
|
|
169
|
-
return this.#viewport.composeDockOnly(dockRows, width, height);
|
|
170
|
+
composeDockOnly(dockRows, width, height, copyableDockRows = []) {
|
|
171
|
+
return this.#viewport.composeDockOnly(dockRows, width, height, copyableDockRows);
|
|
170
172
|
}
|
|
171
173
|
/** Returns true when document wrapping may have changed. */
|
|
172
174
|
setConfig(config) {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
175
|
+
const normalized = { ...config, timeFormat: config.timeFormat ?? "8:00 PM" };
|
|
176
|
+
const layoutChanged = normalized.scrollbarAppearance !== this.#config.scrollbarAppearance
|
|
177
|
+
|| normalized.timeFormat !== this.#config.timeFormat;
|
|
178
|
+
this.#config = normalized;
|
|
179
|
+
this.#viewport.setConfig(normalized);
|
|
176
180
|
this.#requestRender();
|
|
177
|
-
return
|
|
181
|
+
return layoutChanged;
|
|
178
182
|
}
|
|
179
183
|
resumeFollowing() {
|
|
180
184
|
if (!this.#enabled)
|
|
@@ -302,11 +306,9 @@ export class SessionViewportController {
|
|
|
302
306
|
});
|
|
303
307
|
}
|
|
304
308
|
if (data === "\u0003") {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
else if (this.#viewport.hasSelection) {
|
|
309
|
+
// Invariant: the newest complete-frame gesture owns explicit copy even if an
|
|
310
|
+
// older editor word/line selection remains painted beneath it.
|
|
311
|
+
if (this.#viewport.hasSelection) {
|
|
310
312
|
const copySelection = this.#viewport.captureSelectedText();
|
|
311
313
|
this.#viewport.clearSelection();
|
|
312
314
|
this.#stopSelectionAutoScroll();
|
|
@@ -315,9 +317,13 @@ export class SessionViewportController {
|
|
|
315
317
|
? { data: "", consumed: true }
|
|
316
318
|
: { data: "", consumed: true, copySelection };
|
|
317
319
|
}
|
|
320
|
+
if (editorActive && this.#editor.hasSelection()) {
|
|
321
|
+
if (this.#viewport.clearSelection())
|
|
322
|
+
this.#requestRender();
|
|
323
|
+
}
|
|
318
324
|
}
|
|
319
|
-
const previousPrompt =
|
|
320
|
-
if (editorActive && allowWheel && (previousPrompt ||
|
|
325
|
+
const previousPrompt = PROMPT_UP_INPUTS.has(data) || this.#editor.matchesTerminalKey(data, "alt+home");
|
|
326
|
+
if (editorActive && allowWheel && (previousPrompt || PROMPT_DOWN_INPUTS.has(data))) {
|
|
321
327
|
const scrolled = previousPrompt
|
|
322
328
|
? this.#viewport.scrollToPreviousPrompt(now)
|
|
323
329
|
: this.#viewport.scrollToNextPrompt(now);
|
|
@@ -541,6 +547,12 @@ export class SessionViewportController {
|
|
|
541
547
|
const editorRow = pendingEditorClick.row - this.#editorPointerFrame.rowStart + 1;
|
|
542
548
|
this.#editor.handlePointer({ kind: "press", button: 0, column: pendingEditorClick.column, row: editorRow });
|
|
543
549
|
this.#editor.handlePointer({ kind: "release", button: 0, column: pendingEditorClick.column, row: editorRow });
|
|
550
|
+
if (this.#copyOnSelect) {
|
|
551
|
+
const selected = this.#editor.selectedText?.();
|
|
552
|
+
if (selected !== undefined) {
|
|
553
|
+
completedCopy = literalSelectionCopySnapshot(selected, this.#viewport.selectionRevision) ?? undefined;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
544
556
|
}
|
|
545
557
|
forceRepaint = true;
|
|
546
558
|
repaint = true;
|
|
@@ -658,5 +670,7 @@ export class SessionViewportController {
|
|
|
658
670
|
}
|
|
659
671
|
const SELECTION_AUTO_SCROLL_INTERVAL_MS = 30;
|
|
660
672
|
const EDITOR_LINK_DELETION_INPUTS = new Set(["\b", "\u007f", "\u001b[3~"]);
|
|
661
|
-
|
|
662
|
-
|
|
673
|
+
// Platform: Windows Terminal may consume Shift+Arrow for native selection. Ctrl+Arrow matches
|
|
674
|
+
// solo A1's Windows binding while retaining Shift+Arrow whenever the terminal delivers it.
|
|
675
|
+
const PROMPT_UP_INPUTS = new Set(["\u001b[1;2A", "\u001b[1;5A"]);
|
|
676
|
+
const PROMPT_DOWN_INPUTS = new Set(["\u001b[1;2B", "\u001b[1;5B"]);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OwnedUiSessionSettingsPort, OwnedUiSessionSettingsSnapshot } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { OwnedUiPresenterTerminal } from "./shell-host.js";
|
|
3
|
+
import type { OwnedUiSessionShellRoot } from "./session-shell-root.js";
|
|
4
|
+
/** What the session's live setting effects reach: terminal modes, root presentation, and the presenter's progress flag. */
|
|
5
|
+
export interface SessionSettingsTargets {
|
|
6
|
+
readonly terminal: Pick<OwnedUiPresenterTerminal, "setHardwareCursor" | "setClearOnShrink" | "setWheelScrollLines">;
|
|
7
|
+
readonly root: Pick<OwnedUiSessionShellRoot, "setEditorPaddingX" | "setAutocompleteMaxVisible" | "setOutputPad" | "setHideThinkingBlock" | "setMermaidRenderingMode" | "setImagePresentation" | "setFullscreenCopyOnSelect">;
|
|
8
|
+
setTerminalProgress(enabled: boolean): void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Applies the snapshot's presentation settings, then binds every live setting effect the session
|
|
12
|
+
* owns, one owner at a time. The returned function releases the owners in reverse; a failed bind
|
|
13
|
+
* releases the owners already bound before it throws.
|
|
14
|
+
*/
|
|
15
|
+
export declare function bindSessionSettings(settings: Pick<OwnedUiSessionSettingsPort, "bindOwner" | "productMode">, snapshot: OwnedUiSessionSettingsSnapshot, targets: SessionSettingsTargets, options: {
|
|
16
|
+
readonly customViewport: boolean;
|
|
17
|
+
}): () => void;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const isBoolean = (value) => typeof value === "boolean";
|
|
2
|
+
const isNumber = (value) => typeof value === "number";
|
|
3
|
+
const isOutputPad = (value) => value === 0 || value === 1;
|
|
4
|
+
const isMermaidMode = (value) => value === "off" || value === "final" || value === "streaming";
|
|
5
|
+
const isImageWidth = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
|
|
6
|
+
const isWheelDistance = (value) => value === "auto" || typeof value === "number" && Number.isSafeInteger(value) && value >= 1 && value <= 100;
|
|
7
|
+
function snapshotValue(snapshot, key) {
|
|
8
|
+
const values = snapshot;
|
|
9
|
+
return values[key];
|
|
10
|
+
}
|
|
11
|
+
/** One validated setting; `seeded` also installs the snapshot's value at bind time. */
|
|
12
|
+
function setting(owner, key, invalid, accepts, apply, seeded = true) {
|
|
13
|
+
return {
|
|
14
|
+
owner,
|
|
15
|
+
key,
|
|
16
|
+
live: value => {
|
|
17
|
+
if (!accepts(value))
|
|
18
|
+
throw new TypeError(invalid);
|
|
19
|
+
apply(value);
|
|
20
|
+
},
|
|
21
|
+
...(seeded ? {
|
|
22
|
+
seed: (snapshot) => {
|
|
23
|
+
const value = snapshotValue(snapshot, key);
|
|
24
|
+
if (accepts(value))
|
|
25
|
+
apply(value);
|
|
26
|
+
},
|
|
27
|
+
} : {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function settingBindings(targets, snapshot, customViewport, bare) {
|
|
31
|
+
const { root, terminal } = targets;
|
|
32
|
+
let showImages = snapshot.showImages;
|
|
33
|
+
let imageWidthCells = snapshot.imageWidthCells;
|
|
34
|
+
const presentImages = () => root.setImagePresentation(showImages, imageWidthCells);
|
|
35
|
+
return [
|
|
36
|
+
// Invariant: bare A1 prints only the resume hint at exit, so the pinned exit-output
|
|
37
|
+
// choice is hidden there and cannot be bound; the comparison profile binds and honors it.
|
|
38
|
+
...(bare ? [] : [{ owner: "shutdown", key: "fullscreenExitOutput", live: () => { } }]),
|
|
39
|
+
setting("terminal", "showHardwareCursor", "Hardware cursor setting is invalid", isBoolean, value => terminal.setHardwareCursor(value)),
|
|
40
|
+
setting("terminal", "clearOnShrink", "Clear-on-shrink setting is invalid", isBoolean, value => terminal.setClearOnShrink(value)),
|
|
41
|
+
setting("terminal", "showTerminalProgress", "Terminal progress setting is invalid", isBoolean, value => targets.setTerminalProgress(value)),
|
|
42
|
+
setting("shell", "editorPaddingX", "Editor padding is invalid", isNumber, value => root.setEditorPaddingX(value)),
|
|
43
|
+
setting("shell", "autocompleteMaxVisible", "Autocomplete maximum is invalid", isNumber, value => root.setAutocompleteMaxVisible(value)),
|
|
44
|
+
setting("shell", "outputPad", "Output padding is invalid", isOutputPad, value => root.setOutputPad(value)),
|
|
45
|
+
setting("shell", "hideThinkingBlock", "Thinking-block visibility is invalid", isBoolean, value => root.setHideThinkingBlock(value)),
|
|
46
|
+
setting("shell", "mermaidRenderingMode", "Mermaid mode is invalid", isMermaidMode, value => root.setMermaidRenderingMode(value)),
|
|
47
|
+
setting("shell", "showImages", "Image visibility is invalid", isBoolean, value => { showImages = value; presentImages(); }, false),
|
|
48
|
+
setting("shell", "imageWidthCells", "Image width is invalid", isImageWidth, value => { imageWidthCells = value; presentImages(); }, false),
|
|
49
|
+
{ owner: null, key: "imageWidthCells", live: () => { }, seed: presentImages },
|
|
50
|
+
// Invariant: the custom viewport owns copy-on-select; the pinned comparison profile keeps Pi's wheel distance.
|
|
51
|
+
customViewport
|
|
52
|
+
? setting("shell", "fullscreenCopyOnSelect", "Fullscreen copy-on-select setting is invalid", isBoolean, value => root.setFullscreenCopyOnSelect(value))
|
|
53
|
+
: setting("shell", "fullscreenWheelScrollLines", "Fullscreen wheel-scroll distance is invalid", isWheelDistance, value => terminal.setWheelScrollLines(value), false),
|
|
54
|
+
...(customViewport ? [] : [{
|
|
55
|
+
owner: null,
|
|
56
|
+
key: "fullscreenCopyOnSelect",
|
|
57
|
+
live: () => { },
|
|
58
|
+
seed: (initial) => root.setFullscreenCopyOnSelect(initial.fullscreenCopyOnSelect),
|
|
59
|
+
}]),
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Applies the snapshot's presentation settings, then binds every live setting effect the session
|
|
64
|
+
* owns, one owner at a time. The returned function releases the owners in reverse; a failed bind
|
|
65
|
+
* releases the owners already bound before it throws.
|
|
66
|
+
*/
|
|
67
|
+
export function bindSessionSettings(settings, snapshot, targets, options) {
|
|
68
|
+
const bindings = settingBindings(targets, snapshot, options.customViewport, settings.productMode === "bare");
|
|
69
|
+
for (const binding of bindings)
|
|
70
|
+
binding.seed?.(snapshot);
|
|
71
|
+
const owners = [...new Set(bindings.flatMap(binding => binding.owner === null ? [] : [binding.owner]))];
|
|
72
|
+
const releases = [];
|
|
73
|
+
const release = () => {
|
|
74
|
+
for (const unbind of releases.splice(0).reverse())
|
|
75
|
+
unbind();
|
|
76
|
+
};
|
|
77
|
+
try {
|
|
78
|
+
for (const owner of owners) {
|
|
79
|
+
const handlers = {};
|
|
80
|
+
for (const binding of bindings.filter(candidate => candidate.owner === owner)) {
|
|
81
|
+
handlers[binding.key] = { apply: value => binding.live(value) };
|
|
82
|
+
}
|
|
83
|
+
releases.push(settings.bindOwner(owner, handlers));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
release();
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
return release;
|
|
91
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type PiShellEditorOptions, type PiShellEditorPort } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
2
|
+
import type { PasteEvent, PasteSource } from "./paste-protocol.js";
|
|
3
|
+
import type { PromptChipStore } from "./prompt-chips.js";
|
|
4
|
+
/** The shell callbacks the editor is wired to; the editor receives the whole object as its own options. */
|
|
5
|
+
export type ShellEditorHandlers = Omit<PiShellEditorOptions, "onChange" | "onToolsExpand" | "keybindingProfile"> & {
|
|
6
|
+
readonly requestRender: (force?: boolean) => void;
|
|
7
|
+
readonly onEditorChange?: (text: string) => void;
|
|
8
|
+
readonly captureClipboardPaste?: () => PasteSource;
|
|
9
|
+
readonly pasteDiagnostics?: (event: PasteEvent) => void;
|
|
10
|
+
};
|
|
11
|
+
export interface ShellEditorPorts {
|
|
12
|
+
readonly handlers: ShellEditorHandlers;
|
|
13
|
+
readonly customViewport: boolean;
|
|
14
|
+
readonly cwd: string;
|
|
15
|
+
readonly agentDir?: string;
|
|
16
|
+
readonly promptChips: PromptChipStore;
|
|
17
|
+
/** True while a pointer drag selects editor text, which paints links as plain underlines. */
|
|
18
|
+
readonly editorPointerSelecting: () => boolean;
|
|
19
|
+
/** The next payload-free paste diagnostic id, shared with the viewport's own paste diagnostics. */
|
|
20
|
+
readonly nextPasteDiagnosticRequest: () => number;
|
|
21
|
+
readonly toggleToolsExpanded: () => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Builds the session's prompt editor: chip-aware paste, selection, and hyperlink decoration over
|
|
25
|
+
* the Pi editor, plus bare A1's prompt presentation and terminal paste diagnostics.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createShellEditor(ports: ShellEditorPorts): PiShellEditorPort;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { caretCell } from "../../ui/components/line-input.js";
|
|
2
|
+
import { PromptInput } from "../../ui/components/prompt-input.js";
|
|
3
|
+
import { backgroundSgrSpan, hyperlinkSgrSpan } from "../../ui/components/spans.js";
|
|
4
|
+
import { faint, stripAnsi } from "../../ui/components/text.js";
|
|
5
|
+
import { createPiShellEditor } from "../../integrations/pi/components/shell-editor-autocomplete.js";
|
|
6
|
+
import { piTheme } from "../../integrations/pi/components/upstream/theme/theme.js";
|
|
7
|
+
import { piShellTruncateToWidth, piShellVisibleWidth, } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
8
|
+
import { EditorHyperlinkBudget } from "./editor-hyperlink-budget.js";
|
|
9
|
+
import { canPreparePasteInline } from "./paste-text-preparation.js";
|
|
10
|
+
/**
|
|
11
|
+
* Builds the session's prompt editor: chip-aware paste, selection, and hyperlink decoration over
|
|
12
|
+
* the Pi editor, plus bare A1's prompt presentation and terminal paste diagnostics.
|
|
13
|
+
*/
|
|
14
|
+
export function createShellEditor(ports) {
|
|
15
|
+
const { handlers, customViewport, promptChips } = ports;
|
|
16
|
+
let terminalPasteDiagnosticRequest;
|
|
17
|
+
const editor = createPiShellEditor({
|
|
18
|
+
...handlers,
|
|
19
|
+
keybindingProfile: customViewport ? "a1" : "pi",
|
|
20
|
+
...(handlers.keybindings === undefined ? {} : { keybindings: handlers.keybindings }),
|
|
21
|
+
paintEditorSelection: (line, from, to, atomic) => backgroundSgrSpan(line, from, to, atomic ? "\u001b[7m" : "\u001b[27m\u001b[48;2;38;79;120m", atomic ? "\u001b[27m" : "\u001b[49m", piShellVisibleWidth),
|
|
22
|
+
transformPastedContent: content => {
|
|
23
|
+
try {
|
|
24
|
+
return promptChips.transformPastedContent(content, editor.getText());
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
handlers.onPasteRejected?.(error);
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
...(customViewport ? {
|
|
32
|
+
beginClipboardPaste: () => promptChips.beginPaste(editor.getText(), handlers.captureClipboardPaste?.() ?? { kind: "provided", read: signal => handlers.readClipboardContent?.(signal) ?? Promise.resolve(null) }, error => handlers.onPasteRejected?.(error), () => handlers.requestRender()),
|
|
33
|
+
onPasteInput: (bytes, phase) => {
|
|
34
|
+
try {
|
|
35
|
+
if (phase === "framing")
|
|
36
|
+
terminalPasteDiagnosticRequest = ports.nextPasteDiagnosticRequest();
|
|
37
|
+
const request = terminalPasteDiagnosticRequest ?? ports.nextPasteDiagnosticRequest();
|
|
38
|
+
handlers.pasteDiagnostics?.({ request, phase, bytes, atMs: performance.now(), pending: 0, transport: "terminal",
|
|
39
|
+
...(phase === "settled" ? { outcome: "ready" } : {}) });
|
|
40
|
+
if (phase === "settled")
|
|
41
|
+
terminalPasteDiagnosticRequest = undefined;
|
|
42
|
+
}
|
|
43
|
+
catch { /* Invariant: payload-free diagnostics cannot interfere with the input path. */ }
|
|
44
|
+
},
|
|
45
|
+
deferTextPaste: text => !canPreparePasteInline(text),
|
|
46
|
+
beginTextPaste: text => promptChips.beginPaste(editor.getText(), { kind: "text", text }, error => handlers.onPasteRejected?.(error)),
|
|
47
|
+
} : {}),
|
|
48
|
+
editorAtomicRanges: line => promptChips.atomicRanges(line),
|
|
49
|
+
editorHiddenRanges: line => promptChips.hiddenRanges(line),
|
|
50
|
+
decorateEditorRow: editorRowDecorator(promptChips, ports.editorPointerSelecting),
|
|
51
|
+
expandCopiedEditorText: text => promptChips.expandCopiedText(text),
|
|
52
|
+
cwd: ports.cwd,
|
|
53
|
+
...(ports.agentDir === undefined ? {} : { agentDir: ports.agentDir }),
|
|
54
|
+
onToolsExpand: () => ports.toggleToolsExpanded(),
|
|
55
|
+
...(customViewport ? {
|
|
56
|
+
promptPresentation: {
|
|
57
|
+
input: new PromptInput({ fg: (token, text) => piTheme().fg(token, text) }, {
|
|
58
|
+
measure: piShellVisibleWidth,
|
|
59
|
+
truncate: piShellTruncateToWidth,
|
|
60
|
+
}),
|
|
61
|
+
styleSuggestion: faint,
|
|
62
|
+
styleSuggestionCaret: caretCell,
|
|
63
|
+
},
|
|
64
|
+
} : {}),
|
|
65
|
+
onChange: text => {
|
|
66
|
+
handlers.onEditorChange?.(text);
|
|
67
|
+
// Concurrency: Pi clears before onSubmit; capture waiting references before pruning removed chips.
|
|
68
|
+
queueMicrotask(() => promptChips.reconcileDraft(editor.getText()));
|
|
69
|
+
},
|
|
70
|
+
...(handlers.onPromptSuggestionAccepted === undefined ? {} : { onPromptSuggestionAccepted: handlers.onPromptSuggestionAccepted }),
|
|
71
|
+
});
|
|
72
|
+
return editor;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Dims unsent chips and turns the draft's URLs into terminal hyperlinks, each target once per
|
|
76
|
+
* decoration pass; while a pointer drag selects, links paint as plain underlines instead.
|
|
77
|
+
*/
|
|
78
|
+
function editorRowDecorator(promptChips, editorPointerSelecting) {
|
|
79
|
+
const editorHyperlinks = new EditorHyperlinkBudget();
|
|
80
|
+
return (row, width, rowIndex) => {
|
|
81
|
+
if (rowIndex === 0)
|
|
82
|
+
editorHyperlinks.reset();
|
|
83
|
+
const plain = stripAnsi(row);
|
|
84
|
+
const dimmed = promptChips.unsentRanges(plain).reduce((result, range) => backgroundSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), "\u001b[2m", "\u001b[22m", piShellVisibleWidth), row);
|
|
85
|
+
const ranges = promptChips.hyperlinkRanges(plain);
|
|
86
|
+
if (ranges.length === 0 || !editorHyperlinks.takeCleanup())
|
|
87
|
+
return dimmed;
|
|
88
|
+
const linkResetAndTail = `\u001b]8;;\u001b\\\u001b[24m${" ".repeat(Math.max(0, width - piShellVisibleWidth(dimmed)))}`;
|
|
89
|
+
// Platform: VS15 is zero-column and default-ignorable. It breaks Windows Terminal's
|
|
90
|
+
// plain-text URL detector only in the held-button paint; semantic text stays exact.
|
|
91
|
+
const selecting = editorPointerSelecting();
|
|
92
|
+
const paintRow = selecting
|
|
93
|
+
? dimmed.replaceAll("https://", "https:︎//").replaceAll("http://", "http:︎//")
|
|
94
|
+
: dimmed;
|
|
95
|
+
const decorated = selecting
|
|
96
|
+
? ranges.reduce((result, range) => backgroundSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), "\u001b[4:4m", "\u001b[24m", piShellVisibleWidth), paintRow)
|
|
97
|
+
: ranges.filter(range => editorHyperlinks.take(range.target)).reduce((result, range) => hyperlinkSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), range.target, piShellVisibleWidth), dimmed);
|
|
98
|
+
// Platform: Windows Terminal can retain stale native dotted-link cells when a mutable
|
|
99
|
+
// prompt replaces a longer URL. Explicit non-link spaces overwrite that tail.
|
|
100
|
+
return `${decorated}${linkResetAndTail}`;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -78,6 +78,12 @@ export interface OwnedUiTerminalHostOptions {
|
|
|
78
78
|
readonly backgroundSettings?: OwnedUiBackgroundSettingsPort;
|
|
79
79
|
readonly quitOutro?: OwnedUiShellPresentationOptions["quitOutro"];
|
|
80
80
|
}
|
|
81
|
+
/** The size and render request a Pi component reads from the terminal it is shown on, read on every call. */
|
|
82
|
+
export declare function componentRuntime(terminal: Pick<OwnedUiPresenterTerminal, "viewport" | "requestRender">): {
|
|
83
|
+
getColumns(): number;
|
|
84
|
+
getRows(): number;
|
|
85
|
+
requestRender(): void;
|
|
86
|
+
};
|
|
81
87
|
/** The terminal a session's shell options call for: its layout, TUI mode, cursor, and presentation seams. */
|
|
82
88
|
export declare function sessionTerminalHostOptions(options: OwnedUiSessionShellOptions): OwnedUiTerminalHostOptions;
|
|
83
89
|
/**
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { MOUSE_TRACKING_OFF, MOUSE_TRACKING_ON, parseMouseInput } from "../../ui/components/mouse.js";
|
|
2
2
|
import { readVisibleHyperlinks } from "../../ui/components/visible-hyperlinks.js";
|
|
3
3
|
import { piCanvasBackgroundAnsi } from "../../integrations/pi/components/theme.js";
|
|
4
|
+
import { residentFixtureControl } from "../../foundation/resident-tabs/fixture-control.js";
|
|
5
|
+
import { residentProgressObserver } from "../../foundation/resident-tabs/progress-observation.js";
|
|
4
6
|
import { DamageAwareTerminalAdapter, } from "../../integrations/pi/tui-runtime/damage-aware-terminal.js";
|
|
5
|
-
import { PiTuiRuntimeAdapter } from "../../integrations/pi/tui-runtime/adapter.js";
|
|
7
|
+
import { PiTuiRuntimeAdapter, legacyKeyInput } from "../../integrations/pi/tui-runtime/adapter.js";
|
|
6
8
|
import { classifyPiTuiInput } from "../../integrations/pi/tui-runtime/input-presentation-coordinator.js";
|
|
7
9
|
import { pinnedLayoutRoot, } from "./session-shell-root.js";
|
|
10
|
+
/** The size and render request a Pi component reads from the terminal it is shown on, read on every call. */
|
|
11
|
+
export function componentRuntime(terminal) {
|
|
12
|
+
return {
|
|
13
|
+
getColumns: () => terminal.viewport().columns,
|
|
14
|
+
getRows: () => terminal.viewport().rows,
|
|
15
|
+
requestRender: () => terminal.requestRender(),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
8
18
|
/** The terminal a session's shell options call for: its layout, TUI mode, cursor, and presentation seams. */
|
|
9
19
|
export function sessionTerminalHostOptions(options) {
|
|
10
20
|
const { backend, sessionLayout } = options.engine;
|
|
@@ -47,6 +57,8 @@ export class OwnedUiTerminalHost {
|
|
|
47
57
|
this.#customViewport = options.layout === "custom-viewport";
|
|
48
58
|
this.#quitOutro = options.quitOutro;
|
|
49
59
|
const input = options.input;
|
|
60
|
+
const fixtureControl = residentFixtureControl();
|
|
61
|
+
const progressObserver = residentProgressObserver();
|
|
50
62
|
let damageTerminal;
|
|
51
63
|
const surface = {
|
|
52
64
|
render: width => this.#active?.render(width) ?? [],
|
|
@@ -72,6 +84,13 @@ export class OwnedUiTerminalHost {
|
|
|
72
84
|
inspectHyperlinks: readVisibleHyperlinks,
|
|
73
85
|
onResize: () => this.#active?.noteImmediatePresentation(),
|
|
74
86
|
onHyperlinkCleanupRequired: () => this.runtime?.requestRender(true),
|
|
87
|
+
...(fixtureControl === null ? {} : {
|
|
88
|
+
allowWrite: () => !fixtureControl.stopped("child-render-write"),
|
|
89
|
+
writeChunks: data => fixtureControl.fragmentChildWrite(data),
|
|
90
|
+
}),
|
|
91
|
+
...(progressObserver === null ? {} : {
|
|
92
|
+
onWrite: ({ bytes, fragments, transaction, frameId, cause }) => progressObserver.childRenderWrite(bytes, fragments, transaction, frameId, cause),
|
|
93
|
+
}),
|
|
75
94
|
});
|
|
76
95
|
return damageTerminal;
|
|
77
96
|
},
|
|
@@ -83,10 +102,13 @@ export class OwnedUiTerminalHost {
|
|
|
83
102
|
},
|
|
84
103
|
}),
|
|
85
104
|
} : { layoutRoot: pinnedLayoutRoot(this.#delegatingLayoutParts()) }),
|
|
86
|
-
...(input?.onEvent === undefined ? {} : {
|
|
105
|
+
...(input?.onEvent === undefined && progressObserver === null ? {} : {
|
|
87
106
|
inputDiagnostics: {
|
|
88
|
-
onEvent:
|
|
89
|
-
|
|
107
|
+
onEvent: event => {
|
|
108
|
+
input?.onEvent?.(event);
|
|
109
|
+
progressObserver?.inputPhase?.(event.phase, event.revision);
|
|
110
|
+
},
|
|
111
|
+
...(input?.now === undefined ? {} : { now: input.now }),
|
|
90
112
|
},
|
|
91
113
|
}),
|
|
92
114
|
...(options.terminal === undefined ? {} : { terminal: options.terminal }),
|
|
@@ -146,6 +168,8 @@ export class OwnedUiTerminalHost {
|
|
|
146
168
|
active() {
|
|
147
169
|
return this.#active;
|
|
148
170
|
}
|
|
171
|
+
// Invariant: resident tab visibility never gates rendering here; a hidden tab keeps painting into its
|
|
172
|
+
// resident terminal, and the native holder alone withholds inactive surfaces from attach clients.
|
|
149
173
|
requestRender(from, force = false) {
|
|
150
174
|
if (from === this.#active)
|
|
151
175
|
this.runtime.requestRender(force);
|
|
@@ -335,7 +359,8 @@ export class OwnedUiTerminalHost {
|
|
|
335
359
|
callbacks.closed(rendered);
|
|
336
360
|
};
|
|
337
361
|
removeInterruptWatch = runtime.addInputListener(data => {
|
|
338
|
-
|
|
362
|
+
// Compatibility: a kitty-keyboard child reports Ctrl+C as a CSI-u sequence rather than the byte.
|
|
363
|
+
if (!attached() || !data.includes(INTERRUPT) && legacyKeyInput(data) !== INTERRUPT)
|
|
339
364
|
return undefined;
|
|
340
365
|
// Protocol: route hosts decide whether one interrupt closes their app. Raw-input forwarding
|
|
341
366
|
// is required because Pi handles Ctrl+C before the fullscreen overlay receives normal input.
|
|
@@ -393,8 +418,10 @@ export class OwnedUiTerminalHost {
|
|
|
393
418
|
const { events, rest } = parseMouseInput(data);
|
|
394
419
|
for (const event of events)
|
|
395
420
|
surface.handleMouse(event);
|
|
396
|
-
|
|
397
|
-
|
|
421
|
+
// Invariant: owned screens see legacy key bytes whether the terminal reports legacy or kitty keys.
|
|
422
|
+
const key = rest.length > 0 ? legacyKeyInput(rest) : "";
|
|
423
|
+
if (key.length > 0)
|
|
424
|
+
surface.handleInput(key);
|
|
398
425
|
if (surface.isClosed()) {
|
|
399
426
|
closeSurface(true);
|
|
400
427
|
return;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { OwnedUiSessionViewModel } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { TranscriptViewportFrame, TranscriptViewportFrameInput, TranscriptViewportTheme } from "../../ui/components/transcript-viewport.js";
|
|
3
|
+
import type { PiShellEditorPort } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
4
|
+
import type { DockChrome } from "./dock-chrome.js";
|
|
5
|
+
import type { InputSurfaceSwitch } from "./input-surface-switch.js";
|
|
6
|
+
import type { PromptChipStore } from "./prompt-chips.js";
|
|
7
|
+
import type { SessionViewportController } from "./session-viewport-controller.js";
|
|
8
|
+
import type { TranscriptDocumentLayout } from "./transcript-document.js";
|
|
9
|
+
/** The dock's rows and where its input and footer sit inside them. */
|
|
10
|
+
export interface DockLayout {
|
|
11
|
+
readonly rows: readonly string[];
|
|
12
|
+
readonly inputOffset: number;
|
|
13
|
+
readonly editorOffset: number;
|
|
14
|
+
readonly inputRows: number;
|
|
15
|
+
readonly footerRows: number;
|
|
16
|
+
/** Exact status, warning, error, command-result, and notice rows; queued and structural rows stay excluded. */
|
|
17
|
+
readonly copyableMessageRows: NonNullable<TranscriptViewportFrameInput["copyableDockRows"]>;
|
|
18
|
+
}
|
|
19
|
+
/** What a layout reads from the shell root to compose one frame. */
|
|
20
|
+
export interface ShellLayoutPorts {
|
|
21
|
+
readonly viewport: SessionViewportController;
|
|
22
|
+
readonly input: InputSurfaceSwitch;
|
|
23
|
+
readonly editor: Pick<PiShellEditorPort, "getText">;
|
|
24
|
+
readonly promptChips: Pick<PromptChipStore, "atomicRanges">;
|
|
25
|
+
readonly dockChrome: Pick<DockChrome, "renderCopyAcknowledgement" | "renderReleaseBanner" | "locateReleaseClose">;
|
|
26
|
+
readonly theme: TranscriptViewportTheme;
|
|
27
|
+
readonly onFrame?: (frame: TranscriptViewportFrame) => void;
|
|
28
|
+
rows(): number;
|
|
29
|
+
dock(width: number): DockLayout;
|
|
30
|
+
document(width: number): TranscriptDocumentLayout;
|
|
31
|
+
queued(width: number): readonly string[];
|
|
32
|
+
liveStatus(width: number): readonly string[];
|
|
33
|
+
diagnostics(): OwnedUiSessionViewModel["diagnostics"];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* How one session's root composes a frame. The root picks one layout at construction and never
|
|
37
|
+
* consults the layout mode again on the render path.
|
|
38
|
+
*/
|
|
39
|
+
export interface ShellLayout {
|
|
40
|
+
render(width: number): readonly string[];
|
|
41
|
+
/** Visible content changed outside a render, so the next frame may not reuse the last one. */
|
|
42
|
+
invalidate(): void;
|
|
43
|
+
/** What the last composed frame represented, for payload-free evidence; undefined before one exists. */
|
|
44
|
+
composed(): {
|
|
45
|
+
readonly viewportRevision: number;
|
|
46
|
+
readonly pointerPosition: TranscriptViewportFrameInput["pointerPosition"];
|
|
47
|
+
} | undefined;
|
|
48
|
+
compositions(): {
|
|
49
|
+
readonly full: number;
|
|
50
|
+
readonly dockOnly: number;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** The pinned comparison profile: the whole document above the dock; the terminal host scrolls it. */
|
|
54
|
+
export declare class PinnedLayout implements ShellLayout {
|
|
55
|
+
#private;
|
|
56
|
+
constructor(ports: ShellLayoutPorts);
|
|
57
|
+
render(width: number): readonly string[];
|
|
58
|
+
invalidate(): void;
|
|
59
|
+
composed(): undefined;
|
|
60
|
+
compositions(): {
|
|
61
|
+
readonly full: number;
|
|
62
|
+
readonly dockOnly: number;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The pinned comparison profile: the whole document above the dock; the terminal host scrolls it. */
|
|
2
|
+
export class PinnedLayout {
|
|
3
|
+
#ports;
|
|
4
|
+
constructor(ports) {
|
|
5
|
+
this.#ports = ports;
|
|
6
|
+
}
|
|
7
|
+
render(width) {
|
|
8
|
+
this.#ports.viewport.setEditorPointerFrame(undefined);
|
|
9
|
+
return [...this.#ports.document(width).rows, ...this.#ports.dock(width).rows];
|
|
10
|
+
}
|
|
11
|
+
invalidate() { }
|
|
12
|
+
composed() {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
compositions() {
|
|
16
|
+
return { full: 0, dockOnly: 0 };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { OwnedUiEvent, OwnedUiPromptSuggestionIdentity, OwnedUiSessionViewModel, SuggestionDecision } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { ContextualPromptSuggestionController, ContextualPromptSuggestionSurface } from "./prompt-suggestion-controller.js";
|
|
3
|
+
import type { OwnedUiSessionShellRoot } from "./session-shell-root.js";
|
|
4
|
+
type ResponseEvent = Extract<OwnedUiEvent, {
|
|
5
|
+
readonly type: "assistant-message-completed" | "agent-run-settled";
|
|
6
|
+
}>;
|
|
7
|
+
/** The provider/model key a suggestion identity and the session view are compared by; empty without a model. */
|
|
8
|
+
export declare function suggestionModelKey(view: Pick<OwnedUiSessionViewModel, "activeModel">): string;
|
|
9
|
+
/**
|
|
10
|
+
* Why a completed response cannot seed a suggestion, checked in order; `prepareBlockReason` is asked
|
|
11
|
+
* only when the response itself qualifies.
|
|
12
|
+
*/
|
|
13
|
+
export declare function responseSuggestionDecision(event: ResponseEvent, prepareBlockReason: () => SuggestionDecision): SuggestionDecision;
|
|
14
|
+
/** Hands one completed or settled response to the controller: skipped without a model, otherwise considered or settled. */
|
|
15
|
+
export declare function routeResponseToSuggestions(controller: Pick<ContextualPromptSuggestionController, "skip" | "consider" | "settle"> | null, event: ResponseEvent, prepareBlockReason: () => SuggestionDecision): void;
|
|
16
|
+
export interface SuggestionPresentationState {
|
|
17
|
+
readonly disposed: boolean;
|
|
18
|
+
readonly view: Pick<OwnedUiSessionViewModel, "sessionId" | "activeModel">;
|
|
19
|
+
readonly sessionGeneration: number;
|
|
20
|
+
}
|
|
21
|
+
/** Why a prepared suggestion cannot be shown now: a released shell, a different session or model, or the root's own reason. */
|
|
22
|
+
export declare function suggestionPresentationBlockReason(identity: OwnedUiPromptSuggestionIdentity, state: SuggestionPresentationState, rootBlockReason: () => SuggestionDecision): SuggestionDecision;
|
|
23
|
+
/** The controller's view of the shell: ghost text in the root's editor, gated by `blockReason`. */
|
|
24
|
+
export declare function promptSuggestionSurface(root: Pick<OwnedUiSessionShellRoot, "canPresentPromptSuggestion" | "setPromptSuggestion">, blockReason: (identity: OwnedUiPromptSuggestionIdentity) => SuggestionDecision, requestRender: () => void): ContextualPromptSuggestionSurface;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** The provider/model key a suggestion identity and the session view are compared by; empty without a model. */
|
|
2
|
+
export function suggestionModelKey(view) {
|
|
3
|
+
return view.activeModel === null ? "" : `${view.activeModel.providerId}/${view.activeModel.modelId}`;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Why a completed response cannot seed a suggestion, checked in order; `prepareBlockReason` is asked
|
|
7
|
+
* only when the response itself qualifies.
|
|
8
|
+
*/
|
|
9
|
+
export function responseSuggestionDecision(event, prepareBlockReason) {
|
|
10
|
+
if (!event.successful)
|
|
11
|
+
return "failed-response";
|
|
12
|
+
if (event.toolContinuation || event.stopReason === "toolUse")
|
|
13
|
+
return "tool-continuation";
|
|
14
|
+
if (event.stopReason !== "stop")
|
|
15
|
+
return "incomplete-response";
|
|
16
|
+
if (event.assistantMessageCount < 2)
|
|
17
|
+
return "early-conversation";
|
|
18
|
+
return prepareBlockReason();
|
|
19
|
+
}
|
|
20
|
+
/** Hands one completed or settled response to the controller: skipped without a model, otherwise considered or settled. */
|
|
21
|
+
export function routeResponseToSuggestions(controller, event, prepareBlockReason) {
|
|
22
|
+
const identity = {
|
|
23
|
+
sessionId: event.sessionId,
|
|
24
|
+
sessionGeneration: event.sessionGeneration,
|
|
25
|
+
runSequence: event.runSequence,
|
|
26
|
+
responseSequence: event.responseSequence,
|
|
27
|
+
model: event.model,
|
|
28
|
+
};
|
|
29
|
+
if (event.model === null) {
|
|
30
|
+
controller?.skip(identity, "no-model");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const known = { ...identity, model: event.model };
|
|
34
|
+
const decision = responseSuggestionDecision(event, prepareBlockReason);
|
|
35
|
+
if (event.type === "assistant-message-completed")
|
|
36
|
+
controller?.consider(known, decision);
|
|
37
|
+
else
|
|
38
|
+
controller?.settle(known, decision);
|
|
39
|
+
}
|
|
40
|
+
/** Why a prepared suggestion cannot be shown now: a released shell, a different session or model, or the root's own reason. */
|
|
41
|
+
export function suggestionPresentationBlockReason(identity, state, rootBlockReason) {
|
|
42
|
+
if (state.disposed)
|
|
43
|
+
return "disposed";
|
|
44
|
+
if (identity.sessionId !== state.view.sessionId || identity.sessionGeneration !== state.sessionGeneration
|
|
45
|
+
|| suggestionModelKey(state.view) !== `${identity.model.providerId}/${identity.model.modelId}`)
|
|
46
|
+
return "stale-identity";
|
|
47
|
+
return rootBlockReason();
|
|
48
|
+
}
|
|
49
|
+
/** The controller's view of the shell: ghost text in the root's editor, gated by `blockReason`. */
|
|
50
|
+
export function promptSuggestionSurface(root, blockReason, requestRender) {
|
|
51
|
+
return {
|
|
52
|
+
canPresent: identity => blockReason(identity) === null,
|
|
53
|
+
presentationBlockReason: blockReason,
|
|
54
|
+
present: text => {
|
|
55
|
+
if (!root.canPresentPromptSuggestion())
|
|
56
|
+
return false;
|
|
57
|
+
root.setPromptSuggestion(text);
|
|
58
|
+
return true;
|
|
59
|
+
},
|
|
60
|
+
clear: () => root.setPromptSuggestion(null),
|
|
61
|
+
requestRender,
|
|
62
|
+
};
|
|
63
|
+
}
|