@timurproko/a1 0.2.7-dev.1255 → 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/dist/app/session-shell/prompt-submission.d.ts +1 -1
- package/dist/app/session-shell/prompt-submission.js +9 -9
- 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/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 +6 -28
- package/dist/app/session-shell/session-shell-root.js +26 -220
- package/dist/app/session-shell/session-shell.d.ts +3 -23
- package/dist/app/session-shell/session-shell.js +54 -365
- package/dist/app/session-shell/session-viewport-controller.d.ts +2 -10
- package/dist/app/session-shell/session-viewport-controller.js +40 -318
- package/dist/app/session-shell/settings-bindings.d.ts +1 -1
- package/dist/app/session-shell/settings-bindings.js +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/composition/owned-ui.js +63 -59
- package/dist/contracts/owned-ui/index.d.ts +1 -1
- package/dist/contracts/owned-ui/index.js +1 -1
- package/dist/contracts/owned-ui/validation.d.ts +1 -11
- package/dist/contracts/owned-ui/validation.js +8 -104
- package/dist/contracts/presentation/index.d.ts +1 -1
- package/dist/contracts/presentation/terminal.d.ts +0 -6
- package/dist/features/owned-ui/settings-app.js +13 -208
- 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/foundation/release/automatic-update.js +1 -8
- package/dist/foundation/release/dependency-layer.js +3 -3
- package/dist/foundation/release/latest-release.js +1 -1
- package/dist/foundation/release/managed-path.d.ts +10 -0
- package/dist/foundation/release/managed-path.js +26 -0
- package/dist/foundation/release/release-gc.js +6 -8
- package/dist/foundation/release/restart-certification.js +3 -4
- package/dist/foundation/release/update-activation.js +1 -1
- package/dist/foundation/release/update-execution-lease.js +1 -7
- package/dist/foundation/release/update-installer.d.ts +45 -0
- package/dist/foundation/release/update-installer.js +57 -0
- package/dist/foundation/release/update-recovery.js +2 -9
- package/dist/foundation/release/update.d.ts +4 -23
- package/dist/foundation/release/update.js +160 -179
- 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/owned-editor-ux.js +46 -140
- package/dist/integrations/pi/engine/adapter.d.ts +1 -8
- package/dist/integrations/pi/engine/adapter.js +6 -49
- package/dist/integrations/pi/engine/host.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/session-runtime.d.ts +6 -12
- package/dist/integrations/pi/engine/session-runtime.js +21 -178
- 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-runner.d.ts +0 -1
- 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 -14
- package/dist/integrations/pi/engine/workflow-support.js +0 -47
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +9 -19
- package/dist/integrations/pi/tui-runtime/adapter.js +35 -144
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +4 -4
- package/dist/integrations/pi/tui-runtime/index.d.ts +0 -1
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -2
- package/dist/integrations/pi/tui-runtime/presentation-adapter.d.ts +2 -2
- 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.d.ts +2 -147
- package/dist/ui/components/transcript-viewport.js +87 -315
- package/package.json +3 -3
- 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 -22
- /package/dist/{integrations/pi/tui-runtime/contracts.js → ui/components/transcript-viewport-types.js} +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { OwnedUiShellComponents, OwnedUiShellHotkeysPresentation, OwnedUiShellClipboardContent, OwnedUiShellComponentPort, OwnedUiShellEditorPort, OwnedUiShellHeaderOptions, OwnedUiShellHeaderPort, OwnedUiShellHistoryEditor, OwnedUiShellImageAssetResolver, OwnedUiShellKeybindingsHost, OwnedUiShellLoadedResourcesPort
|
|
2
|
-
import type { TerminalComponentPort, TerminalInputCoordinationScheduler, TerminalInputDiagnosticsEvent, TerminalInputSurfaceKind, TerminalLayoutNode,
|
|
1
|
+
import type { OwnedUiShellComponents, OwnedUiShellHotkeysPresentation, OwnedUiShellClipboardContent, OwnedUiShellComponentPort, OwnedUiShellEditorPort, OwnedUiShellHeaderOptions, OwnedUiShellHeaderPort, OwnedUiShellHistoryEditor, OwnedUiShellImageAssetResolver, OwnedUiShellKeybindingsHost, OwnedUiShellLoadedResourcesPort } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { TerminalComponentPort, TerminalInputCoordinationScheduler, TerminalInputDiagnosticsEvent, TerminalInputSurfaceKind, TerminalLayoutNode, TerminalPort } from "../../contracts/presentation/index.js";
|
|
3
3
|
import type { ShellPresentationPorts, ThemeSource } from "../../contracts/presentation/index.js";
|
|
4
4
|
import type { OwnedUiBackgroundSettingsPort, OwnedUiPromptSuggestionGeneratorPort, OwnedUiSessionBackend, OwnedUiSessionPresenters, OwnedUiSessionViewModel, OwnedUiTranscriptRendererPort, OwnedUiViewportSettings, OwnedUiViewportSettingsPort, OwnedUiQuitOutroSettingsPort, SuggestionDecision, SuggestionDiagnosticObserver } from "../../contracts/owned-ui/index.js";
|
|
5
5
|
import type { UiRouteHost, UiRouteInput } from "../../ui/apps/contracts.js";
|
|
6
6
|
import type { TranscriptViewportFrame, TranscriptViewportFrameDescriptor } from "../../ui/components/transcript-viewport.js";
|
|
7
|
-
import { type PreparedPrompt } from "./prompt-chips.js";
|
|
7
|
+
import { PromptChipStore, type PreparedPrompt } from "./prompt-chips.js";
|
|
8
8
|
import type { PastePreparationClientOptions } from "./paste-preparation-client.js";
|
|
9
9
|
import type { OwnedUiClipboardServices } from "./clipboard-services.js";
|
|
10
10
|
import type { OwnedUiClipboardPort } from "./shell-clipboard.js";
|
|
11
|
-
import { type SessionViewportInputResult } from "./session-viewport-controller.js";
|
|
11
|
+
import { SessionViewportController, type SessionViewportInputResult } from "./session-viewport-controller.js";
|
|
12
12
|
import type { ResponseCopyExecutor } from "./response-copy-transport.js";
|
|
13
13
|
import type { ResponseCopyEvent } from "./response-copy-protocol.js";
|
|
14
14
|
import type { PasteEvent, PasteSource } from "./paste-protocol.js";
|
|
@@ -193,6 +193,8 @@ export declare class OwnedUiSessionShellRoot implements TerminalComponentPort {
|
|
|
193
193
|
readonly resources: OwnedUiShellLoadedResourcesPort;
|
|
194
194
|
/** The transcript's semantic rows, caches, and engine-backed block renderers. */
|
|
195
195
|
readonly transcript: TranscriptDocument;
|
|
196
|
+
readonly promptChips: PromptChipStore;
|
|
197
|
+
readonly viewport: SessionViewportController;
|
|
196
198
|
/** Workflow results, messages, and status lines appended to the transcript. */
|
|
197
199
|
readonly workflow: WorkflowOutput;
|
|
198
200
|
/** The dock's notices, copy acknowledgement, and release banner. */
|
|
@@ -204,28 +206,11 @@ export declare class OwnedUiSessionShellRoot implements TerminalComponentPort {
|
|
|
204
206
|
setHideThinkingBlock(hidden: boolean): void;
|
|
205
207
|
setMermaidRenderingMode(mode: "off" | "final" | "streaming"): void;
|
|
206
208
|
setImagePresentation(showImages: boolean, imageWidthCells: number): void;
|
|
207
|
-
prepareHistoryText(text: string): string;
|
|
208
|
-
omitUnsentPromptImages(text: string): string;
|
|
209
|
-
rehydrateHistoryText(text: string, resolveImage: (id: string) => import("../../contracts/owned-ui/index.js").PromptHistoryImageSidecarAttachment | null): string;
|
|
210
|
-
imageChipAttachmentsFromEditor(text: string): {
|
|
211
|
-
readonly id: string;
|
|
212
|
-
readonly tag: string;
|
|
213
|
-
readonly image: {
|
|
214
|
-
readonly type: "image";
|
|
215
|
-
readonly data: string;
|
|
216
|
-
readonly mimeType: string;
|
|
217
|
-
};
|
|
218
|
-
}[];
|
|
219
|
-
preparePromptSubmission(text: string): PreparedPrompt;
|
|
220
209
|
reconcilePromptImageLimitNotice(text?: string): boolean;
|
|
221
|
-
hasPendingPastes(text: string): boolean;
|
|
222
210
|
waitForPromptPastes(text: string, signal: AbortSignal): Promise<PreparedPrompt>;
|
|
223
211
|
resetPendingPastes(): void;
|
|
224
|
-
/** Forks the spare paste helper so the first paste of the session takes a live child. */
|
|
225
|
-
warmPastePreparation(): void;
|
|
226
212
|
disposePendingPastes(): Promise<void>;
|
|
227
213
|
promptSuggestionPrepareBlockReason(): SuggestionDecision;
|
|
228
|
-
canPreparePromptSuggestion(): boolean;
|
|
229
214
|
promptSuggestionPresentationBlockReason(): SuggestionDecision;
|
|
230
215
|
canPresentPromptSuggestion(): boolean;
|
|
231
216
|
setPromptSuggestion(text: string | null): void;
|
|
@@ -261,12 +246,6 @@ export declare class OwnedUiSessionShellRoot implements TerminalComponentPort {
|
|
|
261
246
|
viewportTransientTailRowCount(): number;
|
|
262
247
|
hasActiveSelection(): boolean;
|
|
263
248
|
setViewportConfig(config: OwnedUiViewportSettings): void;
|
|
264
|
-
setFullscreenCopyOnSelect(enabled: boolean): void;
|
|
265
|
-
resumeViewportFollowing(): void;
|
|
266
|
-
noteCompletedAssistantMessage(): void;
|
|
267
|
-
resetViewport(): void;
|
|
268
|
-
clearViewportPointerState(): void;
|
|
269
|
-
setViewportOverlaySurfaces(surfaces: readonly TerminalPointerSurface[] | null): void;
|
|
270
249
|
viewportInputGeometryReady(width: number, height: number): boolean;
|
|
271
250
|
handleViewportPreInput(data: string, allowWheel?: boolean, now?: number, editorActive?: boolean): SessionViewportInputResult;
|
|
272
251
|
/** The pinned-profile layout regions of this session; the terminal host arranges them with `pinnedLayoutRoot`. */
|
|
@@ -306,5 +285,4 @@ export type PinnedLayoutParts = Readonly<Record<PinnedLayoutPart, TerminalCompon
|
|
|
306
285
|
* so its single `transcript` scroll view is shared by whichever session the parts currently resolve to.
|
|
307
286
|
*/
|
|
308
287
|
export declare function pinnedLayoutRoot(parts: PinnedLayoutParts, theme: ThemeSource): TerminalLayoutNode;
|
|
309
|
-
export declare function shellResourceEntries(backend: OwnedUiSessionBackend): readonly OwnedUiShellResourceEntry[];
|
|
310
288
|
export {};
|
|
@@ -28,11 +28,11 @@ export class OwnedUiSessionShellRoot {
|
|
|
28
28
|
#queued;
|
|
29
29
|
#extensionRenderers;
|
|
30
30
|
#imageAssets;
|
|
31
|
-
|
|
31
|
+
promptChips;
|
|
32
32
|
#pasteDiagnosticId = 0;
|
|
33
33
|
#customViewport;
|
|
34
34
|
#submittedPromptComposer;
|
|
35
|
-
|
|
35
|
+
viewport;
|
|
36
36
|
#onPromptSuggestionEligibilityChanged;
|
|
37
37
|
#componentRuntime;
|
|
38
38
|
#toolsExpanded = false;
|
|
@@ -57,7 +57,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
57
57
|
}, sessionLayout = "pinned", imageAssets) {
|
|
58
58
|
this.#view = view;
|
|
59
59
|
this.#customViewport = sessionLayout === "custom-viewport";
|
|
60
|
-
this
|
|
60
|
+
this.promptChips = new PromptChipStore({ isolated: this.#customViewport,
|
|
61
61
|
...(handlers.pasteDiagnostics === undefined ? {} : { onEvent: handlers.pasteDiagnostics }),
|
|
62
62
|
...(handlers.pastePreparation === undefined ? {} : { preparation: handlers.pastePreparation }),
|
|
63
63
|
...(handlers.promptImageLimit === undefined ? {} : { imageLimit: handlers.promptImageLimit }) });
|
|
@@ -84,25 +84,25 @@ export class OwnedUiSessionShellRoot {
|
|
|
84
84
|
customViewport: this.#customViewport,
|
|
85
85
|
cwd,
|
|
86
86
|
...(agentDir === undefined ? {} : { agentDir }),
|
|
87
|
-
promptChips: this
|
|
88
|
-
editorPointerSelecting: () => this
|
|
87
|
+
promptChips: this.promptChips,
|
|
88
|
+
editorPointerSelecting: () => this.viewport.editorPointerSelecting,
|
|
89
89
|
nextPasteDiagnosticRequest: () => --this.#pasteDiagnosticId,
|
|
90
90
|
toggleToolsExpanded: () => this.#setToolsExpanded(!this.#toolsExpanded),
|
|
91
91
|
});
|
|
92
92
|
this.#queued = handlers.components.chrome.queuedInput(view.editor.queuedSubmissions, this.#customViewport ? "custom-viewport" : "pinned", this.#customViewport ? () => this.editor.keybindingConfig() : undefined);
|
|
93
|
-
this
|
|
93
|
+
this.viewport = new SessionViewportController({
|
|
94
94
|
enabled: this.#customViewport,
|
|
95
95
|
editor: this.editor,
|
|
96
96
|
requestRender: force => this.#componentRuntime.requestRender(force),
|
|
97
97
|
requestHyperlinkCleanup: rows => handlers.requestHyperlinkCleanup?.(rows),
|
|
98
|
-
hasEditorLinks: () => this
|
|
98
|
+
hasEditorLinks: () => this.promptChips.hyperlinkRanges(this.editor.getText()).length > 0,
|
|
99
99
|
...(handlers.pasteDiagnostics === undefined ? {} : { pasteDiagnostics: handlers.pasteDiagnostics }),
|
|
100
100
|
nextPasteDiagnosticRequest: () => --this.#pasteDiagnosticId,
|
|
101
101
|
});
|
|
102
102
|
this.chrome = new DockChrome({ theme: handlers.presentation.theme, outputPad: handlers.presentation.pinnedOutputPad, components: handlers.components,
|
|
103
103
|
invalidateChrome: () => this.#invalidateChrome(),
|
|
104
104
|
requestRender: () => this.#componentRuntime.requestRender(),
|
|
105
|
-
viewport: this
|
|
105
|
+
viewport: this.viewport,
|
|
106
106
|
});
|
|
107
107
|
this.workflow = new WorkflowOutput({
|
|
108
108
|
customViewport: this.#customViewport, components: handlers.components,
|
|
@@ -117,7 +117,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
117
117
|
this.editor.setThinkingLevel(view.thinkingLevel);
|
|
118
118
|
this.#input = new InputSurfaceSwitch(this.editor, {
|
|
119
119
|
dockInputReuse: this.#customViewport && (handlers.enableDockInputReuse ?? true), classifyInput: handlers.presentation.terminalRuntime.classifyInput,
|
|
120
|
-
viewport: this
|
|
120
|
+
viewport: this.viewport,
|
|
121
121
|
...(handlers.onInputSurfaceChanged === undefined ? {} : { onChanged: handlers.onInputSurfaceChanged }),
|
|
122
122
|
});
|
|
123
123
|
this.#layout = this.#createLayout(handlers.onViewportFrame, createViewportTheme(handlers.presentation.theme));
|
|
@@ -153,10 +153,10 @@ export class OwnedUiSessionShellRoot {
|
|
|
153
153
|
// Invariant: one layout per root; the render path never consults the layout mode again.
|
|
154
154
|
#createLayout(onFrame, theme) {
|
|
155
155
|
const ports = {
|
|
156
|
-
viewport: this
|
|
156
|
+
viewport: this.viewport,
|
|
157
157
|
input: this.#input,
|
|
158
158
|
editor: this.editor,
|
|
159
|
-
promptChips: this
|
|
159
|
+
promptChips: this.promptChips,
|
|
160
160
|
dockChrome: this.chrome,
|
|
161
161
|
theme,
|
|
162
162
|
...(onFrame === undefined ? {} : { onFrame }),
|
|
@@ -217,40 +217,22 @@ export class OwnedUiSessionShellRoot {
|
|
|
217
217
|
component.setImagePresentation(showImages, imageWidthCells);
|
|
218
218
|
this.#invalidateTranscriptPresentation();
|
|
219
219
|
}
|
|
220
|
-
prepareHistoryText(text) {
|
|
221
|
-
return this.#promptChips.prepareHistoryText(text);
|
|
222
|
-
}
|
|
223
|
-
omitUnsentPromptImages(text) {
|
|
224
|
-
return this.#promptChips.omitUnsentImages(text);
|
|
225
|
-
}
|
|
226
|
-
rehydrateHistoryText(text, resolveImage) {
|
|
227
|
-
return this.#promptChips.rehydrateHistoryText(text, resolveImage);
|
|
228
|
-
}
|
|
229
|
-
imageChipAttachmentsFromEditor(text) {
|
|
230
|
-
return this.#promptChips.imageChipAttachments(text);
|
|
231
|
-
}
|
|
232
|
-
preparePromptSubmission(text) {
|
|
233
|
-
return this.#promptChips.prepareSubmission(text);
|
|
234
|
-
}
|
|
235
220
|
reconcilePromptImageLimitNotice(text = this.editor.getText()) {
|
|
236
|
-
if (this.chrome.notice?.errorCode !== "image-count" || !this
|
|
221
|
+
if (this.chrome.notice?.errorCode !== "image-count" || !this.promptChips.imageLimitState(text).corrected)
|
|
237
222
|
return false;
|
|
238
223
|
this.chrome.dismissNotice();
|
|
239
224
|
return true;
|
|
240
225
|
}
|
|
241
|
-
hasPendingPastes(text) { return this.#promptChips.hasPending(text); }
|
|
242
226
|
waitForPromptPastes(text, signal) {
|
|
243
|
-
return this
|
|
227
|
+
return this.promptChips.waitForPastes(text, signal, () => this.editor.getText());
|
|
244
228
|
}
|
|
245
229
|
resetPendingPastes() {
|
|
246
230
|
this.editor.cancelPendingPastes?.();
|
|
247
|
-
this.editor.setText(this
|
|
231
|
+
this.editor.setText(this.promptChips.resetPastes(this.editor.getText()));
|
|
248
232
|
}
|
|
249
|
-
/** Forks the spare paste helper so the first paste of the session takes a live child. */
|
|
250
|
-
warmPastePreparation() { this.#promptChips.warm(); }
|
|
251
233
|
disposePendingPastes() {
|
|
252
234
|
this.resetPendingPastes();
|
|
253
|
-
return this
|
|
235
|
+
return this.promptChips.dispose();
|
|
254
236
|
}
|
|
255
237
|
promptSuggestionPrepareBlockReason() {
|
|
256
238
|
if (!this.usesDefaultInputSurface())
|
|
@@ -261,7 +243,6 @@ export class OwnedUiSessionShellRoot {
|
|
|
261
243
|
return "draft";
|
|
262
244
|
return null;
|
|
263
245
|
}
|
|
264
|
-
canPreparePromptSuggestion() { return this.promptSuggestionPrepareBlockReason() === null; }
|
|
265
246
|
promptSuggestionPresentationBlockReason() {
|
|
266
247
|
const reason = this.promptSuggestionPrepareBlockReason();
|
|
267
248
|
if (reason !== null)
|
|
@@ -322,18 +303,18 @@ export class OwnedUiSessionShellRoot {
|
|
|
322
303
|
return this.#layout.render(width);
|
|
323
304
|
}
|
|
324
305
|
viewportFrameDescriptor() {
|
|
325
|
-
return this
|
|
306
|
+
return this.viewport.frame?.descriptor ?? null;
|
|
326
307
|
}
|
|
327
308
|
/** Read-only, payload-free evidence; observing a pending frame must never render or repair it. */
|
|
328
309
|
viewportPresentationEvidence() {
|
|
329
|
-
const frame = this
|
|
310
|
+
const frame = this.viewport.frame;
|
|
330
311
|
const snapshot = this.#layout.composed();
|
|
331
312
|
return {
|
|
332
313
|
candidate: this.#input.dockInputCandidate,
|
|
333
314
|
candidateRevision: this.#input.dockInputCandidate ? this.#input.dockInputRevision ?? null : null,
|
|
334
|
-
currentRevision: this
|
|
315
|
+
currentRevision: this.viewport.presentationRevision,
|
|
335
316
|
composedRevision: snapshot?.viewportRevision ?? null,
|
|
336
|
-
currentPointer: this
|
|
317
|
+
currentPointer: this.viewport.pointerPosition ?? null,
|
|
337
318
|
composedPointer: snapshot?.pointerPosition ?? null,
|
|
338
319
|
frameId: frame?.descriptor.frameId ?? null,
|
|
339
320
|
bottom: frame?.hits.bottom ?? null,
|
|
@@ -345,41 +326,23 @@ export class OwnedUiSessionShellRoot {
|
|
|
345
326
|
}
|
|
346
327
|
/** Visible non-persistent Steering, alignment, and Working rows, for rendering evidence. */
|
|
347
328
|
viewportTransientTailRowCount() {
|
|
348
|
-
return this
|
|
329
|
+
return this.viewport.frame?.hits.transientTail.length ?? 0;
|
|
349
330
|
}
|
|
350
331
|
hasActiveSelection() {
|
|
351
|
-
return this
|
|
332
|
+
return this.viewport.hasSelection || this.editor.hasSelection();
|
|
352
333
|
}
|
|
353
334
|
setViewportConfig(config) {
|
|
354
|
-
if (this
|
|
335
|
+
if (this.viewport.setConfig(config)) {
|
|
355
336
|
this.transcript.invalidate("viewport-config");
|
|
356
337
|
this.#layout.invalidate();
|
|
357
338
|
}
|
|
358
339
|
}
|
|
359
|
-
setFullscreenCopyOnSelect(enabled) {
|
|
360
|
-
this.#viewportController.setCopyOnSelect(enabled);
|
|
361
|
-
}
|
|
362
|
-
resumeViewportFollowing() {
|
|
363
|
-
this.#viewportController.resumeFollowing();
|
|
364
|
-
}
|
|
365
|
-
noteCompletedAssistantMessage() {
|
|
366
|
-
this.#viewportController.noteCompletedAssistantMessage();
|
|
367
|
-
}
|
|
368
|
-
resetViewport() {
|
|
369
|
-
this.#viewportController.reset();
|
|
370
|
-
}
|
|
371
|
-
clearViewportPointerState() {
|
|
372
|
-
this.#viewportController.clearPointerState();
|
|
373
|
-
}
|
|
374
|
-
setViewportOverlaySurfaces(surfaces) {
|
|
375
|
-
this.#viewportController.setOverlaySurfaces(surfaces);
|
|
376
|
-
}
|
|
377
340
|
viewportInputGeometryReady(width, height) {
|
|
378
|
-
const frame = this
|
|
379
|
-
return this
|
|
341
|
+
const frame = this.viewport.frame;
|
|
342
|
+
return this.viewport.inputGeometryReady && frame?.descriptor.width === width && frame.descriptor.height === height;
|
|
380
343
|
}
|
|
381
344
|
handleViewportPreInput(data, allowWheel = true, now = Date.now(), editorActive = this.usesDefaultInputSurface()) {
|
|
382
|
-
return this
|
|
345
|
+
return this.viewport.handlePreInput(data, allowWheel, now, editorActive);
|
|
383
346
|
}
|
|
384
347
|
#renderDockLayout(width) {
|
|
385
348
|
const queued = this.#customViewport ? [] : this.#renderQueued(width);
|
|
@@ -552,7 +515,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
552
515
|
}
|
|
553
516
|
dispose() {
|
|
554
517
|
this.chrome.clearCopyAcknowledgement(false);
|
|
555
|
-
this.
|
|
518
|
+
this.viewport.clearPointerState();
|
|
556
519
|
this.#themeUnsubscribe();
|
|
557
520
|
this.header.dispose?.();
|
|
558
521
|
this.resources.dispose?.();
|
|
@@ -650,163 +613,6 @@ function layoutPort(render, invalidate, handleInput) {
|
|
|
650
613
|
...(handleInput === undefined ? {} : { handleInput }),
|
|
651
614
|
};
|
|
652
615
|
}
|
|
653
|
-
export function shellResourceEntries(backend) {
|
|
654
|
-
const resources = backend.extensions.nonVisualResources().map(resource => ({
|
|
655
|
-
section: resource.kind === "skill"
|
|
656
|
-
? "Skills"
|
|
657
|
-
: resource.kind === "prompt-template"
|
|
658
|
-
? "Prompts"
|
|
659
|
-
: resource.kind === "theme"
|
|
660
|
-
? "Themes"
|
|
661
|
-
: "Context",
|
|
662
|
-
label: resource.kind === "prompt-template"
|
|
663
|
-
? `/${resource.label}`
|
|
664
|
-
: resource.kind === "agent-context" || resource.kind === "system-prompt"
|
|
665
|
-
? compactResourceLabel(resource.sourcePath ?? resource.label)
|
|
666
|
-
: resource.label,
|
|
667
|
-
sourcePath: resource.sourcePath,
|
|
668
|
-
diagnostic: resource.diagnostic,
|
|
669
|
-
}));
|
|
670
|
-
const extensions = backend.extensions.extensionResources().filter(extension => !extension.hidden);
|
|
671
|
-
const loadedExtensions = extensions.filter(extension => extension.diagnostic === null);
|
|
672
|
-
const extensionLabels = compactExtensionLabels(loadedExtensions);
|
|
673
|
-
for (const extension of extensions) {
|
|
674
|
-
const labelIndex = loadedExtensions.indexOf(extension);
|
|
675
|
-
resources.push({
|
|
676
|
-
section: "Extensions",
|
|
677
|
-
label: extensionLabels[labelIndex] ?? compactResourceLabel(extension.sourcePath ?? extension.resolvedPath ?? "extension"),
|
|
678
|
-
sourcePath: extension.sourcePath ?? extension.resolvedPath,
|
|
679
|
-
diagnostic: extension.diagnostic,
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
return resources;
|
|
683
|
-
}
|
|
684
|
-
function compactResourceLabel(path) {
|
|
685
|
-
const segments = compactPathSegments(path);
|
|
686
|
-
const leaf = segments.at(-1) ?? path;
|
|
687
|
-
if ((leaf === "index.ts" || leaf === "index.js") && segments.length > 1)
|
|
688
|
-
return segments.at(-2) ?? leaf;
|
|
689
|
-
return leaf;
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
|
-
* Pinned from InteractiveMode's compact extension-label helpers at Pi commit
|
|
693
|
-
* 914cf1472e715297caa30db4b9535d534a9eb718. The source metadata crosses an
|
|
694
|
-
* A1-owned boundary first; the owned shell never inspects Pi's private root.
|
|
695
|
-
*/
|
|
696
|
-
function compactExtensionLabels(extensions) {
|
|
697
|
-
const localExtensions = extensions
|
|
698
|
-
.filter(extension => !isPackageExtensionSource(extension.sourceInfo))
|
|
699
|
-
.map(extension => {
|
|
700
|
-
const path = extension.sourcePath ?? extension.resolvedPath ?? "extension";
|
|
701
|
-
const segments = compactPathSegments(path);
|
|
702
|
-
if (segments.length > 1 && (segments.at(-1) === "index.ts" || segments.at(-1) === "index.js"))
|
|
703
|
-
segments.pop();
|
|
704
|
-
return { extension, segments };
|
|
705
|
-
});
|
|
706
|
-
return extensions.map(extension => {
|
|
707
|
-
const resourcePath = extension.sourcePath ?? extension.resolvedPath ?? "extension";
|
|
708
|
-
if (isPackageExtensionSource(extension.sourceInfo)) {
|
|
709
|
-
return compactPackageExtensionLabel(resourcePath, extension.sourceInfo);
|
|
710
|
-
}
|
|
711
|
-
const localIndex = localExtensions.findIndex(item => item.extension === extension);
|
|
712
|
-
const segments = localExtensions[localIndex]?.segments;
|
|
713
|
-
if (!segments || segments.length === 0)
|
|
714
|
-
return compactResourceLabel(resourcePath);
|
|
715
|
-
for (let count = 1; count <= segments.length; count += 1) {
|
|
716
|
-
const candidate = segments.slice(-count).join("/");
|
|
717
|
-
if (localExtensions.every((item, itemIndex) => itemIndex === localIndex || item.segments.slice(-count).join("/") !== candidate)) {
|
|
718
|
-
return candidate;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
return segments.join("/");
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
function compactPackageExtensionLabel(resourcePath, sourceInfo) {
|
|
725
|
-
const sourceLabel = compactPackageSourceLabel(sourceInfo.source);
|
|
726
|
-
if (!sourceLabel)
|
|
727
|
-
return compactResourceLabel(resourcePath);
|
|
728
|
-
const shortPath = shortPackagePath(resourcePath, sourceInfo).replaceAll("\\", "/");
|
|
729
|
-
const packagePath = shortPath.startsWith("extensions/") ? shortPath.slice("extensions/".length) : shortPath;
|
|
730
|
-
const slash = packagePath.lastIndexOf("/");
|
|
731
|
-
const fileName = slash < 0 ? packagePath : packagePath.slice(slash + 1);
|
|
732
|
-
const directory = slash < 0 ? "" : packagePath.slice(0, slash);
|
|
733
|
-
const extension = fileName.lastIndexOf(".");
|
|
734
|
-
const name = extension <= 0 ? fileName : fileName.slice(0, extension);
|
|
735
|
-
if (name === "index")
|
|
736
|
-
return !directory || directory === "." ? sourceLabel : `${sourceLabel}:${directory}`;
|
|
737
|
-
return `${sourceLabel}:${packagePath}`;
|
|
738
|
-
}
|
|
739
|
-
function compactPackageSourceLabel(source) {
|
|
740
|
-
if (source.startsWith("npm:"))
|
|
741
|
-
return source.slice("npm:".length) || source;
|
|
742
|
-
if (!source.startsWith("git:"))
|
|
743
|
-
return source;
|
|
744
|
-
const gitSource = source.slice("git:".length).trim();
|
|
745
|
-
let repositoryPath;
|
|
746
|
-
const scpLike = gitSource.match(/^git@[^:]+:(.+)$/);
|
|
747
|
-
if (scpLike?.[1]) {
|
|
748
|
-
repositoryPath = scpLike[1];
|
|
749
|
-
}
|
|
750
|
-
else if (/^[a-z]+:\/\//i.test(gitSource)) {
|
|
751
|
-
try {
|
|
752
|
-
repositoryPath = new URL(gitSource).pathname.replace(/^\/+/, "");
|
|
753
|
-
}
|
|
754
|
-
catch {
|
|
755
|
-
return source;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
else {
|
|
759
|
-
const slash = gitSource.indexOf("/");
|
|
760
|
-
if (slash >= 0)
|
|
761
|
-
repositoryPath = gitSource.slice(slash + 1);
|
|
762
|
-
}
|
|
763
|
-
if (!repositoryPath)
|
|
764
|
-
return source;
|
|
765
|
-
const ref = repositoryPath.indexOf("@");
|
|
766
|
-
const withoutRef = ref < 0 ? repositoryPath : repositoryPath.slice(0, ref);
|
|
767
|
-
return withoutRef.replace(/\.git$/, "") || source;
|
|
768
|
-
}
|
|
769
|
-
function shortPackagePath(resourcePath, sourceInfo) {
|
|
770
|
-
const fullPath = normalizeResourcePath(resourcePath);
|
|
771
|
-
const baseDir = sourceInfo.baseDir === null ? undefined : normalizeResourcePath(sourceInfo.baseDir).replace(/\/$/, "");
|
|
772
|
-
if (baseDir) {
|
|
773
|
-
const npmRoot = baseDir.match(/^(.*\/node_modules)\/(@?[^/]+(?:\/[^/]+)?)$/);
|
|
774
|
-
if (npmRoot?.[1] && fullPath.startsWith(`${npmRoot[1]}/`))
|
|
775
|
-
return relativeResourcePath(baseDir, fullPath);
|
|
776
|
-
if (fullPath === baseDir)
|
|
777
|
-
return ".";
|
|
778
|
-
if (fullPath.startsWith(`${baseDir}/`))
|
|
779
|
-
return fullPath.slice(baseDir.length + 1);
|
|
780
|
-
}
|
|
781
|
-
const npmMatch = fullPath.match(/node_modules\/(@?[^/]+(?:\/[^/]+)?)\/(.*)/);
|
|
782
|
-
if (npmMatch?.[2] && sourceInfo.source.startsWith("npm:"))
|
|
783
|
-
return npmMatch[2];
|
|
784
|
-
const gitMatch = fullPath.match(/git\/[^/]+\/[^/]+\/(.*)/);
|
|
785
|
-
if (gitMatch?.[1] && sourceInfo.source.startsWith("git:"))
|
|
786
|
-
return gitMatch[1];
|
|
787
|
-
return resourcePath;
|
|
788
|
-
}
|
|
789
|
-
function relativeResourcePath(from, to) {
|
|
790
|
-
const fromSegments = from.split("/").filter(Boolean);
|
|
791
|
-
const toSegments = to.split("/").filter(Boolean);
|
|
792
|
-
let common = 0;
|
|
793
|
-
while (common < fromSegments.length && common < toSegments.length
|
|
794
|
-
&& fromSegments[common]?.toLowerCase() === toSegments[common]?.toLowerCase())
|
|
795
|
-
common += 1;
|
|
796
|
-
return [...fromSegments.slice(common).map(() => ".."), ...toSegments.slice(common)].join("/") || ".";
|
|
797
|
-
}
|
|
798
|
-
function compactPathSegments(path) {
|
|
799
|
-
return normalizeResourcePath(path).split("/").filter(segment => segment.length > 0 && segment !== "~");
|
|
800
|
-
}
|
|
801
|
-
function normalizeResourcePath(path) {
|
|
802
|
-
return path.replaceAll("\\", "/");
|
|
803
|
-
}
|
|
804
|
-
function isPackageExtensionSource(sourceInfo) {
|
|
805
|
-
const source = sourceInfo?.source ?? "";
|
|
806
|
-
return source.startsWith("npm:") || source.startsWith("git:");
|
|
807
|
-
}
|
|
808
|
-
// Performance: one painter set per root keeps identities stable, so the neutral viewport retains row-level
|
|
809
|
-
// selection variants while each callback still resolves the live theme.
|
|
810
616
|
function createViewportTheme(source) {
|
|
811
617
|
return {
|
|
812
618
|
track: text => `${SCROLLBAR_CELL_RESET}${source.current().fg("dim", text)}`,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { OwnedUiShellSelectorOption } from "../../contracts/owned-ui/index.js";
|
|
2
2
|
import type { TerminalComponentPort, TerminalInputListenerResult, TerminalInputSurfaceKind, TerminalOverlayHandle, TerminalPointerSurface } from "../../contracts/presentation/index.js";
|
|
3
|
+
import { SessionSelectors } from "./session-selectors.js";
|
|
3
4
|
import type { OwnedUiCommandResult, OwnedUiSessionBackend, OwnedUiSessionViewModel, OwnedUiThinkingLevel, OwnedUiWorkflowRequest } from "../../contracts/owned-ui/index.js";
|
|
4
|
-
import type { OwnedUiShellHotkeysPresentation
|
|
5
|
+
import type { OwnedUiShellHotkeysPresentation } from "../../contracts/owned-ui/index.js";
|
|
5
6
|
import type { TerminalDamageDecision, TerminalRuntimePort } from "../../contracts/presentation/index.js";
|
|
6
7
|
import { OwnedUiTerminalHost, type OwnedUiHostedPresenter, type OwnedUiPresenterRelease } from "./shell-host.js";
|
|
7
8
|
import { OwnedUiSessionShellRoot, type OwnedUiSessionShellOptions, type PinnedLayoutPart } from "./session-shell-root.js";
|
|
@@ -15,6 +16,7 @@ export { formatSessionResumeCommand, quoteCommandArgument, type SessionResumeCom
|
|
|
15
16
|
export declare class OwnedUiSessionPresenter implements OwnedUiHostedPresenter {
|
|
16
17
|
#private;
|
|
17
18
|
readonly backend: OwnedUiSessionBackend;
|
|
19
|
+
readonly selectors: SessionSelectors;
|
|
18
20
|
readonly root: OwnedUiSessionShellRoot;
|
|
19
21
|
constructor(host: OwnedUiTerminalHost, options: OwnedUiSessionShellOptions);
|
|
20
22
|
view(): OwnedUiSessionViewModel;
|
|
@@ -30,41 +32,19 @@ export declare class OwnedUiSessionPresenter implements OwnedUiHostedPresenter {
|
|
|
30
32
|
activated(): void;
|
|
31
33
|
handleViewportInput(data: string): TerminalInputListenerResult | undefined;
|
|
32
34
|
start(): void;
|
|
33
|
-
onView(listener: (view: OwnedUiSessionViewModel) => void): () => void;
|
|
34
35
|
waitUntilStopped(): Promise<void>;
|
|
35
36
|
submit(text: string): Promise<OwnedUiCommandResult>;
|
|
36
37
|
clearOrExit(now?: number): Promise<OwnedUiCommandResult>;
|
|
37
38
|
interrupt(now?: number): Promise<OwnedUiCommandResult>;
|
|
38
39
|
abort(): Promise<OwnedUiCommandResult>;
|
|
39
|
-
retry(): Promise<OwnedUiCommandResult>;
|
|
40
|
-
compact(): Promise<OwnedUiCommandResult>;
|
|
41
|
-
newSession(): Promise<OwnedUiCommandResult>;
|
|
42
|
-
resumeSession(sessionPath: string): Promise<OwnedUiCommandResult>;
|
|
43
|
-
setModel(providerId: string, modelId: string): Promise<OwnedUiCommandResult>;
|
|
44
40
|
setThinkingLevel(thinkingLevel: OwnedUiThinkingLevel): Promise<OwnedUiCommandResult>;
|
|
45
41
|
cycleThinkingLevel(): Promise<OwnedUiCommandResult>;
|
|
46
42
|
cycleModel(direction: "forward" | "backward"): Promise<OwnedUiCommandResult>;
|
|
47
43
|
queueFollowUp(): Promise<OwnedUiCommandResult>;
|
|
48
44
|
restoreQueuedInput(): void;
|
|
49
45
|
showSelector(title: string, options: readonly OwnedUiShellSelectorOption[], onSelect: (id: string) => void, onCancel?: () => void): TerminalOverlayHandle;
|
|
50
|
-
showThinkingSelector(): Promise<void>;
|
|
51
|
-
/** The Skills dialog: a replacement input like the model selector, applying the chosen skill through the prompt path. */
|
|
52
|
-
showSkillsSelector(skills?: readonly OwnedUiShellSkillSummary[]): void;
|
|
53
|
-
showModelSelector(initialSearchInput?: string): void;
|
|
54
|
-
showForkSelector(): void;
|
|
55
|
-
showLogoutSelector(): Promise<void>;
|
|
56
|
-
showLoginMethodSelector(providerReference: string): void;
|
|
57
|
-
showTreeSelector(initialSelectedId?: string): Promise<void>;
|
|
58
|
-
showLoginAuthTypeSelector(): void;
|
|
59
|
-
showLoginProviderSelector(authType?: "oauth" | "api_key", initialSearchInput?: string): void;
|
|
60
|
-
showSessionSelector(): Promise<void>;
|
|
61
|
-
showSettingsSelector(): void;
|
|
62
46
|
shutdown(): Promise<OwnedUiCommandResult>;
|
|
63
47
|
runWorkflow(request: OwnedUiWorkflowRequest): Promise<OwnedUiCommandResult>;
|
|
64
|
-
showTrustSelector(): void;
|
|
65
|
-
showScopedModelsSelector(): void;
|
|
66
|
-
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
67
|
-
showModelsDialog(initialQuery?: string): void;
|
|
68
48
|
dispose(): Promise<void>;
|
|
69
49
|
release(terminal: {
|
|
70
50
|
readonly mode: "regular" | "fullscreen";
|