@timurproko/a1 0.1.8-dev.528 → 0.1.8-dev.536
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/session-shell-root.d.ts +1 -0
- package/dist/app/session-shell/session-shell-root.js +3 -1
- package/dist/app/session-shell/session-shell.d.ts +1 -1
- package/dist/app/session-shell/session-shell.js +10 -4
- package/dist/composition/owned-ui.js +4 -3
- package/dist/composition/settings-route-host.d.ts +5 -9
- package/dist/composition/settings-route-host.js +2 -2
- package/dist/contracts/owned-ui/model.d.ts +4 -0
- package/dist/contracts/owned-ui/validation.js +25 -0
- package/dist/features/owned-ui/index.d.ts +1 -1
- package/dist/features/owned-ui/reference-screen-app.d.ts +9 -3
- package/dist/features/owned-ui/reference-screen-app.js +68 -20
- package/dist/features/owned-ui/settings-app.js +69 -24
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/integrations/pi/components/index.d.ts +3 -1
- package/dist/integrations/pi/components/index.js +2 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.d.ts +9 -1
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -9
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +2 -2
- package/dist/integrations/pi/components/shell-hotkey-sections.d.ts +7 -0
- package/dist/integrations/pi/components/shell-hotkey-sections.js +29 -0
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +1 -0
- package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +0 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +1 -7
- package/dist/integrations/pi/components/thinking-selector-dialog.d.ts +8 -0
- package/dist/integrations/pi/components/thinking-selector-dialog.js +22 -0
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +1 -1
- package/dist/integrations/pi/components/upstream/assets/earendil-image.json +2 -2
- package/dist/integrations/pi/components/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/daxnuts.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/daxnuts.js +1 -1
- package/dist/integrations/pi/components/upstream/components/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +7 -2
- package/dist/integrations/pi/components/upstream/components/mermaid.js +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/owned-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/session-footer.js +22 -11
- package/dist/integrations/pi/components/upstream/components/session-selector-search.js +1 -1
- package/dist/integrations/pi/components/upstream/components/session-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/status-indicator.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +33 -0
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +140 -0
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +8 -1
- package/dist/integrations/pi/components/upstream/components/trust-selector.js +1 -1
- package/dist/integrations/pi/components/upstream/external-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/editor-core.js +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/kill-ring.js +1 -1
- package/dist/integrations/pi/components/upstream/history/printable-key.js +1 -1
- package/dist/integrations/pi/components/upstream/history/text-helpers.js +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/history/undo-stack.js +1 -1
- package/dist/integrations/pi/components/upstream/history/word-navigation.js +1 -1
- package/dist/integrations/pi/components/upstream/model-search.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme-controller.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
- package/dist/integrations/pi/engine/adapter.js +1 -0
- package/dist/integrations/pi/engine/repository-pr.d.ts +8 -0
- package/dist/integrations/pi/engine/repository-pr.js +62 -0
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/session-runtime.d.ts +5 -0
- package/dist/integrations/pi/engine/session-runtime.js +60 -1
- package/dist/integrations/pi/engine/workflow-support.js +3 -1
- package/dist/integrations/pi/engine/workflows.d.ts +1 -1
- package/dist/integrations/pi/engine/workflows.js +4 -2
- package/dist/integrations/pi/startup-public.js +63 -56
- package/dist/integrations/pi/startup-public.manifest.json +200 -169
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +1 -1
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +1 -1
- 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/product-identity.d.ts +1 -1
- package/dist/product-identity.js +1 -1
- package/dist/product-identity.json +1 -0
- package/dist/runtime-payload-inventory.json +2948 -2646
- package/dist/ui/components/index.d.ts +1 -1
- package/dist/ui/components/list-block.d.ts +10 -6
- package/dist/ui/components/list-block.js +28 -15
- package/dist/ui/components/list-view.d.ts +1 -1
- package/dist/ui/components/list-view.js +4 -2
- package/dist/ui/components/mouse.js +4 -2
- package/dist/ui/components/theme.d.ts +1 -5
- package/dist/ui/components/theme.js +0 -4
- package/dist/ui/components/value-menu.d.ts +3 -1
- package/dist/ui/components/value-menu.js +13 -5
- package/docs/local-worktree-cleanup.md +1 -1
- package/package.json +3 -3
|
@@ -265,6 +265,7 @@ export declare class OwnedUiSessionShellRoot implements PiTuiComponentPort {
|
|
|
265
265
|
readonly dockOnly: number;
|
|
266
266
|
};
|
|
267
267
|
transcriptRenderCount(): number;
|
|
268
|
+
setFooterLevel(visible: boolean): void;
|
|
268
269
|
setInputSurface(component: PiShellComponentPort | null, disposePrevious?: boolean, coordination?: Exclude<PiTuiInputSurfaceKind, "editor">): void;
|
|
269
270
|
handleInput(data: string): void;
|
|
270
271
|
invalidate(): void;
|
|
@@ -51,6 +51,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
51
51
|
#componentRuntime;
|
|
52
52
|
#toolsExpanded = false;
|
|
53
53
|
#thinkingVisible = true;
|
|
54
|
+
#footerLevel = true;
|
|
54
55
|
#mermaidRenderingMode = "off";
|
|
55
56
|
#showImages = true;
|
|
56
57
|
#imageWidthCells = 80;
|
|
@@ -107,7 +108,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
107
108
|
this.resources = createPiShellLoadedResources(startup.resources ?? [], startup.expanded ?? false);
|
|
108
109
|
this.#status = createPiShellStatus(view, progressStatusText, handlers);
|
|
109
110
|
this.#status.setProgressPresentation(this.#customViewport ? "custom-viewport" : "pinned");
|
|
110
|
-
this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd, this.#customViewport ? "a1" : "pi");
|
|
111
|
+
this.#footer = createPiShellFooter(this.#viewWithExtensionStatuses(view), cwd, this.#customViewport ? "a1" : "pi", () => this.#footerLevel);
|
|
111
112
|
this.#queued = createPiQueuedInputStatus(view.editor.queuedSubmissions, this.#customViewport ? "custom-viewport" : "pinned");
|
|
112
113
|
this.editor = createPiShellEditor({
|
|
113
114
|
...handlers,
|
|
@@ -970,6 +971,7 @@ export class OwnedUiSessionShellRoot {
|
|
|
970
971
|
transcriptRenderCount() {
|
|
971
972
|
return this.#transcriptBlockRenders;
|
|
972
973
|
}
|
|
974
|
+
setFooterLevel(visible) { this.#footerLevel = visible; }
|
|
973
975
|
setInputSurface(component, disposePrevious = true, coordination = "owned") {
|
|
974
976
|
const next = component ?? this.editor;
|
|
975
977
|
const nextCoordination = next === this.editor ? "editor" : coordination;
|
|
@@ -36,7 +36,7 @@ export declare class OwnedUiSessionShell {
|
|
|
36
36
|
queueFollowUp(): Promise<AdapterCommandResult>;
|
|
37
37
|
restoreQueuedInput(): void;
|
|
38
38
|
showSelector(title: string, options: readonly PiShellSelectorOption[], onSelect: (id: string) => void, onCancel?: () => void): PiTuiOverlayHandle;
|
|
39
|
-
showThinkingSelector(): void
|
|
39
|
+
showThinkingSelector(): Promise<void>;
|
|
40
40
|
/** The Skills dialog: a replacement input like the model selector, applying the chosen skill through the prompt path. */
|
|
41
41
|
showSkillsSelector(skills?: readonly PiShellSkillSummary[]): void;
|
|
42
42
|
showModelSelector(initialSearchInput?: string): void;
|
|
@@ -14,7 +14,7 @@ import { createPiExtensionUiBridge } from "../../integrations/pi/components/shel
|
|
|
14
14
|
import { createPiShellEditor } from "../../integrations/pi/components/shell-editor-autocomplete.js";
|
|
15
15
|
import { SKILLS_COMMAND_NAME, findSkillByArgument, rewriteSkillsTunnelSubmission, skillPrompt, skillsFromCommands, } from "../../integrations/pi/components/skills-command.js";
|
|
16
16
|
import { createPiQueuedInputStatus, createPiShellFooter, createPiShellHeader, createPiShellLoadedResources, createPiShellStatus, } from "../../integrations/pi/components/shell-footer-status.js";
|
|
17
|
-
import { createPiShellArmin, createPiShellAuthProviderSelector, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellExtensionSelector, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellSkillsSelector,
|
|
17
|
+
import { createPiShellArmin, createPiShellAuthProviderSelector, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellExtensionSelector, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellSkillsSelector, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, } from "../../integrations/pi/components/shell-selectors-dialogs.js";
|
|
18
18
|
import { createPiShellChangelog, createPiShellHotkeys, createPiShellSessionInfo, renderPiShellStatusText, } from "../../integrations/pi/components/shell-presenters-info.js";
|
|
19
19
|
import { CHANGELOG_ROUTE } from "../../features/owned-ui/reference-routes.js";
|
|
20
20
|
import { createPiShellTranscriptComponent, renderPiShellPackageUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellTranscriptBlock, } from "../../integrations/pi/components/shell-presenters-transcript.js";
|
|
@@ -839,9 +839,10 @@ export class OwnedUiSessionShell {
|
|
|
839
839
|
this.#dialogHandle = handle;
|
|
840
840
|
return handle;
|
|
841
841
|
}
|
|
842
|
-
showThinkingSelector() {
|
|
842
|
+
async showThinkingSelector() {
|
|
843
843
|
const snapshot = this.backend.pinnedSettingsSnapshot();
|
|
844
844
|
const close = () => {
|
|
845
|
+
this.root.setFooterLevel(true);
|
|
845
846
|
this.root.setInputSurface(null);
|
|
846
847
|
this.runtime.requestRender();
|
|
847
848
|
};
|
|
@@ -849,7 +850,12 @@ export class OwnedUiSessionShell {
|
|
|
849
850
|
close();
|
|
850
851
|
void this.runWorkflow({ command: "thinking", argument: "", selection: level, ...(persist ? { persist: true } : {}) });
|
|
851
852
|
};
|
|
852
|
-
const
|
|
853
|
+
const { createPiShellThinkingSelector } = await import("../../integrations/pi/components/thinking-selector-dialog.js");
|
|
854
|
+
const component = createPiShellThinkingSelector(snapshot.thinkingLevel, snapshot.availableThinkingLevels, level => select(level, false), close, level => select(level, true), snapshot.defaultThinkingLevel, this.#customViewport ? {
|
|
855
|
+
profile: "bare",
|
|
856
|
+
cycleBinding: this.root.editor.keybindingConfig()["app.thinking.cycle"] ?? [],
|
|
857
|
+
} : undefined);
|
|
858
|
+
this.root.setFooterLevel(false);
|
|
853
859
|
this.root.setInputSurface(component);
|
|
854
860
|
this.runtime.requestRender();
|
|
855
861
|
}
|
|
@@ -1188,7 +1194,7 @@ export class OwnedUiSessionShell {
|
|
|
1188
1194
|
return { outcome: "completed", diagnostic: null };
|
|
1189
1195
|
}
|
|
1190
1196
|
if (request.command === "thinking" && request.selection === undefined && request.argument.trim().length === 0) {
|
|
1191
|
-
this.showThinkingSelector();
|
|
1197
|
+
await this.showThinkingSelector();
|
|
1192
1198
|
return { outcome: "completed", diagnostic: null };
|
|
1193
1199
|
}
|
|
1194
1200
|
if (request.command === "trust" && request.selection === undefined && request.confirmed === undefined) {
|
|
@@ -12,7 +12,7 @@ import { OwnedUiSessionShell } from "../app/session-shell/session-shell.js";
|
|
|
12
12
|
import { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
13
13
|
import { createPiTerminalBridge } from "../integrations/pi/tui-runtime/presentation-adapter.js";
|
|
14
14
|
import { createOwnedRouteHost } from "./settings-route-host.js";
|
|
15
|
-
import { renderPiShellChangelogLines
|
|
15
|
+
import { renderPiShellChangelogLines } from "../integrations/pi/components/shell-presenters-info.js";
|
|
16
16
|
import { readPinnedCommandChangelog } from "../integrations/pi/engine/changelog.js";
|
|
17
17
|
export async function composeOwnedUiApplication(options = {}) {
|
|
18
18
|
return (await composeOwnedUi(options)).application;
|
|
@@ -47,11 +47,12 @@ export async function composeOwnedUi(options = {}) {
|
|
|
47
47
|
const references = {
|
|
48
48
|
changelog: async (input) => {
|
|
49
49
|
const markdown = input?.document ?? await readPinnedCommandChangelog();
|
|
50
|
-
return width => renderPiShellChangelogLines(markdown, width);
|
|
50
|
+
return { rows: width => renderPiShellChangelogLines(markdown, width) };
|
|
51
51
|
},
|
|
52
52
|
hotkeys: async () => {
|
|
53
53
|
const presentation = shell.hotkeysPresentation();
|
|
54
|
-
|
|
54
|
+
const { renderPiShellHotkeySections } = await import("../integrations/pi/components/shell-hotkey-sections.js");
|
|
55
|
+
return { sections: width => renderPiShellHotkeySections(presentation, width) };
|
|
55
56
|
},
|
|
56
57
|
};
|
|
57
58
|
const routeHost = settings === null || !ownedSurfaces ? null : createOwnedRouteHost(settings, references);
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
+
import type { ReferenceDocumentProvider } from "../features/owned-ui/reference-screen-app.js";
|
|
1
2
|
import type { OwnedSettingsManager } from "../ui/settings/manager.js";
|
|
2
3
|
import type { UiRouteHost, UiRouteInput } from "../ui/apps/contracts.js";
|
|
3
4
|
/** Styled document rows for one content width. */
|
|
4
|
-
export type OwnedReferenceRows =
|
|
5
|
-
/**
|
|
6
|
-
* The documents the reference routes present, supplied by the composition so the
|
|
7
|
-
* route host never reads the changelog or the shell's keybindings itself.
|
|
8
|
-
*/
|
|
5
|
+
export type OwnedReferenceRows = NonNullable<ReferenceDocumentProvider["rows"]>;
|
|
6
|
+
/** Documents supplied by composition so the route host never reads shell data itself. */
|
|
9
7
|
export interface OwnedReferenceProviders {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/** The shell's keyboard shortcuts as they stand when the screen opens. */
|
|
13
|
-
hotkeys(): Promise<OwnedReferenceRows>;
|
|
8
|
+
changelog(input?: UiRouteInput): Promise<ReferenceDocumentProvider>;
|
|
9
|
+
hotkeys(): Promise<ReferenceDocumentProvider>;
|
|
14
10
|
}
|
|
15
11
|
/**
|
|
16
12
|
* Declares the A1-owned settings route, and the changelog and hotkeys reference
|
|
@@ -72,11 +72,11 @@ async function loadSettingsSurface(settings) {
|
|
|
72
72
|
async function loadReferenceSurface(settings, id, route, title, document) {
|
|
73
73
|
// Rationale: the app module and the document load together, so a document that fails
|
|
74
74
|
// to render is reported by the placeholder rather than by a screen that never fills.
|
|
75
|
-
const [{ ReferenceScreenApp },
|
|
75
|
+
const [{ ReferenceScreenApp }, content] = await Promise.all([import("../features/owned-ui/reference-screen-app.js"), document]);
|
|
76
76
|
return hostApp(id, route, () => new ReferenceScreenApp({
|
|
77
77
|
id,
|
|
78
78
|
title,
|
|
79
|
-
document:
|
|
79
|
+
document: content,
|
|
80
80
|
scrollSettings: () => ({
|
|
81
81
|
scrollbarAppearance: settings.value("scrollbarAppearance"),
|
|
82
82
|
scrollbarStyle: settings.value("scrollbarStyle"),
|
|
@@ -115,6 +115,10 @@ export interface OwnedUiUsageView {
|
|
|
115
115
|
}
|
|
116
116
|
export interface OwnedUiFooterView {
|
|
117
117
|
readonly branch: string | null;
|
|
118
|
+
readonly pullRequest?: {
|
|
119
|
+
readonly number: number;
|
|
120
|
+
readonly url: string;
|
|
121
|
+
} | null;
|
|
118
122
|
readonly sessionName: string | null;
|
|
119
123
|
readonly availableProviderCount: number;
|
|
120
124
|
readonly extensionStatuses: readonly (readonly [string, string])[];
|
|
@@ -396,6 +396,13 @@ export function assertOwnedUiStatusView(status) {
|
|
|
396
396
|
}
|
|
397
397
|
if (status.footer !== undefined) {
|
|
398
398
|
assertOptionalText(status.footer.branch, "owned-UI footer branch", MAX_LABEL_LENGTH);
|
|
399
|
+
if (status.footer.pullRequest !== undefined && status.footer.pullRequest !== null) {
|
|
400
|
+
const pullRequest = status.footer.pullRequest;
|
|
401
|
+
assertIntegerInRange(pullRequest.number, 1, Number.MAX_SAFE_INTEGER, "owned-UI footer pull request number");
|
|
402
|
+
if (!isCanonicalGitHubPullRequestUrl(pullRequest.url, pullRequest.number)) {
|
|
403
|
+
throw new TypeError("owned-UI footer pull request URL is invalid");
|
|
404
|
+
}
|
|
405
|
+
}
|
|
399
406
|
assertOptionalText(status.footer.sessionName, "owned-UI footer session name", MAX_LABEL_LENGTH);
|
|
400
407
|
assertIntegerInRange(status.footer.availableProviderCount, 0, 1_000, "owned-UI footer provider count");
|
|
401
408
|
assertCollection(status.footer.extensionStatuses, "owned-UI footer extension statuses", MAX_BADGES);
|
|
@@ -422,6 +429,24 @@ export function assertOwnedUiDiagnostics(diagnostic) {
|
|
|
422
429
|
if (typeof diagnostic.recoverable !== "boolean")
|
|
423
430
|
throw new TypeError("owned-UI diagnostic recoverability is invalid");
|
|
424
431
|
}
|
|
432
|
+
function isCanonicalGitHubPullRequestUrl(value, number) {
|
|
433
|
+
if (typeof value !== "string" || value.length > MAX_LABEL_LENGTH)
|
|
434
|
+
return false;
|
|
435
|
+
try {
|
|
436
|
+
const url = new URL(value);
|
|
437
|
+
return url.protocol === "https:"
|
|
438
|
+
&& url.hostname.toLowerCase() === "github.com"
|
|
439
|
+
&& url.username === ""
|
|
440
|
+
&& url.password === ""
|
|
441
|
+
&& url.port === ""
|
|
442
|
+
&& url.search === ""
|
|
443
|
+
&& url.hash === ""
|
|
444
|
+
&& new RegExp(`^/[^/]+/[^/]+/pull/${number}/?$`, "u").test(url.pathname);
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
425
450
|
function assertOwnedUiModelInfo(model) {
|
|
426
451
|
assertId(model.providerId, "owned-UI provider id");
|
|
427
452
|
assertId(model.modelId, "owned-UI model id");
|
|
@@ -5,5 +5,5 @@ export type { ConsoleProjectTrustPromptOptions, OwnedProjectTrustPrompt, OwnedPr
|
|
|
5
5
|
export { createConsoleSessionForkPrompt } from "./session-fork-prompt.js";
|
|
6
6
|
export { SETTINGS_APP_ID, SETTINGS_ROUTE, SETTINGS_SHORTCUTS, SettingsApp } from "./settings-app.js";
|
|
7
7
|
export { REFERENCE_SCREEN_SHORTCUTS, ReferenceScreenApp } from "./reference-screen-app.js";
|
|
8
|
-
export type { ReferenceDocumentProvider, ReferenceScreenOptions } from "./reference-screen-app.js";
|
|
8
|
+
export type { ReferenceDocumentProvider, ReferenceDocumentSection, ReferenceScreenOptions } from "./reference-screen-app.js";
|
|
9
9
|
export { CHANGELOG_APP_ID, CHANGELOG_ROUTE, CHANGELOG_TITLE, HOTKEYS_APP_ID, HOTKEYS_ROUTE, HOTKEYS_TITLE, } from "./reference-routes.js";
|
|
@@ -4,10 +4,16 @@ import { ShortcutRegistry, type PaneInputResult, type PaneMouseEvent, type PaneR
|
|
|
4
4
|
type Action = "up" | "down" | "page-up" | "page-down" | "first" | "last" | "close";
|
|
5
5
|
export declare const REFERENCE_SCREEN_SHORTCUTS: ShortcutRegistry<Action>;
|
|
6
6
|
/** Rows of a document already styled and wrapped for one content width. */
|
|
7
|
+
export interface ReferenceDocumentSection {
|
|
8
|
+
readonly title: string;
|
|
9
|
+
readonly rows: readonly string[];
|
|
10
|
+
}
|
|
7
11
|
export interface ReferenceDocumentProvider {
|
|
8
|
-
/**
|
|
9
|
-
rows(width: number)
|
|
10
|
-
/**
|
|
12
|
+
/** Flat rows for this width, or null while the document is not available yet. */
|
|
13
|
+
readonly rows?: (width: number) => readonly string[] | null;
|
|
14
|
+
/** Structured groups opt into shared Settings-style headers and pinning. */
|
|
15
|
+
readonly sections?: (width: number) => readonly ReferenceDocumentSection[] | null;
|
|
16
|
+
/** Settles once the selected content provider answers; absent when available at once. */
|
|
11
17
|
readonly ready?: Promise<void>;
|
|
12
18
|
}
|
|
13
19
|
export interface ReferenceScreenOptions {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GLOBAL_SCOPE, PLAIN_THEME, RAIL_COLUMNS, ShortcutRegistry, ScrollbarRails, assertNoShortcutConflicts, displayWidth, padToWidth, scrollForTrackPage, scrollbarGeometry, scrollbarPresentation, scrollbarWheelRows, truncateToWidth, withScrollbarRail, } from "../../ui/components/index.js";
|
|
1
|
+
import { GLOBAL_SCOPE, PLAIN_THEME, RAIL_COLUMNS, ShortcutRegistry, ScrollbarRails, assertNoShortcutConflicts, displayWidth, layoutList, padToWidth, renderGroupHeader, scrollForTrackPage, scrollbarGeometry, scrollbarPresentation, scrollbarWheelRows, truncateToWidth, withScrollbarRail, } from "../../ui/components/index.js";
|
|
2
2
|
const SCOPE = "reference-screen";
|
|
3
3
|
/** Rows above the document: the top rule. */
|
|
4
4
|
const HEADER_ROWS = 1;
|
|
@@ -91,16 +91,38 @@ export class ReferenceScreenApp {
|
|
|
91
91
|
const contentWidth = reservesRail ? Math.max(0, rect.width - RAIL_COLUMNS) : rect.width;
|
|
92
92
|
const bodyHeight = Math.max(0, rect.height - HEADER_ROWS - FOOTER_ROWS);
|
|
93
93
|
this.#bodyHeight = bodyHeight;
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
94
|
+
const content = this.#content(contentWidth, theme);
|
|
95
|
+
const body = [];
|
|
96
|
+
let contentLength;
|
|
97
|
+
let viewportLength = bodyHeight;
|
|
98
|
+
if (content.kind === "sections") {
|
|
99
|
+
const layout = layoutList(content.rows, bodyHeight, this.#scroll, { topPadding: false });
|
|
100
|
+
this.#scroll = layout.scroll;
|
|
101
|
+
contentLength = content.rows.length;
|
|
102
|
+
viewportLength = layout.visible;
|
|
103
|
+
if (layout.stickyHeader !== undefined)
|
|
104
|
+
body.push(renderGroupHeader(layout.stickyHeader, contentWidth, theme));
|
|
105
|
+
for (const index of layout.rowIndexes)
|
|
106
|
+
body.push(this.#renderSectionRow(content.rows[index], contentWidth, theme));
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
contentLength = content.rows.length;
|
|
110
|
+
const maxScroll = Math.max(0, content.rows.length - bodyHeight);
|
|
111
|
+
this.#scroll = Math.min(Math.max(0, this.#scroll), maxScroll);
|
|
112
|
+
for (let index = this.#scroll; index < this.#scroll + bodyHeight; index++) {
|
|
113
|
+
const row = content.rows[index] ?? "";
|
|
114
|
+
body.push(displayWidth(row) > contentWidth ? truncateToWidth(row, contentWidth) : row);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
while (body.length < bodyHeight)
|
|
118
|
+
body.push("");
|
|
97
119
|
const now = Date.now();
|
|
98
120
|
// Rationale: every way of scrolling ends in this frame, so a moved document is noticed here
|
|
99
121
|
// once rather than at each wheel, drag, and key branch.
|
|
100
122
|
if (this.#renderedScroll !== undefined && this.#renderedScroll !== this.#scroll)
|
|
101
123
|
this.#noteScrollActivity(host, now);
|
|
102
124
|
this.#renderedScroll = this.#scroll;
|
|
103
|
-
const geometry = scrollbarGeometry({ contentLength
|
|
125
|
+
const geometry = scrollbarGeometry({ contentLength, viewportHeight: viewportLength, scroll: this.#scroll, trackHeight: bodyHeight });
|
|
104
126
|
const presentation = scrollbarPresentation({
|
|
105
127
|
geometry,
|
|
106
128
|
appearance: settings.scrollbarAppearance,
|
|
@@ -111,14 +133,9 @@ export class ReferenceScreenApp {
|
|
|
111
133
|
now,
|
|
112
134
|
});
|
|
113
135
|
this.#railFrame = reservesRail && geometry !== null
|
|
114
|
-
? { rail: { key: this.id, column: rect.width, rowStart: HEADER_ROWS, trackHeight: geometry.trackHeight }, geometry, page:
|
|
136
|
+
? { rail: { key: this.id, column: rect.width, rowStart: HEADER_ROWS, trackHeight: geometry.trackHeight }, geometry, page: viewportLength }
|
|
115
137
|
: null;
|
|
116
|
-
const
|
|
117
|
-
for (let index = this.#scroll; index < this.#scroll + bodyHeight; index++) {
|
|
118
|
-
const row = rows[index] ?? "";
|
|
119
|
-
body.push(displayWidth(row) > contentWidth ? truncateToWidth(row, contentWidth) : row);
|
|
120
|
-
}
|
|
121
|
-
const withRail = withScrollbarRail(body, geometry, contentWidth, theme, { presentation });
|
|
138
|
+
const withRail = withScrollbarRail(body.slice(0, bodyHeight), geometry, contentWidth, theme, { presentation });
|
|
122
139
|
const hint = this.#interruptArmed ? "press ctrl+c again to exit a1" : REFERENCE_SCREEN_SHORTCUTS.hint(SCOPE, HINT_SEPARATOR);
|
|
123
140
|
// Compatibility: the v2 reference screen frames its document between two border-coloured rules.
|
|
124
141
|
const rule = theme.fg("border", "─".repeat(rect.width));
|
|
@@ -197,19 +214,50 @@ export class ReferenceScreenApp {
|
|
|
197
214
|
return { owned: true, changed: true };
|
|
198
215
|
}
|
|
199
216
|
// Invariant: the title is the first document row, as in v2, so it scrolls with the document.
|
|
200
|
-
#
|
|
217
|
+
#content(width, theme) {
|
|
201
218
|
// Compatibility: one leading space, so the title lines up with the padded Markdown rows as in v2.
|
|
202
219
|
const title = ` ${theme.bold(theme.fg("accent", this.#title))}`;
|
|
203
220
|
if (this.#failure !== null)
|
|
204
|
-
return [title, "", this.#failure];
|
|
221
|
+
return { kind: "flat", rows: [title, "", this.#failure] };
|
|
205
222
|
const cached = this.#cached;
|
|
206
223
|
if (cached !== null && cached.width === width)
|
|
207
|
-
return
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
210
|
-
return [title, "", LOADING_NOTICE];
|
|
211
|
-
|
|
212
|
-
|
|
224
|
+
return this.#withTitle(cached.content, title);
|
|
225
|
+
const sections = this.#document.sections?.(width);
|
|
226
|
+
if (sections === null)
|
|
227
|
+
return { kind: "flat", rows: [title, "", LOADING_NOTICE] };
|
|
228
|
+
if (sections !== undefined) {
|
|
229
|
+
const rows = [];
|
|
230
|
+
sections.forEach((section, sectionIndex) => {
|
|
231
|
+
if (sectionIndex > 0)
|
|
232
|
+
rows.push({ kind: "spacer" });
|
|
233
|
+
const group = `section-${sectionIndex}`;
|
|
234
|
+
rows.push({ kind: "group", group, title: section.title });
|
|
235
|
+
for (const row of section.rows)
|
|
236
|
+
rows.push({ kind: "note", group, text: row });
|
|
237
|
+
});
|
|
238
|
+
const content = { kind: "sections", rows };
|
|
239
|
+
this.#cached = { width, content };
|
|
240
|
+
return this.#withTitle(content, title);
|
|
241
|
+
}
|
|
242
|
+
const flat = this.#document.rows?.(width);
|
|
243
|
+
if (flat === null)
|
|
244
|
+
return { kind: "flat", rows: [title, "", LOADING_NOTICE] };
|
|
245
|
+
const content = { kind: "flat", rows: flat ?? [] };
|
|
246
|
+
this.#cached = { width, content };
|
|
247
|
+
return this.#withTitle(content, title);
|
|
248
|
+
}
|
|
249
|
+
#withTitle(content, title) {
|
|
250
|
+
if (content.kind === "flat")
|
|
251
|
+
return { kind: "flat", rows: [title, ...content.rows] };
|
|
252
|
+
return { kind: "sections", rows: [{ kind: "note", group: "", text: title }, { kind: "spacer" }, ...content.rows] };
|
|
253
|
+
}
|
|
254
|
+
#renderSectionRow(row, width, theme) {
|
|
255
|
+
if (row === undefined || row.kind === "spacer")
|
|
256
|
+
return "";
|
|
257
|
+
if (row.kind === "group")
|
|
258
|
+
return renderGroupHeader(row.title, width, theme);
|
|
259
|
+
const text = row.kind === "note" ? row.text : row.value;
|
|
260
|
+
return displayWidth(text) > width ? truncateToWidth(text, width) : text;
|
|
213
261
|
}
|
|
214
262
|
#scrollBy(distance) {
|
|
215
263
|
// Invariant: the upper clamp happens at render, where the body height and row count are known.
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import { GLOBAL_SCOPE, LineInput, PLAIN_THEME, ShortcutRegistry, assertNoShortcutConflicts, blockJumpTarget, dialogValueColumn, numericValues, RAIL_COLUMNS, renderDialogPanel, renderEmptyState, renderGroupHeader, renderInputRow, renderListRow, renderNote,
|
|
1
|
+
import { GLOBAL_SCOPE, LineInput, PLAIN_THEME, ShortcutRegistry, assertNoShortcutConflicts, blockJumpTarget, dialogValueColumn, numericValues, RAIL_COLUMNS, renderDialogPanel, renderEmptyState, renderGroupHeader, renderInputRow, renderListRow, renderNote, statusText, dialogRowAt, menuRowAt, regionAt, renderValueMenu, withScrollbarRail, stepperEnds, steppedValue, truncateToWidth, valueColumnFor, valueMenuFrame, blockRowSpan, displayWidth, handleLineInputKey, humanizeLabel, humanizeTitle, indexOfKey, isThumbRow, layoutList, moveSelection, rowKey, scrollForSelection, scrollForTrackPage, scrollbarGeometry, scrollbarPresentation, ScrollbarRails, scrollbarWheelRows, selectableIndexes, } from "../../ui/components/index.js";
|
|
2
2
|
import { SETTINGS_APP_ID, SETTINGS_ROUTE } from "./settings-route.js";
|
|
3
3
|
export { SETTINGS_APP_ID, SETTINGS_ROUTE } from "./settings-route.js";
|
|
4
4
|
const SCOPE = SETTINGS_APP_ID;
|
|
5
|
+
const SETTINGS_TOP_RULE_ROWS = 1;
|
|
6
|
+
const SETTINGS_TITLE_ROWS = 1;
|
|
7
|
+
const SETTINGS_FOOTER_DIVIDER_ROWS = 1;
|
|
8
|
+
const SETTINGS_SEARCH_INPUT_ROWS = 3;
|
|
9
|
+
const SETTINGS_STATUS_ROWS = 1;
|
|
10
|
+
const SETTINGS_CONTENT_INSET = 1;
|
|
5
11
|
/** The panel a setting with parts opens: its own keys, its own hint. */
|
|
6
12
|
const DIALOG_SCOPE = `${SETTINGS_APP_ID}-parts`;
|
|
7
|
-
const SCROLLBAR_TOP_INSET =
|
|
13
|
+
const SCROLLBAR_TOP_INSET = 0;
|
|
8
14
|
/** Identity of the settings list rail in the shared rail state. */
|
|
9
15
|
const RAIL_KEY = "settings";
|
|
10
16
|
// Compatibility: the transcript rail stays lit this long after a scroll, and repaints just after.
|
|
@@ -72,13 +78,15 @@ export class SettingsApp {
|
|
|
72
78
|
#reveal;
|
|
73
79
|
#notice = null;
|
|
74
80
|
#filter = null;
|
|
81
|
+
#scrollBeforeFilter = null;
|
|
75
82
|
#menu = null;
|
|
76
83
|
#structured = null;
|
|
77
84
|
#interruptArmed = false;
|
|
78
85
|
// Invariant: pending values remain visible until the source reflects them.
|
|
79
86
|
#pending = new Map();
|
|
80
|
-
#footerHeight = 1;
|
|
81
87
|
#dialogValueColumn = 0;
|
|
88
|
+
#bodyTopForFrame = SETTINGS_TOP_RULE_ROWS + SETTINGS_TITLE_ROWS;
|
|
89
|
+
#bodyHeightForFrame = 0;
|
|
82
90
|
#panelTop = 0;
|
|
83
91
|
#panelTopForFrame = 0;
|
|
84
92
|
#hoverKey = null;
|
|
@@ -109,16 +117,30 @@ export class SettingsApp {
|
|
|
109
117
|
const rows = this.#rows();
|
|
110
118
|
const selected = indexOfKey(rows, this.#selectedKey);
|
|
111
119
|
const footer = this.#footerLines(rect.width, theme);
|
|
112
|
-
this.#
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
const dividerRows = this.#filter === null ? SETTINGS_FOOTER_DIVIDER_ROWS : 0;
|
|
121
|
+
const topRows = Math.min(SETTINGS_TOP_RULE_ROWS, rect.height);
|
|
122
|
+
const contentHeight = Math.max(0, rect.height - topRows - dividerRows - footer.length);
|
|
123
|
+
let titleRows = this.#scroll <= 0 ? Math.min(SETTINGS_TITLE_ROWS, contentHeight) : 0;
|
|
124
|
+
let bodyHeight = contentHeight - titleRows;
|
|
125
|
+
if (this.#selectionNeedsReveal && bodyHeight > 0) {
|
|
117
126
|
this.#scroll = scrollForSelection(rows, bodyHeight, this.#scroll, selected, this.#reveal);
|
|
118
127
|
this.#selectionNeedsReveal = false;
|
|
128
|
+
this.#reveal = undefined;
|
|
129
|
+
}
|
|
130
|
+
if (this.#scroll > 0 && titleRows > 0) {
|
|
131
|
+
titleRows = 0;
|
|
132
|
+
bodyHeight = contentHeight;
|
|
119
133
|
}
|
|
120
|
-
|
|
121
|
-
|
|
134
|
+
let layout = layoutList(rows, bodyHeight, this.#scroll);
|
|
135
|
+
if (layout.scroll === 0 && titleRows === 0) {
|
|
136
|
+
titleRows = Math.min(SETTINGS_TITLE_ROWS, contentHeight);
|
|
137
|
+
bodyHeight = contentHeight - titleRows;
|
|
138
|
+
layout = layoutList(rows, bodyHeight, 0);
|
|
139
|
+
}
|
|
140
|
+
this.#bodyTopForFrame = topRows + titleRows;
|
|
141
|
+
this.#bodyHeightForFrame = bodyHeight;
|
|
142
|
+
this.#panelTopForFrame = topRows + contentHeight + dividerRows;
|
|
143
|
+
this.#panelTop = this.#panelTopForFrame;
|
|
122
144
|
this.#scroll = layout.scroll;
|
|
123
145
|
const now = Date.now();
|
|
124
146
|
// Rationale: every way of scrolling ends in this frame, so a moved list is noticed here
|
|
@@ -136,7 +158,7 @@ export class SettingsApp {
|
|
|
136
158
|
contentLength: rows.length,
|
|
137
159
|
viewportHeight: layout.visible,
|
|
138
160
|
scroll: layout.scroll,
|
|
139
|
-
trackHeight: Math.max(0, bodyHeight - SCROLLBAR_TOP_INSET),
|
|
161
|
+
trackHeight: Math.max(0, titleRows + bodyHeight - SCROLLBAR_TOP_INSET),
|
|
140
162
|
});
|
|
141
163
|
const presentation = scrollbarPresentation({
|
|
142
164
|
geometry,
|
|
@@ -149,7 +171,7 @@ export class SettingsApp {
|
|
|
149
171
|
});
|
|
150
172
|
this.#railFrame = reservesRail && geometry !== null
|
|
151
173
|
? {
|
|
152
|
-
rail: { key: RAIL_KEY, column: rect.width, rowStart: SCROLLBAR_TOP_INSET, trackHeight: geometry.trackHeight },
|
|
174
|
+
rail: { key: RAIL_KEY, column: rect.width, rowStart: topRows + SCROLLBAR_TOP_INSET, trackHeight: geometry.trackHeight },
|
|
153
175
|
geometry,
|
|
154
176
|
page: layout.visible,
|
|
155
177
|
}
|
|
@@ -170,8 +192,8 @@ export class SettingsApp {
|
|
|
170
192
|
const view = this.#viewRow(row.value);
|
|
171
193
|
this.#frameRows.push({
|
|
172
194
|
key: view.key,
|
|
173
|
-
screenRow: body.length,
|
|
174
|
-
valueColumn,
|
|
195
|
+
screenRow: this.#bodyTopForFrame + body.length,
|
|
196
|
+
valueColumn: valueColumn + Math.min(SETTINGS_CONTENT_INSET, contentWidth),
|
|
175
197
|
valueWidth: displayWidth(view.value),
|
|
176
198
|
stepper: view.stepper !== undefined,
|
|
177
199
|
});
|
|
@@ -181,11 +203,15 @@ export class SettingsApp {
|
|
|
181
203
|
while (body.length < bodyHeight)
|
|
182
204
|
body.push("");
|
|
183
205
|
}
|
|
184
|
-
const
|
|
206
|
+
const title = truncateToWidth(` ${theme.bold(theme.fg("accent", "Settings"))}`, contentWidth);
|
|
207
|
+
const scrollingFrame = [...(titleRows === 0 ? [] : [title]), ...body.slice(0, bodyHeight)];
|
|
208
|
+
const withRail = withScrollbarRail(scrollingFrame, geometry, contentWidth, theme, {
|
|
185
209
|
topInset: SCROLLBAR_TOP_INSET,
|
|
186
210
|
presentation,
|
|
187
211
|
});
|
|
188
|
-
|
|
212
|
+
const rule = theme.fg("border", "─".repeat(Math.max(0, rect.width)));
|
|
213
|
+
const frame = this.#withMenu([rule, ...withRail, ...(dividerRows === 0 ? [] : [rule]), ...footer], selected, layout, valueColumn, theme, rect, reservesRail ? RAIL_COLUMNS : 0);
|
|
214
|
+
return frame.slice(0, rect.height).concat(Array(Math.max(0, rect.height - frame.length)).fill(""));
|
|
189
215
|
}
|
|
190
216
|
onInput(data, host) {
|
|
191
217
|
if (this.#structured !== null)
|
|
@@ -205,6 +231,7 @@ export class SettingsApp {
|
|
|
205
231
|
host.close();
|
|
206
232
|
return { consumed: true };
|
|
207
233
|
case "open-filter":
|
|
234
|
+
this.#scrollBeforeFilter = this.#scroll;
|
|
208
235
|
this.#filter = new LineInput("");
|
|
209
236
|
this.#notice = null;
|
|
210
237
|
return { consumed: true };
|
|
@@ -316,9 +343,15 @@ export class SettingsApp {
|
|
|
316
343
|
if (event.kind === "wheel-up" || event.kind === "wheel-down") {
|
|
317
344
|
// Invariant: the whole list pane owns wheel scrolling, including blank space beside
|
|
318
345
|
// short labels. It must not depend on finding an item under the pointer.
|
|
319
|
-
|
|
346
|
+
const screenRow = event.row - 1;
|
|
347
|
+
const wheelBottom = this.#filter === null
|
|
348
|
+
? this.#bodyTopForFrame + this.#bodyHeightForFrame
|
|
349
|
+
: this.#panelTopForFrame + SETTINGS_SEARCH_INPUT_ROWS + SETTINGS_STATUS_ROWS;
|
|
350
|
+
if (screenRow < 0 || screenRow >= wheelBottom)
|
|
320
351
|
return { consumed: false };
|
|
321
352
|
const distance = scrollbarWheelRows(this.#scrollbarSpeed());
|
|
353
|
+
if (this.#filter !== null)
|
|
354
|
+
this.#scrollBeforeFilter = null;
|
|
322
355
|
this.#scroll = Math.max(0, this.#scroll + (event.kind === "wheel-down" ? distance : -distance));
|
|
323
356
|
return { consumed: true };
|
|
324
357
|
}
|
|
@@ -520,6 +553,7 @@ export class SettingsApp {
|
|
|
520
553
|
// Rationale: the boundary chords jump through the results; plain Home and End stay with
|
|
521
554
|
// the search cursor, which the shared line input moves below.
|
|
522
555
|
if (key === "ctrl+home" || key === "ctrl+end") {
|
|
556
|
+
this.#scrollBeforeFilter = null;
|
|
523
557
|
const rows = this.#rows();
|
|
524
558
|
const selectable = selectableIndexes(rows);
|
|
525
559
|
const target = key === "ctrl+end" ? selectable.at(-1) : selectable[0];
|
|
@@ -531,6 +565,7 @@ export class SettingsApp {
|
|
|
531
565
|
return { consumed: true };
|
|
532
566
|
}
|
|
533
567
|
if (key === "up" || key === "down" || key === "shift+up" || key === "shift+down") {
|
|
568
|
+
this.#scrollBeforeFilter = null;
|
|
534
569
|
const rows = this.#rows();
|
|
535
570
|
// Rationale: nothing found means nothing to move through; the key is still swallowed
|
|
536
571
|
// rather than typed into the search.
|
|
@@ -548,9 +583,16 @@ export class SettingsApp {
|
|
|
548
583
|
return { consumed: true };
|
|
549
584
|
}
|
|
550
585
|
const outcome = handleLineInputKey(input, data);
|
|
551
|
-
if (outcome.kind === "cancelled")
|
|
586
|
+
if (outcome.kind === "cancelled") {
|
|
552
587
|
this.#filter = null;
|
|
553
|
-
|
|
588
|
+
if (this.#scrollBeforeFilter !== null)
|
|
589
|
+
this.#scroll = this.#scrollBeforeFilter;
|
|
590
|
+
this.#scrollBeforeFilter = null;
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
this.#scrollBeforeFilter = null;
|
|
594
|
+
this.#scroll = 0;
|
|
595
|
+
}
|
|
554
596
|
return { consumed: true };
|
|
555
597
|
}
|
|
556
598
|
#cycle(rows, selected, delta) {
|
|
@@ -684,16 +726,17 @@ export class SettingsApp {
|
|
|
684
726
|
return renderGroupHeader(humanizeTitle(title), width, theme);
|
|
685
727
|
}
|
|
686
728
|
#renderRow(row, selected, width, valueColumn, theme) {
|
|
687
|
-
if (row === undefined || row.kind === "spacer")
|
|
729
|
+
if (row === undefined || row.kind === "spacer" || width < SETTINGS_CONTENT_INSET)
|
|
688
730
|
return "";
|
|
689
731
|
if (row.kind === "group")
|
|
690
732
|
return this.#header(row.title, theme, width);
|
|
733
|
+
const innerWidth = width - SETTINGS_CONTENT_INSET;
|
|
691
734
|
if (row.kind === "note")
|
|
692
|
-
return renderNote(row.text,
|
|
735
|
+
return ` ${renderNote(row.text, innerWidth, theme)}`;
|
|
693
736
|
const entry = row.value;
|
|
694
737
|
const key = `${entry.backend}:${entry.id}`;
|
|
695
738
|
const hovered = this.#hoverKey === key;
|
|
696
|
-
return renderListRow(this.#viewRow(entry), { selected, hovered, region: this.#hoverRegion }, valueColumn,
|
|
739
|
+
return ` ${renderListRow(this.#viewRow(entry), { selected, hovered, region: this.#hoverRegion }, valueColumn, innerWidth, theme)}`;
|
|
697
740
|
}
|
|
698
741
|
#viewRow(entry) {
|
|
699
742
|
const shown = this.#shownValue(entry);
|
|
@@ -723,7 +766,8 @@ export class SettingsApp {
|
|
|
723
766
|
index: menu.index,
|
|
724
767
|
};
|
|
725
768
|
const frame = valueMenuFrame(state, { screenRow: anchor.screenRow, valueColumn }, {
|
|
726
|
-
|
|
769
|
+
bodyTop: this.#bodyTopForFrame,
|
|
770
|
+
bodyHeight: this.#bodyHeightForFrame,
|
|
727
771
|
surfaceWidth: rect.width,
|
|
728
772
|
reservedRight,
|
|
729
773
|
});
|
|
@@ -749,7 +793,8 @@ export class SettingsApp {
|
|
|
749
793
|
if (open !== null)
|
|
750
794
|
return this.#dialogLines(open, width, theme);
|
|
751
795
|
const hint = this.#interruptArmed ? "press ctrl+c again to exit a1" : SETTINGS_SHORTCUTS.hint(SCOPE);
|
|
752
|
-
const
|
|
796
|
+
const report = statusText({ hint, report: this.#notice });
|
|
797
|
+
const status = truncateToWidth(`${width > 0 ? " " : ""}${theme.fg("dim", report)}`, width);
|
|
753
798
|
const input = this.#filter;
|
|
754
799
|
if (input === null)
|
|
755
800
|
return [status];
|
|
@@ -10,7 +10,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
|
|
|
10
10
|
],
|
|
11
11
|
"generatedArtifact": {
|
|
12
12
|
"path": "dist/integrations/pi/startup-public.js",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "fdd81188cf24be1f187fdcc18d131e7432b114c2094dc51543ef27edbe99b23c"
|
|
14
14
|
},
|
|
15
15
|
"dependencyLayerIdentity": {
|
|
16
16
|
"source": "A1_RELEASE_LAYERS",
|
|
@@ -19,7 +19,7 @@ export const STARTUP_DESCRIPTOR = Object.freeze({
|
|
|
19
19
|
"compileCacheNamespace": {
|
|
20
20
|
"strategy": "node-abi-version-and-ordered-layer-sha256-v1"
|
|
21
21
|
},
|
|
22
|
-
"identity": "
|
|
22
|
+
"identity": "4bf2be3027c6230ec34cfd8dab3df61030de6715ed1f1e9e9dd1fb83edba8522"
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
export function loadDeclaredStartupGraph() {
|
|
@@ -2,7 +2,9 @@ export { adaptPiAssistantMessage, adaptPiToolExecution, adaptPiUserMessage } fro
|
|
|
2
2
|
export { loadHistoryEditor, type HistoryEditorConstructor } from "./history-editor-loader.js";
|
|
3
3
|
export { PiComponentConformanceError, runPiComponentConformance } from "./conformance.js";
|
|
4
4
|
export type { PiComponentConformanceReport, PiComponentConformanceResult } from "./conformance.js";
|
|
5
|
-
export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector,
|
|
5
|
+
export { OWNED_BUILTIN_SLASH_COMMANDS, PINNED_PI_BUILTIN_SLASH_COMMANDS, componentFromPort, componentPort, createPiExtensionUiBridge, createPiQueuedInputStatus, createPiShellArmin, createPiShellAuthProviderSelector, createPiShellChangelog, createPiShellCollapsedChangelog, createPiShellDaxnuts, createPiShellDialog, createPiShellEarendilAnnouncement, createPiShellEditor, createPiShellExtensionSelector, createPiShellFooter, createPiShellHeader, createPiShellHotkeys, createPiShellLoadedResources, createPiShellLoginDialog, createPiShellModelSelector, createPiShellModelsDialog, createPiShellOperationLoader, createPiShellReloadBox, createPiShellScopedModelsSelector, createPiShellSelector, createPiShellSessionInfo, createPiShellSessionSelector, createPiShellSettingsSelector, createPiShellShowImagesSelector, createPiShellSkillsSelector, createPiShellStatus, createPiShellThemeSelector, createPiShellTranscriptComponent, createPiShellTreeSelector, createPiShellTrustSelector, createPiShellUserMessageSelector, createTuiFacade, ensureTheme, formatSessionTokens, isAutocompleteProvider, isPiPromptStyleCompaction, isRecord, paintPiSubmittedPromptTimestamp, piShellHyperlink, piShellTruncateToWidth, piShellVisibleWidth, renderPiShellChangelogLines, renderPiShellCommandMessage, renderPiShellHotkeysLines, renderPiShellPackageUpdateNotice, renderPiShellStartupDiagnostic, renderPiShellStatusText, renderPiShellTranscriptBlock, validatedAssistantMessage, } from "./shell-components.js";
|
|
6
|
+
export { renderPiShellHotkeySections } from "./shell-hotkey-sections.js";
|
|
7
|
+
export type { PiShellHotkeySection } from "./shell-hotkey-sections.js";
|
|
6
8
|
export type { PiExtensionUiBridge, PiExtensionUiBridgeHost, PiShellAuthProviderOption, PiShellAutocompleteCommand, PiShellClipboardContent, PiShellCommandMessagePresentation, PiShellComponentPort, PiShellEditorBodyGeometry, PiShellEditorOptions, PiShellEditorPointerEvent, PiShellEditorPort, PiShellEditorTextRange, PiShellExtensionRendererResolver, PiShellHeaderOptions, PiShellHeaderPort, PiShellHotkeysPresentation, PiShellImageAssetResolver, PiShellLoadedResourcesPort, PiShellLoginDialogPort, PiShellModelSelectorOptions, PiShellModelsDialogOptions, PiShellModelsDialogPort, PiShellOperationLoaderPort, PiShellPasteReservation, PiShellQueuedInputPort, PiShellResourceEntry, PiShellResourceSection, PiShellScopedModelDescriptor, PiShellScopedModelsSelectorOptions, PiShellScopedModelsSelectorPort, PiShellSelectorOption, PiShellSelectorOptions, PiShellSessionInfoPresentation, PiShellSettingsSelectorOptions, PiShellStartupNotice, PiShellStatusPlacement, PiShellStatusPort, PiShellSubmittedPromptComposer, PiShellTranscriptComponentPort, PiShellViewComponentPort, } from "./shell-components.js";
|
|
7
9
|
export { PINNED_PI_LAYOUT, applyConfiguredPiTheme, applyPiTheme, applyPiThemeInstance, currentPiThemeName, detectPiTerminalBackgroundFromEnv, detectPiTerminalBackgroundTheme, detectPiTerminalThemeForAuto, ensurePiTheme, getAvailablePiThemes, loadPiTheme, onPiThemeChange, parsePiAutoThemeSetting, piTheme, resolvePiThemeSetting, stopPiThemeWatcher, } from "./theme.js";
|
|
8
10
|
export type { PiColorMode, PiTerminalTheme, PiTerminalThemeDetection, PiTerminalThemeDetector, PiThemeBackground, PiThemeResult } from "./theme.js";
|