@timurproko/a1 0.2.7-dev.1249 → 0.2.7-dev.1255
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 +11 -36
- package/bin/cli.js +2 -17
- package/bin/ui.js +10 -51
- package/dist/app/session-shell/clipboard-diagnostics.d.ts +2 -2
- package/dist/app/session-shell/clipboard-image.d.ts +0 -1
- package/dist/app/session-shell/clipboard-image.js +1 -1
- package/dist/app/session-shell/dialog-coordinator.d.ts +6 -5
- package/dist/app/session-shell/dialog-coordinator.js +3 -4
- package/dist/app/session-shell/dock-chrome.d.ts +11 -6
- package/dist/app/session-shell/dock-chrome.js +5 -8
- package/dist/app/session-shell/editor-hyperlink-budget.d.ts +0 -2
- package/dist/app/session-shell/editor-hyperlink-budget.js +1 -1
- package/dist/app/session-shell/exit-notice.d.ts +3 -3
- package/dist/app/session-shell/exit-notice.js +10 -10
- package/dist/app/session-shell/extension-surface.d.ts +8 -7
- package/dist/app/session-shell/helper-pool.d.ts +3 -4
- package/dist/app/session-shell/helper-pool.js +1 -1
- package/dist/app/session-shell/image-preparation-client.d.ts +4 -3
- package/dist/app/session-shell/image-preparation.d.ts +0 -2
- package/dist/app/session-shell/image-preparation.js +2 -2
- package/dist/app/session-shell/image-source.d.ts +2 -3
- package/dist/app/session-shell/image-source.js +2 -2
- package/dist/app/session-shell/input-surface-switch.d.ts +9 -7
- package/dist/app/session-shell/input-surface-switch.js +1 -2
- package/dist/app/session-shell/login-interaction.d.ts +5 -4
- package/dist/app/session-shell/login-interaction.js +2 -3
- package/dist/app/session-shell/paste-executor.d.ts +4 -8
- package/dist/app/session-shell/paste-executor.js +2 -2
- package/dist/app/session-shell/paste-protocol.d.ts +2 -2
- package/dist/app/session-shell/path-chip-presentation.d.ts +0 -5
- package/dist/app/session-shell/path-chip-presentation.js +3 -3
- package/dist/app/session-shell/prompt-chips.d.ts +8 -7
- package/dist/app/session-shell/prompt-history-controller.d.ts +3 -3
- package/dist/app/session-shell/prompt-submission.d.ts +7 -6
- package/dist/app/session-shell/prompt-submission.js +7 -28
- package/dist/app/session-shell/quit-outro-effects.d.ts +3 -3
- package/dist/app/session-shell/quit-outro-effects.js +1 -4
- package/dist/app/session-shell/quit-outro.d.ts +9 -12
- package/dist/app/session-shell/quit-outro.js +11 -11
- package/dist/app/session-shell/response-copy-protocol.d.ts +3 -2
- package/dist/app/session-shell/response-copy-transport.d.ts +2 -14
- package/dist/app/session-shell/response-copy-transport.js +2 -3
- package/dist/app/session-shell/session-lifecycle.d.ts +3 -3
- package/dist/app/session-shell/session-lifecycle.js +2 -4
- package/dist/app/session-shell/session-shell-root.d.ts +74 -120
- package/dist/app/session-shell/session-shell-root.js +82 -115
- package/dist/app/session-shell/session-shell.d.ts +13 -16
- package/dist/app/session-shell/session-shell.js +149 -314
- package/dist/app/session-shell/session-viewport-controller.d.ts +7 -6
- package/dist/app/session-shell/session-viewport-controller.js +5 -8
- package/dist/app/session-shell/settings-bindings.d.ts +24 -2
- package/dist/app/session-shell/settings-bindings.js +24 -0
- package/dist/app/session-shell/share-operation.d.ts +3 -3
- package/dist/app/session-shell/share-operation.js +4 -6
- package/dist/app/session-shell/shell-clipboard.d.ts +59 -0
- package/dist/app/session-shell/shell-clipboard.js +119 -0
- package/dist/app/session-shell/shell-editor-factory.d.ts +8 -4
- package/dist/app/session-shell/shell-editor-factory.js +13 -15
- package/dist/app/session-shell/shell-host.d.ts +16 -17
- package/dist/app/session-shell/shell-host.js +20 -37
- package/dist/app/session-shell/shell-layout.d.ts +2 -2
- package/dist/app/session-shell/shell-prompt-suggestions.d.ts +26 -0
- package/dist/app/session-shell/shell-prompt-suggestions.js +48 -0
- package/dist/app/session-shell/suggestion-surface.d.ts +1 -6
- package/dist/app/session-shell/suggestion-surface.js +1 -1
- package/dist/app/session-shell/system-clipboard.d.ts +2 -14
- package/dist/app/session-shell/system-clipboard.js +2 -7
- package/dist/app/session-shell/transcript-document.d.ts +12 -10
- package/dist/app/session-shell/transcript-document.js +15 -41
- package/dist/app/session-shell/viewport-layout.d.ts +2 -2
- package/dist/app/session-shell/workflow-output.d.ts +5 -3
- package/dist/app/session-shell/workflow-output.js +13 -15
- package/dist/app/session-shell/workflow-router.d.ts +1 -3
- package/dist/app/session-shell/workflow-router.js +1 -4
- package/dist/cli/dispatch.d.ts +1 -11
- package/dist/cli/dispatch.js +5 -92
- package/dist/cli/package-messages.d.ts +0 -1
- package/dist/cli/package-messages.js +1 -1
- package/dist/cli/session-context.d.ts +1 -1
- package/dist/cli/session-context.js +5 -7
- package/dist/cli/uninstall.d.ts +4 -7
- package/dist/cli/uninstall.js +6 -35
- package/dist/cli/version-stats.js +4 -7
- package/dist/composition/owned-settings.d.ts +2 -2
- package/dist/composition/owned-settings.js +0 -4
- package/dist/composition/owned-ui.d.ts +3 -25
- package/dist/composition/owned-ui.js +37 -113
- package/dist/composition/reference-selection-options.d.ts +1 -1
- package/dist/composition/reference-selection-options.js +1 -1
- package/dist/composition/release-update-observation.d.ts +4 -4
- package/dist/composition/release-update-observation.js +17 -47
- package/dist/composition/session-backend.d.ts +0 -1
- package/dist/composition/session-runtime-registry.d.ts +5 -4
- package/dist/composition/settings-route-host.d.ts +0 -7
- package/dist/composition/settings-route-host.js +7 -20
- package/dist/composition/settings-search-input.d.ts +2 -1
- package/dist/composition/startup-route.d.ts +2 -3
- package/dist/composition/startup-route.js +2 -3
- package/dist/contracts/owned-ui/extension-ui.d.ts +2 -1
- package/dist/contracts/owned-ui/index.d.ts +2 -1
- package/dist/contracts/owned-ui/model.d.ts +0 -3
- package/dist/contracts/owned-ui/session-presenters.d.ts +3 -0
- package/dist/contracts/owned-ui/session-workflows.d.ts +1 -4
- package/dist/contracts/owned-ui/shell-components.d.ts +543 -0
- package/dist/contracts/presentation/component.d.ts +17 -0
- package/dist/contracts/presentation/component.js +8 -0
- package/dist/contracts/presentation/index.d.ts +6 -15
- package/dist/contracts/presentation/index.js +2 -0
- package/dist/contracts/presentation/terminal.d.ts +290 -0
- package/dist/contracts/presentation/theme.d.ts +46 -0
- package/dist/features/launch/development-launch.js +1 -2
- package/dist/features/launch/index.d.ts +1 -1
- package/dist/features/launch/intent.d.ts +1 -3
- package/dist/features/launch/intent.js +2 -4
- package/dist/features/launch/runtime-selection.d.ts +2 -2
- package/dist/features/launch/runtime-selection.js +2 -2
- package/dist/features/launch/session-context.d.ts +2 -2
- package/dist/features/owned-ui/project-trust-prompt.d.ts +2 -2
- package/dist/features/owned-ui/project-trust-prompt.js +1 -1
- package/dist/features/owned-ui/reference-screen-app.d.ts +0 -2
- package/dist/features/owned-ui/reference-screen-app.js +2 -9
- package/dist/features/owned-ui/release-note-state.d.ts +2 -1
- package/dist/features/owned-ui/settings-app.d.ts +0 -6
- package/dist/features/owned-ui/settings-app.js +42 -254
- package/dist/features/owned-ui/settings-edits.d.ts +31 -0
- package/dist/features/owned-ui/settings-edits.js +139 -0
- package/dist/features/owned-ui/settings-scroll-rail.d.ts +29 -0
- package/dist/features/owned-ui/settings-scroll-rail.js +79 -0
- package/dist/features/owned-ui/settings-search-input.d.ts +2 -1
- package/dist/features/prompt-history/service.d.ts +3 -2
- package/dist/foundation/launch-context/index.d.ts +0 -12
- package/dist/foundation/launch-context/index.js +0 -26
- package/dist/foundation/lifecycle/claim-gate.d.ts +9 -0
- package/dist/foundation/lifecycle/claim-gate.js +37 -0
- package/dist/foundation/lifecycle/index.d.ts +5 -9
- package/dist/foundation/lifecycle/index.js +3 -4
- package/dist/foundation/lifecycle/model.d.ts +2 -59
- package/dist/foundation/lifecycle/model.js +0 -35
- package/dist/foundation/lifecycle/paths.d.ts +0 -24
- package/dist/foundation/lifecycle/paths.js +0 -40
- package/dist/foundation/lifecycle/process-liveness.d.ts +8 -0
- package/dist/foundation/lifecycle/process-liveness.js +18 -0
- package/dist/foundation/lifecycle/session-claim-lock.d.ts +1 -1
- package/dist/foundation/lifecycle/session-claim-lock.js +2 -2
- package/dist/foundation/lifecycle/session-repository-context.d.ts +6 -6
- package/dist/foundation/lifecycle/session-repository-context.js +2 -3
- package/dist/foundation/release/automatic-update.d.ts +6 -17
- package/dist/foundation/release/automatic-update.js +23 -44
- package/dist/foundation/release/bootstrap.d.ts +2 -25
- package/dist/foundation/release/bootstrap.js +37 -348
- package/dist/foundation/release/dependency-certification.d.ts +1 -2
- package/dist/foundation/release/dependency-certification.js +1 -1
- package/dist/foundation/release/early-accent.d.ts +2 -2
- package/dist/foundation/release/early-accent.js +1 -1
- package/dist/foundation/release/index.d.ts +10 -17
- package/dist/foundation/release/index.js +7 -11
- package/dist/foundation/release/latest-release.d.ts +3 -19
- package/dist/foundation/release/latest-release.js +11 -12
- package/dist/foundation/release/ordinary-launch-selection.d.ts +1 -1
- package/dist/foundation/release/ordinary-launch-selection.js +1 -1
- package/dist/foundation/release/process-liveness.d.ts +2 -0
- package/dist/foundation/release/process-liveness.js +12 -0
- package/dist/foundation/release/release-gc.d.ts +13 -10
- package/dist/foundation/release/release-gc.js +37 -101
- package/dist/foundation/release/{cohort-state.d.ts → release-state.d.ts} +44 -69
- package/dist/foundation/release/{cohort-state.js → release-state.js} +38 -70
- package/dist/foundation/release/release-store.d.ts +2 -2
- package/dist/foundation/release/release-store.js +2 -2
- package/dist/foundation/release/restart-certification.js +1 -1
- package/dist/foundation/release/update-activation.d.ts +2 -9
- package/dist/foundation/release/update-activation.js +30 -45
- package/dist/foundation/release/update-execution-lease.d.ts +2 -3
- package/dist/foundation/release/update-execution-lease.js +2 -2
- package/dist/foundation/release/update-launch.d.ts +2 -4
- package/dist/foundation/release/update-launch.js +0 -7
- package/dist/foundation/release/update-recovery.js +1 -1
- package/dist/foundation/release/update-transaction.d.ts +1 -1
- package/dist/foundation/release/update-transaction.js +5 -2
- package/dist/foundation/release/update.d.ts +2 -12
- package/dist/foundation/release/update.js +37 -214
- package/dist/foundation/session-writer-lock/index.d.ts +14 -6
- package/dist/foundation/session-writer-lock/index.js +48 -103
- package/dist/foundation/startup/startup-budget.d.ts +5 -5
- package/dist/foundation/startup/startup-budget.js +2 -2
- package/dist/foundation/startup/startup-runtime.d.ts +1 -1
- package/dist/foundation/terminal-cleanup/exit-notice.d.ts +6 -0
- package/dist/foundation/terminal-cleanup/exit-notice.js +36 -0
- package/dist/foundation/terminal-cleanup/index.d.ts +2 -1
- package/dist/foundation/terminal-cleanup/index.js +2 -1
- package/dist/foundation/terminal-cleanup/terminal-reset.d.ts +0 -5
- package/dist/foundation/terminal-cleanup/terminal-reset.js +0 -5
- package/dist/integrations/pi/components/editor-interaction.d.ts +4 -12
- package/dist/integrations/pi/components/index.d.ts +15 -9
- package/dist/integrations/pi/components/index.js +9 -5
- package/dist/integrations/pi/components/lazy-selectors.d.ts +2 -10
- package/dist/integrations/pi/components/lazy-selectors.js +1 -1
- package/dist/integrations/pi/components/modal-frame.d.ts +5 -22
- package/dist/integrations/pi/components/modal-frame.js +3 -23
- package/dist/integrations/pi/components/owned-editor-ux.d.ts +4 -3
- package/dist/integrations/pi/components/prompt-input-port.d.ts +2 -19
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +3 -2
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +1 -4
- package/dist/integrations/pi/components/shell-footer-status.d.ts +3 -3
- package/dist/integrations/pi/components/shell-footer-status.js +5 -4
- package/dist/integrations/pi/components/shell-hotkey-sections.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +6 -8
- package/dist/integrations/pi/components/shell-presenters-info.js +6 -19
- package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +1 -1
- package/dist/integrations/pi/components/shell-presenters-transcript.js +1 -1
- package/dist/integrations/pi/components/shell-session-info-reference.d.ts +2 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +33 -229
- package/dist/integrations/pi/components/shell-shared-facade.js +8 -1
- package/dist/integrations/pi/components/skills-command.d.ts +1 -9
- package/dist/integrations/pi/components/skills-command.js +5 -5
- package/dist/integrations/pi/components/submitted-prompt-adapter.d.ts +2 -5
- package/dist/integrations/pi/components/submitted-prompt-adapter.js +2 -16
- package/dist/integrations/pi/components/theme.d.ts +9 -2
- package/dist/integrations/pi/components/theme.js +17 -2
- package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +2 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +1 -2
- package/dist/integrations/pi/components/upstream/components/session-footer.js +6 -8
- package/dist/integrations/pi/engine/adapter.d.ts +3 -6
- package/dist/integrations/pi/engine/adapter.js +4 -28
- package/dist/integrations/pi/engine/changelog.d.ts +2 -2
- package/dist/integrations/pi/engine/changelog.js +3 -3
- package/dist/integrations/pi/engine/compaction-progress.d.ts +2 -3
- package/dist/integrations/pi/engine/compaction-progress.js +1 -1
- package/dist/integrations/pi/engine/conformance.d.ts +2 -1
- package/dist/integrations/pi/engine/default-model-setting.d.ts +0 -2
- package/dist/integrations/pi/engine/default-model-setting.js +1 -2
- package/dist/integrations/pi/engine/diagnostics-state.d.ts +0 -1
- package/dist/integrations/pi/engine/diagnostics-state.js +0 -14
- package/dist/integrations/pi/engine/event-delivery.d.ts +2 -1
- package/dist/integrations/pi/engine/extension-ui-binding.d.ts +2 -1
- package/dist/integrations/pi/engine/host.js +2 -2
- package/dist/integrations/pi/engine/message-values.d.ts +0 -1
- package/dist/integrations/pi/engine/message-values.js +1 -1
- package/dist/integrations/pi/engine/pending-delivery.d.ts +0 -4
- package/dist/integrations/pi/engine/pending-delivery.js +3 -3
- package/dist/integrations/pi/engine/ports.d.ts +7 -1
- package/dist/integrations/pi/engine/ports.js +4 -0
- package/dist/integrations/pi/engine/project-trust-preflight.d.ts +2 -1
- package/dist/integrations/pi/engine/prompt-suggestions.d.ts +3 -3
- package/dist/integrations/pi/engine/prompt-suggestions.js +0 -40
- package/dist/integrations/pi/engine/provider-authentication.d.ts +1 -1
- package/dist/integrations/pi/engine/public-main-entry.d.ts +1 -5
- package/dist/integrations/pi/engine/public-main-entry.js +1 -1
- package/dist/integrations/pi/engine/repository-pr-rest.d.ts +1 -9
- package/dist/integrations/pi/engine/repository-pr-rest.js +2 -2
- package/dist/integrations/pi/engine/repository-pr.d.ts +1 -3
- package/dist/integrations/pi/engine/repository-pr.js +1 -1
- package/dist/integrations/pi/engine/resource-catalog.d.ts +2 -1
- package/dist/integrations/pi/engine/session-integration.d.ts +1 -1
- package/dist/integrations/pi/engine/session-runtime.d.ts +4 -3
- package/dist/integrations/pi/engine/session-runtime.js +0 -2
- package/dist/integrations/pi/engine/settings-bridge.d.ts +0 -2
- package/dist/integrations/pi/engine/settings-bridge.js +1 -1
- package/dist/integrations/pi/engine/settings-port.d.ts +3 -2
- package/dist/integrations/pi/engine/transcript-projection.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-contexts.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.js +1 -1
- package/dist/integrations/pi/engine/workflow-support.d.ts +0 -6
- package/dist/integrations/pi/engine/workflow-support.js +4 -18
- package/dist/integrations/pi/engine/workflows.d.ts +5 -5
- package/dist/integrations/pi/session-presenters/components.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/components.js +75 -0
- package/dist/integrations/pi/session-presenters/index.d.ts +1 -0
- package/dist/integrations/pi/session-presenters/index.js +1 -0
- package/dist/integrations/pi/session-presenters/presentation.d.ts +3 -0
- package/dist/integrations/pi/session-presenters/presentation.js +10 -0
- package/dist/integrations/pi/session-presenters/presenters.d.ts +2 -1
- package/dist/integrations/pi/session-presenters/presenters.js +3 -1
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +2 -2
- package/dist/integrations/pi/tui-runtime/adapter.js +23 -32
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +22 -166
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +5 -40
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -0
- package/dist/integrations/pi/tui-runtime/index.js +1 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +4 -6
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -8
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +3 -9
- package/dist/integrations/pi/tui-runtime/runtime-factory.d.ts +3 -0
- package/dist/integrations/pi/tui-runtime/runtime-factory.js +11 -0
- package/dist/product-identity.d.ts +4 -6
- package/dist/product-identity.js +6 -11
- package/dist/product-identity.json +1 -40
- package/dist/runtime-payload-inventory.json +0 -3
- package/dist/ui/components/index.d.ts +4 -4
- package/dist/ui/components/index.js +2 -2
- package/dist/ui/components/selection-copy.d.ts +0 -1
- package/dist/ui/components/selection-copy.js +0 -12
- package/dist/ui/components/submitted-prompt.d.ts +3 -13
- package/dist/ui/components/submitted-prompt.js +8 -41
- package/dist/ui/components/theme.d.ts +4 -19
- package/dist/ui/components/theme.js +6 -0
- package/dist/ui/components/transcript-viewport.d.ts +1 -3
- package/dist/ui/components/transcript-viewport.js +1 -4
- package/dist/ui/settings/declarations.d.ts +2 -97
- package/dist/ui/settings/declarations.js +2 -78
- package/dist/ui/settings/early-accent.js +1 -1
- package/dist/ui/settings/index.d.ts +3 -5
- package/dist/ui/settings/index.js +2 -3
- package/dist/ui/settings/manager.d.ts +0 -4
- package/dist/ui/settings/manager.js +6 -62
- package/dist/ui/settings/resolution.d.ts +6 -18
- package/dist/ui/settings/resolution.js +4 -103
- package/dist/ui/settings/sections.d.ts +0 -4
- package/dist/ui/settings/sections.js +1 -1
- package/docs/architecture/boundaries.md +23 -40
- package/docs/architecture/code-documentation.md +2 -2
- package/docs/architecture/internal-naming.md +11 -17
- package/docs/architecture/project-structure.md +13 -16
- package/docs/architecture/resource-and-data-policy.md +16 -31
- package/docs/architecture/toolchain.md +14 -19
- package/docs/architecture/ui-reference-provenance.md +2 -2
- package/docs/ci-release-runbook.md +5 -5
- package/docs/features/launch-profiles.md +11 -17
- package/docs/features/prompt-history.md +10 -11
- package/docs/local-worktree-cleanup.md +28 -1
- package/docs/manual-owned-ui-checkpoint.md +0 -1
- package/docs/validation.md +5 -11
- package/docs/worktree-link-recovery.md +6 -6
- package/package.json +7 -20
- package/bin/guardian.js +0 -42
- package/bin/supervisor.js +0 -7
- package/bin/tab-launch-context.d.ts +0 -27
- package/bin/tab-launch-context.js +0 -94
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +0 -38
- package/dist/app/session-shell/resident-tab-coordinator.js +0 -77
- package/dist/cli/tabs-request.d.ts +0 -7
- package/dist/cli/tabs.d.ts +0 -14
- package/dist/cli/tabs.js +0 -151
- package/dist/composition/resident-tab-bridge.d.ts +0 -41
- package/dist/composition/resident-tab-bridge.js +0 -209
- package/dist/composition/utility-tab.d.ts +0 -28
- package/dist/composition/utility-tab.js +0 -244
- package/dist/features/owned-ui/plus-menu-dialog.d.ts +0 -28
- package/dist/features/owned-ui/plus-menu-dialog.js +0 -89
- package/dist/features/resident-tab/auto-name.d.ts +0 -11
- package/dist/features/resident-tab/auto-name.js +0 -44
- package/dist/features/resident-tab/index.d.ts +0 -5
- package/dist/features/resident-tab/index.js +0 -7
- package/dist/features/resident-tab/shortcut-bindings-file.d.ts +0 -8
- package/dist/features/resident-tab/shortcut-bindings-file.js +0 -40
- package/dist/features/resident-tab/shortcut-declarations.d.ts +0 -13
- package/dist/features/resident-tab/shortcut-declarations.js +0 -26
- package/dist/features/resident-tab/shortcut-projection.d.ts +0 -29
- package/dist/features/resident-tab/shortcut-projection.js +0 -64
- package/dist/features/resident-tab/status-deriver.d.ts +0 -10
- package/dist/features/resident-tab/status-deriver.js +0 -12
- package/dist/foundation/launch-guardian/exit-watcher.d.ts +0 -14
- package/dist/foundation/launch-guardian/exit-watcher.js +0 -103
- package/dist/foundation/launch-guardian/index.d.ts +0 -2
- package/dist/foundation/launch-guardian/index.js +0 -1
- package/dist/foundation/launch-guardian/main.d.ts +0 -39
- package/dist/foundation/launch-guardian/main.js +0 -232
- package/dist/foundation/lifecycle/commands.d.ts +0 -40
- package/dist/foundation/lifecycle/launch-instance.d.ts +0 -46
- package/dist/foundation/lifecycle/launch-instance.js +0 -134
- package/dist/foundation/lifecycle/native-claim-gate.d.ts +0 -5
- package/dist/foundation/lifecycle/native-claim-gate.js +0 -41
- package/dist/foundation/lifecycle/supervisor-startup.d.ts +0 -30
- package/dist/foundation/lifecycle/supervisor-startup.js +0 -106
- package/dist/foundation/process-containment/addon-containment.d.ts +0 -20
- package/dist/foundation/process-containment/addon-containment.js +0 -139
- package/dist/foundation/process-containment/addon-process-inspector.d.ts +0 -11
- package/dist/foundation/process-containment/addon-process-inspector.js +0 -36
- package/dist/foundation/process-containment/addon.d.ts +0 -47
- package/dist/foundation/process-containment/addon.js +0 -57
- package/dist/foundation/process-containment/artifact.d.ts +0 -1
- package/dist/foundation/process-containment/artifact.js +0 -35
- package/dist/foundation/process-containment/contracts.d.ts +0 -33
- package/dist/foundation/process-containment/contracts.js +0 -35
- package/dist/foundation/process-containment/index.d.ts +0 -9
- package/dist/foundation/process-containment/index.js +0 -7
- package/dist/foundation/process-containment/linux-process-inspector.d.ts +0 -7
- package/dist/foundation/process-containment/linux-process-inspector.js +0 -27
- package/dist/foundation/process-containment/native-process-inspector.d.ts +0 -4
- package/dist/foundation/process-containment/native-process-inspector.js +0 -21
- package/dist/foundation/protocol/client.d.ts +0 -18
- package/dist/foundation/protocol/client.js +0 -130
- package/dist/foundation/protocol/index.d.ts +0 -3
- package/dist/foundation/protocol/index.js +0 -2
- package/dist/foundation/protocol/messages.d.ts +0 -90
- package/dist/foundation/protocol/messages.js +0 -100
- package/dist/foundation/release/cohort-selection.d.ts +0 -33
- package/dist/foundation/release/cohort-selection.js +0 -67
- package/dist/foundation/release/endpoint-lock.d.ts +0 -2
- package/dist/foundation/release/endpoint-lock.js +0 -37
- package/dist/foundation/release/endpoint-recovery.d.ts +0 -10
- package/dist/foundation/release/endpoint-recovery.js +0 -45
- package/dist/foundation/release/endpoints.d.ts +0 -32
- package/dist/foundation/release/endpoints.js +0 -152
- package/dist/foundation/release/prepared-update-activation.d.ts +0 -3
- package/dist/foundation/release/prepared-update-activation.js +0 -27
- package/dist/foundation/release/process-cleanup.d.ts +0 -14
- package/dist/foundation/release/process-cleanup.js +0 -76
- package/dist/foundation/release/supervisor-identity.d.ts +0 -15
- package/dist/foundation/release/supervisor-identity.js +0 -63
- package/dist/foundation/resident-tabs/boot-identity.d.ts +0 -6
- package/dist/foundation/resident-tabs/boot-identity.js +0 -16
- package/dist/foundation/resident-tabs/bounded-host-command.d.ts +0 -20
- package/dist/foundation/resident-tabs/bounded-host-command.js +0 -62
- package/dist/foundation/resident-tabs/bridge-client.d.ts +0 -73
- package/dist/foundation/resident-tabs/bridge-client.js +0 -327
- package/dist/foundation/resident-tabs/continuity.d.ts +0 -12
- package/dist/foundation/resident-tabs/continuity.js +0 -63
- package/dist/foundation/resident-tabs/doctor.d.ts +0 -28
- package/dist/foundation/resident-tabs/doctor.js +0 -166
- package/dist/foundation/resident-tabs/draft-checkpoint.d.ts +0 -27
- package/dist/foundation/resident-tabs/draft-checkpoint.js +0 -145
- package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +0 -36
- package/dist/foundation/resident-tabs/ensure-terminal-host.js +0 -151
- package/dist/foundation/resident-tabs/fault-injection.d.ts +0 -8
- package/dist/foundation/resident-tabs/fault-injection.js +0 -26
- package/dist/foundation/resident-tabs/fixture-control.d.ts +0 -7
- package/dist/foundation/resident-tabs/fixture-control.js +0 -35
- package/dist/foundation/resident-tabs/host-entry.js +0 -17
- package/dist/foundation/resident-tabs/index.d.ts +0 -15
- package/dist/foundation/resident-tabs/index.js +0 -10
- package/dist/foundation/resident-tabs/maintenance.d.ts +0 -39
- package/dist/foundation/resident-tabs/maintenance.js +0 -75
- package/dist/foundation/resident-tabs/progress-observation-schema.d.ts +0 -34
- package/dist/foundation/resident-tabs/progress-observation-schema.js +0 -1
- package/dist/foundation/resident-tabs/progress-observation.d.ts +0 -4
- package/dist/foundation/resident-tabs/progress-observation.js +0 -150
- package/dist/foundation/resident-tabs/prompt-journal.d.ts +0 -63
- package/dist/foundation/resident-tabs/prompt-journal.js +0 -213
- package/dist/foundation/resident-tabs/protocol.d.ts +0 -12
- package/dist/foundation/resident-tabs/protocol.js +0 -195
- package/dist/foundation/resident-tabs/recovery.d.ts +0 -26
- package/dist/foundation/resident-tabs/recovery.js +0 -205
- package/dist/foundation/resident-tabs/release-holds.d.ts +0 -28
- package/dist/foundation/resident-tabs/release-holds.js +0 -78
- package/dist/foundation/resident-tabs/routes.d.ts +0 -5
- package/dist/foundation/resident-tabs/routes.js +0 -5
- package/dist/foundation/resident-tabs/routing.d.ts +0 -11
- package/dist/foundation/resident-tabs/routing.js +0 -10
- package/dist/foundation/resident-tabs/runtime-control.d.ts +0 -38
- package/dist/foundation/resident-tabs/runtime-control.js +0 -74
- package/dist/foundation/resident-tabs/session-sync.d.ts +0 -14
- package/dist/foundation/resident-tabs/session-sync.js +0 -37
- package/dist/foundation/resident-tabs/settings.d.ts +0 -16
- package/dist/foundation/resident-tabs/settings.js +0 -60
- package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +0 -14
- package/dist/foundation/resident-tabs/terminal-host-artifact.js +0 -78
- package/dist/foundation/resident-tabs/zip-archive.d.ts +0 -9
- package/dist/foundation/resident-tabs/zip-archive.js +0 -56
- package/dist/foundation/storage/control-store.d.ts +0 -20
- package/dist/foundation/storage/control-store.js +0 -331
- package/dist/foundation/storage/index.d.ts +0 -1
- package/dist/foundation/storage/index.js +0 -1
- package/dist/foundation/supervision/index.d.ts +0 -3
- package/dist/foundation/supervision/index.js +0 -3
- package/dist/foundation/supervision/main.d.ts +0 -1
- package/dist/foundation/supervision/main.js +0 -86
- package/dist/foundation/supervision/paths.d.ts +0 -1
- package/dist/foundation/supervision/paths.js +0 -1
- package/dist/foundation/supervision/server.d.ts +0 -46
- package/dist/foundation/supervision/server.js +0 -611
- package/dist/integrations/pi/components/components.d.ts +0 -4
- package/dist/integrations/pi/components/components.js +0 -48
- package/dist/integrations/pi/components/conformance.d.ts +0 -18
- package/dist/integrations/pi/components/conformance.js +0 -70
- package/dist/integrations/pi/components/shell-components.d.ts +0 -7
- package/dist/integrations/pi/components/shell-components.js +0 -7
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +0 -33
- package/dist/integrations/pi/components/upstream/theme/theme-controller.js +0 -114
- package/dist/integrations/pi/engine/offline-settings-port.d.ts +0 -23
- package/dist/integrations/pi/engine/offline-settings-port.js +0 -54
- package/dist/native/darwin-arm64/manifest.json +0 -23
- package/dist/native/darwin-arm64/process-guardian.node +0 -0
- package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10500
- package/dist/native/darwin-arm64/terminal-host.manifest.json +0 -46
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +0 -23
- package/dist/native/darwin-x64/process-guardian.node +0 -0
- package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10737
- package/dist/native/darwin-x64/terminal-host.manifest.json +0 -46
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +0 -23
- package/dist/native/linux-x64/process-guardian.node +0 -0
- package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -11226
- package/dist/native/linux-x64/terminal-host.manifest.json +0 -46
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +0 -23
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +0 -10757
- package/dist/native/win32-x64/terminal-host.manifest.json +0 -46
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/ui/settings/migrations.d.ts +0 -19
- package/dist/ui/settings/migrations.js +0 -209
- package/dist/ui/settings/progress-palette.generated.d.ts +0 -139
- package/dist/ui/settings/progress-palette.generated.js +0 -139
- package/docs/architecture/evidence/resident-tabs/linux-x64.md +0 -37
- package/docs/architecture/evidence/resident-tabs/macos-arm64.md +0 -36
- package/docs/architecture/evidence/resident-tabs/macos-x64.md +0 -35
- package/docs/architecture/evidence/resident-tabs/windows-x64.md +0 -36
- package/docs/architecture/evidence/terminal-host-spike/manual-one-pane-terminal-host.md +0 -70
- package/docs/architecture/evidence/terminal-host-spike/manual-two-by-two-basic-terminal-host.md +0 -32
- package/docs/architecture/evidence/terminal-host-spike/milestone-baseline.json +0 -115
- package/docs/architecture/evidence/terminal-host-spike/owned-ui-foundation-prerequisite.json +0 -48
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-provenance.json +0 -125
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-1.json +0 -56
- package/docs/architecture/evidence/terminal-host-spike/terminal-host-task-5-3.json +0 -174
- package/docs/architecture/evidence/terminal-host-spike/terminal-spike-acceptance-record.json +0 -18
- package/docs/architecture/native-fixture-isolation.md +0 -23
- package/docs/architecture/process-guardian-provenance.md +0 -36
- package/docs/architecture/resident-tabs-requirements.md +0 -18
- package/docs/architecture/resident-tabs.md +0 -668
- package/docs/architecture/terminal-host-proof-gate.md +0 -34
- package/docs/architecture/terminal-host-provenance.md +0 -81
- package/docs/architecture/terminal-host-spike-evidence.md +0 -39
- package/docs/launch-recovery.md +0 -23
- package/docs/manual-launch-instance-acceptance.md +0 -43
- package/docs/manual-resident-tabs-acceptance.md +0 -51
- /package/dist/{cli/tabs-request.js → contracts/owned-ui/shell-components.js} +0 -0
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.d.ts +0 -0
- /package/dist/{foundation/release → contracts/presentation}/progress-palette.generated.js +0 -0
- /package/dist/{foundation/lifecycle/commands.js → contracts/presentation/terminal.js} +0 -0
- /package/dist/{foundation/resident-tabs/host-entry.d.ts → contracts/presentation/theme.js} +0 -0
|
@@ -1,42 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createResponseCopyExecutor, responseCopyDestination } from "./response-copy-transport.js";
|
|
3
|
-
import { MAX_COPY_CONTROL_BYTES } from "./response-copy-protocol.js";
|
|
1
|
+
import { ShellClipboard } from "./shell-clipboard.js";
|
|
4
2
|
import { PromptHistoryController } from "./prompt-history-controller.js";
|
|
5
3
|
import { SessionDialogCoordinator } from "./dialog-coordinator.js";
|
|
6
4
|
import { LoginInteraction } from "./login-interaction.js";
|
|
7
5
|
import { PromptSubmission } from "./prompt-submission.js";
|
|
8
|
-
import { ResidentTabCoordinator } from "./resident-tab-coordinator.js";
|
|
9
6
|
import { SessionConcerns } from "./session-concern.js";
|
|
10
7
|
import { composeExitText, SessionStopLatch } from "./session-lifecycle.js";
|
|
11
8
|
import { openWorkflowSelector } from "./workflow-router.js";
|
|
12
|
-
import { bindSessionSettings } from "./settings-bindings.js";
|
|
13
|
-
import { promptSuggestionSurface,
|
|
9
|
+
import { bindSessionSettings, bindShellSettings } from "./settings-bindings.js";
|
|
10
|
+
import { promptSuggestionSurface, suggestionPresentationBlockReason, } from "./suggestion-surface.js";
|
|
14
11
|
import { CLEAR_EXIT_INTERVAL_MS, boundedCleanup } from "../../foundation/terminal-cleanup/terminal-reset.js";
|
|
15
12
|
import { OWNED_UI_HIDDEN_COMMAND_NAMES } from "../../contracts/owned-ui/index.js";
|
|
16
|
-
import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
|
|
17
13
|
import { copyAcknowledgementText } from "../../ui/components/selection-copy.js";
|
|
18
|
-
import {
|
|
19
|
-
import { workflowCommandNames } from "../../integrations/pi/engine/workflows.js";
|
|
20
|
-
import { createPiExtensionUiBridge } from "../../integrations/pi/components/shell-extension-ui.js";
|
|
21
|
-
import { ProgramStatusReporter } from "../../integrations/pi/components/upstream/program-status-reporter.js";
|
|
22
|
-
import { SKILLS_COMMAND_NAME, findSkillByArgument, rewriteSkillsTunnelSubmission, skillPrompt, skillsFromCommands, } from "../../integrations/pi/components/skills-command.js";
|
|
23
|
-
import { createPiShellAuthProviderSelector, createPiShellExtensionSelector, createPiShellLoginDialog, createPiShellReloadBox, createPiShellSkillsSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
|
|
14
|
+
import { ShellPromptSuggestions } from "./shell-prompt-suggestions.js";
|
|
24
15
|
import { OwnedUiTerminalHost, componentRuntime, sessionTerminalHostOptions, } from "./shell-host.js";
|
|
25
|
-
import { runImageWorker } from "./image-preparation-client.js";
|
|
26
16
|
import { STREAM_PRESENTATION_INTERVAL_MS, StreamPresentationCoalescer, } from "./stream-presentation-coalescer.js";
|
|
27
|
-
import { writeSystemClipboardText, } from "./system-clipboard.js";
|
|
28
17
|
import { OwnedUiSessionShellRoot, shellResourceEntries, } from "./session-shell-root.js";
|
|
29
18
|
// Invariant: a disposed shell leaves the engine a host that holds no reference back to it.
|
|
30
19
|
const DETACHED_WORKFLOW_INTERACTION = { prompt: async () => null, notify() { } };
|
|
31
|
-
// Invariant: the resume mode belongs to the presenter instance, not the persisted session or profile.
|
|
32
|
-
const SOLO_RESUME_HINTS = new WeakSet();
|
|
33
|
-
/** Resident Agents refuse the commands their tab bar serves instead, naming where they live. */
|
|
34
|
-
const RESIDENT_UTILITY_TAB_REFUSALS = Object.freeze({
|
|
35
|
-
settings: "Settings is available from the global Settings tab.",
|
|
36
|
-
// Platform: macOS labels Alt `Option`.
|
|
37
|
-
changelog: `The changelog opens as its own tab from the command palette (${process.platform === "darwin" ? "Option" : "Alt"}+/).`,
|
|
38
|
-
name: "Rename the session by renaming its tab (F2).",
|
|
39
|
-
});
|
|
40
20
|
export { OwnedUiSessionShellRoot, } from "./session-shell-root.js";
|
|
41
21
|
export { OwnedUiTerminalHost, sessionTerminalHostOptions } from "./shell-host.js";
|
|
42
22
|
export { formatSessionResumeCommand, quoteCommandArgument } from "./session-lifecycle.js";
|
|
@@ -51,18 +31,14 @@ export class OwnedUiSessionPresenter {
|
|
|
51
31
|
root;
|
|
52
32
|
#host;
|
|
53
33
|
#terminal;
|
|
54
|
-
#resident;
|
|
55
34
|
#submission;
|
|
56
35
|
#login;
|
|
57
36
|
#concerns;
|
|
58
37
|
#listeners = new Set();
|
|
59
38
|
#unsubscribe;
|
|
60
|
-
#unsubscribePromptSuggestions;
|
|
61
39
|
#promptSuggestions;
|
|
62
40
|
#promptImages;
|
|
63
41
|
#skills;
|
|
64
|
-
#unsubscribePromptImages;
|
|
65
|
-
#unsubscribeSkills;
|
|
66
42
|
#installedCommandSignature = "";
|
|
67
43
|
#promptHistory = null;
|
|
68
44
|
#historyBinding;
|
|
@@ -76,21 +52,17 @@ export class OwnedUiSessionPresenter {
|
|
|
76
52
|
#shutdownPromise;
|
|
77
53
|
#disposePromise;
|
|
78
54
|
#layoutParts;
|
|
79
|
-
#pendingClipboardWrite = Promise.resolve();
|
|
80
55
|
// Invariant: translated startup diagnostics create at most one dock notice per kind per shell.
|
|
81
56
|
#startupTrustHandled = false;
|
|
82
57
|
#customViewport;
|
|
83
|
-
#
|
|
84
|
-
#lazySelectorsPromise;
|
|
85
|
-
#responseCopy;
|
|
58
|
+
#clipboard;
|
|
86
59
|
// Rationale: only an executor this shell created owns a spare copy helper worth warming and disposing.
|
|
87
|
-
#copyExecutor;
|
|
88
60
|
#copyIntentSequence = 0;
|
|
89
61
|
#unbindClipboardWriter;
|
|
90
62
|
#reloadPresentation;
|
|
91
63
|
#streamPresentation;
|
|
92
64
|
#inputCoordination;
|
|
93
|
-
#
|
|
65
|
+
#unbindShellSettings;
|
|
94
66
|
#unbindSessionSettings;
|
|
95
67
|
#terminalProgressEnabled = false;
|
|
96
68
|
#programStatus;
|
|
@@ -99,7 +71,6 @@ export class OwnedUiSessionPresenter {
|
|
|
99
71
|
#lastEscapeTime = 0;
|
|
100
72
|
#sessionGeneration;
|
|
101
73
|
#sessionBindingGeneration;
|
|
102
|
-
#suggestionModelKey;
|
|
103
74
|
constructor(host, options) {
|
|
104
75
|
const { backend, cwd, routeHost, sessionLayout } = options.engine;
|
|
105
76
|
const { terminal, startup, viewportSettings, reload: reloadPresentation, stream: streamPresentationOptions, input: inputPresentation, } = options.presentation ?? {};
|
|
@@ -110,17 +81,12 @@ export class OwnedUiSessionPresenter {
|
|
|
110
81
|
this.#presenters = options.presenters;
|
|
111
82
|
this.#sessionGeneration = this.backend.identity.sessionGeneration;
|
|
112
83
|
this.#sessionBindingGeneration = this.backend.identity.sessionBindingGeneration;
|
|
113
|
-
this.#suggestionModelKey = suggestionModelKey(this.backend.session.view());
|
|
114
84
|
this.#customViewport = sessionLayout === "custom-viewport";
|
|
115
|
-
if (options.presentation?.soloResumeHint)
|
|
116
|
-
SOLO_RESUME_HINTS.add(this);
|
|
117
85
|
this.#inputCoordination = inputPresentation?.coordination !== false;
|
|
118
86
|
this.#host = host;
|
|
119
87
|
this.#terminal = host.connect(this);
|
|
120
88
|
// Invariant: the host's optional members follow the layout, so it is built only once the layout is known.
|
|
121
89
|
this.#dialogHost = this.#createDialogHost();
|
|
122
|
-
this.#lazySelectors = options.diagnostics?.lazySelectors;
|
|
123
|
-
let promptSuggestionController = null;
|
|
124
90
|
// Invariant: owned prompt limits and collapsed skills are bare-A1 replacements; comparison profiles keep pinned behavior.
|
|
125
91
|
this.#promptImages = this.#customViewport ? options.promptImages ?? null : null;
|
|
126
92
|
this.#skills = this.#customViewport ? options.skills ?? null : null;
|
|
@@ -128,48 +94,19 @@ export class OwnedUiSessionPresenter {
|
|
|
128
94
|
// throw releases them in reverse, so a shell that never finished constructing holds nothing.
|
|
129
95
|
const constructed = [() => host.disconnect(this)];
|
|
130
96
|
try {
|
|
131
|
-
this.#
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
this.#terminal.writeControl(control);
|
|
146
|
-
} },
|
|
147
|
-
})),
|
|
148
|
-
...(responseCopy?.onEvent === undefined ? {} : { onEvent: responseCopy.onEvent }),
|
|
149
|
-
}) : null;
|
|
150
|
-
constructed.push(() => { this.#responseCopy?.dispose(); this.#copyExecutor?.dispose(); });
|
|
151
|
-
const readClipboard = async (signal) => {
|
|
152
|
-
if (signal.aborted)
|
|
153
|
-
throw new ImageAttachmentError("image-canceled");
|
|
154
|
-
if (clipboard === undefined)
|
|
155
|
-
return runImageWorker({ kind: "clipboard" }, signal);
|
|
156
|
-
try {
|
|
157
|
-
const image = await clipboard.readImage?.(signal);
|
|
158
|
-
if (image !== null && image !== undefined) {
|
|
159
|
-
const canonical = await runImageWorker({ kind: "canonicalize", source: image }, signal);
|
|
160
|
-
if (canonical !== null)
|
|
161
|
-
return { kind: "image", ...canonical };
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
if (error instanceof ImageAttachmentError)
|
|
166
|
-
throw error;
|
|
167
|
-
// Compatibility: an unavailable image reader can still provide text.
|
|
168
|
-
}
|
|
169
|
-
const text = await clipboard.readText(signal);
|
|
170
|
-
return text === null ? null : { kind: "text", text };
|
|
171
|
-
};
|
|
172
|
-
this.root = new OwnedUiSessionShellRoot(this.backend.session.view(), cwd, {
|
|
97
|
+
this.#clipboard = new ShellClipboard({
|
|
98
|
+
ownedCopy: this.#customViewport, substituteTerminal: terminal !== undefined,
|
|
99
|
+
...(sharedClipboard === undefined ? {} : { shared: sharedClipboard }),
|
|
100
|
+
...(clipboard === undefined ? {} : { clipboard }),
|
|
101
|
+
...(responseCopy === undefined ? {} : { responseCopy }),
|
|
102
|
+
...(pastePreparation === undefined ? {} : { pastePreparation }),
|
|
103
|
+
disposed: () => this.#disposed,
|
|
104
|
+
terminalAttached: () => this.#terminal.running && this.#terminal.attached,
|
|
105
|
+
writeControl: control => this.#terminal.writeControl(control),
|
|
106
|
+
});
|
|
107
|
+
constructed.push(() => this.#clipboard.dispose());
|
|
108
|
+
const pastePreparationOptions = this.#clipboard.pastePreparation();
|
|
109
|
+
this.root = new OwnedUiSessionShellRoot(this.backend.session.view(), cwd, { presentation: options.presenters, components: options.presenters.components,
|
|
173
110
|
getColumns: () => this.#terminal.viewport().columns,
|
|
174
111
|
getRows: () => this.#terminal.viewport().rows,
|
|
175
112
|
requestRender: force => this.#terminal.requestRender(force),
|
|
@@ -180,8 +117,6 @@ export class OwnedUiSessionPresenter {
|
|
|
180
117
|
replacementSurfaceActive: !this.root.usesDefaultInputSurface(),
|
|
181
118
|
}),
|
|
182
119
|
enableDockInputReuse: inputPresentation?.viewportReuse !== false,
|
|
183
|
-
footerSessionName: options.engine.residentTab === undefined,
|
|
184
|
-
hideUtilityTabCommands: options.engine.residentTab !== undefined,
|
|
185
120
|
persistentHistory: this.#customViewport && promptHistory !== undefined,
|
|
186
121
|
...(promptHistory === undefined ? {} : { historyEditor: promptHistory.editor }),
|
|
187
122
|
onSubmit: text => { void this.submit(text).catch(() => this.#submission.reportError()); },
|
|
@@ -201,56 +136,31 @@ export class OwnedUiSessionPresenter {
|
|
|
201
136
|
onDequeue: () => this.restoreQueuedInput(),
|
|
202
137
|
onEditorChange: text => {
|
|
203
138
|
this.#submission.noteEditorChange();
|
|
204
|
-
this.#
|
|
205
|
-
promptSuggestionController?.abortPending();
|
|
139
|
+
this.#promptSuggestions?.abortPending();
|
|
206
140
|
if (text.length === 0) {
|
|
207
141
|
// Concurrency: the editor synchronizes deletion-owned autocomplete after onChange.
|
|
208
142
|
// Reassert retained ghost text in the microtask before Pi emits its scheduled frame.
|
|
209
|
-
queueMicrotask(() =>
|
|
143
|
+
queueMicrotask(() => this.#promptSuggestions?.restoreAvailable());
|
|
210
144
|
}
|
|
211
145
|
this.root.reconcilePromptImageLimitNotice(text);
|
|
212
146
|
},
|
|
213
|
-
onPromptSuggestionAccepted: () =>
|
|
147
|
+
onPromptSuggestionAccepted: () => this.#promptSuggestions?.accept(),
|
|
214
148
|
onPromptSuggestionEligibilityChanged: () => {
|
|
215
|
-
queueMicrotask(() =>
|
|
149
|
+
queueMicrotask(() => this.#promptSuggestions?.restoreAvailable());
|
|
216
150
|
},
|
|
217
151
|
onInputSurfaceChanged: () => {
|
|
218
|
-
|
|
152
|
+
this.#promptSuggestions?.invalidate();
|
|
219
153
|
this.#promptHistory?.synchronize();
|
|
220
154
|
},
|
|
221
155
|
onCopyText: (text, cut) => {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
const write = () => {
|
|
227
|
-
if (this.#disposed)
|
|
228
|
-
return Promise.resolve();
|
|
229
|
-
this.#terminal.writeControl(`\u001b]52;c;${Buffer.from(text, "utf8").toString("base64")}\u0007`);
|
|
230
|
-
return clipboard === undefined ? writeSystemClipboardText(text)
|
|
231
|
-
: clipboard.writeText?.(text) ?? Promise.resolve();
|
|
232
|
-
};
|
|
233
|
-
// Compatibility: comparison profiles retain their existing clipboard path.
|
|
234
|
-
this.#pendingClipboardWrite = write().catch(() => { });
|
|
235
|
-
},
|
|
236
|
-
readClipboardContent: async (signal = new AbortController().signal) => {
|
|
237
|
-
await this.#pendingClipboardWrite;
|
|
238
|
-
return readClipboard(signal);
|
|
239
|
-
},
|
|
240
|
-
captureClipboardPaste: () => {
|
|
241
|
-
const before = this.#responseCopy?.capturePasteBarrier() ?? (async () => true);
|
|
242
|
-
if (clipboard !== undefined)
|
|
243
|
-
return { kind: "provided", read: readClipboard, before };
|
|
244
|
-
if (responseCopyDestination(process.env) === "terminal")
|
|
245
|
-
return {
|
|
246
|
-
kind: "provided", before, read: async () => { throw new ImageAttachmentError("paste-unavailable"); },
|
|
247
|
-
};
|
|
248
|
-
return { kind: "native", before };
|
|
156
|
+
const delivery = this.#clipboard.copyText(text);
|
|
157
|
+
if (delivery !== undefined)
|
|
158
|
+
this.#trackCopy(delivery, cut ? undefined : text.length);
|
|
249
159
|
},
|
|
160
|
+
readClipboardContent: signal => this.#clipboard.readContent(signal),
|
|
161
|
+
captureClipboardPaste: () => this.#clipboard.capturePaste(),
|
|
250
162
|
...(pasteDiagnostics === undefined ? {} : { pasteDiagnostics: pasteDiagnostics }),
|
|
251
|
-
...(
|
|
252
|
-
pastePreparation: { ...pastePreparation, ...(sharedClipboard === undefined ? {} : { pool: sharedClipboard.paste }) },
|
|
253
|
-
}),
|
|
163
|
+
...(pastePreparationOptions === undefined ? {} : { pastePreparation: pastePreparationOptions }),
|
|
254
164
|
...(sharedKeybindings === undefined ? {} : { keybindings: sharedKeybindings }),
|
|
255
165
|
...(this.#promptImages === null ? {} : { promptImageLimit: this.#promptImages.limit }),
|
|
256
166
|
skillsPresentation: () => this.#skills?.presentation() ?? "expand",
|
|
@@ -263,76 +173,46 @@ export class OwnedUiSessionPresenter {
|
|
|
263
173
|
// Invariant: the presenter owns its root (theme subscription and helper clients) and disposes it once the
|
|
264
174
|
// terminal no longer renders it.
|
|
265
175
|
constructed.push(() => this.root.dispose());
|
|
266
|
-
this.#resident = new ResidentTabCoordinator(options.engine.residentTab, { root: this.root });
|
|
267
|
-
constructed.push(() => this.#resident.dispose());
|
|
268
176
|
const startupRoute = options.engine.startupRoute;
|
|
269
177
|
this.#dialogs = new SessionDialogCoordinator({
|
|
270
178
|
terminal: this.#terminal,
|
|
271
179
|
root: this.root,
|
|
272
|
-
routeHost: routeHost ?? null,
|
|
180
|
+
routeHost: routeHost ?? null, dialogs: options.presenters.components.dialogs,
|
|
273
181
|
disposed: () => this.#disposed,
|
|
274
182
|
exit: () => { void this.shutdown(); },
|
|
275
|
-
routeClosed: route => this.#resident.closeOwnedRoute(route),
|
|
276
183
|
...(startupRoute === undefined ? {} : { startupRoute }),
|
|
277
184
|
});
|
|
278
185
|
constructed.push(() => this.#dialogs.dispose());
|
|
279
186
|
const initialPiSettings = this.backend.settings.snapshot();
|
|
280
|
-
this.#programStatus =
|
|
187
|
+
this.#programStatus = options.presenters.components.chrome.programStatusReporter(status => this.#terminal.setProgramStatus(status), () => this.view().status.footer?.sessionName ?? undefined);
|
|
281
188
|
this.#login = new LoginInteraction({
|
|
282
|
-
terminal: this.#terminal, root: this.root, programStatus: this.#programStatus,
|
|
189
|
+
terminal: this.#terminal, root: this.root, programStatus: this.#programStatus, dialogs: options.presenters.components.dialogs,
|
|
283
190
|
syncProgress: () => this.#syncTerminalProgress(this.view()),
|
|
284
191
|
});
|
|
285
192
|
this.#submission = this.#createSubmission(cwd);
|
|
286
|
-
this.#resident.restoreInput(options.history?.imageSidecar);
|
|
287
193
|
this.#reloadPresentation = reloadPresentation;
|
|
288
|
-
|
|
289
|
-
this.#streamPresentation = streamPresentationOptions?.scheduler === undefined
|
|
290
|
-
? new StreamPresentationCoalescer(() => this.#terminal.requestRender(), presentationInterval)
|
|
291
|
-
: new StreamPresentationCoalescer(() => this.#terminal.requestRender(), presentationInterval, streamPresentationOptions.scheduler);
|
|
194
|
+
this.#streamPresentation = new StreamPresentationCoalescer(() => this.#terminal.requestRender(), streamPresentationOptions?.intervalMs ?? STREAM_PRESENTATION_INTERVAL_MS, streamPresentationOptions?.scheduler);
|
|
292
195
|
constructed.push(() => this.#streamPresentation.dispose());
|
|
293
|
-
|
|
294
|
-
promptSuggestionController = promptSuggestionOptions === undefined ? null : new ContextualPromptSuggestionController({
|
|
295
|
-
generator: promptSuggestionOptions.generator,
|
|
296
|
-
enabled: promptSuggestionOptions.enabled(),
|
|
297
|
-
...(promptSuggestionOptions.diagnostics === undefined ? {} : { diagnostics: promptSuggestionOptions.diagnostics }),
|
|
298
|
-
surface: promptSuggestionSurface(this.root, identity => this.#promptSuggestionPresentationBlockReason(identity), () => this.#terminal.requestRender()),
|
|
299
|
-
});
|
|
300
|
-
this.#promptSuggestions = promptSuggestionController;
|
|
196
|
+
this.#promptSuggestions = new ShellPromptSuggestions(this.#customViewport ? options.suggestions : undefined, promptSuggestionSurface(this.root, identity => suggestionPresentationBlockReason(identity, { disposed: this.#disposed, view: this.view(), sessionGeneration: this.backend.identity.sessionGeneration }, () => this.root.promptSuggestionPresentationBlockReason()), () => this.#terminal.requestRender()), this.backend.session.view());
|
|
301
197
|
constructed.push(() => this.#promptSuggestions?.dispose());
|
|
302
|
-
this.#
|
|
303
|
-
|
|
304
|
-
:
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
198
|
+
this.#fullscreenExitOutput = initialPiSettings.fullscreenExitOutput;
|
|
199
|
+
this.#unbindShellSettings = bindShellSettings({
|
|
200
|
+
customViewport: this.#customViewport, promptImages: this.#promptImages, skills: this.#skills,
|
|
201
|
+
viewport: viewportSettings, historyScope: promptHistory?.onScopeChange,
|
|
202
|
+
}, {
|
|
203
|
+
root: this.root,
|
|
204
|
+
promptImageLimitChanged: () => { if (!this.#disposed && this.root.reconcilePromptImageLimitNotice())
|
|
205
|
+
this.#terminal.requestRender(); },
|
|
206
|
+
skillsChanged: () => {
|
|
207
|
+
// Invariant: reinstalling drops extension provider wrappers, so an unrelated setting change leaves the list alone.
|
|
208
|
+
if (this.#disposed || this.#commandListSignature() === this.#installedCommandSignature)
|
|
209
|
+
return;
|
|
210
|
+
this.#installAutocompleteCommands();
|
|
308
211
|
this.#terminal.requestRender();
|
|
212
|
+
},
|
|
213
|
+
historyScopeChanged: scope => this.#rebindTranscript(scope),
|
|
309
214
|
});
|
|
310
|
-
constructed.push(this.#
|
|
311
|
-
// Rationale: the same listener refreshes the menu for the A1 presentation choice and for the engine's
|
|
312
|
-
// skill-command registration, both of which the owned settings manager reports through one change.
|
|
313
|
-
this.#unsubscribeSkills = this.#skills === null ? () => { } : this.#skills.onChange(() => {
|
|
314
|
-
// Invariant: reinstalling drops extension provider wrappers, so an unrelated setting change leaves the list alone.
|
|
315
|
-
if (this.#disposed || this.#commandListSignature() === this.#installedCommandSignature)
|
|
316
|
-
return;
|
|
317
|
-
this.#installAutocompleteCommands();
|
|
318
|
-
this.#terminal.requestRender();
|
|
319
|
-
});
|
|
320
|
-
constructed.push(this.#unsubscribeSkills);
|
|
321
|
-
this.#fullscreenExitOutput = initialPiSettings.fullscreenExitOutput;
|
|
322
|
-
const applyViewportSettings = () => {
|
|
323
|
-
const snapshot = viewportSettings?.snapshot();
|
|
324
|
-
this.root.setViewportConfig(snapshot ?? {
|
|
325
|
-
scrollbarAppearance: "auto",
|
|
326
|
-
scrollbarStyle: "thin",
|
|
327
|
-
scrollbarSpeed: "normal",
|
|
328
|
-
});
|
|
329
|
-
};
|
|
330
|
-
applyViewportSettings();
|
|
331
|
-
const unsubscribeViewport = this.#customViewport && viewportSettings ? viewportSettings.onChange(settings => this.root.setViewportConfig(settings)) : () => { };
|
|
332
|
-
const unsubscribeHistoryScope = this.#customViewport && promptHistory?.onScopeChange?.(scope => this.#rebindTranscript(scope));
|
|
333
|
-
this.#unsubscribeSettings = () => { unsubscribeViewport(); if (unsubscribeHistoryScope)
|
|
334
|
-
unsubscribeHistoryScope(); };
|
|
335
|
-
constructed.push(this.#unsubscribeSettings);
|
|
215
|
+
constructed.push(this.#unbindShellSettings);
|
|
336
216
|
this.#unbindSessionSettings = bindSessionSettings(this.backend.settings, initialPiSettings, {
|
|
337
217
|
terminal: this.#terminal,
|
|
338
218
|
root: this.root,
|
|
@@ -365,65 +245,16 @@ export class OwnedUiSessionPresenter {
|
|
|
365
245
|
prompt: request => this.#login.requestInput(request),
|
|
366
246
|
notify: event => this.#login.notify(event),
|
|
367
247
|
publish: message => {
|
|
368
|
-
this.root.
|
|
248
|
+
this.root.workflow.appendMessage(message);
|
|
369
249
|
this.#terminal.requestRender();
|
|
370
250
|
},
|
|
371
251
|
finishLogin: () => this.#login.finish(),
|
|
372
252
|
});
|
|
373
253
|
this.#installAutocompleteCommands();
|
|
374
|
-
this.#unsubscribe = this.backend.session.onEvent(event =>
|
|
375
|
-
// Invariant: once disposal begins no event touches the view; only the stop still settles the shell.
|
|
376
|
-
if (this.#disposed) {
|
|
377
|
-
if (event.type === "session-lifecycle" && event.lifecycle === "stopped")
|
|
378
|
-
this.#stop.settleAfter(() => this.dispose());
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
this.#resident.observeLifecycle(event);
|
|
382
|
-
// Performance: a streamed chunk names one block, and touching only that block is what keeps the
|
|
383
|
-
// cost of a chunk the same in a long session as in a new one. Everything else
|
|
384
|
-
// resynchronizes the view, which is cheap next to re-reading the transcript.
|
|
385
|
-
if (event.type === "agent-run-started") {
|
|
386
|
-
this.#promptSuggestions?.invalidate();
|
|
387
|
-
this.root.resumeViewportFollowing();
|
|
388
|
-
}
|
|
389
|
-
if (event.type === "assistant-message-completed" && !event.successful) {
|
|
390
|
-
this.#programStatus.setErrorMessage(this.view().status.diagnostics.at(-1));
|
|
391
|
-
}
|
|
392
|
-
if (event.type === "agent-run-started" || event.type === "assistant-message-completed" || event.type === "agent-run-settled") {
|
|
393
|
-
this.#programStatus.handleEvent(event);
|
|
394
|
-
}
|
|
395
|
-
if (event.type === "assistant-message-completed") {
|
|
396
|
-
this.root.noteCompletedAssistantMessage();
|
|
397
|
-
routeResponseToSuggestions(this.#promptSuggestions, event, () => this.root.promptSuggestionPrepareBlockReason());
|
|
398
|
-
}
|
|
399
|
-
const semanticOnly = event.type === "agent-run-started" || event.type === "assistant-message-completed";
|
|
400
|
-
const view = event.type === "transcript-block" && this.#sessionGeneration === this.backend.identity.sessionGeneration
|
|
401
|
-
? this.#syncBlock(event.block)
|
|
402
|
-
: semanticOnly ? this.view() : this.#syncView();
|
|
403
|
-
this.#syncTerminalProgress(view);
|
|
404
|
-
const currentModelKey = suggestionModelKey(view);
|
|
405
|
-
if (this.backend.identity.sessionGeneration !== this.#sessionGeneration || currentModelKey !== this.#suggestionModelKey) {
|
|
406
|
-
this.#promptSuggestions?.invalidate();
|
|
407
|
-
this.#suggestionModelKey = currentModelKey;
|
|
408
|
-
}
|
|
409
|
-
if (event.type === "status" && /^(Retrying|Compacting)/.test(event.status.workingMessage ?? "")) {
|
|
410
|
-
this.#promptSuggestions?.invalidate();
|
|
411
|
-
}
|
|
412
|
-
if (event.type === "agent-run-settled") {
|
|
413
|
-
routeResponseToSuggestions(this.#promptSuggestions, event, () => this.root.promptSuggestionPrepareBlockReason());
|
|
414
|
-
}
|
|
415
|
-
if (event.type === "session-lifecycle" && event.lifecycle === "stopped")
|
|
416
|
-
this.#stop.settleAfter(() => this.dispose());
|
|
417
|
-
});
|
|
254
|
+
this.#unsubscribe = this.backend.session.onEvent(event => this.#onSessionEvent(event));
|
|
418
255
|
constructed.push(this.#unsubscribe);
|
|
419
|
-
this.#unbindClipboardWriter = this.#responseCopy === null ? () => { }
|
|
420
|
-
|
|
421
|
-
if (result.outcome === "delivered")
|
|
422
|
-
return true;
|
|
423
|
-
if (result.outcome === "submitted-unverified")
|
|
424
|
-
return false;
|
|
425
|
-
throw new Error(result.outcome === "timed-out" ? "Clipboard delivery timed out" : "Clipboard delivery could not be completed");
|
|
426
|
-
});
|
|
256
|
+
this.#unbindClipboardWriter = this.#clipboard.responseCopy === null ? () => { }
|
|
257
|
+
: this.backend.extensions.bindClipboardWriter(text => this.#clipboard.writeForExtension(text));
|
|
427
258
|
constructed.push(this.#unbindClipboardWriter);
|
|
428
259
|
if (this.backend.session.view().lifecycle === "stopped")
|
|
429
260
|
this.#stop.resolve();
|
|
@@ -503,7 +334,7 @@ export class OwnedUiSessionPresenter {
|
|
|
503
334
|
const routed = this.root.handleViewportPreInput(data, true, Date.now(), this.root.usesDefaultInputSurface() && !this.#terminal.hasFocusedOverlay());
|
|
504
335
|
if (routed.copySelection !== undefined) {
|
|
505
336
|
const snapshot = routed.copySelection;
|
|
506
|
-
this.#trackCopy(this.#
|
|
337
|
+
this.#trackCopy(this.#clipboard.copySelection(snapshot), copyCharacters(snapshot));
|
|
507
338
|
}
|
|
508
339
|
if (routed.copyLastMessage)
|
|
509
340
|
void this.runWorkflow({ command: "copy", argument: "" });
|
|
@@ -511,18 +342,54 @@ export class OwnedUiSessionPresenter {
|
|
|
511
342
|
return routed.data === data ? undefined : { data: routed.data };
|
|
512
343
|
return routed.data.length === 0 ? { consume: true } : { data: routed.data };
|
|
513
344
|
}
|
|
345
|
+
#onSessionEvent(event) {
|
|
346
|
+
// Invariant: once disposal begins no event touches the view; only the stop still settles the shell.
|
|
347
|
+
if (this.#disposed) {
|
|
348
|
+
if (event.type === "session-lifecycle" && event.lifecycle === "stopped")
|
|
349
|
+
this.#stop.settleAfter(() => this.dispose());
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
// Performance: a streamed chunk names one block, and touching only that block is what keeps the
|
|
353
|
+
// cost of a chunk the same in a long session as in a new one. Everything else
|
|
354
|
+
// resynchronizes the view, which is cheap next to re-reading the transcript.
|
|
355
|
+
if (event.type === "agent-run-started") {
|
|
356
|
+
this.#promptSuggestions?.invalidate();
|
|
357
|
+
this.root.resumeViewportFollowing();
|
|
358
|
+
}
|
|
359
|
+
if (event.type === "assistant-message-completed" && !event.successful) {
|
|
360
|
+
this.#programStatus.setErrorMessage(this.view().status.diagnostics.at(-1));
|
|
361
|
+
}
|
|
362
|
+
if (event.type === "agent-run-started" || event.type === "assistant-message-completed" || event.type === "agent-run-settled") {
|
|
363
|
+
this.#programStatus.handleEvent(event);
|
|
364
|
+
}
|
|
365
|
+
if (event.type === "assistant-message-completed") {
|
|
366
|
+
this.root.noteCompletedAssistantMessage();
|
|
367
|
+
this.#promptSuggestions?.route(event, () => this.root.promptSuggestionPrepareBlockReason());
|
|
368
|
+
}
|
|
369
|
+
const semanticOnly = event.type === "agent-run-started" || event.type === "assistant-message-completed";
|
|
370
|
+
const view = event.type === "transcript-block" && this.#sessionGeneration === this.backend.identity.sessionGeneration
|
|
371
|
+
? this.#syncBlock(event.block)
|
|
372
|
+
: semanticOnly ? this.view() : this.#syncView();
|
|
373
|
+
this.#syncTerminalProgress(view);
|
|
374
|
+
this.#promptSuggestions?.noteView(view, this.backend.identity.sessionGeneration !== this.#sessionGeneration);
|
|
375
|
+
if (event.type === "status" && /^(Retrying|Compacting)/.test(event.status.workingMessage ?? "")) {
|
|
376
|
+
this.#promptSuggestions?.invalidate();
|
|
377
|
+
}
|
|
378
|
+
if (event.type === "agent-run-settled") {
|
|
379
|
+
this.#promptSuggestions?.route(event, () => this.root.promptSuggestionPrepareBlockReason());
|
|
380
|
+
}
|
|
381
|
+
if (event.type === "session-lifecycle" && event.lifecycle === "stopped")
|
|
382
|
+
this.#stop.settleAfter(() => this.dispose());
|
|
383
|
+
}
|
|
514
384
|
#trackCopy(delivery, count) {
|
|
515
385
|
const intent = ++this.#copyIntentSequence;
|
|
516
386
|
void delivery?.then(({ outcome }) => {
|
|
517
387
|
if (count === undefined || this.#disposed || !this.#terminal.running || intent !== this.#copyIntentSequence
|
|
518
388
|
|| outcome !== "delivered" && outcome !== "submitted-unverified")
|
|
519
389
|
return;
|
|
520
|
-
this.root.showCopyAcknowledgement(copyAcknowledgementText(count));
|
|
390
|
+
this.root.chrome.showCopyAcknowledgement(copyAcknowledgementText(count));
|
|
521
391
|
});
|
|
522
392
|
}
|
|
523
|
-
#promptSuggestionPresentationBlockReason(identity) {
|
|
524
|
-
return suggestionPresentationBlockReason(identity, { disposed: this.#disposed, view: this.view(), sessionGeneration: this.backend.identity.sessionGeneration }, () => this.root.promptSuggestionPresentationBlockReason());
|
|
525
|
-
}
|
|
526
393
|
start() {
|
|
527
394
|
if (this.#started)
|
|
528
395
|
return;
|
|
@@ -537,9 +404,9 @@ export class OwnedUiSessionPresenter {
|
|
|
537
404
|
if (this.#disposed || !this.#customViewport)
|
|
538
405
|
return;
|
|
539
406
|
this.#dialogs.presentStartupRoute();
|
|
540
|
-
void this.#
|
|
407
|
+
void this.#presenters.components.dialogs.lazySelectors().then(selectors => selectors.prepare()).catch(() => { });
|
|
541
408
|
this.root.warmPastePreparation();
|
|
542
|
-
this.#
|
|
409
|
+
this.#clipboard.warm();
|
|
543
410
|
});
|
|
544
411
|
}
|
|
545
412
|
onView(listener) {
|
|
@@ -639,7 +506,7 @@ export class OwnedUiSessionPresenter {
|
|
|
639
506
|
}
|
|
640
507
|
async cycleModel(direction) {
|
|
641
508
|
const result = await this.backend.workflows.cycleModelWorkflow(direction);
|
|
642
|
-
this.root.
|
|
509
|
+
this.root.workflow.appendResult(result);
|
|
643
510
|
this.#terminal.requestRender();
|
|
644
511
|
return workflowAdapterResult(result);
|
|
645
512
|
}
|
|
@@ -660,8 +527,8 @@ export class OwnedUiSessionPresenter {
|
|
|
660
527
|
setInputSurface: surface => this.root.setInputSurface(surface),
|
|
661
528
|
requestRender: () => this.#terminal.requestRender(),
|
|
662
529
|
viewport: () => this.#terminal.viewport(),
|
|
663
|
-
appendWorkflowStatus: text => this.root.
|
|
664
|
-
appendWorkflowResult: result => this.root.
|
|
530
|
+
appendWorkflowStatus: text => this.root.workflow.appendStatus(text),
|
|
531
|
+
appendWorkflowResult: result => this.root.workflow.appendResult(result),
|
|
665
532
|
runWorkflow: request => this.runWorkflow(request),
|
|
666
533
|
// Invariant: the custom bare-A1 surface holds frames while optional selectors load and is permanently
|
|
667
534
|
// fullscreen; the pinned comparison profiles render immediately and keep Pi's TUI mode switch.
|
|
@@ -670,14 +537,6 @@ export class OwnedUiSessionPresenter {
|
|
|
670
537
|
: { switchTuiMode: mode => this.#terminal.switchMode(mode) }),
|
|
671
538
|
};
|
|
672
539
|
}
|
|
673
|
-
#loadLazySelectors() {
|
|
674
|
-
if (this.#lazySelectors !== undefined)
|
|
675
|
-
return Promise.resolve(this.#lazySelectors);
|
|
676
|
-
return this.#lazySelectorsPromise ??= import("../../integrations/pi/components/lazy-selectors.js").then(module => {
|
|
677
|
-
this.#lazySelectors = module.piShellLazySelectors;
|
|
678
|
-
return module.piShellLazySelectors;
|
|
679
|
-
});
|
|
680
|
-
}
|
|
681
540
|
async showThinkingSelector() {
|
|
682
541
|
const snapshot = this.backend.settings.snapshot();
|
|
683
542
|
const close = () => {
|
|
@@ -691,7 +550,7 @@ export class OwnedUiSessionPresenter {
|
|
|
691
550
|
};
|
|
692
551
|
const releasePresentation = this.#customViewport ? this.#terminal.beginPresentationHold() : undefined;
|
|
693
552
|
try {
|
|
694
|
-
const selectors = await this.#
|
|
553
|
+
const selectors = await this.#presenters.components.dialogs.lazySelectors();
|
|
695
554
|
const component = await selectors.createThinking({
|
|
696
555
|
currentLevel: snapshot.thinkingLevel,
|
|
697
556
|
availableLevels: snapshot.availableThinkingLevels,
|
|
@@ -699,7 +558,7 @@ export class OwnedUiSessionPresenter {
|
|
|
699
558
|
onCancel: close,
|
|
700
559
|
onSelectAsDefault: level => this.backend.settings.setDefaultThinkingLevel(level),
|
|
701
560
|
defaultLevel: snapshot.defaultThinkingLevel,
|
|
702
|
-
...(this
|
|
561
|
+
...(this.backend.settings.productMode === "bare" ? {
|
|
703
562
|
presentation: {
|
|
704
563
|
profile: "bare",
|
|
705
564
|
cycleBinding: this.root.editor.keybindingConfig()["app.thinking.cycle"] ?? [],
|
|
@@ -719,11 +578,11 @@ export class OwnedUiSessionPresenter {
|
|
|
719
578
|
/** The Skills dialog: a replacement input like the model selector, applying the chosen skill through the prompt path. */
|
|
720
579
|
showSkillsSelector(skills = this.#skillSummaries()) {
|
|
721
580
|
const close = this.#dialogs.closeInputSurface;
|
|
722
|
-
const component =
|
|
581
|
+
const component = this.#presenters.components.dialogs.skillsSelector({
|
|
723
582
|
skills,
|
|
724
583
|
onSelect: name => {
|
|
725
584
|
close();
|
|
726
|
-
void this.#submission.sendSlashPrompt(
|
|
585
|
+
void this.#submission.sendSlashPrompt(this.#presenters.components.skills.prompt(name), this.#presenters.components.skills.prompt(name)).catch(() => this.#submission.reportError());
|
|
727
586
|
},
|
|
728
587
|
onCancel: close,
|
|
729
588
|
});
|
|
@@ -736,12 +595,12 @@ export class OwnedUiSessionPresenter {
|
|
|
736
595
|
showForkSelector() {
|
|
737
596
|
const options = this.backend.catalog.pinnedForkOptions();
|
|
738
597
|
if (options.length === 0) {
|
|
739
|
-
this.root.
|
|
598
|
+
this.root.workflow.appendResult({ command: "fork", outcome: "completed", message: "No messages to fork from", messageKind: "status" });
|
|
740
599
|
this.#terminal.requestRender();
|
|
741
600
|
return;
|
|
742
601
|
}
|
|
743
602
|
const close = this.#dialogs.closeInputSurface;
|
|
744
|
-
const component =
|
|
603
|
+
const component = this.#presenters.components.dialogs.userMessageSelector(options, selection => {
|
|
745
604
|
close();
|
|
746
605
|
void this.runWorkflow({ command: "fork", argument: "", selection });
|
|
747
606
|
}, close);
|
|
@@ -754,7 +613,7 @@ export class OwnedUiSessionPresenter {
|
|
|
754
613
|
options = await this.backend.catalog.pinnedLogoutOptions();
|
|
755
614
|
}
|
|
756
615
|
catch (error) {
|
|
757
|
-
this.root.
|
|
616
|
+
this.root.workflow.appendResult({
|
|
758
617
|
command: "logout",
|
|
759
618
|
outcome: "failed",
|
|
760
619
|
message: `Could not read stored credentials: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -763,12 +622,12 @@ export class OwnedUiSessionPresenter {
|
|
|
763
622
|
return;
|
|
764
623
|
}
|
|
765
624
|
if (options.length === 0) {
|
|
766
|
-
this.root.
|
|
625
|
+
this.root.workflow.appendStatus("No stored credentials to remove. /logout only removes credentials saved by /login; environment variables and models.json config are unchanged.");
|
|
767
626
|
this.#terminal.requestRender();
|
|
768
627
|
return;
|
|
769
628
|
}
|
|
770
629
|
const close = this.#dialogs.closeInputSurface;
|
|
771
|
-
const component =
|
|
630
|
+
const component = this.#presenters.components.dialogs.authProviderSelector("logout", options, selection => {
|
|
772
631
|
close();
|
|
773
632
|
void this.runWorkflow({ command: "logout", argument: "", selection });
|
|
774
633
|
}, close);
|
|
@@ -789,7 +648,7 @@ export class OwnedUiSessionPresenter {
|
|
|
789
648
|
}
|
|
790
649
|
const close = this.#dialogs.closeInputSurface;
|
|
791
650
|
const labels = method.options.map(option => option.label);
|
|
792
|
-
const component =
|
|
651
|
+
const component = this.#presenters.components.dialogs.extensionSelector(method.title, labels, label => {
|
|
793
652
|
const selection = method.options.find(option => option.label === label)?.id;
|
|
794
653
|
if (!selection)
|
|
795
654
|
return;
|
|
@@ -807,7 +666,7 @@ export class OwnedUiSessionPresenter {
|
|
|
807
666
|
showLoginAuthTypeSelector() {
|
|
808
667
|
const close = this.#dialogs.closeInputSurface;
|
|
809
668
|
const labels = ["Sign in with an account", "Sign in with an API key"];
|
|
810
|
-
const component =
|
|
669
|
+
const component = this.#presenters.components.dialogs.extensionSelector("Select authentication method:", labels, label => {
|
|
811
670
|
close();
|
|
812
671
|
this.showLoginProviderSelector(label === labels[0] ? "oauth" : "api_key");
|
|
813
672
|
}, close);
|
|
@@ -817,12 +676,12 @@ export class OwnedUiSessionPresenter {
|
|
|
817
676
|
showLoginProviderSelector(authType, initialSearchInput) {
|
|
818
677
|
const options = this.backend.catalog.pinnedLoginOptions(authType);
|
|
819
678
|
if (options.length === 0) {
|
|
820
|
-
this.root.
|
|
679
|
+
this.root.workflow.appendStatus(authType === "oauth" ? "No account providers available." : authType === "api_key" ? "No API key providers available." : "No login providers available.");
|
|
821
680
|
this.#terminal.requestRender();
|
|
822
681
|
return;
|
|
823
682
|
}
|
|
824
683
|
const close = this.#dialogs.closeInputSurface;
|
|
825
|
-
const component =
|
|
684
|
+
const component = this.#presenters.components.dialogs.authProviderSelector("login", options, id => {
|
|
826
685
|
close();
|
|
827
686
|
void this.runWorkflow({ command: "login", argument: "", selection: id });
|
|
828
687
|
}, () => {
|
|
@@ -841,21 +700,13 @@ export class OwnedUiSessionPresenter {
|
|
|
841
700
|
}
|
|
842
701
|
shutdown() {
|
|
843
702
|
this.#shutdownPromise ??= this.#shutdown().finally(() => {
|
|
844
|
-
// Invariant: a
|
|
703
|
+
// Invariant: a failed quit is retryable; ordinary shutdown has disposed the shell already.
|
|
845
704
|
if (!this.#disposed)
|
|
846
705
|
this.#shutdownPromise = undefined;
|
|
847
706
|
});
|
|
848
707
|
return this.#shutdownPromise;
|
|
849
708
|
}
|
|
850
709
|
async #shutdown() {
|
|
851
|
-
const detached = await this.#resident.detach();
|
|
852
|
-
if (detached === true)
|
|
853
|
-
return { outcome: "completed", diagnostic: null };
|
|
854
|
-
if (detached !== undefined) {
|
|
855
|
-
this.root.appendWorkflowStatus(detached);
|
|
856
|
-
this.#terminal.requestRender();
|
|
857
|
-
return rejected("resident tab detach is unavailable");
|
|
858
|
-
}
|
|
859
710
|
try {
|
|
860
711
|
const quit = this.backend.workflows.executeWorkflow({ command: "quit", argument: "" });
|
|
861
712
|
// Invariant: a slow or hung engine quit never holds the terminal past the cleanup deadline. The
|
|
@@ -889,7 +740,7 @@ export class OwnedUiSessionPresenter {
|
|
|
889
740
|
}).catch(error => {
|
|
890
741
|
if (this.#disposed)
|
|
891
742
|
return;
|
|
892
|
-
this.root.
|
|
743
|
+
this.root.workflow.appendResult({ command: "name", outcome: "failed", message: error instanceof Error ? error.message : String(error) });
|
|
893
744
|
this.#terminal.requestRender();
|
|
894
745
|
});
|
|
895
746
|
return { outcome: "completed", diagnostic: null };
|
|
@@ -899,20 +750,20 @@ export class OwnedUiSessionPresenter {
|
|
|
899
750
|
const setup = this.backend.catalog.pinnedAmbientAuthentication(request.selection);
|
|
900
751
|
if (setup) {
|
|
901
752
|
const close = this.#dialogs.closeInputSurface;
|
|
902
|
-
const dialog =
|
|
753
|
+
const dialog = this.#presenters.components.dialogs.loginDialog(componentRuntime(this.#terminal), setup.providerId, close, setup.providerName, setup.title);
|
|
903
754
|
dialog.showInfo(setup.message, [], true);
|
|
904
755
|
this.root.setInputSurface(dialog);
|
|
905
756
|
this.#terminal.requestRender();
|
|
906
757
|
return { outcome: "completed", diagnostic: null };
|
|
907
758
|
}
|
|
908
759
|
}
|
|
909
|
-
const selected = openWorkflowSelector(request, this
|
|
760
|
+
const selected = openWorkflowSelector(request, this);
|
|
910
761
|
if (selected !== undefined)
|
|
911
762
|
return selected;
|
|
912
763
|
if (request.command === "reload") {
|
|
913
764
|
const blocked = this.backend.workflows.reloadBlockedResult();
|
|
914
765
|
if (blocked) {
|
|
915
|
-
this.root.
|
|
766
|
+
this.root.workflow.appendResult(blocked);
|
|
916
767
|
this.#terminal.requestRender();
|
|
917
768
|
return workflowAdapterResult(blocked);
|
|
918
769
|
}
|
|
@@ -922,8 +773,8 @@ export class OwnedUiSessionPresenter {
|
|
|
922
773
|
? await import("./share-operation.js")
|
|
923
774
|
: undefined;
|
|
924
775
|
const shareSurface = shareDialog === undefined ? undefined
|
|
925
|
-
:
|
|
926
|
-
const operationSurface = shareSurface ?? (request.command === "reload" ?
|
|
776
|
+
: await this.#presenters.components.dialogs.shareProgress(componentRuntime(this.#terminal), "Creating gist…", this.#customViewport ? "dialog" : "loader");
|
|
777
|
+
const operationSurface = shareSurface ?? (request.command === "reload" ? this.#presenters.components.info.reloadBox() : undefined);
|
|
927
778
|
const now = this.#reloadPresentation?.now ?? Date.now;
|
|
928
779
|
const shownAt = now();
|
|
929
780
|
if (operationSurface) {
|
|
@@ -954,7 +805,7 @@ export class OwnedUiSessionPresenter {
|
|
|
954
805
|
if (result.outcome === "requires-selection" && request.command === "model") {
|
|
955
806
|
if (result.messages !== undefined) {
|
|
956
807
|
for (const message of result.messages)
|
|
957
|
-
this.root.
|
|
808
|
+
this.root.workflow.appendMessage(message);
|
|
958
809
|
}
|
|
959
810
|
this.showModelSelector((result.detail ?? request.argument.trim()) || undefined);
|
|
960
811
|
return { outcome: "completed", diagnostic: null };
|
|
@@ -973,7 +824,7 @@ export class OwnedUiSessionPresenter {
|
|
|
973
824
|
});
|
|
974
825
|
}
|
|
975
826
|
if (result.outcome === "requires-selection" || result.outcome === "requires-confirmation") {
|
|
976
|
-
this.root.
|
|
827
|
+
this.root.workflow.appendResult({ command: request.command, outcome: "failed", message: `Owned controller missing for ${request.command}` });
|
|
977
828
|
this.#terminal.requestRender();
|
|
978
829
|
return { outcome: "failed", diagnostic: `Owned controller missing for ${request.command}` };
|
|
979
830
|
}
|
|
@@ -988,10 +839,10 @@ export class OwnedUiSessionPresenter {
|
|
|
988
839
|
this.root.resumeViewportFollowing();
|
|
989
840
|
}
|
|
990
841
|
if (shareDialog !== undefined && this.#customViewport && result.outcome === "completed" && result.detail !== undefined) {
|
|
991
|
-
this.root.
|
|
842
|
+
this.root.workflow.appendStatus(shareDialog.renderShellShareResult(result.message, result.detail, this.#presenters.theme.current(), url => this.#presenters.components.text.hyperlink(url)));
|
|
992
843
|
}
|
|
993
844
|
else {
|
|
994
|
-
this.root.
|
|
845
|
+
this.root.workflow.appendResult(result);
|
|
995
846
|
}
|
|
996
847
|
this.#terminal.requestRender();
|
|
997
848
|
return workflowAdapterResult(result);
|
|
@@ -1007,17 +858,17 @@ export class OwnedUiSessionPresenter {
|
|
|
1007
858
|
showTrustSelector() {
|
|
1008
859
|
const context = this.backend.catalog.pinnedProjectTrustContext();
|
|
1009
860
|
const close = this.#dialogs.closeInputSurface;
|
|
1010
|
-
const component =
|
|
861
|
+
const component = this.#presenters.components.dialogs.trustSelector({
|
|
1011
862
|
...context,
|
|
1012
863
|
onSelect: selection => {
|
|
1013
864
|
try {
|
|
1014
865
|
this.backend.catalog.persistProjectTrust(selection.updates);
|
|
1015
866
|
close();
|
|
1016
|
-
this.root.
|
|
867
|
+
this.root.workflow.appendStatus(`Saved trust decision: ${selection.trusted ? "trusted" : "untrusted"}. Restart pi for this to take effect.`);
|
|
1017
868
|
}
|
|
1018
869
|
catch (error) {
|
|
1019
870
|
close();
|
|
1020
|
-
this.root.
|
|
871
|
+
this.root.workflow.appendResult({ command: "trust", outcome: "failed", message: error instanceof Error ? error.message : String(error) });
|
|
1021
872
|
}
|
|
1022
873
|
this.#terminal.requestRender();
|
|
1023
874
|
},
|
|
@@ -1031,7 +882,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1031
882
|
}
|
|
1032
883
|
// Invariant: bare A1 routes `models`; the comparison profile keeps the pinned `model`/`scoped-models` pair. Hidden routes are shared.
|
|
1033
884
|
#isWorkflowRoute(value) {
|
|
1034
|
-
return
|
|
885
|
+
return this.#presenters.components.workflows.commandNames(this.backend.settings.productMode).includes(value)
|
|
1035
886
|
|| OWNED_UI_HIDDEN_COMMAND_NAMES.includes(value);
|
|
1036
887
|
}
|
|
1037
888
|
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
@@ -1068,8 +919,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1068
919
|
// Invariant: events stop first, so nothing re-enters the view during history close, outro, or restoration.
|
|
1069
920
|
attempt(() => this.#unsubscribe());
|
|
1070
921
|
this.#copyIntentSequence += 1;
|
|
1071
|
-
this.#
|
|
1072
|
-
this.#copyExecutor?.dispose();
|
|
922
|
+
this.#clipboard.dispose();
|
|
1073
923
|
this.#submission.cancelWaiting();
|
|
1074
924
|
let pasteCleanup = Promise.resolve();
|
|
1075
925
|
let historyCleanup = Promise.resolve(true);
|
|
@@ -1078,10 +928,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1078
928
|
attempt(() => this.root.clearViewportPointerState());
|
|
1079
929
|
attempt(() => this.#streamPresentation.dispose());
|
|
1080
930
|
attempt(() => this.#promptSuggestions?.dispose());
|
|
1081
|
-
attempt(() => this.#
|
|
1082
|
-
attempt(() => this.#unsubscribePromptImages());
|
|
1083
|
-
attempt(() => this.#unsubscribeSkills());
|
|
1084
|
-
attempt(() => this.#unsubscribeSettings());
|
|
931
|
+
attempt(() => this.#unbindShellSettings());
|
|
1085
932
|
let exitText = "";
|
|
1086
933
|
attempt(() => {
|
|
1087
934
|
exitText = composeExitText({
|
|
@@ -1089,8 +936,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1089
936
|
customViewport: this.#customViewport,
|
|
1090
937
|
exitMode: this.backend.identity.disposed ? this.#fullscreenExitOutput : this.backend.settings.snapshot().fullscreenExitOutput,
|
|
1091
938
|
resume: this.backend.identity.currentSessionResumeMetadata(),
|
|
1092
|
-
|
|
1093
|
-
transcript: () => this.root.exitTranscript(terminal.columns),
|
|
939
|
+
transcript: () => this.root.transcript.exitTranscript(terminal.columns),
|
|
1094
940
|
});
|
|
1095
941
|
});
|
|
1096
942
|
attempt(() => this.#unbindClipboardWriter());
|
|
@@ -1110,8 +956,6 @@ export class OwnedUiSessionPresenter {
|
|
|
1110
956
|
}
|
|
1111
957
|
await historyCleanup.catch(() => false); // Security: background durability outcomes never enter terminal output.
|
|
1112
958
|
await boundedCleanup(() => pasteCleanup).catch(error => settled.push(error));
|
|
1113
|
-
await boundedCleanup(() => this.#resident.gracefulStop(this.#currentSessionFile()))
|
|
1114
|
-
.catch(error => settled.push(error));
|
|
1115
959
|
await boundedCleanup(() => this.backend.extensions.unbindExtensionUi()).catch(error => settled.push(error));
|
|
1116
960
|
return settled;
|
|
1117
961
|
};
|
|
@@ -1120,7 +964,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1120
964
|
}
|
|
1121
965
|
// Invariant: incremental block updates notify listeners with the same complete view contract.
|
|
1122
966
|
#syncBlock(block) {
|
|
1123
|
-
this.root.
|
|
967
|
+
this.root.transcript.apply(block);
|
|
1124
968
|
if (this.#customViewport && block.status === "live" && isCoalescedStreamBlock(block.kind)) {
|
|
1125
969
|
this.#streamPresentation.request();
|
|
1126
970
|
}
|
|
@@ -1137,7 +981,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1137
981
|
}
|
|
1138
982
|
// Rationale: extensions reach the shell only through this bridge; every surface they draw lands in the root.
|
|
1139
983
|
#createExtensionBridge() {
|
|
1140
|
-
return
|
|
984
|
+
return this.#presenters.components.dialogs.extensionUiBridge({
|
|
1141
985
|
runtime: componentRuntime(this.#terminal),
|
|
1142
986
|
agentDir: this.backend.identity.agentDir,
|
|
1143
987
|
setInputSurface: component => this.root.setInputSurface(component, true, "opaque"),
|
|
@@ -1166,8 +1010,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1166
1010
|
backend: this.backend,
|
|
1167
1011
|
root: this.root,
|
|
1168
1012
|
terminal: this.#terminal,
|
|
1169
|
-
|
|
1170
|
-
cwd,
|
|
1013
|
+
cwd, statusText: this.#presenters.components.info.statusText,
|
|
1171
1014
|
promptHistory: () => this.#promptHistory,
|
|
1172
1015
|
imageSidecar: () => this.#historyBinding?.imageSidecar,
|
|
1173
1016
|
disposed: () => this.#disposed,
|
|
@@ -1181,7 +1024,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1181
1024
|
// Invariant: the order is the reset order on session replacement; copy intent before pastes before the input surface.
|
|
1182
1025
|
#createConcerns() {
|
|
1183
1026
|
return new SessionConcerns([
|
|
1184
|
-
{ onSessionReplaced: () => { this.#copyIntentSequence += 1; this.#
|
|
1027
|
+
{ onSessionReplaced: () => { this.#copyIntentSequence += 1; this.#clipboard.reset(); } },
|
|
1185
1028
|
this.#submission,
|
|
1186
1029
|
{ onSessionReplaced: () => this.root.resetPendingPastes() },
|
|
1187
1030
|
{ onSessionReplaced: () => this.#promptSuggestions?.invalidate() },
|
|
@@ -1195,7 +1038,6 @@ export class OwnedUiSessionPresenter {
|
|
|
1195
1038
|
{ onSessionReplaced: () => this.root.setInputSurface(null) },
|
|
1196
1039
|
{ onSessionReplaced: () => this.root.resetExtensionUi() },
|
|
1197
1040
|
{ onSessionReplaced: () => this.root.resetWorkflowPresentation() },
|
|
1198
|
-
this.#resident,
|
|
1199
1041
|
]);
|
|
1200
1042
|
}
|
|
1201
1043
|
// Invariant: delivery recovery does not replace a store; conversation or live scope changes can.
|
|
@@ -1205,7 +1047,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1205
1047
|
return;
|
|
1206
1048
|
if (replaced) {
|
|
1207
1049
|
this.#sessionBindingGeneration = this.backend.identity.sessionBindingGeneration;
|
|
1208
|
-
this.root.
|
|
1050
|
+
this.root.transcript.reset();
|
|
1209
1051
|
}
|
|
1210
1052
|
const binding = this.#historyBinding;
|
|
1211
1053
|
if (binding?.options.forSession !== undefined || binding?.options.forScope !== undefined) {
|
|
@@ -1288,42 +1130,38 @@ export class OwnedUiSessionPresenter {
|
|
|
1288
1130
|
if (diagnostic === undefined || !this.#terminal.running)
|
|
1289
1131
|
return;
|
|
1290
1132
|
this.#startupTrustHandled = true;
|
|
1291
|
-
this.root.
|
|
1133
|
+
this.root.workflow.appendMessage({ kind: "warning", message: diagnostic.message });
|
|
1292
1134
|
}
|
|
1293
1135
|
openOwnedRoute(route) {
|
|
1294
1136
|
if (this.#disposed)
|
|
1295
1137
|
return;
|
|
1296
|
-
// Invariant: a route requested before the runtime runs
|
|
1297
|
-
//
|
|
1138
|
+
// Invariant: a route requested before the runtime runs is retained, latest wins, and presented
|
|
1139
|
+
// through the startup-route path once started.
|
|
1298
1140
|
if (!this.#terminal.running) {
|
|
1299
1141
|
this.#dialogs.retainStartupRoute(route);
|
|
1300
1142
|
return;
|
|
1301
1143
|
}
|
|
1302
1144
|
const result = this.#dialogs.openRoute(route);
|
|
1303
1145
|
if (result.outcome !== "completed" && result.diagnostic !== null) {
|
|
1304
|
-
this.root.
|
|
1146
|
+
this.root.workflow.appendMessage({ kind: "warning", message: result.diagnostic });
|
|
1305
1147
|
}
|
|
1306
1148
|
}
|
|
1307
1149
|
hotkeysPresentation() {
|
|
1308
|
-
|
|
1309
|
-
return this.#resident.active ? { ...presentation, residentTabs: true } : presentation;
|
|
1150
|
+
return this.root.hotkeysPresentation();
|
|
1310
1151
|
}
|
|
1311
1152
|
async #slashCommand(text) {
|
|
1312
1153
|
const body = text.slice(1).trim();
|
|
1313
1154
|
const separator = body.search(/\s/);
|
|
1314
1155
|
const name = separator < 0 ? body : body.slice(0, separator);
|
|
1315
1156
|
const argument = separator < 0 ? "" : body.slice(separator + 1).trimStart();
|
|
1316
|
-
const utilityTab = this.#resident.active ? RESIDENT_UTILITY_TAB_REFUSALS[name] : undefined;
|
|
1317
|
-
if (utilityTab !== undefined)
|
|
1318
|
-
return rejected(utilityTab);
|
|
1319
1157
|
if (this.#dialogs.claimsRoute(name))
|
|
1320
1158
|
return this.#dialogs.openRoute(name);
|
|
1321
1159
|
if (this.#isWorkflowRoute(name))
|
|
1322
1160
|
return this.runWorkflow({ command: name, argument });
|
|
1323
1161
|
if (this.#skillsCollapsed()) {
|
|
1324
|
-
if (name ===
|
|
1162
|
+
if (name === this.#presenters.components.skills.commandName)
|
|
1325
1163
|
return this.#runSkillsCommand(text, argument);
|
|
1326
|
-
const rewritten =
|
|
1164
|
+
const rewritten = this.#presenters.components.skills.rewriteTunnelSubmission(text);
|
|
1327
1165
|
if (rewritten !== text)
|
|
1328
1166
|
return this.#submission.sendSlashPrompt(rewritten, text);
|
|
1329
1167
|
}
|
|
@@ -1343,7 +1181,7 @@ export class OwnedUiSessionPresenter {
|
|
|
1343
1181
|
&& !this.backend.identity.disposed && this.backend.settings.snapshot().enableSkillCommands;
|
|
1344
1182
|
}
|
|
1345
1183
|
#skillSummaries() {
|
|
1346
|
-
return
|
|
1184
|
+
return this.#presenters.components.skills.fromCommands(this.backend.workflows.workflowAutocompleteCommands());
|
|
1347
1185
|
}
|
|
1348
1186
|
// Protocol: bare "/skills" opens the dialog, "/skills <name> [args]" applies directly, and an unknown name is a command outcome.
|
|
1349
1187
|
async #runSkillsCommand(text, argument) {
|
|
@@ -1355,18 +1193,18 @@ export class OwnedUiSessionPresenter {
|
|
|
1355
1193
|
}
|
|
1356
1194
|
const separator = trimmed.search(/\s/u);
|
|
1357
1195
|
const token = separator < 0 ? trimmed : trimmed.slice(0, separator);
|
|
1358
|
-
const skill =
|
|
1196
|
+
const skill = this.#presenters.components.skills.findByArgument(skills, token);
|
|
1359
1197
|
if (skill === undefined) {
|
|
1360
1198
|
const message = "Unknown skill: " + token;
|
|
1361
|
-
this.root.
|
|
1199
|
+
this.root.workflow.appendMessage({ kind: "error", message });
|
|
1362
1200
|
this.#terminal.requestRender();
|
|
1363
1201
|
return { outcome: "failed", diagnostic: message };
|
|
1364
1202
|
}
|
|
1365
|
-
return this.#submission.sendSlashPrompt(
|
|
1203
|
+
return this.#submission.sendSlashPrompt(this.#presenters.components.skills.prompt(skill.name, separator < 0 ? "" : trimmed.slice(separator + 1)), text);
|
|
1366
1204
|
}
|
|
1367
1205
|
#treeSummary() {
|
|
1368
1206
|
return new Promise(resolve => {
|
|
1369
|
-
this.root.setInputSurface(
|
|
1207
|
+
this.root.setInputSurface(this.#presenters.components.dialogs.extensionSelector("Summarize Branch?", ["No summary", "Summarize", "Summarize with custom prompt"], resolve, () => resolve(undefined)), true, "opaque");
|
|
1370
1208
|
this.#terminal.requestRender();
|
|
1371
1209
|
});
|
|
1372
1210
|
}
|
|
@@ -1447,9 +1285,6 @@ function copyCharacters(snapshot) {
|
|
|
1447
1285
|
}
|
|
1448
1286
|
return hasContent ? count : undefined;
|
|
1449
1287
|
}
|
|
1450
|
-
function rejected(diagnostic) {
|
|
1451
|
-
return { outcome: "rejected", diagnostic };
|
|
1452
|
-
}
|
|
1453
1288
|
function workflowAdapterResult(result) {
|
|
1454
1289
|
if (result.outcome === "completed")
|
|
1455
1290
|
return { outcome: "completed", diagnostic: null };
|