@timurproko/a1 0.2.7-dev.1269 → 0.2.7-dev.1275
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 +6 -0
- package/dist/app/session-shell/apps-dialog.d.ts +33 -0
- package/dist/app/session-shell/apps-dialog.js +61 -0
- package/dist/app/session-shell/dialog-coordinator.d.ts +8 -0
- package/dist/app/session-shell/dialog-coordinator.js +72 -3
- package/dist/app/session-shell/session-selectors.d.ts +1 -1
- package/dist/app/session-shell/session-selectors.js +1 -1
- package/dist/app/session-shell/session-shell.js +9 -3
- package/dist/app/session-shell/shell-host.d.ts +1 -0
- package/dist/app/session-shell/shell-host.js +22 -11
- package/dist/app/session-shell/workflow-output.js +12 -0
- package/dist/app/session-shell/workflow-router.d.ts +1 -1
- package/dist/composition/owned-ui.js +17 -13
- package/dist/contracts/owned-ui/session-presenters.d.ts +1 -1
- package/dist/contracts/owned-ui/session-workflows.d.ts +3 -1
- package/dist/contracts/owned-ui/shell-components.d.ts +2 -0
- package/dist/contracts/presentation/progress-palette.generated.d.ts +1 -1
- package/dist/contracts/presentation/progress-palette.generated.js +1 -1
- package/dist/contracts/presentation/terminal.d.ts +4 -0
- package/dist/contracts/presentation/theme.d.ts +2 -0
- package/dist/foundation/lifecycle/user-exports.d.ts +5 -0
- package/dist/foundation/lifecycle/user-exports.js +37 -0
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- package/dist/integrations/pi/components/models-dialog-loader.d.ts +11 -0
- package/dist/integrations/pi/components/models-dialog-loader.js +45 -0
- package/dist/integrations/pi/components/models-dialog.d.ts +2 -0
- package/dist/integrations/pi/components/models-dialog.js +13 -7
- package/dist/integrations/pi/components/resources/builtin-themes.d.ts +2 -2
- package/dist/integrations/pi/components/resources/builtin-themes.js +2 -2
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +21 -15
- package/dist/integrations/pi/components/shell-footer-status.js +3 -2
- package/dist/integrations/pi/components/shell-presenters-info.js +1 -1
- package/dist/integrations/pi/components/shell-presenters-transcript.js +3 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.d.ts +2 -1
- package/dist/integrations/pi/components/shell-selectors-dialogs.js +2 -8
- package/dist/integrations/pi/components/theme.d.ts +2 -0
- package/dist/integrations/pi/components/theme.js +5 -0
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.d.ts +8 -7
- package/dist/integrations/pi/components/upstream/adjacent/core/keybindings.js +13 -7
- 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/earendil-announcement.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-editor.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-input.js +1 -1
- package/dist/integrations/pi/components/upstream/components/extension-selector.js +9 -2
- package/dist/integrations/pi/components/upstream/components/mermaid.d.ts +2 -1
- package/dist/integrations/pi/components/upstream/components/mermaid.js +26 -21
- 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/pi-logo.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.js +9 -14
- 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 +6 -2
- package/dist/integrations/pi/components/upstream/components/skill-invocation-message.js +27 -3
- 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/themed-text.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/themed-text.js +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/thinking-selector.js +1 -1
- 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 +7 -6
- 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 +2 -2
- 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/program-status-reporter.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/theme/theme.js +1 -1
- package/dist/integrations/pi/engine/adapter.d.ts +1 -1
- package/dist/integrations/pi/engine/adapter.js +3 -3
- package/dist/integrations/pi/engine/host.d.ts +1 -1
- package/dist/integrations/pi/engine/resources/changelog.json +4 -4
- package/dist/integrations/pi/engine/workflow-export.d.ts +4 -0
- package/dist/integrations/pi/engine/workflow-export.js +25 -0
- package/dist/integrations/pi/engine/workflow-runner.d.ts +1 -0
- package/dist/integrations/pi/engine/workflow-runner.js +6 -10
- package/dist/integrations/pi/engine/workflow-support.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-support.js +28 -25
- package/dist/integrations/pi/engine/workflows.d.ts +6 -1
- package/dist/integrations/pi/engine/workflows.js +1 -1
- package/dist/integrations/pi/session-presenters/presentation.js +2 -1
- package/dist/integrations/pi/session-presenters/presenters.js +22 -10
- package/dist/integrations/pi/startup-public.js +289 -240
- package/dist/integrations/pi/startup-public.manifest.json +579 -363
- package/dist/integrations/pi/tui-runtime/adapter.js +3 -1
- 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/integrations/pi/tui-runtime/overlay-geometry.d.ts +5 -2
- package/dist/integrations/pi/tui-runtime/overlay-geometry.js +12 -2
- package/dist/runtime-payload-inventory.json +8044 -6930
- package/dist/ui/components/dialog-panel.d.ts +4 -3
- package/dist/ui/components/dialog-panel.js +9 -13
- package/dist/ui/components/index.d.ts +1 -1
- package/dist/ui/components/index.js +1 -1
- package/dist/ui/components/scrollbar.d.ts +2 -2
- package/dist/ui/components/scrollbar.js +2 -2
- package/dist/ui/components/spans.d.ts +7 -0
- package/dist/ui/components/spans.js +63 -1
- package/dist/ui/components/surface.js +1 -1
- package/docs/architecture/prompt-suggestions.md +1 -1
- package/docs/architecture/ui-reference-provenance.md +2 -1
- package/docs/features/prompt-history.md +1 -1
- package/docs/features/session-exports.md +15 -0
- package/docs/local-worktree-cleanup.md +24 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -59,6 +59,12 @@ Launch A1, one agent in this terminal (profile: `~/.a1/agent`):
|
|
|
59
59
|
a1
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
In A1, **Ctrl+P** opens the searchable **Launcher**: Agent, Settings, Changelog, and Hotkeys. You can switch from any of those screens; returning to Agent keeps the current session and draft. Settings, Changelog, and Hotkeys are applications rather than Agent slash commands.
|
|
63
|
+
|
|
64
|
+
**Ctrl+M** cycles to the next model: all available models when no scope is set, or only available scoped models when a scope exists. **`/models`** opens the in-place Models selector to select a model or manage that scope. **Ctrl+L** cycles thinking levels, and **Alt+Up** restores queued messages. In legacy terminals that encode Ctrl+M as Enter, ordinary Enter still sends the prompt; use `/models` to select a model instead. Explicit keybinding overrides remain supported. Successful model changes update the status bar without an extra success message; errors and warnings remain visible.
|
|
65
|
+
|
|
66
|
+
Session exports without an explicit destination are saved in **`~/.a1/exports/`**, outside disposable worktrees. Use `/export` for HTML or `/export --jsonl` for JSONL; explicit destinations retain their existing meaning. See [session exports](docs/features/session-exports.md).
|
|
67
|
+
|
|
62
68
|
Resume a saved session:
|
|
63
69
|
|
|
64
70
|
```text
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TerminalComponentPort } from "../../contracts/presentation/index.js";
|
|
2
|
+
import { type UiTheme } from "../../ui/components/index.js";
|
|
3
|
+
declare const APPS: readonly [{
|
|
4
|
+
readonly id: "agent";
|
|
5
|
+
readonly label: "Agent";
|
|
6
|
+
}, {
|
|
7
|
+
readonly id: "settings";
|
|
8
|
+
readonly label: "Settings";
|
|
9
|
+
}, {
|
|
10
|
+
readonly id: "changelog";
|
|
11
|
+
readonly label: "Changelog";
|
|
12
|
+
}, {
|
|
13
|
+
readonly id: "hotkeys";
|
|
14
|
+
readonly label: "Hotkeys";
|
|
15
|
+
}];
|
|
16
|
+
type AppId = typeof APPS[number]["id"];
|
|
17
|
+
/** A compact application chooser; actions return to the same session and never launch a process. */
|
|
18
|
+
export declare class AppsDialog implements TerminalComponentPort {
|
|
19
|
+
#private;
|
|
20
|
+
readonly ports: {
|
|
21
|
+
theme(): UiTheme;
|
|
22
|
+
height(): number;
|
|
23
|
+
legacyKey(data: string): string;
|
|
24
|
+
select(id: AppId): void;
|
|
25
|
+
cancel(): void;
|
|
26
|
+
requestRender(): void;
|
|
27
|
+
};
|
|
28
|
+
constructor(ports: AppsDialog["ports"]);
|
|
29
|
+
render(width: number): readonly string[];
|
|
30
|
+
handleInput(data: string): void;
|
|
31
|
+
invalidate(): void;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { LineInput, handleLineInputKey, ShortcutRegistry, configureDialogChoiceCapacity, renderSteppedDialogPanel } from "../../ui/components/index.js";
|
|
2
|
+
const APPS = [
|
|
3
|
+
{ id: "agent", label: "Agent" },
|
|
4
|
+
{ id: "settings", label: "Settings" },
|
|
5
|
+
{ id: "changelog", label: "Changelog" },
|
|
6
|
+
{ id: "hotkeys", label: "Hotkeys" },
|
|
7
|
+
];
|
|
8
|
+
const SCOPE = "apps";
|
|
9
|
+
const SHORTCUTS = new ShortcutRegistry();
|
|
10
|
+
SHORTCUTS.declare({ key: "up", scope: SCOPE, description: "Previous app", hint: { keys: "↑↓", does: "navigate" } }, "previous");
|
|
11
|
+
SHORTCUTS.declare({ key: "down", scope: SCOPE, description: "Next app", hint: { keys: "↑↓", does: "navigate" } }, "next");
|
|
12
|
+
SHORTCUTS.declare({ key: "enter", scope: SCOPE, description: "Open app", hint: { keys: "Enter", does: "open" } }, "open");
|
|
13
|
+
SHORTCUTS.declare({ key: "escape", scope: SCOPE, description: "Close Launcher", hint: { keys: "Esc", does: "close" } }, "close");
|
|
14
|
+
/** A compact application chooser; actions return to the same session and never launch a process. */
|
|
15
|
+
export class AppsDialog {
|
|
16
|
+
#input = new LineInput();
|
|
17
|
+
#index = 0;
|
|
18
|
+
ports;
|
|
19
|
+
constructor(ports) { this.ports = ports; }
|
|
20
|
+
#matches() { return APPS.filter(app => app.label.toLowerCase().includes(this.#input.value.toLowerCase())); }
|
|
21
|
+
render(width) {
|
|
22
|
+
const matches = this.#matches();
|
|
23
|
+
const height = Math.max(1, this.ports.height());
|
|
24
|
+
const compact = height < 12;
|
|
25
|
+
const capacity = compact ? Math.max(1, height - 3) : configureDialogChoiceCapacity(height, true, 0);
|
|
26
|
+
const start = Math.max(0, this.#index - capacity + 1);
|
|
27
|
+
return renderSteppedDialogPanel({
|
|
28
|
+
title: "Launcher", input: this.#input, compact,
|
|
29
|
+
rows: matches.length === 0 ? [{ label: "No apps found", value: "" }]
|
|
30
|
+
: matches.slice(start, start + capacity).map(app => ({ label: app.label, value: "" })),
|
|
31
|
+
index: matches.length === 0 ? -1 : this.#index - start,
|
|
32
|
+
hint: [{ key: "Type", action: "search" }, ...SHORTCUTS.hintEntries(SCOPE)],
|
|
33
|
+
}, width, this.ports.theme()).slice(0, height);
|
|
34
|
+
}
|
|
35
|
+
handleInput(data) {
|
|
36
|
+
const key = this.ports.legacyKey(data);
|
|
37
|
+
const token = key === "\u001b[A" ? "up" : key === "\u001b[B" ? "down"
|
|
38
|
+
: key === "\r" || key === "\n" ? "enter" : key === "\u001b" || key === "\u0003" ? "escape" : "edit";
|
|
39
|
+
const action = SHORTCUTS.resolve(token, SCOPE);
|
|
40
|
+
const matches = this.#matches();
|
|
41
|
+
if (action === "close") {
|
|
42
|
+
this.ports.cancel();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (action === "open") {
|
|
46
|
+
const selected = matches[this.#index];
|
|
47
|
+
if (selected !== undefined)
|
|
48
|
+
this.ports.select(selected.id);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (action === "previous" || action === "next") {
|
|
52
|
+
this.#index = Math.max(0, Math.min(matches.length - 1, this.#index + (action === "next" ? 1 : -1)));
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
handleLineInputKey(this.#input, key);
|
|
56
|
+
this.#index = 0;
|
|
57
|
+
}
|
|
58
|
+
this.ports.requestRender();
|
|
59
|
+
}
|
|
60
|
+
invalidate() { }
|
|
61
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OwnedUiShellComponents, OwnedUiShellSelectorOption } from "../../contracts/owned-ui/index.js";
|
|
2
|
+
import type { ShellPresentationPorts } from "../../contracts/presentation/index.js";
|
|
2
3
|
import type { TerminalOverlayHandle } from "../../contracts/presentation/index.js";
|
|
3
4
|
import type { OwnedUiCommandResult, OwnedUiDialog } from "../../contracts/owned-ui/index.js";
|
|
4
5
|
import type { UiRouteHost, UiRouteInput } from "../../ui/apps/contracts.js";
|
|
@@ -7,6 +8,10 @@ import type { OwnedUiSessionShellOptions, OwnedUiSessionShellRoot } from "./sess
|
|
|
7
8
|
type StartupRoute = NonNullable<OwnedUiSessionShellOptions["engine"]["startupRoute"]>;
|
|
8
9
|
interface SessionDialogPorts {
|
|
9
10
|
readonly terminal: Pick<OwnedUiPresenterTerminal, "running" | "hasOverlay" | "showOverlay" | "openRoute" | "requestRender">;
|
|
11
|
+
readonly presentation?: Pick<ShellPresentationPorts, "theme" | "terminalRuntime">;
|
|
12
|
+
readonly viewport?: () => {
|
|
13
|
+
rows: number;
|
|
14
|
+
};
|
|
10
15
|
readonly root: Pick<OwnedUiSessionShellRoot, "chrome" | "setInputSurface" | "usesDefaultInputSurface">;
|
|
11
16
|
readonly routeHost: UiRouteHost | null;
|
|
12
17
|
readonly dialogs: Pick<OwnedUiShellComponents["dialogs"], "dialog" | "selector">;
|
|
@@ -25,6 +30,9 @@ interface SessionDialogPorts {
|
|
|
25
30
|
export declare class SessionDialogCoordinator {
|
|
26
31
|
#private;
|
|
27
32
|
constructor(ports: SessionDialogPorts);
|
|
33
|
+
/** Apps may cover a full-screen route, but never steal another dialog's local shortcuts. */
|
|
34
|
+
canOpenApps(): boolean;
|
|
35
|
+
showApps(): void;
|
|
28
36
|
/** Clears the replacement input surface a selector put in the dock; the shared close action of every dock selector. */
|
|
29
37
|
readonly closeInputSurface: () => void;
|
|
30
38
|
showSelector(title: string, options: readonly OwnedUiShellSelectorOption[], onSelect: (id: string) => void, onCancel?: () => void): TerminalOverlayHandle;
|
|
@@ -10,12 +10,75 @@ export class SessionDialogCoordinator {
|
|
|
10
10
|
#handle;
|
|
11
11
|
#id;
|
|
12
12
|
#source;
|
|
13
|
+
#route;
|
|
14
|
+
#apps;
|
|
13
15
|
#startupRoute;
|
|
14
16
|
#startupRouteTimer;
|
|
15
17
|
constructor(ports) {
|
|
16
18
|
this.#ports = ports;
|
|
17
19
|
this.#startupRoute = ports.startupRoute;
|
|
18
20
|
}
|
|
21
|
+
/** Apps may cover a full-screen route, but never steal another dialog's local shortcuts. */
|
|
22
|
+
canOpenApps() {
|
|
23
|
+
return this.#apps === undefined && (this.#source === "route"
|
|
24
|
+
|| !this.#ports.terminal.hasOverlay() && this.#ports.root.usesDefaultInputSurface());
|
|
25
|
+
}
|
|
26
|
+
showApps() {
|
|
27
|
+
const presentation = this.#ports.presentation;
|
|
28
|
+
if (presentation === undefined || !this.#ports.terminal.running || !this.canOpenApps())
|
|
29
|
+
return;
|
|
30
|
+
let dialog;
|
|
31
|
+
let closed = false;
|
|
32
|
+
let loading = "Loading Launcher…";
|
|
33
|
+
const pending = [];
|
|
34
|
+
const cancel = () => { closed = true; pending.length = 0; this.#apps?.hide(); this.#apps = undefined; };
|
|
35
|
+
this.#apps = this.#ports.terminal.showOverlay({
|
|
36
|
+
render: width => dialog?.render(width) ?? [loading.slice(0, width)],
|
|
37
|
+
handleInput: data => {
|
|
38
|
+
if (dialog !== undefined)
|
|
39
|
+
dialog.handleInput?.(data);
|
|
40
|
+
else if (presentation.terminalRuntime.legacyKeyInput(data) === "\u001b")
|
|
41
|
+
cancel();
|
|
42
|
+
else if (pending.length < 32)
|
|
43
|
+
pending.push(data);
|
|
44
|
+
},
|
|
45
|
+
invalidate: () => dialog?.invalidate(),
|
|
46
|
+
dispose: () => { closed = true; pending.length = 0; },
|
|
47
|
+
}, { width: 60, maxHeight: "100%", anchor: "center", inputCoordination: "owned", modal: true });
|
|
48
|
+
// Performance: Apps and its search/list controller are optional workflows, not eager startup dependencies.
|
|
49
|
+
void import("./apps-dialog.js").then(({ AppsDialog }) => {
|
|
50
|
+
if (closed || this.#ports.disposed())
|
|
51
|
+
return;
|
|
52
|
+
dialog = new AppsDialog({
|
|
53
|
+
theme: () => presentation.theme.current(),
|
|
54
|
+
height: () => this.#ports.viewport?.().rows ?? 24,
|
|
55
|
+
legacyKey: data => presentation.terminalRuntime.legacyKeyInput(data),
|
|
56
|
+
requestRender: () => this.#ports.terminal.requestRender(),
|
|
57
|
+
cancel,
|
|
58
|
+
select: route => {
|
|
59
|
+
cancel();
|
|
60
|
+
if (route === this.#route)
|
|
61
|
+
return;
|
|
62
|
+
this.#handle?.close?.();
|
|
63
|
+
if (route === "agent")
|
|
64
|
+
this.#close();
|
|
65
|
+
else {
|
|
66
|
+
const result = this.openRoute(route);
|
|
67
|
+
if (result.diagnostic !== null)
|
|
68
|
+
this.#ports.root.chrome.setNotice({ kind: "error", message: result.diagnostic });
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
for (const key of pending.splice(0)) {
|
|
73
|
+
if (!closed)
|
|
74
|
+
dialog.handleInput?.(key);
|
|
75
|
+
}
|
|
76
|
+
this.#ports.terminal.requestRender();
|
|
77
|
+
}).catch(() => { if (!closed && !this.#ports.disposed()) {
|
|
78
|
+
loading = "Launcher unavailable — Esc close";
|
|
79
|
+
this.#ports.terminal.requestRender();
|
|
80
|
+
} });
|
|
81
|
+
}
|
|
19
82
|
/** Clears the replacement input surface a selector put in the dock; the shared close action of every dock selector. */
|
|
20
83
|
closeInputSurface = () => {
|
|
21
84
|
this.#ports.root.setInputSurface(null);
|
|
@@ -29,15 +92,15 @@ export class SessionDialogCoordinator {
|
|
|
29
92
|
title,
|
|
30
93
|
options,
|
|
31
94
|
onSelect: id => {
|
|
32
|
-
onSelect(id);
|
|
33
95
|
this.#close();
|
|
96
|
+
onSelect(id);
|
|
34
97
|
},
|
|
35
98
|
onCancel: () => {
|
|
36
99
|
this.#close();
|
|
37
100
|
onCancel?.();
|
|
38
101
|
},
|
|
39
102
|
});
|
|
40
|
-
const handle = this.#ports.terminal.showOverlay(component, OVERLAY_OPTIONS);
|
|
103
|
+
const handle = this.#ports.terminal.showOverlay(component, { ...OVERLAY_OPTIONS, modal: true });
|
|
41
104
|
this.#handle = handle;
|
|
42
105
|
return handle;
|
|
43
106
|
}
|
|
@@ -57,7 +120,7 @@ export class SessionDialogCoordinator {
|
|
|
57
120
|
this.#handle?.hide();
|
|
58
121
|
this.#source = "backend";
|
|
59
122
|
const component = this.#ports.dialogs.dialog(dialog, { onSelect: () => this.#close(), onCancel: () => this.#close() });
|
|
60
|
-
this.#handle = this.#ports.terminal.showOverlay(component, OVERLAY_OPTIONS);
|
|
123
|
+
this.#handle = this.#ports.terminal.showOverlay(component, { ...OVERLAY_OPTIONS, modal: true });
|
|
61
124
|
this.#id = dialog.id;
|
|
62
125
|
}
|
|
63
126
|
openRoute(route, input, onClosed) {
|
|
@@ -69,6 +132,7 @@ export class SessionDialogCoordinator {
|
|
|
69
132
|
this.#ports.root.chrome.dismissNotice();
|
|
70
133
|
this.#handle?.hide();
|
|
71
134
|
this.#source = "route";
|
|
135
|
+
this.#route = route;
|
|
72
136
|
const handle = this.#ports.terminal.openRoute(surface, {
|
|
73
137
|
exit: () => this.#ports.exit(),
|
|
74
138
|
closed: rendered => {
|
|
@@ -118,9 +182,13 @@ export class SessionDialogCoordinator {
|
|
|
118
182
|
if (this.#startupRouteTimer !== undefined)
|
|
119
183
|
clearTimeout(this.#startupRouteTimer);
|
|
120
184
|
this.#startupRouteTimer = undefined;
|
|
185
|
+
this.#apps?.hide();
|
|
186
|
+
this.#apps = undefined;
|
|
121
187
|
this.#handle?.hide();
|
|
122
188
|
}
|
|
123
189
|
#close() {
|
|
190
|
+
this.#apps?.hide();
|
|
191
|
+
this.#apps = undefined;
|
|
124
192
|
this.#handle?.hide();
|
|
125
193
|
this.#clear();
|
|
126
194
|
}
|
|
@@ -128,5 +196,6 @@ export class SessionDialogCoordinator {
|
|
|
128
196
|
this.#handle = undefined;
|
|
129
197
|
this.#id = undefined;
|
|
130
198
|
this.#source = undefined;
|
|
199
|
+
this.#route = undefined;
|
|
131
200
|
}
|
|
132
201
|
}
|
|
@@ -42,5 +42,5 @@ export declare class SessionSelectors implements WorkflowSelectors {
|
|
|
42
42
|
showTrustSelector(): void;
|
|
43
43
|
showScopedModelsSelector(): void;
|
|
44
44
|
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
45
|
-
showModelsDialog(initialQuery?: string): void
|
|
45
|
+
showModelsDialog(initialQuery?: string): void | Promise<void>;
|
|
46
46
|
}
|
|
@@ -220,7 +220,7 @@ export class SessionSelectors {
|
|
|
220
220
|
}
|
|
221
221
|
/** The bare-A1 unified Models dialog: switch on Enter, scope on Space, persist on Ctrl+S, all through the engine. */
|
|
222
222
|
showModelsDialog(initialQuery) {
|
|
223
|
-
this.#presenters.openModelsDialog(this.#dialogHost, initialQuery);
|
|
223
|
+
return this.#presenters.openModelsDialog(this.#dialogHost, initialQuery);
|
|
224
224
|
}
|
|
225
225
|
#treeSummary() {
|
|
226
226
|
return new Promise(resolve => {
|
|
@@ -79,7 +79,7 @@ export class OwnedUiSessionPresenter {
|
|
|
79
79
|
#sessionGeneration;
|
|
80
80
|
#sessionBindingGeneration;
|
|
81
81
|
constructor(host, options) {
|
|
82
|
-
const { backend, cwd, routeHost, sessionLayout } = options.engine;
|
|
82
|
+
const { backend, cwd, routeHost, startupRoute, sessionLayout } = options.engine;
|
|
83
83
|
const { terminal, startup, viewportSettings, reload: reloadPresentation, stream: streamPresentationOptions, input: inputPresentation, } = options.presentation ?? {};
|
|
84
84
|
const { clipboard, responseCopy, paste: pasteDiagnostics, pastePreparation } = options.diagnostics ?? {};
|
|
85
85
|
const promptHistory = options.history;
|
|
@@ -178,11 +178,11 @@ export class OwnedUiSessionPresenter {
|
|
|
178
178
|
// Invariant: the presenter owns its root (theme subscription and helper clients) and disposes it once the
|
|
179
179
|
// terminal no longer renders it.
|
|
180
180
|
constructed.push(() => this.root.dispose());
|
|
181
|
-
const startupRoute = options.engine.startupRoute;
|
|
182
181
|
this.#dialogs = new SessionDialogCoordinator({
|
|
183
182
|
terminal: this.#terminal,
|
|
184
183
|
root: this.root,
|
|
185
184
|
routeHost: routeHost ?? null, dialogs: options.presenters.components.dialogs,
|
|
185
|
+
presentation: options.presenters, viewport: () => this.#terminal.viewport(),
|
|
186
186
|
disposed: () => this.#disposed,
|
|
187
187
|
exit: () => { void this.shutdown(); },
|
|
188
188
|
...(startupRoute === undefined ? {} : { startupRoute }),
|
|
@@ -308,6 +308,11 @@ export class OwnedUiSessionPresenter {
|
|
|
308
308
|
handleViewportInput(data) {
|
|
309
309
|
if (!this.#inputCoordination)
|
|
310
310
|
this.#streamPresentation.noteImmediatePresentation();
|
|
311
|
+
if (this.#customViewport && this.#dialogs.canOpenApps()
|
|
312
|
+
&& this.root.editor.matchesAction?.(data, "owned.apps.open")) {
|
|
313
|
+
this.#dialogs.showApps();
|
|
314
|
+
return { consume: true };
|
|
315
|
+
}
|
|
311
316
|
// Compatibility: route modal paging and boundary keys before Pi's fullscreen handlers.
|
|
312
317
|
const isDefault = this.root.usesDefaultInputSurface();
|
|
313
318
|
if (!this.#terminal.hasOverlay() && !isDefault
|
|
@@ -881,7 +886,8 @@ export class OwnedUiSessionPresenter {
|
|
|
881
886
|
const separator = body.search(/\s/);
|
|
882
887
|
const name = separator < 0 ? body : body.slice(0, separator);
|
|
883
888
|
const argument = separator < 0 ? "" : body.slice(separator + 1).trimStart();
|
|
884
|
-
|
|
889
|
+
const applicationOnly = this.#customViewport && (name === "settings" || name === "changelog" || name === "hotkeys");
|
|
890
|
+
if (!applicationOnly && this.#dialogs.claimsRoute(name))
|
|
885
891
|
return this.#dialogs.openRoute(name);
|
|
886
892
|
if (this.#isWorkflowRoute(name))
|
|
887
893
|
return this.runWorkflow({ command: name, argument });
|
|
@@ -49,6 +49,7 @@ export interface OwnedUiPresenterTerminal extends OwnedUiPresenterHost {
|
|
|
49
49
|
requestHyperlinkCleanup(rows?: readonly number[]): void;
|
|
50
50
|
openRoute(surface: UiRouteSurface, callbacks: OwnedUiRouteCallbacks): {
|
|
51
51
|
hide(): void;
|
|
52
|
+
close?(): void;
|
|
52
53
|
};
|
|
53
54
|
beginPresentationHold(): () => void;
|
|
54
55
|
switchMode(mode: "regular" | "fullscreen"): boolean;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { MOUSE_TRACKING_OFF, MOUSE_TRACKING_ON, parseMouseInput } from "../../ui/components/mouse.js";
|
|
2
|
+
import { renderModalBackdrop } from "../../ui/components/spans.js";
|
|
3
|
+
import { padToWidth } from "../../ui/components/text.js";
|
|
2
4
|
import { readVisibleHyperlinks } from "../../ui/components/visible-hyperlinks.js";
|
|
3
5
|
import { pinnedLayoutRoot, } from "./session-shell-root.js";
|
|
4
6
|
/** The size and render request a Pi component reads from the terminal it is shown on, read on every call. */
|
|
@@ -37,7 +39,7 @@ export function sessionTerminalHostOptions(options) {
|
|
|
37
39
|
export class OwnedUiTerminalHost {
|
|
38
40
|
runtime;
|
|
39
41
|
#customViewport;
|
|
40
|
-
#
|
|
42
|
+
#presentation;
|
|
41
43
|
#damageTerminal;
|
|
42
44
|
#quitOutro;
|
|
43
45
|
#presenters = new Set();
|
|
@@ -51,7 +53,7 @@ export class OwnedUiTerminalHost {
|
|
|
51
53
|
#ending;
|
|
52
54
|
constructor(options) {
|
|
53
55
|
this.#customViewport = options.layout === "custom-viewport";
|
|
54
|
-
this.#
|
|
56
|
+
this.#presentation = options.presentation;
|
|
55
57
|
this.#quitOutro = options.quitOutro;
|
|
56
58
|
const input = options.input;
|
|
57
59
|
let damageTerminal;
|
|
@@ -73,8 +75,9 @@ export class OwnedUiTerminalHost {
|
|
|
73
75
|
mouse: false,
|
|
74
76
|
consumeUnhandledMouse: true,
|
|
75
77
|
onOverlayGeometry: surfaces => this.#active?.setOverlaySurfaces(surfaces),
|
|
78
|
+
paintModalBackdrop: renderModalBackdrop,
|
|
76
79
|
decorateTerminal: (terminal) => {
|
|
77
|
-
damageTerminal = this.#
|
|
80
|
+
damageTerminal = this.#presentation.terminalRuntime.createDamageTerminal(terminal, {
|
|
78
81
|
regionalScroll: process.env.TERM !== "dumb",
|
|
79
82
|
inspectHyperlinks: readVisibleHyperlinks,
|
|
80
83
|
onResize: () => this.#active?.noteImmediatePresentation(),
|
|
@@ -84,7 +87,7 @@ export class OwnedUiTerminalHost {
|
|
|
84
87
|
},
|
|
85
88
|
...(input?.coordination === false ? {} : {
|
|
86
89
|
inputCoordination: {
|
|
87
|
-
classify: (data, focusedOverlay) => this.#
|
|
90
|
+
classify: (data, focusedOverlay) => this.#presentation.terminalRuntime.classifyInput(data, focusedOverlay ?? this.#active?.inputCoordinationSurface() ?? "opaque"),
|
|
88
91
|
onReceipt: () => this.#active?.noteImmediatePresentation(),
|
|
89
92
|
...(input?.scheduler === undefined ? {} : { scheduler: input.scheduler }),
|
|
90
93
|
},
|
|
@@ -100,7 +103,7 @@ export class OwnedUiTerminalHost {
|
|
|
100
103
|
hardwareCursor: options.hardwareCursor,
|
|
101
104
|
...(options.wheelScrollLines === undefined ? {} : { wheelScrollLines: options.wheelScrollLines }),
|
|
102
105
|
};
|
|
103
|
-
this.runtime = this.#
|
|
106
|
+
this.runtime = this.#presentation.terminalRuntime.createRuntime(runtimeOptions);
|
|
104
107
|
this.#damageTerminal = damageTerminal ?? null;
|
|
105
108
|
const background = this.#customViewport ? options.backgroundSettings : undefined;
|
|
106
109
|
if (background !== undefined)
|
|
@@ -285,7 +288,14 @@ export class OwnedUiTerminalHost {
|
|
|
285
288
|
#showOverlay(presenter, component, options) {
|
|
286
289
|
const owned = this.#overlays.get(presenter) ?? new Set();
|
|
287
290
|
this.#overlays.set(presenter, owned);
|
|
288
|
-
const overlay = new PresenterOverlay(this.runtime.showOverlay(
|
|
291
|
+
const overlay = new PresenterOverlay(this.runtime.showOverlay(this.#customViewport && options?.modal ? {
|
|
292
|
+
...component,
|
|
293
|
+
render: width => component.render(width).map(line => (this.#presentation.floatingDialogSurface ?? (text => text))(`\u001b[22;39;49m${padToWidth(line, width)}`)),
|
|
294
|
+
invalidate: () => component.invalidate(),
|
|
295
|
+
handleInput: data => component.handleInput?.(data),
|
|
296
|
+
setFocused: focused => component.setFocused?.(focused),
|
|
297
|
+
dispose: () => component.dispose?.(),
|
|
298
|
+
} : component, options), () => this.#active === presenter, () => owned.delete(overlay));
|
|
289
299
|
overlay.syncVisibility();
|
|
290
300
|
owned.add(overlay);
|
|
291
301
|
return overlay;
|
|
@@ -338,6 +348,7 @@ export class OwnedUiTerminalHost {
|
|
|
338
348
|
closed = true;
|
|
339
349
|
removeSurfacePreInput();
|
|
340
350
|
removeInterruptWatch();
|
|
351
|
+
surface.close();
|
|
341
352
|
this.#setPointerReporting(false);
|
|
342
353
|
overlay?.hide();
|
|
343
354
|
if (notify)
|
|
@@ -345,7 +356,7 @@ export class OwnedUiTerminalHost {
|
|
|
345
356
|
};
|
|
346
357
|
removeInterruptWatch = runtime.addInputListener(data => {
|
|
347
358
|
// Compatibility: a kitty-keyboard child reports Ctrl+C as a CSI-u sequence rather than the byte.
|
|
348
|
-
if (!attached() || !data.includes(INTERRUPT) && this.#
|
|
359
|
+
if (!attached() || overlay?.isFocused() !== true || !data.includes(INTERRUPT) && this.#presentation.terminalRuntime.legacyKeyInput(data) !== INTERRUPT)
|
|
349
360
|
return undefined;
|
|
350
361
|
// Protocol: route hosts decide whether one interrupt closes their app. Raw-input forwarding
|
|
351
362
|
// is required because Pi handles Ctrl+C before the fullscreen overlay receives normal input.
|
|
@@ -378,7 +389,7 @@ export class OwnedUiTerminalHost {
|
|
|
378
389
|
// at the pre-input boundary so dropdowns, value hover, and numeric +/- work,
|
|
379
390
|
// and consume even unhandled reports so settings content is never selected.
|
|
380
391
|
const routeMouse = data => {
|
|
381
|
-
if (!attached())
|
|
392
|
+
if (!attached() || overlay?.isFocused() !== true)
|
|
382
393
|
return undefined;
|
|
383
394
|
const { events, rest } = parseMouseInput(data);
|
|
384
395
|
if (events.length === 0)
|
|
@@ -404,7 +415,7 @@ export class OwnedUiTerminalHost {
|
|
|
404
415
|
for (const event of events)
|
|
405
416
|
surface.handleMouse(event);
|
|
406
417
|
// Invariant: owned screens see legacy key bytes whether the terminal reports legacy or kitty keys.
|
|
407
|
-
const key = rest.length > 0 ? this.#
|
|
418
|
+
const key = rest.length > 0 ? this.#presentation.terminalRuntime.legacyKeyInput(rest) : "";
|
|
408
419
|
if (key.length > 0)
|
|
409
420
|
surface.handleInput(key);
|
|
410
421
|
if (surface.isClosed()) {
|
|
@@ -426,7 +437,7 @@ export class OwnedUiTerminalHost {
|
|
|
426
437
|
anchor: "top-left",
|
|
427
438
|
inputCoordination: "owned",
|
|
428
439
|
});
|
|
429
|
-
return { hide: () => closeSurface(false) };
|
|
440
|
+
return { hide: () => closeSurface(false), close: () => closeSurface(true) };
|
|
430
441
|
}
|
|
431
442
|
// Invariant: the snapshot is synchronous; the outro module itself loads only at quit.
|
|
432
443
|
#captureQuitOutroFrame() {
|
|
@@ -472,7 +483,7 @@ export class OwnedUiTerminalHost {
|
|
|
472
483
|
write: data => this.runtime.writeControl(data),
|
|
473
484
|
...(capture.settings.canvasBackgroundAnsi === null
|
|
474
485
|
? {}
|
|
475
|
-
: { canvas: { ansi: capture.settings.canvasBackgroundAnsi, rebase: this.#
|
|
486
|
+
: { canvas: { ansi: capture.settings.canvasBackgroundAnsi, rebase: this.#presentation.terminalRuntime.rebaseDefaultBackground } }),
|
|
476
487
|
...(outro.now === undefined ? {} : { now: outro.now }),
|
|
477
488
|
...(outro.sleep === undefined ? {} : { sleep: outro.sleep }),
|
|
478
489
|
...(outro.seed === undefined ? {} : { seed: outro.seed }),
|
|
@@ -53,6 +53,18 @@ export class WorkflowOutput {
|
|
|
53
53
|
this.#appendAnchored(width => this.#ports.components.info.commandMessage(presentation, width, this.#ports.outputPad()));
|
|
54
54
|
}
|
|
55
55
|
appendResult(result, errorCode) {
|
|
56
|
+
// Rationale: model state already repaints the footer; only actionable diagnostics need another surface.
|
|
57
|
+
if (this.#ports.customViewport && result.outcome === "completed"
|
|
58
|
+
&& result.presentation?.kind === "model-change") {
|
|
59
|
+
for (const message of result.messages ?? []) {
|
|
60
|
+
if (message.kind !== "status")
|
|
61
|
+
this.appendMessage(message, errorCode);
|
|
62
|
+
}
|
|
63
|
+
if (result.messages === undefined && (result.messageKind === "warning" || result.messageKind === "error")) {
|
|
64
|
+
this.appendMessage({ kind: result.messageKind, message: result.message }, errorCode);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
56
68
|
if (result.messages !== undefined) {
|
|
57
69
|
for (const message of result.messages)
|
|
58
70
|
this.appendMessage(message, errorCode);
|
|
@@ -2,7 +2,7 @@ import type { OwnedUiCommandResult, OwnedUiWorkflowRequest } from "../../contrac
|
|
|
2
2
|
/** The owned selectors a workflow can open in place of asking the engine to choose. */
|
|
3
3
|
export interface WorkflowSelectors {
|
|
4
4
|
showScopedModelsSelector(): void;
|
|
5
|
-
showModelsDialog(initialQuery?: string): void
|
|
5
|
+
showModelsDialog(initialQuery?: string): void | Promise<void>;
|
|
6
6
|
showModelSelector(initialSearchInput?: string): void;
|
|
7
7
|
showForkSelector(): void;
|
|
8
8
|
showThinkingSelector(): Promise<void>;
|
|
@@ -44,21 +44,9 @@ export async function composeOwnedUi(options = {}) {
|
|
|
44
44
|
});
|
|
45
45
|
// Invariant: bare A1 owns the settings-driven ports; the comparison profile receives none of them.
|
|
46
46
|
const bareSettings = bare ? settings : null;
|
|
47
|
-
const projectTrustPrompt = options.projectTrustPrompt;
|
|
48
47
|
// Invariant: process-wide engine state has one owner. The host installs the HTTP dispatcher, applies
|
|
49
48
|
// the theme singletons, and announces startup notices once; every session is created through it.
|
|
50
|
-
const host = await (options.createEngineHost ?? (
|
|
51
|
-
productMode,
|
|
52
|
-
availableThemes: () => getAvailablePiThemes().map(theme => theme.name),
|
|
53
|
-
announceStartupChangelog: !bare,
|
|
54
|
-
theme: {
|
|
55
|
-
base: bare ? "dark" : "engine-configured",
|
|
56
|
-
accentColor: bareSettings?.value("accentColor") ?? "purple",
|
|
57
|
-
packageBorderProjection: bare,
|
|
58
|
-
apply: { base: applyConfiguredPiTheme, accentColor: setPiAccentColor, packageBorderProjection: setPiPackageBorderProjectionEnabled },
|
|
59
|
-
},
|
|
60
|
-
...(projectTrustPrompt === undefined ? {} : { projectTrustPrompt }),
|
|
61
|
-
});
|
|
49
|
+
const host = await (options.createEngineHost ?? createPiEngineHost)(engineHostOptions(options, productMode, bareSettings));
|
|
62
50
|
const sessionForkPrompt = options.sessionForkPrompt;
|
|
63
51
|
try {
|
|
64
52
|
backend = await host.create({
|
|
@@ -247,6 +235,22 @@ function bareShellPorts(settings, generator, diagnostics) {
|
|
|
247
235
|
},
|
|
248
236
|
};
|
|
249
237
|
}
|
|
238
|
+
function engineHostOptions(options, productMode, settings) {
|
|
239
|
+
const bare = productMode === "bare";
|
|
240
|
+
return {
|
|
241
|
+
productMode,
|
|
242
|
+
availableThemes: () => getAvailablePiThemes().map(theme => theme.name),
|
|
243
|
+
...(bare ? { workflowHost: { reserveExport: async (id, format) => (await import("../foundation/lifecycle/user-exports.js")).reserveUserExport(id, format) } } : {}),
|
|
244
|
+
announceStartupChangelog: !bare,
|
|
245
|
+
theme: {
|
|
246
|
+
base: bare ? "dark" : "engine-configured",
|
|
247
|
+
accentColor: settings?.value("accentColor") ?? "purple",
|
|
248
|
+
packageBorderProjection: bare,
|
|
249
|
+
apply: { base: applyConfiguredPiTheme, accentColor: setPiAccentColor, packageBorderProjection: setPiPackageBorderProjectionEnabled },
|
|
250
|
+
},
|
|
251
|
+
...(options.projectTrustPrompt === undefined ? {} : { projectTrustPrompt: options.projectTrustPrompt }),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
250
254
|
async function createPromptHistoryConfiguration(settings, backend, bare) {
|
|
251
255
|
const limit = settings?.value("promptHistoryMaxItems") ?? 100;
|
|
252
256
|
const scope = settings?.value("promptHistoryScope") ?? "unique";
|
|
@@ -80,6 +80,6 @@ export interface OwnedUiSessionPresenters {
|
|
|
80
80
|
/** `navigate` completes a selection that leaves the current leaf, including any summary prompt. */
|
|
81
81
|
openTreeSelector(host: OwnedUiDialogHost, navigate: (entryId: string, skipSummaryPrompt: boolean) => void, initialSelectedId?: string): Promise<void>;
|
|
82
82
|
openSettingsSelector(host: OwnedUiDialogHost): void;
|
|
83
|
-
openModelsDialog(host: OwnedUiDialogHost, initialQuery?: string): void
|
|
83
|
+
openModelsDialog(host: OwnedUiDialogHost, initialQuery?: string): void | Promise<void>;
|
|
84
84
|
openScopedModelsSelector(host: OwnedUiDialogHost): void;
|
|
85
85
|
}
|
|
@@ -108,7 +108,9 @@ export interface OwnedUiCacheWarmingPresentation {
|
|
|
108
108
|
};
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
|
-
export type OwnedUiWorkflowPresentation = OwnedUiSessionInfoPresentation
|
|
111
|
+
export type OwnedUiWorkflowPresentation = OwnedUiSessionInfoPresentation | {
|
|
112
|
+
readonly kind: "model-change";
|
|
113
|
+
};
|
|
112
114
|
export type OwnedUiWorkflowMessageKind = "status" | "warning" | "error" | "accent" | "silent";
|
|
113
115
|
export interface OwnedUiWorkflowMessage {
|
|
114
116
|
readonly kind: Exclude<OwnedUiWorkflowMessageKind, "silent">;
|
|
@@ -53,6 +53,8 @@ export interface OwnedUiShellEditorPort extends OwnedUiShellComponentPort {
|
|
|
53
53
|
/** Restores the shared keybindings if anything replaced the active registry; a no-op when it is already active. */
|
|
54
54
|
activateKeybindings(): void;
|
|
55
55
|
keybindingConfig(): OwnedUiShellKeybindings;
|
|
56
|
+
/** Resolves application-host actions against the same active declarations as editor dispatch. */
|
|
57
|
+
matchesAction?(data: string, action: "owned.apps.open"): boolean;
|
|
56
58
|
reloadKeybindings(): void;
|
|
57
59
|
/** Uses the vendor's terminal decoder rather than assuming one terminal escape spelling. */
|
|
58
60
|
matchesTerminalKey(data: string, key: "home" | "end" | "pageUp" | "pageDown" | "ctrl+home" | "ctrl+end" | "alt+home" | "ctrl+v"): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generated by scripts/pi/sync-progress-palette.ts from A1's named accent projection
|
|
3
|
-
* over pinned Pi 1.5.
|
|
3
|
+
* over pinned Pi 1.5.1 (MIT), commit dd30101cfc5b0609411dd80b6f93adbc14db14cf. Do not edit directly.
|
|
4
4
|
*/
|
|
5
5
|
export declare const SHARED_PROGRESS_PALETTE: Readonly<{
|
|
6
6
|
blue: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generated by scripts/pi/sync-progress-palette.ts from A1's named accent projection
|
|
3
|
-
* over pinned Pi 1.5.
|
|
3
|
+
* over pinned Pi 1.5.1 (MIT), commit dd30101cfc5b0609411dd80b6f93adbc14db14cf. Do not edit directly.
|
|
4
4
|
*/
|
|
5
5
|
export const SHARED_PROGRESS_PALETTE = Object.freeze({
|
|
6
6
|
"blue": {
|
|
@@ -68,6 +68,8 @@ export interface TerminalOverlayOptions {
|
|
|
68
68
|
readonly margin?: TerminalOverlayMargin | number;
|
|
69
69
|
readonly visible?: (columns: number, rows: number) => boolean;
|
|
70
70
|
readonly nonCapturing?: boolean;
|
|
71
|
+
/** An owned floating panel; the host supplies its surface and dims the completed backdrop. */
|
|
72
|
+
readonly modal?: boolean;
|
|
71
73
|
/** A1-owned input scheduling declaration; omitted extension overlays fail closed. */
|
|
72
74
|
readonly inputCoordination?: Exclude<TerminalInputSurfaceKind, "editor">;
|
|
73
75
|
}
|
|
@@ -141,6 +143,8 @@ export interface TerminalRuntimeOptions {
|
|
|
141
143
|
readonly root: TerminalComponentPort;
|
|
142
144
|
/** Bare viewport only: painted overlays in back-to-front order; null while geometry is stale. */
|
|
143
145
|
readonly onOverlayGeometry?: (surfaces: readonly TerminalPointerSurface[] | null) => void;
|
|
146
|
+
/** Presentation policy applied after composition around the topmost owned floating panel. */
|
|
147
|
+
readonly paintModalBackdrop?: (lines: readonly string[], width: number, height: number, panel: TerminalPointerSurface) => string[];
|
|
144
148
|
readonly mode?: "regular" | "fullscreen";
|
|
145
149
|
readonly layoutRoot?: TerminalLayoutNode;
|
|
146
150
|
readonly terminal?: TerminalPort;
|
|
@@ -42,5 +42,7 @@ export interface ShellPresentationPorts {
|
|
|
42
42
|
canvasBackground(style: CanvasBackgroundStyle): string | null;
|
|
43
43
|
/** Columns the pinned comparison layout pads command output with. */
|
|
44
44
|
readonly pinnedOutputPad: 0 | 1;
|
|
45
|
+
/** Live color-capability-aware background for owned floating panels only. */
|
|
46
|
+
readonly floatingDialogSurface?: (text: string) => string;
|
|
45
47
|
readonly terminalRuntime: TerminalRuntimeFactory;
|
|
46
48
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Exclusively reserve a default export; failure cleanup may remove only this same regular file. */
|
|
2
|
+
export declare function reserveUserExport(sessionId: string, format: "html" | "jsonl", home?: string): Promise<{
|
|
3
|
+
readonly path: string;
|
|
4
|
+
failed(): Promise<void>;
|
|
5
|
+
}>;
|