@timurproko/a1 0.2.7-dev.1252 → 0.2.7-dev.1264
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/bin/ui.js +3 -3
- 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 +2 -2
- package/dist/app/session-shell/exit-notice.js +1 -1
- 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 +5 -2
- package/dist/app/session-shell/prompt-submission.js +13 -14
- 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/resource-labels.d.ts +2 -0
- package/dist/app/session-shell/resource-labels.js +158 -0
- 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 +1 -1
- package/dist/app/session-shell/session-lifecycle.d.ts +2 -1
- package/dist/app/session-shell/session-prompt-history.d.ts +29 -0
- package/dist/app/session-shell/session-prompt-history.js +80 -0
- package/dist/app/session-shell/session-selectors.d.ts +46 -0
- package/dist/app/session-shell/session-selectors.js +269 -0
- package/dist/app/session-shell/session-shell-root.d.ts +76 -113
- package/dist/app/session-shell/session-shell-root.js +103 -329
- package/dist/app/session-shell/session-shell.d.ts +14 -37
- package/dist/app/session-shell/session-shell.js +177 -612
- package/dist/app/session-shell/session-viewport-controller.d.ts +9 -16
- package/dist/app/session-shell/session-viewport-controller.js +42 -320
- package/dist/app/session-shell/settings-bindings.d.ts +25 -3
- package/dist/app/session-shell/settings-bindings.js +26 -2
- 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 +18 -19
- 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 +11 -8
- package/dist/app/session-shell/transcript-document.js +13 -14
- package/dist/app/session-shell/viewport-layout.d.ts +2 -2
- package/dist/app/session-shell/viewport-pointer.d.ts +83 -0
- package/dist/app/session-shell/viewport-pointer.js +361 -0
- package/dist/app/session-shell/workflow-output.d.ts +5 -3
- package/dist/app/session-shell/workflow-output.js +13 -15
- 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/uninstall.d.ts +3 -2
- package/dist/composition/owned-settings.d.ts +2 -1
- package/dist/composition/owned-settings.js +0 -3
- package/dist/composition/owned-ui.d.ts +1 -1
- package/dist/composition/owned-ui.js +77 -73
- package/dist/composition/reference-selection-options.d.ts +1 -1
- package/dist/composition/reference-selection-options.js +1 -1
- package/dist/composition/session-runtime-registry.d.ts +2 -1
- package/dist/composition/settings-route-host.js +3 -10
- package/dist/composition/settings-search-input.d.ts +2 -1
- package/dist/composition/startup-route.d.ts +2 -2
- package/dist/composition/startup-route.js +2 -2
- 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/index.js +1 -1
- package/dist/contracts/owned-ui/session-presenters.d.ts +3 -0
- package/dist/contracts/owned-ui/shell-components.d.ts +543 -0
- package/dist/contracts/owned-ui/validation.d.ts +1 -11
- package/dist/contracts/owned-ui/validation.js +8 -104
- 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 +284 -0
- package/dist/contracts/presentation/terminal.js +1 -0
- package/dist/contracts/presentation/theme.d.ts +46 -0
- package/dist/contracts/presentation/theme.js +1 -0
- package/dist/features/launch/development-launch.js +1 -1
- package/dist/features/launch/runtime-selection.d.ts +2 -2
- package/dist/features/launch/runtime-selection.js +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/release-note-state.d.ts +2 -1
- package/dist/features/owned-ui/settings-app.js +49 -425
- 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-model-dialog.d.ts +41 -0
- package/dist/features/owned-ui/settings-model-dialog.js +194 -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/lifecycle/claim-gate.d.ts +2 -1
- package/dist/foundation/release/automatic-update.d.ts +5 -14
- package/dist/foundation/release/automatic-update.js +15 -22
- package/dist/foundation/release/bootstrap.js +4 -4
- package/dist/foundation/release/dependency-certification.d.ts +0 -1
- package/dist/foundation/release/dependency-certification.js +1 -1
- package/dist/foundation/release/dependency-layer.js +3 -3
- 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 +2 -2
- package/dist/foundation/release/index.js +1 -1
- package/dist/foundation/release/latest-release.d.ts +3 -18
- package/dist/foundation/release/latest-release.js +11 -11
- package/dist/foundation/release/managed-path.d.ts +10 -0
- package/dist/foundation/release/managed-path.js +26 -0
- 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/release-gc.d.ts +3 -3
- package/dist/foundation/release/release-gc.js +10 -12
- package/dist/foundation/release/{cohort-state.d.ts → release-state.d.ts} +23 -23
- package/dist/foundation/release/{cohort-state.js → release-state.js} +8 -8
- package/dist/foundation/release/restart-certification.js +3 -4
- package/dist/foundation/release/update-activation.js +3 -3
- package/dist/foundation/release/update-execution-lease.d.ts +2 -3
- package/dist/foundation/release/update-execution-lease.js +2 -8
- package/dist/foundation/release/update-installer.d.ts +45 -0
- package/dist/foundation/release/update-installer.js +57 -0
- package/dist/foundation/release/update-launch.d.ts +2 -2
- package/dist/foundation/release/update-recovery.js +2 -9
- package/dist/foundation/release/update.d.ts +4 -25
- package/dist/foundation/release/update.js +164 -183
- package/dist/foundation/startup/startup-budget.d.ts +5 -5
- package/dist/foundation/startup/startup-budget.js +2 -2
- package/dist/integrations/pi/components/bracketed-paste.d.ts +33 -0
- package/dist/integrations/pi/components/bracketed-paste.js +123 -0
- 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/owned-editor-ux.js +46 -140
- 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-footer-status.d.ts +2 -2
- package/dist/integrations/pi/components/shell-footer-status.js +3 -2
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +6 -5
- package/dist/integrations/pi/components/shell-presenters-info.js +2 -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 -227
- 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/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/engine/adapter.d.ts +4 -13
- package/dist/integrations/pi/engine/adapter.js +9 -61
- 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/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 +3 -3
- 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 -2
- 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-metadata.d.ts +49 -0
- package/dist/integrations/pi/engine/repository-metadata.js +189 -0
- 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 +7 -12
- package/dist/integrations/pi/engine/session-runtime.js +21 -178
- 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/view-state.d.ts +21 -2
- package/dist/integrations/pi/engine/view-state.js +129 -1
- package/dist/integrations/pi/engine/workflow-contexts.d.ts +1 -1
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -2
- package/dist/integrations/pi/engine/workflow-runner.js +254 -365
- package/dist/integrations/pi/engine/workflow-share.d.ts +9 -0
- package/dist/integrations/pi/engine/workflow-share.js +168 -0
- package/dist/integrations/pi/engine/workflow-support.d.ts +0 -20
- package/dist/integrations/pi/engine/workflow-support.js +4 -65
- 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 +9 -19
- package/dist/integrations/pi/tui-runtime/adapter.js +56 -174
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +9 -44
- package/dist/integrations/pi/tui-runtime/index.d.ts +1 -1
- 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 +4 -10
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +3 -9
- package/dist/integrations/pi/tui-runtime/presentation-adapter.d.ts +2 -2
- 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/ui/components/index.d.ts +2 -2
- package/dist/ui/components/index.js +1 -1
- package/dist/ui/components/selection-copy.d.ts +0 -1
- package/dist/ui/components/selection-copy.js +0 -12
- package/dist/ui/components/theme.d.ts +4 -19
- package/dist/ui/components/theme.js +6 -0
- package/dist/ui/components/transcript-viewport-frame.d.ts +120 -0
- package/dist/ui/components/transcript-viewport-frame.js +314 -0
- package/dist/ui/components/transcript-viewport-types.d.ts +147 -0
- package/dist/ui/components/transcript-viewport-types.js +1 -0
- package/dist/ui/components/transcript-viewport.d.ts +2 -147
- package/dist/ui/components/transcript-viewport.js +87 -315
- package/dist/ui/settings/declarations.d.ts +2 -3
- package/dist/ui/settings/declarations.js +2 -3
- 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 +2 -2
- package/docs/architecture/internal-naming.md +2 -0
- package/docs/architecture/project-structure.md +4 -2
- package/docs/validation.md +1 -1
- package/package.json +3 -4
- 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/diagnostics-state.d.ts +0 -9
- package/dist/integrations/pi/engine/diagnostics-state.js +0 -34
- package/dist/integrations/pi/engine/usage-view.d.ts +0 -4
- package/dist/integrations/pi/engine/usage-view.js +0 -56
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +0 -166
- package/dist/ui/settings/migrations.d.ts +0 -19
- package/dist/ui/settings/migrations.js +0 -225
- package/dist/ui/settings/progress-palette.generated.d.ts +0 -139
- package/dist/ui/settings/progress-palette.generated.js +0 -139
- /package/dist/{integrations/pi/tui-runtime/contracts.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
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
import { ImageAttachmentError } from "../../contracts/owned-ui/index.js";
|
|
2
1
|
import { promptArrow } from "../../ui/components/prompt-input.js";
|
|
3
2
|
import { composeSubmittedPromptRows, submittedPromptLayout, } from "../../ui/components/submitted-prompt.js";
|
|
4
3
|
import { nativeHyperlinkStyle } from "../../ui/components/spans.js";
|
|
5
4
|
import { paintTextSelection } from "../../ui/components/text-selection.js";
|
|
6
5
|
import { progressStatusFrame, progressStatusText } from "../../ui/components/progress-status.js";
|
|
7
|
-
import { createPiQueuedInputStatus, createPiShellFooter, createPiShellHeader, createPiShellLoadedResources, createPiShellStatus, } from "../../integrations/pi/components/shell-footer-status.js";
|
|
8
|
-
import { createPiShellTranscriptComponent, } from "../../integrations/pi/components/shell-presenters-transcript.js";
|
|
9
|
-
import { onPiThemeChange, piTheme } from "../../integrations/pi/components/upstream/theme/theme.js";
|
|
10
|
-
import { piShellTruncateToWidth, } from "../../integrations/pi/components/shell-shared-facade.js";
|
|
11
|
-
import {} from "../../integrations/pi/tui-runtime/input-presentation-coordinator.js";
|
|
12
6
|
import { PromptChipStore } from "./prompt-chips.js";
|
|
13
7
|
import { SessionViewportController } from "./session-viewport-controller.js";
|
|
14
8
|
import { createShellEditor } from "./shell-editor-factory.js";
|
|
@@ -18,14 +12,15 @@ import { WorkflowOutput } from "./workflow-output.js";
|
|
|
18
12
|
import { InputSurfaceSwitch } from "./input-surface-switch.js";
|
|
19
13
|
import { PinnedLayout } from "./shell-layout.js";
|
|
20
14
|
import { ViewportLayout } from "./viewport-layout.js";
|
|
21
|
-
import {
|
|
15
|
+
import { transcriptLinkColor, TranscriptDocument } from "./transcript-document.js";
|
|
22
16
|
/** Composes session state into the owned transcript, viewport, editor, and dock. */
|
|
23
17
|
export class OwnedUiSessionShellRoot {
|
|
24
18
|
editor;
|
|
25
19
|
header;
|
|
26
20
|
resources;
|
|
27
21
|
#cwd;
|
|
28
|
-
|
|
22
|
+
/** The transcript's semantic rows, caches, and engine-backed block renderers. */
|
|
23
|
+
transcript;
|
|
29
24
|
#themeUnsubscribe;
|
|
30
25
|
#view;
|
|
31
26
|
#status;
|
|
@@ -33,11 +28,11 @@ export class OwnedUiSessionShellRoot {
|
|
|
33
28
|
#queued;
|
|
34
29
|
#extensionRenderers;
|
|
35
30
|
#imageAssets;
|
|
36
|
-
|
|
31
|
+
promptChips;
|
|
37
32
|
#pasteDiagnosticId = 0;
|
|
38
33
|
#customViewport;
|
|
39
34
|
#submittedPromptComposer;
|
|
40
|
-
|
|
35
|
+
viewport;
|
|
41
36
|
#onPromptSuggestionEligibilityChanged;
|
|
42
37
|
#componentRuntime;
|
|
43
38
|
#toolsExpanded = false;
|
|
@@ -47,11 +42,13 @@ export class OwnedUiSessionShellRoot {
|
|
|
47
42
|
#showImages = true;
|
|
48
43
|
#imageWidthCells = 80;
|
|
49
44
|
#outputPad = 1;
|
|
50
|
-
|
|
45
|
+
/** Workflow results, messages, and status lines appended to the transcript. */
|
|
46
|
+
workflow;
|
|
51
47
|
#input;
|
|
52
48
|
#layout;
|
|
53
49
|
#extensions = new ExtensionSurface();
|
|
54
|
-
|
|
50
|
+
/** The dock's notices, copy acknowledgement, and release banner. */
|
|
51
|
+
chrome;
|
|
55
52
|
#imageSubmissionsSending = 0;
|
|
56
53
|
constructor(view, cwd, handlers, startup = {}, agentDir, extensionRenderers = {
|
|
57
54
|
getMessageRenderer: () => undefined,
|
|
@@ -60,57 +57,57 @@ export class OwnedUiSessionShellRoot {
|
|
|
60
57
|
}, sessionLayout = "pinned", imageAssets) {
|
|
61
58
|
this.#view = view;
|
|
62
59
|
this.#customViewport = sessionLayout === "custom-viewport";
|
|
63
|
-
this
|
|
60
|
+
this.promptChips = new PromptChipStore({ isolated: this.#customViewport,
|
|
64
61
|
...(handlers.pasteDiagnostics === undefined ? {} : { onEvent: handlers.pasteDiagnostics }),
|
|
65
62
|
...(handlers.pastePreparation === undefined ? {} : { preparation: handlers.pastePreparation }),
|
|
66
63
|
...(handlers.promptImageLimit === undefined ? {} : { imageLimit: handlers.promptImageLimit }) });
|
|
67
|
-
this.#submittedPromptComposer = this.#customViewport ? this.#createSubmittedPromptComposer() : undefined;
|
|
64
|
+
this.#submittedPromptComposer = this.#customViewport ? this.#createSubmittedPromptComposer(handlers.presentation.theme) : undefined;
|
|
68
65
|
this.#cwd = cwd;
|
|
69
|
-
this
|
|
66
|
+
this.transcript = this.#createDocument(cwd, handlers.presentation.theme, handlers.components);
|
|
70
67
|
this.#extensionRenderers = extensionRenderers;
|
|
71
68
|
this.#imageAssets = imageAssets;
|
|
72
69
|
this.#componentRuntime = handlers;
|
|
73
70
|
this.#onPromptSuggestionEligibilityChanged = handlers.onPromptSuggestionEligibilityChanged;
|
|
74
|
-
this.header =
|
|
71
|
+
this.header = handlers.components.chrome.header({
|
|
75
72
|
...startup,
|
|
76
73
|
...(this.#customViewport ? { getKeybindings: () => this.editor.keybindingConfig() } : {}),
|
|
77
74
|
});
|
|
78
|
-
this.resources =
|
|
79
|
-
this.#status =
|
|
75
|
+
this.resources = handlers.components.chrome.loadedResources(startup.resources ?? [], startup.expanded ?? false);
|
|
76
|
+
this.#status = handlers.components.chrome.status(view, {
|
|
80
77
|
text: (message, mode) => progressStatusText(message, mode === "custom-viewport" ? "…" : "..."),
|
|
81
78
|
frame: progressStatusFrame,
|
|
82
79
|
}, handlers);
|
|
83
80
|
this.#status.setProgressPresentation(this.#customViewport ? "custom-viewport" : "pinned");
|
|
84
|
-
this.#footer =
|
|
81
|
+
this.#footer = handlers.components.chrome.footer(this.#extensions.withStatuses(view), cwd, this.#customViewport ? "a1" : "pi", () => this.#footerLevel);
|
|
85
82
|
this.editor = createShellEditor({
|
|
86
|
-
handlers,
|
|
83
|
+
handlers, theme: handlers.presentation.theme, components: handlers.components,
|
|
87
84
|
customViewport: this.#customViewport,
|
|
88
85
|
cwd,
|
|
89
86
|
...(agentDir === undefined ? {} : { agentDir }),
|
|
90
|
-
promptChips: this
|
|
91
|
-
editorPointerSelecting: () => this
|
|
87
|
+
promptChips: this.promptChips,
|
|
88
|
+
editorPointerSelecting: () => this.viewport.editorPointerSelecting,
|
|
92
89
|
nextPasteDiagnosticRequest: () => --this.#pasteDiagnosticId,
|
|
93
90
|
toggleToolsExpanded: () => this.#setToolsExpanded(!this.#toolsExpanded),
|
|
94
91
|
});
|
|
95
|
-
this.#queued =
|
|
96
|
-
this
|
|
92
|
+
this.#queued = handlers.components.chrome.queuedInput(view.editor.queuedSubmissions, this.#customViewport ? "custom-viewport" : "pinned", this.#customViewport ? () => this.editor.keybindingConfig() : undefined);
|
|
93
|
+
this.viewport = new SessionViewportController({
|
|
97
94
|
enabled: this.#customViewport,
|
|
98
95
|
editor: this.editor,
|
|
99
96
|
requestRender: force => this.#componentRuntime.requestRender(force),
|
|
100
97
|
requestHyperlinkCleanup: rows => handlers.requestHyperlinkCleanup?.(rows),
|
|
101
|
-
hasEditorLinks: () => this
|
|
98
|
+
hasEditorLinks: () => this.promptChips.hyperlinkRanges(this.editor.getText()).length > 0,
|
|
102
99
|
...(handlers.pasteDiagnostics === undefined ? {} : { pasteDiagnostics: handlers.pasteDiagnostics }),
|
|
103
100
|
nextPasteDiagnosticRequest: () => --this.#pasteDiagnosticId,
|
|
104
101
|
});
|
|
105
|
-
this
|
|
102
|
+
this.chrome = new DockChrome({ theme: handlers.presentation.theme, outputPad: handlers.presentation.pinnedOutputPad, components: handlers.components,
|
|
106
103
|
invalidateChrome: () => this.#invalidateChrome(),
|
|
107
104
|
requestRender: () => this.#componentRuntime.requestRender(),
|
|
108
|
-
viewport: this
|
|
105
|
+
viewport: this.viewport,
|
|
109
106
|
});
|
|
110
|
-
this
|
|
111
|
-
customViewport: this.#customViewport,
|
|
112
|
-
document: this
|
|
113
|
-
dock: this
|
|
107
|
+
this.workflow = new WorkflowOutput({
|
|
108
|
+
customViewport: this.#customViewport, components: handlers.components,
|
|
109
|
+
document: this.transcript,
|
|
110
|
+
dock: this.chrome,
|
|
114
111
|
transcriptLength: () => this.#view.transcript.length,
|
|
115
112
|
outputPad: () => this.#outputPad,
|
|
116
113
|
hotkeysPresentation: () => this.hotkeysPresentation(),
|
|
@@ -119,26 +116,27 @@ export class OwnedUiSessionShellRoot {
|
|
|
119
116
|
});
|
|
120
117
|
this.editor.setThinkingLevel(view.thinkingLevel);
|
|
121
118
|
this.#input = new InputSurfaceSwitch(this.editor, {
|
|
122
|
-
dockInputReuse: this.#customViewport && (handlers.enableDockInputReuse ?? true),
|
|
123
|
-
viewport: this
|
|
119
|
+
dockInputReuse: this.#customViewport && (handlers.enableDockInputReuse ?? true), classifyInput: handlers.presentation.terminalRuntime.classifyInput,
|
|
120
|
+
viewport: this.viewport,
|
|
124
121
|
...(handlers.onInputSurfaceChanged === undefined ? {} : { onChanged: handlers.onInputSurfaceChanged }),
|
|
125
122
|
});
|
|
126
|
-
this.#layout = this.#createLayout(handlers.onViewportFrame);
|
|
123
|
+
this.#layout = this.#createLayout(handlers.onViewportFrame, createViewportTheme(handlers.presentation.theme));
|
|
127
124
|
for (const block of view.transcript) {
|
|
128
125
|
if (block.kind === "user")
|
|
129
126
|
this.editor.addToHistory(block.text);
|
|
130
127
|
}
|
|
131
|
-
this
|
|
128
|
+
this.transcript.sync(view.transcript);
|
|
132
129
|
// Invariant: rendered rows expire when
|
|
133
130
|
// their active theme changes.
|
|
134
|
-
this.#themeUnsubscribe =
|
|
131
|
+
this.#themeUnsubscribe = handlers.presentation.theme.onChange(() => {
|
|
135
132
|
this.invalidate();
|
|
136
133
|
this.#componentRuntime.requestRender(true);
|
|
137
134
|
});
|
|
138
135
|
}
|
|
139
136
|
// Invariant: the document reads the shell's chrome lazily, so it may be built before the header and viewport.
|
|
140
|
-
#createDocument(cwd) {
|
|
137
|
+
#createDocument(cwd, theme, components) {
|
|
141
138
|
return new TranscriptDocument({
|
|
139
|
+
theme, components,
|
|
142
140
|
customViewport: this.#customViewport,
|
|
143
141
|
cwd,
|
|
144
142
|
mount: block => this.#mountTranscript(block),
|
|
@@ -153,33 +151,34 @@ export class OwnedUiSessionShellRoot {
|
|
|
153
151
|
});
|
|
154
152
|
}
|
|
155
153
|
// Invariant: one layout per root; the render path never consults the layout mode again.
|
|
156
|
-
#createLayout(onFrame) {
|
|
154
|
+
#createLayout(onFrame, theme) {
|
|
157
155
|
const ports = {
|
|
158
|
-
viewport: this
|
|
156
|
+
viewport: this.viewport,
|
|
159
157
|
input: this.#input,
|
|
160
158
|
editor: this.editor,
|
|
161
|
-
promptChips: this
|
|
162
|
-
dockChrome: this
|
|
163
|
-
theme
|
|
159
|
+
promptChips: this.promptChips,
|
|
160
|
+
dockChrome: this.chrome,
|
|
161
|
+
theme,
|
|
164
162
|
...(onFrame === undefined ? {} : { onFrame }),
|
|
165
163
|
rows: () => this.#componentRuntime.getRows(),
|
|
166
164
|
dock: width => this.#renderDockLayout(width),
|
|
167
|
-
document: width => this
|
|
165
|
+
document: width => this.transcript.layout(width),
|
|
168
166
|
queued: width => this.#renderQueued(width),
|
|
169
167
|
liveStatus: width => this.#renderStatus(width),
|
|
170
168
|
diagnostics: () => this.#view.diagnostics,
|
|
171
169
|
};
|
|
172
170
|
return this.#customViewport ? new ViewportLayout(ports) : new PinnedLayout(ports);
|
|
173
171
|
}
|
|
174
|
-
#createSubmittedPromptComposer() {
|
|
172
|
+
#createSubmittedPromptComposer(theme) {
|
|
173
|
+
const linkColor = transcriptLinkColor(theme);
|
|
175
174
|
return {
|
|
176
175
|
layout: width => submittedPromptLayout(width),
|
|
177
|
-
compose: (rows, width, style) => composeSubmittedPromptRows(rows, width, { ...style, prefix: text => promptArrow(text,
|
|
176
|
+
compose: (rows, width, style) => composeSubmittedPromptRows(rows, width, { ...style, prefix: text => promptArrow(text, theme.current()) }).map(row => nativeHyperlinkStyle(row, linkColor)),
|
|
178
177
|
};
|
|
179
178
|
}
|
|
180
179
|
setEditorPaddingX(padding) {
|
|
181
180
|
this.editor.setPaddingX(padding);
|
|
182
|
-
this
|
|
181
|
+
this.transcript.invalidate("editor-padding");
|
|
183
182
|
}
|
|
184
183
|
setAutocompleteMaxVisible(maxVisible) {
|
|
185
184
|
this.editor.setAutocompleteMaxVisible(maxVisible);
|
|
@@ -189,7 +188,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
189
188
|
return;
|
|
190
189
|
this.#outputPad = padding;
|
|
191
190
|
this.#status.setOutputPad(padding);
|
|
192
|
-
for (const component of this
|
|
191
|
+
for (const component of this.transcript.components())
|
|
193
192
|
component.setOutputPad(padding);
|
|
194
193
|
this.#invalidateTranscriptPresentation();
|
|
195
194
|
}
|
|
@@ -197,7 +196,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
197
196
|
if (this.#thinkingVisible === !hidden)
|
|
198
197
|
return;
|
|
199
198
|
this.#thinkingVisible = !hidden;
|
|
200
|
-
for (const component of this
|
|
199
|
+
for (const component of this.transcript.components())
|
|
201
200
|
component.setHideThinkingBlock(hidden);
|
|
202
201
|
this.#invalidateTranscriptPresentation();
|
|
203
202
|
}
|
|
@@ -205,7 +204,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
205
204
|
if (this.#mermaidRenderingMode === mode)
|
|
206
205
|
return;
|
|
207
206
|
this.#mermaidRenderingMode = mode;
|
|
208
|
-
for (const component of this
|
|
207
|
+
for (const component of this.transcript.components())
|
|
209
208
|
component.setMermaidRenderingMode(mode);
|
|
210
209
|
this.#invalidateTranscriptPresentation();
|
|
211
210
|
}
|
|
@@ -214,44 +213,26 @@ export class OwnedUiSessionShellRoot {
|
|
|
214
213
|
return;
|
|
215
214
|
this.#showImages = showImages;
|
|
216
215
|
this.#imageWidthCells = imageWidthCells;
|
|
217
|
-
for (const component of this
|
|
216
|
+
for (const component of this.transcript.components())
|
|
218
217
|
component.setImagePresentation(showImages, imageWidthCells);
|
|
219
218
|
this.#invalidateTranscriptPresentation();
|
|
220
219
|
}
|
|
221
|
-
prepareHistoryText(text) {
|
|
222
|
-
return this.#promptChips.prepareHistoryText(text);
|
|
223
|
-
}
|
|
224
|
-
omitUnsentPromptImages(text) {
|
|
225
|
-
return this.#promptChips.omitUnsentImages(text);
|
|
226
|
-
}
|
|
227
|
-
rehydrateHistoryText(text, resolveImage) {
|
|
228
|
-
return this.#promptChips.rehydrateHistoryText(text, resolveImage);
|
|
229
|
-
}
|
|
230
|
-
imageChipAttachmentsFromEditor(text) {
|
|
231
|
-
return this.#promptChips.imageChipAttachments(text);
|
|
232
|
-
}
|
|
233
|
-
preparePromptSubmission(text) {
|
|
234
|
-
return this.#promptChips.prepareSubmission(text);
|
|
235
|
-
}
|
|
236
220
|
reconcilePromptImageLimitNotice(text = this.editor.getText()) {
|
|
237
|
-
if (this
|
|
221
|
+
if (this.chrome.notice?.errorCode !== "image-count" || !this.promptChips.imageLimitState(text).corrected)
|
|
238
222
|
return false;
|
|
239
|
-
this.dismissNotice();
|
|
223
|
+
this.chrome.dismissNotice();
|
|
240
224
|
return true;
|
|
241
225
|
}
|
|
242
|
-
hasPendingPastes(text) { return this.#promptChips.hasPending(text); }
|
|
243
226
|
waitForPromptPastes(text, signal) {
|
|
244
|
-
return this
|
|
227
|
+
return this.promptChips.waitForPastes(text, signal, () => this.editor.getText());
|
|
245
228
|
}
|
|
246
229
|
resetPendingPastes() {
|
|
247
230
|
this.editor.cancelPendingPastes?.();
|
|
248
|
-
this.editor.setText(this
|
|
231
|
+
this.editor.setText(this.promptChips.resetPastes(this.editor.getText()));
|
|
249
232
|
}
|
|
250
|
-
/** Forks the spare paste helper so the first paste of the session takes a live child. */
|
|
251
|
-
warmPastePreparation() { this.#promptChips.warm(); }
|
|
252
233
|
disposePendingPastes() {
|
|
253
234
|
this.resetPendingPastes();
|
|
254
|
-
return this
|
|
235
|
+
return this.promptChips.dispose();
|
|
255
236
|
}
|
|
256
237
|
promptSuggestionPrepareBlockReason() {
|
|
257
238
|
if (!this.usesDefaultInputSurface())
|
|
@@ -262,7 +243,6 @@ export class OwnedUiSessionShellRoot {
|
|
|
262
243
|
return "draft";
|
|
263
244
|
return null;
|
|
264
245
|
}
|
|
265
|
-
canPreparePromptSuggestion() { return this.promptSuggestionPrepareBlockReason() === null; }
|
|
266
246
|
promptSuggestionPresentationBlockReason() {
|
|
267
247
|
const reason = this.promptSuggestionPrepareBlockReason();
|
|
268
248
|
if (reason !== null)
|
|
@@ -280,14 +260,14 @@ export class OwnedUiSessionShellRoot {
|
|
|
280
260
|
const becameReady = this.#view.lifecycle !== "ready" && view.lifecycle === "ready";
|
|
281
261
|
if (view.diagnostics.length !== this.#view.diagnostics.length
|
|
282
262
|
|| view.diagnostics.some((diagnostic, index) => diagnostic.sequence !== this.#view.diagnostics[index]?.sequence)) {
|
|
283
|
-
this
|
|
263
|
+
this.transcript.invalidate("diagnostics");
|
|
284
264
|
}
|
|
285
265
|
const promptAccepted = this.#view.lifecycle !== "busy" && view.lifecycle === "busy";
|
|
286
266
|
this.#view = view;
|
|
287
267
|
// Invariant: the idle new-session confirmation yields to the first truthful live status;
|
|
288
268
|
// ordinary dock notices deliberately remain visible below Working during a run.
|
|
289
|
-
if (promptAccepted && this
|
|
290
|
-
this
|
|
269
|
+
if (promptAccepted && this.chrome.notice?.kind === "new-session")
|
|
270
|
+
this.chrome.forgetNotice();
|
|
291
271
|
if (promptAccepted && this.#imageSubmissionsSending > 0) {
|
|
292
272
|
this.#imageSubmissionsSending = 0;
|
|
293
273
|
this.#syncWorkingOverride();
|
|
@@ -295,7 +275,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
295
275
|
this.#status.update(view);
|
|
296
276
|
this.#footer.update(this.#extensions.withStatuses(view));
|
|
297
277
|
this.#queued.update(view.editor.queuedSubmissions);
|
|
298
|
-
this
|
|
278
|
+
this.transcript.sync(view.transcript);
|
|
299
279
|
this.editor.setSubmitEnabled(view.lifecycle !== "stopping" && view.lifecycle !== "stopped" && view.lifecycle !== "failed");
|
|
300
280
|
this.editor.setThinkingLevel(view.thinkingLevel);
|
|
301
281
|
// Performance: semantic updates already invalidate affected transcript blocks. Chrome is a separate authority.
|
|
@@ -303,23 +283,15 @@ export class OwnedUiSessionShellRoot {
|
|
|
303
283
|
if (becameReady)
|
|
304
284
|
this.#onPromptSuggestionEligibilityChanged?.();
|
|
305
285
|
}
|
|
306
|
-
/**
|
|
307
|
-
* Applies one block: its component is created or updated in place and the order grows
|
|
308
|
-
* only when the block is new. A streamed chunk costs one component update rather than a
|
|
309
|
-
* walk of the whole transcript.
|
|
310
|
-
*/
|
|
311
|
-
applyTranscriptBlock(block) {
|
|
312
|
-
this.#document.apply(block);
|
|
313
|
-
}
|
|
314
286
|
#mountTranscript(block) {
|
|
315
287
|
// Invariant: the notice answers the reader's last command, so only their next prompt or
|
|
316
288
|
// shell command retires it; assistant, tool, and compaction blocks streaming in keep it.
|
|
317
289
|
if (block.kind === "user" || block.kind === "bash")
|
|
318
|
-
this.dismissNotice();
|
|
319
|
-
const created =
|
|
320
|
-
if (this
|
|
290
|
+
this.chrome.dismissNotice();
|
|
291
|
+
const created = this.#componentRuntime.components.transcript.component(block, this.#cwd, this.#extensionRenderers, this.#submittedPromptComposer, this.#outputPad, !this.#thinkingVisible, this.#mermaidRenderingMode, this.#showImages, this.#imageWidthCells, this.#imageAssets, { ...this.#componentRuntime, changed: () => {
|
|
292
|
+
if (this.transcript.component(block.id) !== created)
|
|
321
293
|
return;
|
|
322
|
-
this
|
|
294
|
+
this.transcript.blockChanged(block.id);
|
|
323
295
|
this.#layout.invalidate();
|
|
324
296
|
this.#input.clearDockInputCandidate();
|
|
325
297
|
this.#componentRuntime.requestRender();
|
|
@@ -331,18 +303,18 @@ export class OwnedUiSessionShellRoot {
|
|
|
331
303
|
return this.#layout.render(width);
|
|
332
304
|
}
|
|
333
305
|
viewportFrameDescriptor() {
|
|
334
|
-
return this
|
|
306
|
+
return this.viewport.frame?.descriptor ?? null;
|
|
335
307
|
}
|
|
336
308
|
/** Read-only, payload-free evidence; observing a pending frame must never render or repair it. */
|
|
337
309
|
viewportPresentationEvidence() {
|
|
338
|
-
const frame = this
|
|
310
|
+
const frame = this.viewport.frame;
|
|
339
311
|
const snapshot = this.#layout.composed();
|
|
340
312
|
return {
|
|
341
313
|
candidate: this.#input.dockInputCandidate,
|
|
342
314
|
candidateRevision: this.#input.dockInputCandidate ? this.#input.dockInputRevision ?? null : null,
|
|
343
|
-
currentRevision: this
|
|
315
|
+
currentRevision: this.viewport.presentationRevision,
|
|
344
316
|
composedRevision: snapshot?.viewportRevision ?? null,
|
|
345
|
-
currentPointer: this
|
|
317
|
+
currentPointer: this.viewport.pointerPosition ?? null,
|
|
346
318
|
composedPointer: snapshot?.pointerPosition ?? null,
|
|
347
319
|
frameId: frame?.descriptor.frameId ?? null,
|
|
348
320
|
bottom: frame?.hits.bottom ?? null,
|
|
@@ -354,53 +326,28 @@ export class OwnedUiSessionShellRoot {
|
|
|
354
326
|
}
|
|
355
327
|
/** Visible non-persistent Steering, alignment, and Working rows, for rendering evidence. */
|
|
356
328
|
viewportTransientTailRowCount() {
|
|
357
|
-
return this
|
|
329
|
+
return this.viewport.frame?.hits.transientTail.length ?? 0;
|
|
358
330
|
}
|
|
359
331
|
hasActiveSelection() {
|
|
360
|
-
return this
|
|
332
|
+
return this.viewport.hasSelection || this.editor.hasSelection();
|
|
361
333
|
}
|
|
362
334
|
setViewportConfig(config) {
|
|
363
|
-
if (this
|
|
364
|
-
this
|
|
335
|
+
if (this.viewport.setConfig(config)) {
|
|
336
|
+
this.transcript.invalidate("viewport-config");
|
|
365
337
|
this.#layout.invalidate();
|
|
366
338
|
}
|
|
367
339
|
}
|
|
368
|
-
setFullscreenCopyOnSelect(enabled) {
|
|
369
|
-
this.#viewportController.setCopyOnSelect(enabled);
|
|
370
|
-
}
|
|
371
|
-
showCopyAcknowledgement(message) {
|
|
372
|
-
this.#dockChrome.showCopyAcknowledgement(message);
|
|
373
|
-
}
|
|
374
|
-
resumeViewportFollowing() {
|
|
375
|
-
this.#viewportController.resumeFollowing();
|
|
376
|
-
}
|
|
377
|
-
noteCompletedAssistantMessage() {
|
|
378
|
-
this.#viewportController.noteCompletedAssistantMessage();
|
|
379
|
-
}
|
|
380
|
-
/** A new session binding owns new mounts even when it reuses semantic invocation ids. */
|
|
381
|
-
resetTranscript() {
|
|
382
|
-
this.#document.reset();
|
|
383
|
-
}
|
|
384
|
-
resetViewport() {
|
|
385
|
-
this.#viewportController.reset();
|
|
386
|
-
}
|
|
387
|
-
clearViewportPointerState() {
|
|
388
|
-
this.#viewportController.clearPointerState();
|
|
389
|
-
}
|
|
390
|
-
setViewportOverlaySurfaces(surfaces) {
|
|
391
|
-
this.#viewportController.setOverlaySurfaces(surfaces);
|
|
392
|
-
}
|
|
393
340
|
viewportInputGeometryReady(width, height) {
|
|
394
|
-
const frame = this
|
|
395
|
-
return this
|
|
341
|
+
const frame = this.viewport.frame;
|
|
342
|
+
return this.viewport.inputGeometryReady && frame?.descriptor.width === width && frame.descriptor.height === height;
|
|
396
343
|
}
|
|
397
344
|
handleViewportPreInput(data, allowWheel = true, now = Date.now(), editorActive = this.usesDefaultInputSurface()) {
|
|
398
|
-
return this
|
|
345
|
+
return this.viewport.handlePreInput(data, allowWheel, now, editorActive);
|
|
399
346
|
}
|
|
400
347
|
#renderDockLayout(width) {
|
|
401
348
|
const queued = this.#customViewport ? [] : this.#renderQueued(width);
|
|
402
349
|
const statusRows = this.#customViewport ? this.#status.renderDock(width) : this.#renderStatus(width);
|
|
403
|
-
const noticeRows = this
|
|
350
|
+
const noticeRows = this.chrome.renderNotice(width, this.#outputPad);
|
|
404
351
|
const transientRows = [...queued, ...statusRows, ...noticeRows];
|
|
405
352
|
const messageStart = queued.length;
|
|
406
353
|
const copyableMessageRows = Array.from({ length: statusRows.length + noticeRows.length }, (_value, index) => ({ row: messageStart + index }));
|
|
@@ -420,9 +367,6 @@ export class OwnedUiSessionShellRoot {
|
|
|
420
367
|
copyableMessageRows,
|
|
421
368
|
};
|
|
422
369
|
}
|
|
423
|
-
dismissNotice() {
|
|
424
|
-
this.#dockChrome.dismissNotice();
|
|
425
|
-
}
|
|
426
370
|
#renderQueued(width) {
|
|
427
371
|
return this.#view.editor.queuedSubmissions.length === 0 ? [] : this.#queued.render(width);
|
|
428
372
|
}
|
|
@@ -439,22 +383,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
439
383
|
};
|
|
440
384
|
}
|
|
441
385
|
#renderDocument(width) {
|
|
442
|
-
return this
|
|
443
|
-
}
|
|
444
|
-
transcriptComponent(id) {
|
|
445
|
-
return this.#document.component(id);
|
|
446
|
-
}
|
|
447
|
-
exitTranscript(width) {
|
|
448
|
-
return this.#document.exitTranscript(width);
|
|
449
|
-
}
|
|
450
|
-
appendWorkflowStatus(message) {
|
|
451
|
-
this.#workflowOutput.appendStatus(message);
|
|
452
|
-
}
|
|
453
|
-
appendWorkflowMessage(message, errorCode) {
|
|
454
|
-
this.#workflowOutput.appendMessage(message, errorCode);
|
|
455
|
-
}
|
|
456
|
-
appendWorkflowResult(result, errorCode) {
|
|
457
|
-
this.#workflowOutput.appendResult(result, errorCode);
|
|
386
|
+
return this.transcript.layout(width).rows;
|
|
458
387
|
}
|
|
459
388
|
toggleThinkingVisibility() {
|
|
460
389
|
this.setHideThinkingBlock(this.#thinkingVisible);
|
|
@@ -471,7 +400,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
471
400
|
}
|
|
472
401
|
setExtensionHeader(component) {
|
|
473
402
|
this.#extensions.replaceHeader(component);
|
|
474
|
-
this
|
|
403
|
+
this.transcript.invalidate("extension-header");
|
|
475
404
|
this.invalidate();
|
|
476
405
|
}
|
|
477
406
|
setExtensionFooter(component) {
|
|
@@ -516,9 +445,9 @@ export class OwnedUiSessionShellRoot {
|
|
|
516
445
|
};
|
|
517
446
|
}
|
|
518
447
|
resetWorkflowPresentation() {
|
|
519
|
-
this
|
|
520
|
-
this
|
|
521
|
-
this
|
|
448
|
+
this.chrome.forgetNotice();
|
|
449
|
+
this.chrome.clearCopyAcknowledgement(false);
|
|
450
|
+
this.workflow.reset();
|
|
522
451
|
this.invalidate();
|
|
523
452
|
}
|
|
524
453
|
resetExtensionUi() {
|
|
@@ -526,15 +455,15 @@ export class OwnedUiSessionShellRoot {
|
|
|
526
455
|
this.#syncWorkingOverride();
|
|
527
456
|
this.#footer.update(this.#extensions.withStatuses(this.#view));
|
|
528
457
|
// Invariant: an extension renderer may have drawn transcript blocks that are now unrendered by it.
|
|
529
|
-
this
|
|
458
|
+
this.transcript.invalidate("extension-renderers");
|
|
530
459
|
this.invalidate();
|
|
531
460
|
}
|
|
532
461
|
addExtensionNotification(message, type) {
|
|
533
462
|
if (type === "info") {
|
|
534
|
-
this.
|
|
463
|
+
this.workflow.appendStatus(message);
|
|
535
464
|
return;
|
|
536
465
|
}
|
|
537
|
-
this.
|
|
466
|
+
this.workflow.appendMessage({ kind: type, message });
|
|
538
467
|
}
|
|
539
468
|
extensionFooterData() {
|
|
540
469
|
return {
|
|
@@ -554,7 +483,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
554
483
|
return this.#layout.compositions();
|
|
555
484
|
}
|
|
556
485
|
transcriptRenderCount() {
|
|
557
|
-
return this
|
|
486
|
+
return this.transcript.renderCount;
|
|
558
487
|
}
|
|
559
488
|
setFooterLevel(visible) { this.#footerLevel = visible; }
|
|
560
489
|
setInputSurface(component, disposePrevious = true, coordination = "owned") {
|
|
@@ -565,7 +494,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
565
494
|
this.#input.handleInput(data);
|
|
566
495
|
}
|
|
567
496
|
invalidate() {
|
|
568
|
-
this
|
|
497
|
+
this.transcript.invalidate("repaint");
|
|
569
498
|
this.#invalidateChrome();
|
|
570
499
|
}
|
|
571
500
|
#invalidateChrome() {
|
|
@@ -585,12 +514,12 @@ export class OwnedUiSessionShellRoot {
|
|
|
585
514
|
this.#onPromptSuggestionEligibilityChanged?.();
|
|
586
515
|
}
|
|
587
516
|
dispose() {
|
|
588
|
-
this
|
|
589
|
-
this.
|
|
517
|
+
this.chrome.clearCopyAcknowledgement(false);
|
|
518
|
+
this.viewport.clearPointerState();
|
|
590
519
|
this.#themeUnsubscribe();
|
|
591
520
|
this.header.dispose?.();
|
|
592
521
|
this.resources.dispose?.();
|
|
593
|
-
this
|
|
522
|
+
this.transcript.dispose();
|
|
594
523
|
this.#layout.invalidate();
|
|
595
524
|
this.#input.dispose();
|
|
596
525
|
this.#extensions.dispose();
|
|
@@ -600,7 +529,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
600
529
|
this.#queued.dispose?.();
|
|
601
530
|
}
|
|
602
531
|
#invalidateTranscriptPresentation() {
|
|
603
|
-
this
|
|
532
|
+
this.transcript.invalidate("block-presentation");
|
|
604
533
|
this.invalidate();
|
|
605
534
|
}
|
|
606
535
|
#renderStatus(width) {
|
|
@@ -611,16 +540,16 @@ export class OwnedUiSessionShellRoot {
|
|
|
611
540
|
if (!this.#customViewport)
|
|
612
541
|
return footer.render(width);
|
|
613
542
|
width = Math.max(0, width - 2);
|
|
614
|
-
return footer.render(width).map(row => ` ${
|
|
543
|
+
return footer.render(width).map(row => ` ${this.#componentRuntime.components.text.truncateToWidth(row, width)}`);
|
|
615
544
|
}
|
|
616
545
|
#setToolsExpanded(expanded) {
|
|
617
546
|
this.#toolsExpanded = expanded;
|
|
618
547
|
this.header.setExpanded(expanded);
|
|
619
548
|
this.resources.setExpanded(expanded);
|
|
620
|
-
for (const component of this
|
|
549
|
+
for (const component of this.transcript.components())
|
|
621
550
|
component.setExpanded(expanded);
|
|
622
551
|
// Invariant: expansion changes what a block draws without changing its revision.
|
|
623
|
-
this
|
|
552
|
+
this.transcript.invalidate("tools-expanded");
|
|
624
553
|
this.invalidate();
|
|
625
554
|
}
|
|
626
555
|
}
|
|
@@ -634,7 +563,7 @@ function withoutTerminalBackground(text) {
|
|
|
634
563
|
* The pinned-profile screen: a followed transcript scroll above the dock. The runtime mounts one such layout,
|
|
635
564
|
* so its single `transcript` scroll view is shared by whichever session the parts currently resolve to.
|
|
636
565
|
*/
|
|
637
|
-
export function pinnedLayoutRoot(parts) {
|
|
566
|
+
export function pinnedLayoutRoot(parts, theme) {
|
|
638
567
|
return {
|
|
639
568
|
type: "stack",
|
|
640
569
|
direction: "vertical",
|
|
@@ -651,8 +580,8 @@ export function pinnedLayoutRoot(parts) {
|
|
|
651
580
|
primary: true,
|
|
652
581
|
overscroll: "chain",
|
|
653
582
|
scrollbar: "auto",
|
|
654
|
-
scrollbarTrackStyle: text =>
|
|
655
|
-
scrollbarThumbStyle: text =>
|
|
583
|
+
scrollbarTrackStyle: text => theme.current().fg("scrollbarTrack", text),
|
|
584
|
+
scrollbarThumbStyle: text => theme.current().fg("scrollbarThumb", text),
|
|
656
585
|
child: { type: "component", component: parts.document },
|
|
657
586
|
},
|
|
658
587
|
},
|
|
@@ -684,168 +613,13 @@ function layoutPort(render, invalidate, handleInput) {
|
|
|
684
613
|
...(handleInput === undefined ? {} : { handleInput }),
|
|
685
614
|
};
|
|
686
615
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
label: resource.kind === "prompt-template"
|
|
697
|
-
? `/${resource.label}`
|
|
698
|
-
: resource.kind === "agent-context" || resource.kind === "system-prompt"
|
|
699
|
-
? compactResourceLabel(resource.sourcePath ?? resource.label)
|
|
700
|
-
: resource.label,
|
|
701
|
-
sourcePath: resource.sourcePath,
|
|
702
|
-
diagnostic: resource.diagnostic,
|
|
703
|
-
}));
|
|
704
|
-
const extensions = backend.extensions.extensionResources().filter(extension => !extension.hidden);
|
|
705
|
-
const loadedExtensions = extensions.filter(extension => extension.diagnostic === null);
|
|
706
|
-
const extensionLabels = compactExtensionLabels(loadedExtensions);
|
|
707
|
-
for (const extension of extensions) {
|
|
708
|
-
const labelIndex = loadedExtensions.indexOf(extension);
|
|
709
|
-
resources.push({
|
|
710
|
-
section: "Extensions",
|
|
711
|
-
label: extensionLabels[labelIndex] ?? compactResourceLabel(extension.sourcePath ?? extension.resolvedPath ?? "extension"),
|
|
712
|
-
sourcePath: extension.sourcePath ?? extension.resolvedPath,
|
|
713
|
-
diagnostic: extension.diagnostic,
|
|
714
|
-
});
|
|
715
|
-
}
|
|
716
|
-
return resources;
|
|
717
|
-
}
|
|
718
|
-
function compactResourceLabel(path) {
|
|
719
|
-
const segments = compactPathSegments(path);
|
|
720
|
-
const leaf = segments.at(-1) ?? path;
|
|
721
|
-
if ((leaf === "index.ts" || leaf === "index.js") && segments.length > 1)
|
|
722
|
-
return segments.at(-2) ?? leaf;
|
|
723
|
-
return leaf;
|
|
724
|
-
}
|
|
725
|
-
/**
|
|
726
|
-
* Pinned from InteractiveMode's compact extension-label helpers at Pi commit
|
|
727
|
-
* 914cf1472e715297caa30db4b9535d534a9eb718. The source metadata crosses an
|
|
728
|
-
* A1-owned boundary first; the owned shell never inspects Pi's private root.
|
|
729
|
-
*/
|
|
730
|
-
function compactExtensionLabels(extensions) {
|
|
731
|
-
const localExtensions = extensions
|
|
732
|
-
.filter(extension => !isPackageExtensionSource(extension.sourceInfo))
|
|
733
|
-
.map(extension => {
|
|
734
|
-
const path = extension.sourcePath ?? extension.resolvedPath ?? "extension";
|
|
735
|
-
const segments = compactPathSegments(path);
|
|
736
|
-
if (segments.length > 1 && (segments.at(-1) === "index.ts" || segments.at(-1) === "index.js"))
|
|
737
|
-
segments.pop();
|
|
738
|
-
return { extension, segments };
|
|
739
|
-
});
|
|
740
|
-
return extensions.map(extension => {
|
|
741
|
-
const resourcePath = extension.sourcePath ?? extension.resolvedPath ?? "extension";
|
|
742
|
-
if (isPackageExtensionSource(extension.sourceInfo)) {
|
|
743
|
-
return compactPackageExtensionLabel(resourcePath, extension.sourceInfo);
|
|
744
|
-
}
|
|
745
|
-
const localIndex = localExtensions.findIndex(item => item.extension === extension);
|
|
746
|
-
const segments = localExtensions[localIndex]?.segments;
|
|
747
|
-
if (!segments || segments.length === 0)
|
|
748
|
-
return compactResourceLabel(resourcePath);
|
|
749
|
-
for (let count = 1; count <= segments.length; count += 1) {
|
|
750
|
-
const candidate = segments.slice(-count).join("/");
|
|
751
|
-
if (localExtensions.every((item, itemIndex) => itemIndex === localIndex || item.segments.slice(-count).join("/") !== candidate)) {
|
|
752
|
-
return candidate;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
return segments.join("/");
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
function compactPackageExtensionLabel(resourcePath, sourceInfo) {
|
|
759
|
-
const sourceLabel = compactPackageSourceLabel(sourceInfo.source);
|
|
760
|
-
if (!sourceLabel)
|
|
761
|
-
return compactResourceLabel(resourcePath);
|
|
762
|
-
const shortPath = shortPackagePath(resourcePath, sourceInfo).replaceAll("\\", "/");
|
|
763
|
-
const packagePath = shortPath.startsWith("extensions/") ? shortPath.slice("extensions/".length) : shortPath;
|
|
764
|
-
const slash = packagePath.lastIndexOf("/");
|
|
765
|
-
const fileName = slash < 0 ? packagePath : packagePath.slice(slash + 1);
|
|
766
|
-
const directory = slash < 0 ? "" : packagePath.slice(0, slash);
|
|
767
|
-
const extension = fileName.lastIndexOf(".");
|
|
768
|
-
const name = extension <= 0 ? fileName : fileName.slice(0, extension);
|
|
769
|
-
if (name === "index")
|
|
770
|
-
return !directory || directory === "." ? sourceLabel : `${sourceLabel}:${directory}`;
|
|
771
|
-
return `${sourceLabel}:${packagePath}`;
|
|
772
|
-
}
|
|
773
|
-
function compactPackageSourceLabel(source) {
|
|
774
|
-
if (source.startsWith("npm:"))
|
|
775
|
-
return source.slice("npm:".length) || source;
|
|
776
|
-
if (!source.startsWith("git:"))
|
|
777
|
-
return source;
|
|
778
|
-
const gitSource = source.slice("git:".length).trim();
|
|
779
|
-
let repositoryPath;
|
|
780
|
-
const scpLike = gitSource.match(/^git@[^:]+:(.+)$/);
|
|
781
|
-
if (scpLike?.[1]) {
|
|
782
|
-
repositoryPath = scpLike[1];
|
|
783
|
-
}
|
|
784
|
-
else if (/^[a-z]+:\/\//i.test(gitSource)) {
|
|
785
|
-
try {
|
|
786
|
-
repositoryPath = new URL(gitSource).pathname.replace(/^\/+/, "");
|
|
787
|
-
}
|
|
788
|
-
catch {
|
|
789
|
-
return source;
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
else {
|
|
793
|
-
const slash = gitSource.indexOf("/");
|
|
794
|
-
if (slash >= 0)
|
|
795
|
-
repositoryPath = gitSource.slice(slash + 1);
|
|
796
|
-
}
|
|
797
|
-
if (!repositoryPath)
|
|
798
|
-
return source;
|
|
799
|
-
const ref = repositoryPath.indexOf("@");
|
|
800
|
-
const withoutRef = ref < 0 ? repositoryPath : repositoryPath.slice(0, ref);
|
|
801
|
-
return withoutRef.replace(/\.git$/, "") || source;
|
|
802
|
-
}
|
|
803
|
-
function shortPackagePath(resourcePath, sourceInfo) {
|
|
804
|
-
const fullPath = normalizeResourcePath(resourcePath);
|
|
805
|
-
const baseDir = sourceInfo.baseDir === null ? undefined : normalizeResourcePath(sourceInfo.baseDir).replace(/\/$/, "");
|
|
806
|
-
if (baseDir) {
|
|
807
|
-
const npmRoot = baseDir.match(/^(.*\/node_modules)\/(@?[^/]+(?:\/[^/]+)?)$/);
|
|
808
|
-
if (npmRoot?.[1] && fullPath.startsWith(`${npmRoot[1]}/`))
|
|
809
|
-
return relativeResourcePath(baseDir, fullPath);
|
|
810
|
-
if (fullPath === baseDir)
|
|
811
|
-
return ".";
|
|
812
|
-
if (fullPath.startsWith(`${baseDir}/`))
|
|
813
|
-
return fullPath.slice(baseDir.length + 1);
|
|
814
|
-
}
|
|
815
|
-
const npmMatch = fullPath.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);
|
|
816
|
-
if (npmMatch?.[2] && sourceInfo.source.startsWith("npm:"))
|
|
817
|
-
return npmMatch[2];
|
|
818
|
-
const gitMatch = fullPath.match(/git\/[^/]+\/[^/]+\/(.*)/);
|
|
819
|
-
if (gitMatch?.[1] && sourceInfo.source.startsWith("git:"))
|
|
820
|
-
return gitMatch[1];
|
|
821
|
-
return resourcePath;
|
|
822
|
-
}
|
|
823
|
-
function relativeResourcePath(from, to) {
|
|
824
|
-
const fromSegments = from.split("/").filter(Boolean);
|
|
825
|
-
const toSegments = to.split("/").filter(Boolean);
|
|
826
|
-
let common = 0;
|
|
827
|
-
while (common < fromSegments.length && common < toSegments.length
|
|
828
|
-
&& fromSegments[common]?.toLowerCase() === toSegments[common]?.toLowerCase())
|
|
829
|
-
common += 1;
|
|
830
|
-
return [...fromSegments.slice(common).map(() => ".."), ...toSegments.slice(common)].join("/") || ".";
|
|
831
|
-
}
|
|
832
|
-
function compactPathSegments(path) {
|
|
833
|
-
return normalizeResourcePath(path).split("/").filter(segment => segment.length > 0 && segment !== "~");
|
|
834
|
-
}
|
|
835
|
-
function normalizeResourcePath(path) {
|
|
836
|
-
return path.replaceAll("\\", "/");
|
|
837
|
-
}
|
|
838
|
-
function isPackageExtensionSource(sourceInfo) {
|
|
839
|
-
const source = sourceInfo?.source ?? "";
|
|
840
|
-
return source.startsWith("npm:") || source.startsWith("git:");
|
|
616
|
+
function createViewportTheme(source) {
|
|
617
|
+
return {
|
|
618
|
+
track: text => `${SCROLLBAR_CELL_RESET}${source.current().fg("dim", text)}`,
|
|
619
|
+
thumb: text => `${SCROLLBAR_CELL_RESET}${source.current().fg("accent", text)}`,
|
|
620
|
+
sticky: (text, hovered) => source.current().background(hovered ? "selectedBg" : "toolPendingBg", source.current().fg("text", withoutTerminalBackground(text))),
|
|
621
|
+
quietSticky: text => `\u001b[2m${text.replace(/\u001b\[(?:0|22)m/g, "$&\u001b[2m")}\u001b[22m`,
|
|
622
|
+
bottomControl: (text, hovered) => source.current().background(hovered ? "selectedBg" : "toolPendingBg", source.current().fg("text", text)),
|
|
623
|
+
selection: paintTextSelection,
|
|
624
|
+
};
|
|
841
625
|
}
|
|
842
|
-
// Performance: stable painter identities let the neutral viewport retain row-level
|
|
843
|
-
// selection variants while each callback still resolves the live Pi theme.
|
|
844
|
-
const VIEWPORT_THEME = {
|
|
845
|
-
track: text => `${SCROLLBAR_CELL_RESET}${piTheme().fg("dim", text)}`,
|
|
846
|
-
thumb: text => `${SCROLLBAR_CELL_RESET}${piTheme().fg("accent", text)}`,
|
|
847
|
-
sticky: (text, hovered) => piTheme().bg(hovered ? "selectedBg" : "toolPendingBg", piTheme().fg("text", withoutTerminalBackground(text))),
|
|
848
|
-
quietSticky: text => `\u001b[2m${text.replace(/\u001b\[(?:0|22)m/g, "$&\u001b[2m")}\u001b[22m`,
|
|
849
|
-
bottomControl: (text, hovered) => piTheme().bg(hovered ? "selectedBg" : "toolPendingBg", piTheme().fg("text", text)),
|
|
850
|
-
selection: paintTextSelection,
|
|
851
|
-
};
|