@timurproko/a1 0.1.8-dev.157 → 0.1.8-dev.214
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 +32 -0
- package/bin/cli.js +2 -2
- package/bin/sync-pi-tui-proxy.js +1 -1
- package/bin/ui.js +18 -3
- package/dist/cli/dispatch.js +3 -3
- package/dist/cli/packages.js +1 -1
- package/dist/cli/version-stats.js +3 -3
- package/dist/composition/owned-ui.d.ts +4 -1
- package/dist/composition/owned-ui.js +9 -6
- package/dist/composition/settings-route-host.js +6 -4
- package/dist/contracts/agent-engine/capability-ports.d.ts +2 -2
- package/dist/contracts/agent-engine/domain-validation.js +22 -4
- package/dist/contracts/agent-engine/domain.d.ts +17 -0
- package/dist/contracts/owned-ui/model.d.ts +8 -0
- package/dist/contracts/owned-ui/validation.js +11 -0
- package/dist/features/launch/development-launch.js +1 -1
- package/dist/features/owned-ui/customization.d.ts +2 -0
- package/dist/features/owned-ui/customization.js +2 -0
- package/dist/features/owned-ui/diagnostics.d.ts +1 -0
- package/dist/features/owned-ui/diagnostics.js +1 -0
- package/dist/features/owned-ui/index.d.ts +1 -0
- package/dist/features/owned-ui/index.js +1 -0
- package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
- package/dist/features/owned-ui/project-trust-prompt.js +149 -0
- package/dist/features/owned-ui/settings-app.js +69 -44
- package/dist/features/workspace/reducer.d.ts +1 -0
- package/dist/features/workspace/reducer.js +1 -0
- package/dist/features/workspace/router.d.ts +1 -0
- package/dist/features/workspace/router.js +1 -0
- package/dist/features/workspace/store.d.ts +1 -0
- package/dist/features/workspace/store.js +1 -0
- package/dist/foundation/launch-guardian/main.js +1 -1
- package/dist/foundation/native-host-protocol/codec.d.ts +2 -0
- package/dist/foundation/native-host-protocol/codec.js +2 -0
- package/dist/foundation/process-containment/linux-process-inspector.d.ts +1 -0
- package/dist/foundation/process-containment/linux-process-inspector.js +1 -0
- package/dist/foundation/process-containment/native-guardian-containment.d.ts +1 -0
- package/dist/foundation/process-containment/native-guardian-containment.js +1 -0
- package/dist/foundation/process-containment/windows-process-inspector.d.ts +1 -0
- package/dist/foundation/process-containment/windows-process-inspector.js +1 -0
- package/dist/foundation/protocol/client.d.ts +1 -0
- package/dist/foundation/protocol/client.js +1 -0
- package/dist/foundation/protocol/messages.d.ts +1 -0
- package/dist/foundation/protocol/messages.js +1 -0
- package/dist/foundation/release/bootstrap.js +6 -6
- package/dist/foundation/release/cohort-state.d.ts +1 -0
- package/dist/foundation/release/cohort-state.js +1 -0
- package/dist/foundation/release/release-gc.js +1 -1
- package/dist/foundation/release/release.js +1 -1
- package/dist/foundation/release/update-transaction.d.ts +1 -0
- package/dist/foundation/release/update-transaction.js +1 -0
- package/dist/foundation/release/update.js +12 -12
- package/dist/foundation/storage/control-store.d.ts +1 -0
- package/dist/foundation/storage/control-store.js +1 -0
- package/dist/foundation/structured-agent-runtime/backpressure.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/backpressure.js +1 -0
- package/dist/foundation/structured-agent-runtime/commands.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/commands.js +1 -0
- package/dist/foundation/structured-agent-runtime/reconnection.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/reconnection.js +1 -0
- package/dist/foundation/structured-agent-runtime/state.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/state.js +1 -0
- package/dist/foundation/supervision/main.js +1 -1
- package/dist/foundation/supervision/server.d.ts +1 -0
- package/dist/foundation/supervision/server.js +4 -6
- package/dist/integrations/pi/components/conformance.d.ts +1 -0
- package/dist/integrations/pi/components/conformance.js +1 -0
- package/dist/integrations/pi/components/shell-components.d.ts +1 -0
- package/dist/integrations/pi/components/shell-components.js +1 -0
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -0
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +19 -13
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +36 -0
- package/dist/integrations/pi/components/shell-presenters-info.js +78 -0
- package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +3 -36
- package/dist/integrations/pi/components/shell-presenters-transcript.js +88 -128
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +11 -1
- package/dist/integrations/pi/components/shell-shared-facade.js +1 -1
- package/dist/integrations/pi/engine/adapter.d.ts +22 -4
- package/dist/integrations/pi/engine/adapter.js +220 -70
- package/dist/integrations/pi/engine/conformance.d.ts +2 -0
- package/dist/integrations/pi/engine/conformance.js +2 -0
- package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
- package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
- package/dist/integrations/pi/engine/index.d.ts +3 -0
- package/dist/integrations/pi/engine/index.js +3 -0
- package/dist/integrations/pi/engine/model-auth-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/model-auth-integration.js +1 -0
- package/dist/integrations/pi/engine/package-integration.js +1 -1
- package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
- package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
- package/dist/integrations/pi/engine/resource-extension-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/resource-extension-integration.js +1 -0
- package/dist/integrations/pi/engine/runtime-integration.d.ts +16 -1
- package/dist/integrations/pi/engine/runtime-integration.js +34 -4
- package/dist/integrations/pi/engine/session-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/session-integration.js +2 -1
- package/dist/integrations/pi/engine/settings-effects.d.ts +66 -0
- package/dist/integrations/pi/engine/settings-effects.js +249 -0
- package/dist/integrations/pi/engine/settings-integration.d.ts +14 -26
- package/dist/integrations/pi/engine/settings-integration.js +102 -108
- package/dist/integrations/pi/engine/workflow-controllers.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-controllers.js +1 -0
- package/dist/integrations/pi/session-ui/clipboard-image.d.ts +11 -0
- package/dist/integrations/pi/session-ui/clipboard-image.js +29 -0
- package/dist/integrations/pi/session-ui/index.d.ts +1 -0
- package/dist/integrations/pi/session-ui/index.js +1 -0
- package/dist/integrations/pi/session-ui/prompt-chips.js +6 -2
- package/dist/integrations/pi/session-ui/session-shell-root.d.ts +39 -4
- package/dist/integrations/pi/session-ui/session-shell-root.js +215 -80
- package/dist/integrations/pi/session-ui/session-shell.d.ts +10 -1
- package/dist/integrations/pi/session-ui/session-shell.js +256 -45
- package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +5 -0
- package/dist/integrations/pi/session-ui/session-viewport-controller.js +76 -11
- package/dist/integrations/pi/session-ui/stream-presentation-coalescer.d.ts +29 -0
- package/dist/integrations/pi/session-ui/stream-presentation-coalescer.js +79 -0
- package/dist/integrations/pi/session-ui/system-clipboard.d.ts +9 -0
- package/dist/integrations/pi/session-ui/system-clipboard.js +38 -9
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
- package/dist/integrations/pi/tui-runtime/adapter.js +166 -8
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +25 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +63 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +240 -0
- package/dist/integrations/pi/tui-runtime/index.d.ts +2 -0
- package/dist/integrations/pi/tui-runtime/index.js +2 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/ui/apps/host.js +5 -9
- package/dist/ui/apps/registry.d.ts +1 -0
- package/dist/ui/apps/registry.js +1 -0
- package/dist/ui/components/dialog-panel.js +5 -3
- package/dist/ui/components/frame.d.ts +1 -0
- package/dist/ui/components/frame.js +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/line-input.d.ts +1 -6
- package/dist/ui/components/line-input.js +4 -9
- package/dist/ui/components/list-view.d.ts +0 -6
- package/dist/ui/components/list-view.js +14 -7
- package/dist/ui/components/progress-status.d.ts +2 -0
- package/dist/ui/components/progress-status.js +4 -0
- package/dist/ui/components/scrollbar.js +1 -1
- package/dist/ui/components/shortcuts.d.ts +1 -0
- package/dist/ui/components/shortcuts.js +1 -0
- package/dist/ui/components/spans.d.ts +2 -5
- package/dist/ui/components/spans.js +28 -8
- package/dist/ui/components/surface.d.ts +0 -5
- package/dist/ui/components/surface.js +1 -5
- package/dist/ui/components/text-selection.d.ts +10 -1
- package/dist/ui/components/text-selection.js +96 -29
- package/dist/ui/components/text.js +3 -3
- package/dist/ui/components/transcript-viewport.d.ts +42 -0
- package/dist/ui/components/transcript-viewport.js +287 -39
- package/dist/ui/settings/sections.d.ts +6 -19
- package/dist/ui/settings/sections.js +17 -15
- package/dist/ui/settings/session.d.ts +8 -18
- package/dist/ui/settings/session.js +60 -52
- package/dist/ui/settings/store.d.ts +1 -0
- package/dist/ui/settings/store.js +2 -1
- package/docs/architecture/code-documentation.md +77 -0
- package/docs/architecture/project-structure.md +15 -1
- package/docs/architecture/ui-reference-provenance.md +23 -3
- package/docs/ci-release-runbook.md +98 -7
- package/docs/manual-owned-ui-checkpoint.md +28 -1
- package/docs/manual-terminal-colour-check.md +4 -3
- package/docs/repository-governance-live-acceptance.md +77 -0
- package/package.json +11 -3
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { backgroundSgrSpan, composeSubmittedPromptRows, displayWidth, formatSubmittedPromptTime, heldNativeHyperlinkStyle, hyperlinkSgrSpan, nativeHyperlinkStyle, overlaySpan, submittedPromptLayout, stripAnsi, } from "../../../ui/components/index.js";
|
|
1
|
+
import { backgroundSgrSpan, composeSubmittedPromptRows, displayWidth, formatSubmittedPromptTime, heldNativeHyperlinkStyle, hyperlinkSgrSpan, nativeHyperlinkStyle, overlaySpan, progressStatusText, submittedPromptLayout, stripAnsi, } from "../../../ui/components/index.js";
|
|
2
2
|
import { PINNED_PI_HIDDEN_COMMAND_NAMES, PINNED_PI_WORKFLOW_COMMAND_NAMES, } from "../engine/index.js";
|
|
3
|
-
import { createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellStatus, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, onPiThemeChange, piShellVisibleWidth, piTheme, renderPiShellPackageUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, } from "../components/index.js";
|
|
4
|
-
import { PiTuiRuntimeAdapter, } from "../tui-runtime/index.js";
|
|
3
|
+
import { createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellStatus, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, onPiThemeChange, piShellVisibleWidth, piTheme, renderPiShellPackageUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, } from "../components/index.js";
|
|
4
|
+
import { PiTuiRuntimeAdapter, classifyPiTuiInput, } from "../tui-runtime/index.js";
|
|
5
5
|
import { PromptChipStore } from "./prompt-chips.js";
|
|
6
6
|
import { SessionViewportController } from "./session-viewport-controller.js";
|
|
7
|
+
/** Composes backend session state into the owned transcript, viewport, editor, and dock presentation. */
|
|
7
8
|
export class OwnedUiSessionShellRoot {
|
|
8
9
|
editor;
|
|
9
10
|
header;
|
|
@@ -12,7 +13,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
12
13
|
#transcript = new Map();
|
|
13
14
|
#blocksById = new Map();
|
|
14
15
|
#renderedRows = new Map();
|
|
15
|
-
|
|
16
|
+
// Performance: document layouts are shared by wheel, rail, jump, and selection frames.
|
|
16
17
|
#documentLayouts = new Map();
|
|
17
18
|
#themeUnsubscribe;
|
|
18
19
|
#transcriptOrder = [];
|
|
@@ -21,18 +22,32 @@ export class OwnedUiSessionShellRoot {
|
|
|
21
22
|
#footer;
|
|
22
23
|
#queued;
|
|
23
24
|
#extensionRenderers;
|
|
25
|
+
#imageAssets;
|
|
24
26
|
#promptChips = new PromptChipStore();
|
|
25
27
|
#customViewport;
|
|
26
28
|
#submittedPromptComposer;
|
|
27
29
|
#viewportController;
|
|
30
|
+
#viewportTheme;
|
|
31
|
+
#onViewportFrame;
|
|
28
32
|
#componentRuntime;
|
|
29
33
|
#toolsExpanded = false;
|
|
30
34
|
#thinkingVisible = true;
|
|
35
|
+
#mermaidRenderingMode = "off";
|
|
36
|
+
#showImages = true;
|
|
37
|
+
#imageWidthCells = 80;
|
|
38
|
+
#outputPad = 1;
|
|
31
39
|
#workflowTranscriptSequence = 0;
|
|
32
40
|
#workflowStatusAnchors = new Map();
|
|
33
41
|
#workflowStatusMessages = new Map();
|
|
34
42
|
#lastWorkflowStatusId;
|
|
35
43
|
#inputSurface;
|
|
44
|
+
#inputSurfaceCoordination = "editor";
|
|
45
|
+
#dockInputReuseEnabled;
|
|
46
|
+
#dockInputCandidate = false;
|
|
47
|
+
#visibleViewportSnapshot;
|
|
48
|
+
#fullViewportCompositions = 0;
|
|
49
|
+
#dockOnlyViewportCompositions = 0;
|
|
50
|
+
#transcriptBlockRenders = 0;
|
|
36
51
|
#extensionHeader = null;
|
|
37
52
|
#extensionFooter = null;
|
|
38
53
|
#extensionWidgets = new Map();
|
|
@@ -42,7 +57,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
42
57
|
constructor(view, cwd, handlers, startup = {}, agentDir, extensionRenderers = {
|
|
43
58
|
getMessageRenderer: () => undefined,
|
|
44
59
|
getToolDefinition: () => undefined,
|
|
45
|
-
}, sessionLayout = "pinned") {
|
|
60
|
+
}, sessionLayout = "pinned", imageAssets) {
|
|
46
61
|
this.#view = view;
|
|
47
62
|
this.#customViewport = sessionLayout === "custom-viewport";
|
|
48
63
|
this.#submittedPromptComposer = this.#customViewport
|
|
@@ -54,10 +69,13 @@ export class OwnedUiSessionShellRoot {
|
|
|
54
69
|
: undefined;
|
|
55
70
|
this.#cwd = cwd;
|
|
56
71
|
this.#extensionRenderers = extensionRenderers;
|
|
72
|
+
this.#imageAssets = imageAssets;
|
|
57
73
|
this.#componentRuntime = handlers;
|
|
74
|
+
this.#onViewportFrame = handlers.onViewportFrame;
|
|
75
|
+
this.#dockInputReuseEnabled = handlers.enableDockInputReuse ?? true;
|
|
58
76
|
this.header = createPiShellHeader(startup);
|
|
59
77
|
this.resources = createPiShellLoadedResources(startup.resources ?? [], startup.expanded ?? false);
|
|
60
|
-
this.#status = createPiShellStatus(view, handlers);
|
|
78
|
+
this.#status = createPiShellStatus(view, progressStatusText, handlers);
|
|
61
79
|
this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd);
|
|
62
80
|
this.#queued = createPiQueuedInputStatus(view.editor.queuedSubmissions, this.#customViewport ? "custom-viewport" : "pinned");
|
|
63
81
|
this.editor = createPiShellEditor({
|
|
@@ -72,7 +90,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
72
90
|
if (ranges.length === 0)
|
|
73
91
|
return row;
|
|
74
92
|
const linkResetAndTail = `\u001b]8;;\u001b\\\u001b[24m${" ".repeat(Math.max(0, width - piShellVisibleWidth(row)))}`;
|
|
75
|
-
// VS15 is zero-column and default-ignorable. It breaks Windows Terminal's
|
|
93
|
+
// Platform: VS15 is zero-column and default-ignorable. It breaks Windows Terminal's
|
|
76
94
|
// plain-text URL detector only in the held-button paint; semantic text stays exact.
|
|
77
95
|
const paintRow = this.#viewportController.editorPointerSelecting
|
|
78
96
|
? row.replaceAll("https://", "https:\uFE0E//").replaceAll("http://", "http:\uFE0E//")
|
|
@@ -80,7 +98,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
80
98
|
const decorated = this.#viewportController.editorPointerSelecting
|
|
81
99
|
? ranges.reduce((result, range) => backgroundSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), "\u001b[4:4m", "\u001b[24m", piShellVisibleWidth), paintRow)
|
|
82
100
|
: ranges.reduce((result, range) => hyperlinkSgrSpan(result, piShellVisibleWidth(plain.slice(0, range.start)), piShellVisibleWidth(plain.slice(0, range.end)), range.target, piShellVisibleWidth), row);
|
|
83
|
-
// Windows Terminal can retain stale native dotted-link cells when a mutable
|
|
101
|
+
// Platform: Windows Terminal can retain stale native dotted-link cells when a mutable
|
|
84
102
|
// prompt replaces a longer URL. Explicit non-link spaces overwrite that tail.
|
|
85
103
|
return `${decorated}${linkResetAndTail}`;
|
|
86
104
|
},
|
|
@@ -95,6 +113,16 @@ export class OwnedUiSessionShellRoot {
|
|
|
95
113
|
requestRender: force => this.#componentRuntime.requestRender(force),
|
|
96
114
|
hasEditorLinks: () => this.#promptChips.hyperlinkRanges(this.editor.getText()).length > 0,
|
|
97
115
|
});
|
|
116
|
+
// Performance: stable painter identities let the neutral viewport retain row-level
|
|
117
|
+
// selection variants while each callback still resolves the live Pi theme.
|
|
118
|
+
this.#viewportTheme = {
|
|
119
|
+
track: text => `${SCROLLBAR_CELL_RESET}${piTheme().fg("dim", text)}`,
|
|
120
|
+
thumb: text => `${SCROLLBAR_CELL_RESET}${piTheme().fg("accent", text)}`,
|
|
121
|
+
sticky: (text, hovered) => piTheme().bg(hovered ? "selectedBg" : "toolPendingBg", piTheme().fg("text", withoutTerminalBackground(text))),
|
|
122
|
+
quietSticky: text => `\u001b[2m${text.replace(/\u001b\[(?:0|22)m/g, "$&\u001b[2m")}\u001b[22m`,
|
|
123
|
+
bottomControl: (text, hovered) => piTheme().bg(hovered ? "selectedBg" : "toolPendingBg", piTheme().fg("text", text)),
|
|
124
|
+
selection: (line, from, to) => backgroundSgrSpan(line, from, to, "\u001b[48;2;38;79;120m", "\u001b[49m"),
|
|
125
|
+
};
|
|
98
126
|
this.editor.setThinkingLevel(view.thinkingLevel);
|
|
99
127
|
this.#inputSurface = this.editor;
|
|
100
128
|
for (const block of view.transcript) {
|
|
@@ -102,13 +130,54 @@ export class OwnedUiSessionShellRoot {
|
|
|
102
130
|
this.editor.addToHistory(block.text);
|
|
103
131
|
}
|
|
104
132
|
this.#syncTranscript(view.transcript);
|
|
105
|
-
//
|
|
133
|
+
// Invariant: colours come from the active theme, so rendered rows outlive their revision only
|
|
106
134
|
// until the theme under them changes.
|
|
107
135
|
this.#themeUnsubscribe = onPiThemeChange(() => {
|
|
108
136
|
this.#renderedRows.clear();
|
|
109
137
|
this.#documentLayouts.clear();
|
|
110
138
|
});
|
|
111
139
|
}
|
|
140
|
+
setEditorPaddingX(padding) {
|
|
141
|
+
this.editor.setPaddingX(padding);
|
|
142
|
+
this.#documentLayouts.clear();
|
|
143
|
+
}
|
|
144
|
+
setAutocompleteMaxVisible(maxVisible) {
|
|
145
|
+
this.editor.setAutocompleteMaxVisible(maxVisible);
|
|
146
|
+
}
|
|
147
|
+
setOutputPad(padding) {
|
|
148
|
+
if (this.#outputPad === padding)
|
|
149
|
+
return;
|
|
150
|
+
this.#outputPad = padding;
|
|
151
|
+
this.#status.setOutputPad(padding);
|
|
152
|
+
for (const component of this.#transcript.values())
|
|
153
|
+
component.setOutputPad(padding);
|
|
154
|
+
this.#invalidateTranscriptPresentation();
|
|
155
|
+
}
|
|
156
|
+
setHideThinkingBlock(hidden) {
|
|
157
|
+
if (this.#thinkingVisible === !hidden)
|
|
158
|
+
return;
|
|
159
|
+
this.#thinkingVisible = !hidden;
|
|
160
|
+
for (const component of this.#transcript.values())
|
|
161
|
+
component.setHideThinkingBlock(hidden);
|
|
162
|
+
this.#invalidateTranscriptPresentation();
|
|
163
|
+
}
|
|
164
|
+
setMermaidRenderingMode(mode) {
|
|
165
|
+
if (this.#mermaidRenderingMode === mode)
|
|
166
|
+
return;
|
|
167
|
+
this.#mermaidRenderingMode = mode;
|
|
168
|
+
for (const component of this.#transcript.values())
|
|
169
|
+
component.setMermaidRenderingMode(mode);
|
|
170
|
+
this.#invalidateTranscriptPresentation();
|
|
171
|
+
}
|
|
172
|
+
setImagePresentation(showImages, imageWidthCells) {
|
|
173
|
+
if (this.#showImages === showImages && this.#imageWidthCells === imageWidthCells)
|
|
174
|
+
return;
|
|
175
|
+
this.#showImages = showImages;
|
|
176
|
+
this.#imageWidthCells = imageWidthCells;
|
|
177
|
+
for (const component of this.#transcript.values())
|
|
178
|
+
component.setImagePresentation(showImages, imageWidthCells);
|
|
179
|
+
this.#invalidateTranscriptPresentation();
|
|
180
|
+
}
|
|
112
181
|
preparePromptSubmission(text) {
|
|
113
182
|
return this.#promptChips.prepareSubmission(text);
|
|
114
183
|
}
|
|
@@ -135,7 +204,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
135
204
|
this.#blocksById.set(block.id, block);
|
|
136
205
|
const component = this.#transcript.get(block.id);
|
|
137
206
|
if (component === undefined) {
|
|
138
|
-
const created = createPiShellTranscriptComponent(block, this.#cwd, this.#extensionRenderers, this.#submittedPromptComposer);
|
|
207
|
+
const created = createPiShellTranscriptComponent(block, this.#cwd, this.#extensionRenderers, this.#submittedPromptComposer, this.#outputPad, !this.#thinkingVisible, this.#mermaidRenderingMode, this.#showImages, this.#imageWidthCells, this.#imageAssets);
|
|
139
208
|
created.setExpanded(this.#toolsExpanded);
|
|
140
209
|
this.#transcript.set(block.id, created);
|
|
141
210
|
this.#transcriptOrder.push(block.id);
|
|
@@ -143,7 +212,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
143
212
|
else if (component.revision !== block.revision) {
|
|
144
213
|
component.update(block);
|
|
145
214
|
}
|
|
146
|
-
//
|
|
215
|
+
// Performance: one chunk touches one block, and the updated component tracks its own dirtiness.
|
|
147
216
|
// Invalidating the whole shell here would re-wrap the entire transcript per chunk.
|
|
148
217
|
this.#renderedRows.delete(block.id);
|
|
149
218
|
this.#documentLayouts.clear();
|
|
@@ -155,62 +224,79 @@ export class OwnedUiSessionShellRoot {
|
|
|
155
224
|
}
|
|
156
225
|
const height = Math.max(0, this.#componentRuntime.getRows());
|
|
157
226
|
const dock = this.#renderDockLayout(width);
|
|
158
|
-
|
|
159
|
-
// Ordinary transcript content uses the full terminal width. The rail is an
|
|
227
|
+
// Invariant: ordinary transcript content uses the full terminal width. The rail is an
|
|
160
228
|
// overlay, not a lost wrapping cell. Submitted prompts alone retain the
|
|
161
229
|
// intentional final gutter after their right-aligned timestamp.
|
|
162
230
|
const documentWidth = width;
|
|
163
|
-
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
// stable editor/footer dock.
|
|
169
|
-
const pinTransient = document.rows.length + dock.transientRows.length <= availableWithoutTransient;
|
|
170
|
-
const dockRows = pinTransient ? dock.rows : dock.rowsWithoutTransient;
|
|
231
|
+
const document = this.#renderDocumentLayout(documentWidth);
|
|
232
|
+
// Invariant: prompt-adjacent transient surfaces always belong to the dock.
|
|
233
|
+
// Changing from fitting to overflowing content reallocates transcript rows
|
|
234
|
+
// only; it never moves queued or Working rows into selectable history.
|
|
235
|
+
const dockRows = dock.rows;
|
|
171
236
|
const selectableDocumentRowCount = document.rows.length;
|
|
172
|
-
if (!pinTransient)
|
|
173
|
-
document = { ...document, rows: [...document.rows, ...dock.transientRows] };
|
|
174
237
|
const dockStartRow = height - dockRows.length + 1;
|
|
175
|
-
const editorOffset =
|
|
238
|
+
const editorOffset = dock.editorOffset;
|
|
176
239
|
this.#viewportController.setEditorPointerFrame(this.usesDefaultInputSurface()
|
|
177
240
|
? {
|
|
178
241
|
rowStart: dockStartRow + editorOffset,
|
|
179
242
|
rowEnd: dockStartRow + editorOffset + dock.inputRows - 1,
|
|
180
243
|
}
|
|
181
244
|
: undefined);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
245
|
+
const snapshot = this.#visibleViewportSnapshot;
|
|
246
|
+
const dockInputCandidate = this.#dockInputCandidate;
|
|
247
|
+
this.#dockInputCandidate = false;
|
|
248
|
+
let frame = dockInputCandidate
|
|
249
|
+
&& snapshot !== undefined
|
|
250
|
+
&& snapshot.width === width
|
|
251
|
+
&& snapshot.height === height
|
|
252
|
+
&& snapshot.documentRows === document.rows
|
|
253
|
+
&& snapshot.promptAnchors === document.promptAnchors
|
|
254
|
+
&& snapshot.dockLength === dockRows.length
|
|
255
|
+
&& snapshot.inputSurface === this.#inputSurface
|
|
256
|
+
&& snapshot.viewportRevision === this.#viewportController.presentationRevision
|
|
257
|
+
&& snapshot.selectionRevision === this.#viewportController.selectionRevision
|
|
258
|
+
? this.#viewportController.composeDockOnly(dockRows, width, height)
|
|
259
|
+
: null;
|
|
260
|
+
if (frame === null) {
|
|
261
|
+
frame = this.#viewportController.compose({
|
|
262
|
+
documentRows: document.rows,
|
|
263
|
+
...(this.#viewportController.transcriptPointerSelecting
|
|
264
|
+
? { paintDocumentRow: heldNativeHyperlinkStyle }
|
|
265
|
+
: {}),
|
|
266
|
+
// Invariant: selection and copying stop at the real document tail; queued
|
|
267
|
+
// and Working rows remain dock-owned status chrome at every fit boundary.
|
|
268
|
+
selectableDocumentRowCount,
|
|
269
|
+
dockRows,
|
|
270
|
+
promptAnchors: document.promptAnchors,
|
|
271
|
+
width,
|
|
272
|
+
height,
|
|
273
|
+
// Invariant: the control belongs immediately above the complete dock,
|
|
274
|
+
// never on top of a queued or Working row.
|
|
275
|
+
bottomControlRow: Math.max(0, height - Math.min(height, dockRows.length) - 1),
|
|
276
|
+
theme: this.#viewportTheme,
|
|
277
|
+
});
|
|
278
|
+
this.#fullViewportCompositions += 1;
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
this.#dockOnlyViewportCompositions += 1;
|
|
282
|
+
this.#visibleViewportSnapshot = {
|
|
192
283
|
width,
|
|
193
284
|
height,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
// foreground roles (including links, warnings, muted text, and bold
|
|
210
|
-
// intensity) remain exactly as rendered instead of being inverted.
|
|
211
|
-
selection: (line, from, to) => backgroundSgrSpan(line, from, to, "\u001b[48;2;38;79;120m", "\u001b[49m"),
|
|
212
|
-
},
|
|
213
|
-
}).rows;
|
|
285
|
+
documentRows: document.rows,
|
|
286
|
+
promptAnchors: document.promptAnchors,
|
|
287
|
+
dockLength: dockRows.length,
|
|
288
|
+
inputSurface: this.#inputSurface,
|
|
289
|
+
viewportRevision: this.#viewportController.presentationRevision,
|
|
290
|
+
selectionRevision: this.#viewportController.selectionRevision,
|
|
291
|
+
};
|
|
292
|
+
this.#onViewportFrame?.(frame);
|
|
293
|
+
return frame.rows;
|
|
294
|
+
}
|
|
295
|
+
viewportFrameDescriptor() {
|
|
296
|
+
return this.#viewportController.frame?.descriptor ?? null;
|
|
297
|
+
}
|
|
298
|
+
hasActiveSelection() {
|
|
299
|
+
return this.#viewportController.hasSelection || this.editor.hasSelection();
|
|
214
300
|
}
|
|
215
301
|
setViewportConfig(config) {
|
|
216
302
|
if (this.#viewportController.setConfig(config))
|
|
@@ -245,11 +331,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
245
331
|
const rowsWithoutTransient = [...aboveWidgets, ...input, ...belowWidgets, ...footer];
|
|
246
332
|
return {
|
|
247
333
|
rows: [...transientRows, ...rowsWithoutTransient],
|
|
248
|
-
|
|
249
|
-
transientRows,
|
|
250
|
-
stableBottomRows: rowsWithoutTransient.length,
|
|
251
|
-
editorOffsetWithTransient: transientRows.length + aboveWidgets.length,
|
|
252
|
-
editorOffsetWithoutTransient: aboveWidgets.length,
|
|
334
|
+
editorOffset: transientRows.length + aboveWidgets.length,
|
|
253
335
|
inputRows: input.length,
|
|
254
336
|
};
|
|
255
337
|
}
|
|
@@ -306,7 +388,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
306
388
|
return this.#renderDocumentLayout(width).rows;
|
|
307
389
|
}
|
|
308
390
|
#renderDocumentLayout(width) {
|
|
309
|
-
//
|
|
391
|
+
// Performance: extension headers may animate independently of transcript revisions, so
|
|
310
392
|
// only the stable built-in document participates in this frame cache.
|
|
311
393
|
const cached = this.#extensionHeader === null ? this.#documentLayouts.get(width) : undefined;
|
|
312
394
|
if (cached !== undefined)
|
|
@@ -340,7 +422,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
340
422
|
: width;
|
|
341
423
|
const blockRows = this.#blockRows(id, block, blockWidth);
|
|
342
424
|
if (block?.kind === "user") {
|
|
343
|
-
//
|
|
425
|
+
// Compatibility: the first natural prompt gets one breathing row at the document top.
|
|
344
426
|
// Once scrolling advances, the prompt itself reaches row zero and then
|
|
345
427
|
// becomes sticky there, so the spacer is never pinned with it.
|
|
346
428
|
if (this.#customViewport && index === 0)
|
|
@@ -363,7 +445,13 @@ export class OwnedUiSessionShellRoot {
|
|
|
363
445
|
.filter(diagnostic => diagnostic.code === "package-updates")
|
|
364
446
|
.flatMap(diagnostic => renderPiShellPackageUpdateNotice(diagnostic.message.split("\n").filter(line => line.startsWith("- ")).map(line => line.slice(2)), width)));
|
|
365
447
|
rows.push(...diagnostics
|
|
366
|
-
.filter(diagnostic => diagnostic.code
|
|
448
|
+
.filter(diagnostic => diagnostic.code === "changelog-collapsed" || diagnostic.code === "changelog-expanded")
|
|
449
|
+
.flatMap(diagnostic => diagnostic.code === "changelog-collapsed"
|
|
450
|
+
? createPiShellCollapsedChangelog().render(width)
|
|
451
|
+
: createPiShellChangelog(diagnostic.message).render(width)));
|
|
452
|
+
rows.push(...diagnostics
|
|
453
|
+
.filter(diagnostic => diagnostic.code !== "engine-startup" && diagnostic.code !== "package-updates"
|
|
454
|
+
&& diagnostic.code !== "changelog-collapsed" && diagnostic.code !== "changelog-expanded")
|
|
367
455
|
.slice(-3)
|
|
368
456
|
.flatMap(diagnostic => renderPiShellTranscriptBlock({
|
|
369
457
|
id: `diagnostic-${diagnostic.sequence}`,
|
|
@@ -377,23 +465,19 @@ export class OwnedUiSessionShellRoot {
|
|
|
377
465
|
const layout = { rows: Object.freeze(rows), promptAnchors: Object.freeze(promptAnchors) };
|
|
378
466
|
if (this.#extensionHeader === null) {
|
|
379
467
|
this.#documentLayouts.set(width, layout);
|
|
380
|
-
//
|
|
468
|
+
// Performance: the custom viewport commonly probes full width and reserved-rail width.
|
|
381
469
|
while (this.#documentLayouts.size > 2)
|
|
382
470
|
this.#documentLayouts.delete(this.#documentLayouts.keys().next().value);
|
|
383
471
|
}
|
|
384
472
|
return layout;
|
|
385
473
|
}
|
|
386
|
-
|
|
387
|
-
* Rows for one transcript block. A finalized block renders once for a given revision
|
|
388
|
-
* and width and is reused after that, so a frame costs what changed rather than what
|
|
389
|
-
* the session has accumulated. A live block, and anything the shell drives itself, is
|
|
390
|
-
* rendered every time because its content is still moving.
|
|
391
|
-
*/
|
|
474
|
+
// Performance: finalized blocks cache by revision and width; live blocks always render.
|
|
392
475
|
#blockRows(id, block, width) {
|
|
393
476
|
const component = this.#transcript.get(id);
|
|
394
477
|
if (component === undefined)
|
|
395
478
|
return [];
|
|
396
479
|
const render = () => {
|
|
480
|
+
this.#transcriptBlockRenders += 1;
|
|
397
481
|
const rows = component.render(width);
|
|
398
482
|
if (!this.#customViewport || block?.kind === "user")
|
|
399
483
|
return rows;
|
|
@@ -411,7 +495,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
411
495
|
this.#renderedRows.set(id, byWidth);
|
|
412
496
|
}
|
|
413
497
|
byWidth.set(width, { revision: block.revision, rows });
|
|
414
|
-
//
|
|
498
|
+
// Invariant: bare A1 probes full width before reserving the overflowing rail column;
|
|
415
499
|
// retain both widths without turning resize history into an unbounded cache.
|
|
416
500
|
while (byWidth.size > 2)
|
|
417
501
|
byWidth.delete(byWidth.keys().next().value);
|
|
@@ -420,6 +504,20 @@ export class OwnedUiSessionShellRoot {
|
|
|
420
504
|
transcriptComponent(id) {
|
|
421
505
|
return this.#transcript.get(id);
|
|
422
506
|
}
|
|
507
|
+
exitTranscript(width) {
|
|
508
|
+
const rows = [];
|
|
509
|
+
for (const id of this.#transcriptOrder) {
|
|
510
|
+
const block = this.#blocksById.get(id);
|
|
511
|
+
if (block === undefined || (!this.#thinkingVisible && block.kind === "thinking"))
|
|
512
|
+
continue;
|
|
513
|
+
if (rows.length > 0 && block.kind === "user")
|
|
514
|
+
rows.push("");
|
|
515
|
+
rows.push(...this.#blockRows(id, block, width).map(sanitizeExitTranscriptRow));
|
|
516
|
+
}
|
|
517
|
+
while (rows.at(-1) === "")
|
|
518
|
+
rows.pop();
|
|
519
|
+
return rows.join("\n");
|
|
520
|
+
}
|
|
423
521
|
appendWorkflowStatus(message) {
|
|
424
522
|
const previousId = this.#lastWorkflowStatusId;
|
|
425
523
|
if (previousId !== undefined
|
|
@@ -432,7 +530,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
432
530
|
}
|
|
433
531
|
const id = this.#appendAnchoredWorkflowComponent(width => [
|
|
434
532
|
"",
|
|
435
|
-
...renderPiShellStatusText(this.#workflowStatusMessages.get(id) ?? message, width),
|
|
533
|
+
...renderPiShellStatusText(this.#workflowStatusMessages.get(id) ?? message, width, this.#outputPad),
|
|
436
534
|
]);
|
|
437
535
|
this.#workflowStatusMessages.set(id, message);
|
|
438
536
|
this.#lastWorkflowStatusId = id;
|
|
@@ -517,9 +615,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
517
615
|
this.#appendAnchoredWorkflowComponent(width => ["", ...daxnuts.render(width)], () => daxnuts.dispose?.());
|
|
518
616
|
}
|
|
519
617
|
toggleThinkingVisibility() {
|
|
520
|
-
this
|
|
521
|
-
this.#documentLayouts.clear();
|
|
522
|
-
this.invalidate();
|
|
618
|
+
this.setHideThinkingBlock(this.#thinkingVisible);
|
|
523
619
|
}
|
|
524
620
|
get toolsExpanded() {
|
|
525
621
|
return this.#toolsExpanded;
|
|
@@ -588,7 +684,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
588
684
|
this.#extensionWorkingMessage = undefined;
|
|
589
685
|
this.#status.setWorkingOverride(undefined);
|
|
590
686
|
this.#footer.update(this.#viewWithExtensionStatuses(this.#view));
|
|
591
|
-
//
|
|
687
|
+
// Invariant: an extension renderer may have drawn transcript blocks that are now unrendered by it.
|
|
592
688
|
this.#renderedRows.clear();
|
|
593
689
|
this.#documentLayouts.clear();
|
|
594
690
|
this.invalidate();
|
|
@@ -613,19 +709,41 @@ export class OwnedUiSessionShellRoot {
|
|
|
613
709
|
usesDefaultInputSurface() {
|
|
614
710
|
return this.#inputSurface === this.editor;
|
|
615
711
|
}
|
|
616
|
-
|
|
712
|
+
inputCoordinationSurface() {
|
|
713
|
+
return this.#inputSurfaceCoordination;
|
|
714
|
+
}
|
|
715
|
+
viewportCompositionEvidence() {
|
|
716
|
+
return { full: this.#fullViewportCompositions, dockOnly: this.#dockOnlyViewportCompositions };
|
|
717
|
+
}
|
|
718
|
+
transcriptRenderCount() {
|
|
719
|
+
return this.#transcriptBlockRenders;
|
|
720
|
+
}
|
|
721
|
+
setInputSurface(component, disposePrevious = true, coordination = "owned") {
|
|
617
722
|
const next = component ?? this.editor;
|
|
618
|
-
|
|
723
|
+
const nextCoordination = next === this.editor ? "editor" : coordination;
|
|
724
|
+
if (next === this.#inputSurface) {
|
|
725
|
+
this.#inputSurfaceCoordination = nextCoordination;
|
|
619
726
|
return;
|
|
727
|
+
}
|
|
728
|
+
this.#dockInputCandidate = false;
|
|
620
729
|
this.#inputSurface.setFocused?.(false);
|
|
621
730
|
if (disposePrevious && this.#inputSurface !== this.editor)
|
|
622
731
|
this.#inputSurface.dispose?.();
|
|
623
732
|
this.#inputSurface = next;
|
|
733
|
+
this.#inputSurfaceCoordination = nextCoordination;
|
|
624
734
|
this.#inputSurface.setFocused?.(true);
|
|
625
735
|
this.invalidate();
|
|
626
736
|
}
|
|
627
737
|
handleInput(data) {
|
|
628
|
-
this.#
|
|
738
|
+
this.#dockInputCandidate = this.#customViewport && this.#dockInputReuseEnabled
|
|
739
|
+
&& classifyPiTuiInput(data, this.#inputSurfaceCoordination) === "safe";
|
|
740
|
+
try {
|
|
741
|
+
this.#inputSurface.handleInput?.(data);
|
|
742
|
+
}
|
|
743
|
+
catch (error) {
|
|
744
|
+
this.#dockInputCandidate = false;
|
|
745
|
+
throw error;
|
|
746
|
+
}
|
|
629
747
|
}
|
|
630
748
|
invalidate() {
|
|
631
749
|
this.header.invalidate();
|
|
@@ -653,6 +771,8 @@ export class OwnedUiSessionShellRoot {
|
|
|
653
771
|
this.#transcript.clear();
|
|
654
772
|
this.#renderedRows.clear();
|
|
655
773
|
this.#documentLayouts.clear();
|
|
774
|
+
this.#visibleViewportSnapshot = undefined;
|
|
775
|
+
this.#dockInputCandidate = false;
|
|
656
776
|
if (this.#inputSurface !== this.editor)
|
|
657
777
|
this.#inputSurface.dispose?.();
|
|
658
778
|
this.#extensionHeader?.dispose?.();
|
|
@@ -665,6 +785,11 @@ export class OwnedUiSessionShellRoot {
|
|
|
665
785
|
this.#footer.dispose?.();
|
|
666
786
|
this.#queued.dispose?.();
|
|
667
787
|
}
|
|
788
|
+
#invalidateTranscriptPresentation() {
|
|
789
|
+
this.#renderedRows.clear();
|
|
790
|
+
this.#documentLayouts.clear();
|
|
791
|
+
this.invalidate();
|
|
792
|
+
}
|
|
668
793
|
#syncTranscript(blocks) {
|
|
669
794
|
const previousIds = this.#transcriptOrder.filter(id => !id.startsWith("workflow-status-"));
|
|
670
795
|
const transcriptChanged = previousIds.length !== blocks.length || blocks.some((block, index) => {
|
|
@@ -687,7 +812,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
687
812
|
for (const block of blocks) {
|
|
688
813
|
const component = this.#transcript.get(block.id);
|
|
689
814
|
if (component === undefined) {
|
|
690
|
-
const created = createPiShellTranscriptComponent(block, this.#cwd, this.#extensionRenderers, this.#submittedPromptComposer);
|
|
815
|
+
const created = createPiShellTranscriptComponent(block, this.#cwd, this.#extensionRenderers, this.#submittedPromptComposer, this.#outputPad, !this.#thinkingVisible, this.#mermaidRenderingMode, this.#showImages, this.#imageWidthCells, this.#imageAssets);
|
|
691
816
|
created.setExpanded(this.#toolsExpanded);
|
|
692
817
|
this.#transcript.set(block.id, created);
|
|
693
818
|
}
|
|
@@ -724,6 +849,10 @@ export class OwnedUiSessionShellRoot {
|
|
|
724
849
|
invalidate() { },
|
|
725
850
|
update() { },
|
|
726
851
|
setExpanded() { },
|
|
852
|
+
setOutputPad() { },
|
|
853
|
+
setHideThinkingBlock() { },
|
|
854
|
+
setMermaidRenderingMode() { },
|
|
855
|
+
setImagePresentation() { },
|
|
727
856
|
...(dispose === undefined ? {} : { dispose }),
|
|
728
857
|
};
|
|
729
858
|
this.#transcript.set(id, component);
|
|
@@ -775,13 +904,19 @@ export class OwnedUiSessionShellRoot {
|
|
|
775
904
|
this.resources.setExpanded(expanded);
|
|
776
905
|
for (const component of this.#transcript.values())
|
|
777
906
|
component.setExpanded(expanded);
|
|
778
|
-
//
|
|
907
|
+
// Invariant: expansion changes what a block draws without changing its revision.
|
|
779
908
|
this.#renderedRows.clear();
|
|
780
909
|
this.#documentLayouts.clear();
|
|
781
910
|
this.invalidate();
|
|
782
911
|
}
|
|
783
912
|
}
|
|
784
913
|
const SCROLLBAR_CELL_RESET = "\u001b[22;23;24;25;27;28;29;39;54;55m";
|
|
914
|
+
const KITTY_IMAGE_CONTROL = /\u001b_G[\s\S]*?\u001b\\/g;
|
|
915
|
+
const ITERM_IMAGE_CONTROL = /\u001b]1337;File=[^\u0007]*(?:\u0007|\u001b\\)/g;
|
|
916
|
+
/** Keep semantic SGR/OSC styling while excluding non-replayable image payloads. */
|
|
917
|
+
function sanitizeExitTranscriptRow(row) {
|
|
918
|
+
return row.replace(KITTY_IMAGE_CONTROL, "").replace(ITERM_IMAGE_CONTROL, "");
|
|
919
|
+
}
|
|
785
920
|
const TERMINAL_BACKGROUND = /\u001b\[(?:4[0-9]|10[0-7]|48(?:[;:][0-9;:]*)?)m/g;
|
|
786
921
|
/** Web URLs use link blue; file targets retain A1's cyan interactive accent. */
|
|
787
922
|
function nativeTranscriptLinkColor(text, target) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { OwnedUiSessionViewModel, OwnedUiThinkingLevel } from "../../../contracts/owned-ui/index.js";
|
|
2
2
|
import { type AdapterCommandResult, type PiWorkflowRequest } from "../engine/index.js";
|
|
3
3
|
import { type PiShellSelectorOption } from "../components/index.js";
|
|
4
|
-
import { PiTuiRuntimeAdapter, type PiTuiOverlayHandle } from "../tui-runtime/index.js";
|
|
4
|
+
import { PiTuiRuntimeAdapter, type PiTuiDamageDecision, type PiTuiOverlayHandle } from "../tui-runtime/index.js";
|
|
5
5
|
import { OwnedUiSessionShellRoot, type OwnedUiBackendPort, type OwnedUiSessionShellOptions } from "./session-shell-root.js";
|
|
6
6
|
export { OwnedUiSessionShellRoot, type OwnedUiSessionShellOptions } from "./session-shell-root.js";
|
|
7
|
+
/** Coordinates backend, owned presentation, and Pi TUI lifecycles for one interactive session. */
|
|
7
8
|
export declare class OwnedUiSessionShell {
|
|
8
9
|
#private;
|
|
9
10
|
readonly backend: OwnedUiBackendPort;
|
|
@@ -11,6 +12,7 @@ export declare class OwnedUiSessionShell {
|
|
|
11
12
|
readonly runtime: PiTuiRuntimeAdapter;
|
|
12
13
|
constructor(options: OwnedUiSessionShellOptions);
|
|
13
14
|
view(): OwnedUiSessionViewModel;
|
|
15
|
+
damagePresentationDecision(): PiTuiDamageDecision | null;
|
|
14
16
|
start(): void;
|
|
15
17
|
onView(listener: (view: OwnedUiSessionViewModel) => void): () => void;
|
|
16
18
|
waitUntilStopped(): Promise<void>;
|
|
@@ -44,3 +46,10 @@ export declare class OwnedUiSessionShell {
|
|
|
44
46
|
showScopedModelsSelector(): void;
|
|
45
47
|
dispose(): Promise<void>;
|
|
46
48
|
}
|
|
49
|
+
export interface SessionResumeCommandMetadata {
|
|
50
|
+
readonly sessionId: string;
|
|
51
|
+
readonly sessionDir: string;
|
|
52
|
+
readonly usesDefaultSessionDir: boolean;
|
|
53
|
+
}
|
|
54
|
+
export declare function formatSessionResumeCommand(metadata: SessionResumeCommandMetadata): string;
|
|
55
|
+
export declare function quoteCommandArgument(value: string): string;
|