@timurproko/a1 0.2.7-dev.809 → 0.2.7-dev.820
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 +4 -2
- package/dist/app/session-shell/resident-tab-coordinator.d.ts +6 -9
- package/dist/app/session-shell/resident-tab-coordinator.js +9 -52
- package/dist/app/session-shell/response-copy-transport.d.ts +13 -0
- package/dist/app/session-shell/response-copy-transport.js +16 -7
- package/dist/app/session-shell/session-shell-root.d.ts +1 -2
- package/dist/app/session-shell/session-shell.js +2 -2
- package/dist/app/session-shell/session-viewport-controller.js +6 -4
- package/dist/composition/owned-ui.js +1 -2
- package/dist/features/owned-ui/settings-app.js +1 -1
- package/dist/foundation/release/progress-palette.generated.d.ts +2 -2
- package/dist/foundation/release/progress-palette.generated.js +2 -2
- package/dist/foundation/resident-tabs/bridge-client.d.ts +1 -1
- package/dist/foundation/resident-tabs/bridge-client.js +1 -1
- package/dist/foundation/resident-tabs/settings.d.ts +0 -1
- package/dist/foundation/resident-tabs/settings.js +0 -2
- package/dist/foundation/startup/startup-descriptor.js +2 -2
- 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-extension-ui.js +79 -60
- 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/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 +1 -1
- 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/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 +1 -1
- 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/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.d.ts +2 -4
- package/dist/integrations/pi/components/upstream/components/tool-execution.js +77 -98
- package/dist/integrations/pi/components/upstream/components/tree-selector.d.ts +1 -1
- package/dist/integrations/pi/components/upstream/components/tree-selector.js +1 -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/program-status-reporter.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/resources/changelog.json +4 -4
- package/dist/integrations/pi/startup-public.js +164 -150
- package/dist/integrations/pi/startup-public.manifest.json +351 -310
- package/dist/integrations/pi/tui-runtime/adapter.js +4 -0
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +5 -0
- 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/darwin-arm64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +1 -1
- package/dist/native/darwin-x64/terminal-host.manifest.json +3 -3
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/linux-x64/terminal-host.manifest.json +3 -3
- package/dist/native/linux-x64/terminal-host.node +0 -0
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host.manifest.json +3 -3
- package/dist/native/win32-x64/terminal-host.node +0 -0
- package/dist/runtime-payload-inventory.json +5181 -5369
- package/dist/ui/components/dialog-panel.js +1 -1
- package/dist/ui/components/prompt-input.d.ts +2 -2
- package/dist/ui/components/prompt-input.js +2 -2
- package/dist/ui/components/submitted-prompt.d.ts +2 -2
- package/dist/ui/components/submitted-prompt.js +3 -3
- package/dist/ui/components/transcript-viewport.d.ts +1 -1
- package/dist/ui/components/transcript-viewport.js +151 -43
- package/dist/ui/settings/declarations.d.ts +13 -9
- package/dist/ui/settings/declarations.js +10 -7
- package/dist/ui/settings/migrations.js +7 -0
- package/docs/architecture/resident-tabs.md +6 -6
- package/docs/architecture/response-copy-delivery.md +1 -1
- package/docs/architecture/toolchain.md +2 -2
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -185,13 +185,15 @@ a1 update npm:pi-mcp-adapter
|
|
|
185
185
|
|
|
186
186
|
## Develop
|
|
187
187
|
|
|
188
|
+
A source build needs Node.js, npm, git, and Rustup. Windows additionally needs Visual Studio or Visual Studio Build Tools with the **Desktop development with C++** workload, MSVC x64/x86 tools, and a Windows SDK; Visual Studio Code is not required. A1 discovers installed Rustup and Visual Studio tools and initializes them for build children, so Git Bash and ordinary PowerShell do not need manual `PATH` or developer-shell setup. It never installs these tools or accepts their licenses automatically.
|
|
189
|
+
|
|
188
190
|
Install exact locked dependencies:
|
|
189
191
|
|
|
190
192
|
```text
|
|
191
193
|
npm ci
|
|
192
194
|
```
|
|
193
195
|
|
|
194
|
-
Compile TypeScript and the
|
|
196
|
+
Compile TypeScript and the native addons into `dist`:
|
|
195
197
|
|
|
196
198
|
```text
|
|
197
199
|
npm run build
|
|
@@ -221,7 +223,7 @@ Complete non-physical suite:
|
|
|
221
223
|
npm run test:full
|
|
222
224
|
```
|
|
223
225
|
|
|
224
|
-
Report Node, npm, git, Rust, and
|
|
226
|
+
Report Node, npm, git, Rust, dependency, and Windows C++ readiness. Missing Windows tools are listed in setup order; after installing them, rerun the same build command:
|
|
225
227
|
|
|
226
228
|
```text
|
|
227
229
|
npm run doctor
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
import type { OwnedUiEvent, PromptHistoryImageSidecarPort } from "../../contracts/owned-ui/index.js";
|
|
2
2
|
import type { SessionConcern } from "./session-concern.js";
|
|
3
3
|
import type { OwnedUiShellEngineOptions, OwnedUiSessionShellRoot } from "./session-shell-root.js";
|
|
4
|
-
import type { OwnedUiPresenterTerminal } from "./shell-host.js";
|
|
5
4
|
export type ResidentTabOptions = NonNullable<OwnedUiShellEngineOptions["residentTab"]>;
|
|
6
5
|
export interface ResidentTabCoordinatorPorts {
|
|
7
6
|
readonly root: Pick<OwnedUiSessionShellRoot, "appendWorkflowStatus" | "rehydrateHistoryText" | "editor">;
|
|
8
|
-
readonly terminal: Pick<OwnedUiPresenterTerminal, "requestRender">;
|
|
9
|
-
readonly disposed: () => boolean;
|
|
10
7
|
}
|
|
11
8
|
/**
|
|
12
|
-
* The session presenter's side of a resident tab: recovered input, the
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* The session presenter's side of a resident tab: recovered input, the idle status it reports to
|
|
10
|
+
* the strip, prompt admission and correlation through the recovery journal, draft checkpoints,
|
|
11
|
+
* detach on quit, and the graceful stop when the presenter is released. Outside a resident tab
|
|
12
|
+
* every operation is a no-op.
|
|
16
13
|
*/
|
|
17
14
|
export declare class ResidentTabCoordinator implements SessionConcern {
|
|
18
15
|
#private;
|
|
@@ -23,8 +20,8 @@ export declare class ResidentTabCoordinator implements SessionConcern {
|
|
|
23
20
|
closeOwnedRoute(route: string): void;
|
|
24
21
|
/** Puts the prompts and draft a previous tab process left unfinished back into the editor. */
|
|
25
22
|
restoreInput(imageSidecar?: PromptHistoryImageSidecarPort): void;
|
|
26
|
-
/**
|
|
27
|
-
|
|
23
|
+
/** Reports idle to the strip whenever the session leaves its busy lifecycle. */
|
|
24
|
+
observeLifecycle(event: OwnedUiEvent): void;
|
|
28
25
|
/** Journals a prompt before it is sent; undefined outside a resident tab. Rejects when the journal cannot sync. */
|
|
29
26
|
admit(input: Parameters<NonNullable<ResidentTabOptions["admit"]>>[0]): Promise<{
|
|
30
27
|
readonly id: string;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
const PROGRESS_EVENTS = new Set([
|
|
2
|
-
"transcript-block", "session-view", "assistant-message-completed", "agent-run-started",
|
|
3
|
-
]);
|
|
4
1
|
/**
|
|
5
|
-
* The session presenter's side of a resident tab: recovered input, the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
2
|
+
* The session presenter's side of a resident tab: recovered input, the idle status it reports to
|
|
3
|
+
* the strip, prompt admission and correlation through the recovery journal, draft checkpoints,
|
|
4
|
+
* detach on quit, and the graceful stop when the presenter is released. Outside a resident tab
|
|
5
|
+
* every operation is a no-op.
|
|
9
6
|
*/
|
|
10
7
|
export class ResidentTabCoordinator {
|
|
11
8
|
#options;
|
|
12
9
|
#ports;
|
|
13
|
-
#progressTimer;
|
|
14
|
-
#working = false;
|
|
15
|
-
#stalled = false;
|
|
16
10
|
constructor(options, ports) {
|
|
17
11
|
this.#options = options;
|
|
18
12
|
this.#ports = ports;
|
|
@@ -51,40 +45,10 @@ export class ResidentTabCoordinator {
|
|
|
51
45
|
root.appendWorkflowStatus("Recovered the editor draft from the previous tab process.");
|
|
52
46
|
}
|
|
53
47
|
}
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (resident === undefined || seconds === undefined)
|
|
59
|
-
return;
|
|
60
|
-
if (event.type === "session-lifecycle") {
|
|
61
|
-
this.#working = event.lifecycle === "busy";
|
|
62
|
-
if (!this.#working) {
|
|
63
|
-
this.#clearTimer();
|
|
64
|
-
this.#stalled = false;
|
|
65
|
-
resident.reportStatus?.("idle");
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
else if (!this.#working || !PROGRESS_EVENTS.has(event.type)) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
if (this.#stalled) {
|
|
73
|
-
this.#stalled = false;
|
|
74
|
-
resident.reportStatus?.("working");
|
|
75
|
-
}
|
|
76
|
-
this.#clearTimer();
|
|
77
|
-
this.#progressTimer = setTimeout(() => {
|
|
78
|
-
this.#progressTimer = undefined;
|
|
79
|
-
if (this.#ports.disposed() || !this.#working)
|
|
80
|
-
return;
|
|
81
|
-
this.#stalled = true;
|
|
82
|
-
resident.reportStatus?.("stalled");
|
|
83
|
-
const minutes = Math.max(1, Math.round(seconds / 60));
|
|
84
|
-
this.#ports.root.appendWorkflowStatus(`No progress for ${minutes} min — Esc interrupts · use the tab restart action to restart`);
|
|
85
|
-
this.#ports.terminal.requestRender();
|
|
86
|
-
}, seconds * 1_000);
|
|
87
|
-
this.#progressTimer.unref?.();
|
|
48
|
+
/** Reports idle to the strip whenever the session leaves its busy lifecycle. */
|
|
49
|
+
observeLifecycle(event) {
|
|
50
|
+
if (event.type === "session-lifecycle" && event.lifecycle !== "busy")
|
|
51
|
+
this.#options?.reportStatus?.("idle");
|
|
88
52
|
}
|
|
89
53
|
/** Journals a prompt before it is sent; undefined outside a resident tab. Rejects when the journal cannot sync. */
|
|
90
54
|
admit(input) {
|
|
@@ -109,12 +73,5 @@ export class ResidentTabCoordinator {
|
|
|
109
73
|
gracefulStop(sessionFile) {
|
|
110
74
|
return this.#options?.gracefulStop?.(sessionFile) ?? Promise.resolve();
|
|
111
75
|
}
|
|
112
|
-
dispose() {
|
|
113
|
-
this.#clearTimer();
|
|
114
|
-
}
|
|
115
|
-
#clearTimer() {
|
|
116
|
-
if (this.#progressTimer !== undefined)
|
|
117
|
-
clearTimeout(this.#progressTimer);
|
|
118
|
-
this.#progressTimer = undefined;
|
|
119
|
-
}
|
|
76
|
+
dispose() { }
|
|
120
77
|
}
|
|
@@ -22,6 +22,19 @@ export interface ResponseCopyTerminal {
|
|
|
22
22
|
}
|
|
23
23
|
/** Never substitute a remote host's native clipboard for the terminal user's clipboard. */
|
|
24
24
|
export declare function responseCopyDestination(env: NodeJS.ProcessEnv): "native" | "terminal";
|
|
25
|
+
/**
|
|
26
|
+
* Spawn options for one operating-system clipboard writer.
|
|
27
|
+
* Platform: on POSIX the writer is detached into its own process group, as pinned Pi 1.4 does, so a writer
|
|
28
|
+
* that daemonizes to keep serving the clipboard is not stopped when Ctrl+Z sends SIGTSTP to the shell's group.
|
|
29
|
+
*/
|
|
30
|
+
export declare function platformClipboardWriteOptions(signal: AbortSignal, platform?: NodeJS.Platform): {
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
windowsHide: boolean;
|
|
33
|
+
timeout: number;
|
|
34
|
+
killSignal: "SIGKILL";
|
|
35
|
+
maxBuffer: number;
|
|
36
|
+
detached: boolean;
|
|
37
|
+
};
|
|
25
38
|
/** Isolates preparation and native clipboard access; only the owner may submit terminal controls. */
|
|
26
39
|
export declare function createResponseCopyExecutor(options?: {
|
|
27
40
|
readonly terminal?: ResponseCopyTerminal;
|
|
@@ -21,6 +21,21 @@ function platformClipboardCommands() {
|
|
|
21
21
|
{ command: "xclip", args: ["-selection", "clipboard", "-in"] },
|
|
22
22
|
];
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Spawn options for one operating-system clipboard writer.
|
|
26
|
+
* Platform: on POSIX the writer is detached into its own process group, as pinned Pi 1.4 does, so a writer
|
|
27
|
+
* that daemonizes to keep serving the clipboard is not stopped when Ctrl+Z sends SIGTSTP to the shell's group.
|
|
28
|
+
*/
|
|
29
|
+
export function platformClipboardWriteOptions(signal, platform = process.platform) {
|
|
30
|
+
return {
|
|
31
|
+
signal,
|
|
32
|
+
windowsHide: true,
|
|
33
|
+
timeout: PLATFORM_WRITE_TIMEOUT_MS,
|
|
34
|
+
killSignal: "SIGKILL",
|
|
35
|
+
maxBuffer: 1_024,
|
|
36
|
+
detached: platform !== "win32",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
24
39
|
async function writePlatformClipboardText(text, signal) {
|
|
25
40
|
for (const route of platformClipboardCommands()) {
|
|
26
41
|
if (signal.aborted)
|
|
@@ -33,13 +48,7 @@ async function writePlatformClipboardText(text, signal) {
|
|
|
33
48
|
settled = true;
|
|
34
49
|
resolve(value);
|
|
35
50
|
};
|
|
36
|
-
const child = execFile(route.command, [...route.args],
|
|
37
|
-
signal,
|
|
38
|
-
windowsHide: true,
|
|
39
|
-
timeout: PLATFORM_WRITE_TIMEOUT_MS,
|
|
40
|
-
killSignal: "SIGKILL",
|
|
41
|
-
maxBuffer: 1_024,
|
|
42
|
-
}, error => done(error === null));
|
|
51
|
+
const child = execFile(route.command, [...route.args], platformClipboardWriteOptions(signal), error => done(error === null));
|
|
43
52
|
child.once("error", () => done(false));
|
|
44
53
|
if (child.stdin === null) {
|
|
45
54
|
child.kill("SIGKILL");
|
|
@@ -47,8 +47,7 @@ export interface OwnedUiShellEngineOptions {
|
|
|
47
47
|
readonly residentTab?: {
|
|
48
48
|
requestDetach(): Promise<boolean>;
|
|
49
49
|
closeOwnedRoute?(route: string): void;
|
|
50
|
-
reportStatus?(status: "working" | "idle"
|
|
51
|
-
readonly stallNoticeSeconds?: number;
|
|
50
|
+
reportStatus?(status: "working" | "idle"): void;
|
|
52
51
|
admit?(input: {
|
|
53
52
|
readonly sessionId: string;
|
|
54
53
|
readonly sessionFile: string | null;
|
|
@@ -251,7 +251,7 @@ export class OwnedUiSessionPresenter {
|
|
|
251
251
|
// Invariant: the presenter owns its root (theme subscription and helper clients) and disposes it once the
|
|
252
252
|
// terminal no longer renders it.
|
|
253
253
|
constructed.push(() => this.root.dispose());
|
|
254
|
-
this.#resident = new ResidentTabCoordinator(options.engine.residentTab, { root: this.root
|
|
254
|
+
this.#resident = new ResidentTabCoordinator(options.engine.residentTab, { root: this.root });
|
|
255
255
|
constructed.push(() => this.#resident.dispose());
|
|
256
256
|
const startupRoute = options.engine.startupRoute;
|
|
257
257
|
this.#dialogs = new SessionDialogCoordinator({
|
|
@@ -366,7 +366,7 @@ export class OwnedUiSessionPresenter {
|
|
|
366
366
|
this.#stop.settleAfter(() => this.dispose());
|
|
367
367
|
return;
|
|
368
368
|
}
|
|
369
|
-
this.#resident.
|
|
369
|
+
this.#resident.observeLifecycle(event);
|
|
370
370
|
// Performance: a streamed chunk names one block, and touching only that block is what keeps the
|
|
371
371
|
// cost of a chunk the same in a long session as in a new one. Everything else
|
|
372
372
|
// resynchronizes the view, which is cheap next to re-reading the transcript.
|
|
@@ -322,8 +322,8 @@ export class SessionViewportController {
|
|
|
322
322
|
this.#requestRender();
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
const previousPrompt =
|
|
326
|
-
if (editorActive && allowWheel && (previousPrompt ||
|
|
325
|
+
const previousPrompt = PROMPT_UP_INPUTS.has(data) || this.#editor.matchesTerminalKey(data, "alt+home");
|
|
326
|
+
if (editorActive && allowWheel && (previousPrompt || PROMPT_DOWN_INPUTS.has(data))) {
|
|
327
327
|
const scrolled = previousPrompt
|
|
328
328
|
? this.#viewport.scrollToPreviousPrompt(now)
|
|
329
329
|
: this.#viewport.scrollToNextPrompt(now);
|
|
@@ -670,5 +670,7 @@ export class SessionViewportController {
|
|
|
670
670
|
}
|
|
671
671
|
const SELECTION_AUTO_SCROLL_INTERVAL_MS = 30;
|
|
672
672
|
const EDITOR_LINK_DELETION_INPUTS = new Set(["\b", "\u007f", "\u001b[3~"]);
|
|
673
|
-
|
|
674
|
-
|
|
673
|
+
// Platform: Windows Terminal may consume Shift+Arrow for native selection. Ctrl+Arrow matches
|
|
674
|
+
// solo A1's Windows binding while retaining Shift+Arrow whenever the terminal delivers it.
|
|
675
|
+
const PROMPT_UP_INPUTS = new Set(["\u001b[1;2A", "\u001b[1;5A"]);
|
|
676
|
+
const PROMPT_DOWN_INPUTS = new Set(["\u001b[1;2B", "\u001b[1;5B"]);
|
|
@@ -50,7 +50,7 @@ export async function composeOwnedUi(options = {}) {
|
|
|
50
50
|
namespace: PRODUCT_IDENTITY.commandName,
|
|
51
51
|
legacyConfigDir: productPaths.configDir,
|
|
52
52
|
agentProvider: () => backend.settingsPort(),
|
|
53
|
-
...(options.hideTabSettings ? { hiddenOwnedSettingIds: ["tabsAutoName"] } : {}),
|
|
53
|
+
...(options.hideTabSettings ? { hiddenOwnedSettingIds: ["tabsAutoName", "tabsPosition"] } : {}),
|
|
54
54
|
hiddenAgentSettingIds: ["fullscreenWheelScrollLines"],
|
|
55
55
|
agentSettingLabelOverrides: { fullscreenCopyOnSelect: "Copy on select" },
|
|
56
56
|
});
|
|
@@ -221,7 +221,6 @@ export async function composeOwnedUi(options = {}) {
|
|
|
221
221
|
void tabBridge.requestClose();
|
|
222
222
|
},
|
|
223
223
|
reportStatus: status => tabBridge.status(status),
|
|
224
|
-
stallNoticeSeconds: 300,
|
|
225
224
|
admit: input => tabRecovery.admit({ ...input, incarnation: options.tab.incarnation }),
|
|
226
225
|
dispatched: () => tabRecovery.dispatched(),
|
|
227
226
|
correlated: (submissionId, entryId) => correlateResidentTabSubmission(tabRecovery, backend, submissionId, entryId),
|
|
@@ -1026,7 +1026,7 @@ export class SettingsApp {
|
|
|
1026
1026
|
const input = this.#filter;
|
|
1027
1027
|
if (input === null)
|
|
1028
1028
|
return [status];
|
|
1029
|
-
return [...renderInputRow(input, width, { placeholder: SEARCH_PLACEHOLDER, theme }).lines, status];
|
|
1029
|
+
return [...renderInputRow(input, width, { placeholder: SEARCH_PLACEHOLDER, promptGlyph: "", theme }).lines, status];
|
|
1030
1030
|
}
|
|
1031
1031
|
}
|
|
1032
1032
|
function modelLabelParts(label) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by scripts/pi/sync-progress-palette.ts from @earendil-works/pi-coding-agent 1.
|
|
3
|
-
* (MIT), commit
|
|
2
|
+
* Generated by scripts/pi/sync-progress-palette.ts from @earendil-works/pi-coding-agent 1.4.0
|
|
3
|
+
* (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0. Do not edit directly.
|
|
4
4
|
*/
|
|
5
5
|
export declare const SHARED_PROGRESS_ACCENT_ANSI = "\u001B[38;2;167;152;215m";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by scripts/pi/sync-progress-palette.ts from @earendil-works/pi-coding-agent 1.
|
|
3
|
-
* (MIT), commit
|
|
2
|
+
* Generated by scripts/pi/sync-progress-palette.ts from @earendil-works/pi-coding-agent 1.4.0
|
|
3
|
+
* (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0. Do not edit directly.
|
|
4
4
|
*/
|
|
5
5
|
export const SHARED_PROGRESS_ACCENT_ANSI = "\u001b[38;2;167;152;215m";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ResidentTabStatus = "starting" | "working" | "needs-input" | "done-unseen" | "done" | "aborted" | "error" | "idle" | "unresponsive" | "
|
|
1
|
+
export type ResidentTabStatus = "starting" | "working" | "needs-input" | "done-unseen" | "done" | "aborted" | "error" | "idle" | "unresponsive" | "crashed" | "restarting" | "failed";
|
|
2
2
|
export interface TabBridgeCredentials {
|
|
3
3
|
readonly tabId: string;
|
|
4
4
|
readonly token: string;
|
|
@@ -80,7 +80,7 @@ export class TabBridgeClient {
|
|
|
80
80
|
}
|
|
81
81
|
status(state, degraded = false, pendingRequests = 0, queuedInput = 0) {
|
|
82
82
|
this.#latestStatus = { state, degraded, accent: this.#accent, pendingRequests, queuedInput };
|
|
83
|
-
const recoveryState = state === "unresponsive" || state === "
|
|
83
|
+
const recoveryState = state === "unresponsive" || state === "crashed" || state === "restarting" || state === "failed";
|
|
84
84
|
if (recoveryState && !this.#supports("recovery-status"))
|
|
85
85
|
return;
|
|
86
86
|
this.#send("bridge.status", {
|
|
@@ -7,7 +7,6 @@ export interface ResidentTabLaunchSettings {
|
|
|
7
7
|
readonly maxConcurrentStarts: number;
|
|
8
8
|
readonly prewarmCount: number;
|
|
9
9
|
readonly unresponsiveRestartSeconds: number;
|
|
10
|
-
readonly stallNoticeSeconds: number;
|
|
11
10
|
}
|
|
12
11
|
/** Read only resident-launch values before any UI or extension module is loaded. */
|
|
13
12
|
export declare function readResidentTabLaunchSettings(profileDir: string, namespace?: string, legacyConfigDir?: string, profileId?: string): Promise<ResidentTabLaunchSettings>;
|
|
@@ -11,7 +11,6 @@ const DEFAULTS = Object.freeze({
|
|
|
11
11
|
maxConcurrentStarts: RESIDENT_TABS_MAX_CONCURRENT_STARTS,
|
|
12
12
|
prewarmCount: RESIDENT_TABS_PREWARM_COUNT,
|
|
13
13
|
unresponsiveRestartSeconds: 120,
|
|
14
|
-
stallNoticeSeconds: 300,
|
|
15
14
|
});
|
|
16
15
|
/** Read only resident-launch values before any UI or extension module is loaded. */
|
|
17
16
|
export async function readResidentTabLaunchSettings(profileDir, namespace = "a1", legacyConfigDir, profileId = namespace) {
|
|
@@ -55,6 +54,5 @@ function resolveLaunchValues(document, migrations) {
|
|
|
55
54
|
maxConcurrentStarts: RESIDENT_TABS_MAX_CONCURRENT_STARTS,
|
|
56
55
|
prewarmCount: RESIDENT_TABS_PREWARM_COUNT,
|
|
57
56
|
unresponsiveRestartSeconds: DEFAULTS.unresponsiveRestartSeconds,
|
|
58
|
-
stallNoticeSeconds: DEFAULTS.stallNoticeSeconds,
|
|
59
57
|
};
|
|
60
58
|
}
|
|
@@ -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": "e065933fe374d7953c5aac0ff1735fa47d119ab97551e955c2a65e8c2df667eb"
|
|
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": "5c1afab4657c251b840e042279290bd1fa03ce608bc81bc6e7eaf8d332486eef"
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
export function loadDeclaredStartupGraph() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.
|
|
3
|
-
* commit
|
|
2
|
+
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.4.0 (MIT),
|
|
3
|
+
* commit 4a080252f06caf63a525d7873c5d94d3c23887e0.
|
|
4
4
|
* Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
|
|
5
5
|
* Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
|
|
6
6
|
* Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.
|
|
3
|
-
* commit
|
|
2
|
+
* Attributed owned theme resources adapted from @earendil-works/pi-coding-agent 1.4.0 (MIT),
|
|
3
|
+
* commit 4a080252f06caf63a525d7873c5d94d3c23887e0.
|
|
4
4
|
* Upstream dark.json SHA-256: e1f96982f8cb7d2a48eca7db03c9cb282cb1e14a243680cd855638ecd6a251b6
|
|
5
5
|
* Upstream light.json SHA-256: 2dee6a4be7f765e7fd7728166b7ebf8c29e4ce313f8ec6b38ae50699e3abc2f3
|
|
6
6
|
* Modifications: removed upstream schema/export metadata; runtime color data is unchanged.
|
|
@@ -15,22 +15,8 @@ export function createPiExtensionUiBridge(host) {
|
|
|
15
15
|
const keybindings = KeybindingsManager.create(host.agentDir);
|
|
16
16
|
const disposers = new Set();
|
|
17
17
|
let customEditorFactory;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const closeSurface = (surface) => {
|
|
21
|
-
if (surface !== undefined && activeSurface !== surface)
|
|
22
|
-
return;
|
|
23
|
-
activeSurface = undefined;
|
|
24
|
-
host.setInputSurface(null);
|
|
25
|
-
host.runtime.requestRender();
|
|
26
|
-
};
|
|
27
|
-
const mountSurface = (surface) => {
|
|
28
|
-
if (activeSurface !== undefined && activeSurface !== surface)
|
|
29
|
-
activeSurface.dispose?.();
|
|
30
|
-
activeSurface = surface;
|
|
31
|
-
host.setInputSurface(surface);
|
|
32
|
-
host.runtime.requestRender();
|
|
33
|
-
};
|
|
18
|
+
const dialogs = createExtensionDialogStack(host);
|
|
19
|
+
const overlayCancels = new Set();
|
|
34
20
|
const trackAbort = (signal, cancel) => {
|
|
35
21
|
if (signal === undefined)
|
|
36
22
|
return () => { };
|
|
@@ -54,26 +40,24 @@ export function createPiExtensionUiBridge(host) {
|
|
|
54
40
|
if (settled)
|
|
55
41
|
return;
|
|
56
42
|
settled = true;
|
|
57
|
-
if (activeCancel === cancel)
|
|
58
|
-
activeCancel = undefined;
|
|
59
43
|
untrack();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
44
|
+
if (surface !== undefined) {
|
|
45
|
+
const retained = retainSurfaceOnSettle && dialogs.isOnly(surface);
|
|
46
|
+
// Rationale: like pinned Pi, a settled dialog is disposed so its countdown stops, unless it stays painted.
|
|
47
|
+
if (!retained)
|
|
48
|
+
surface.dispose?.();
|
|
49
|
+
dialogs.remove(surface, retained);
|
|
50
|
+
}
|
|
67
51
|
resolve(value);
|
|
68
52
|
};
|
|
69
53
|
const cancel = () => finish(undefined);
|
|
70
|
-
|
|
54
|
+
const created = create(finish, cancel);
|
|
55
|
+
surface = created;
|
|
71
56
|
untrack = trackAbort(options?.signal, cancel);
|
|
72
|
-
if (!settled)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
57
|
+
if (!settled)
|
|
58
|
+
dialogs.push({ surface: created, blocked, cancel });
|
|
59
|
+
else
|
|
60
|
+
created.dispose?.();
|
|
77
61
|
});
|
|
78
62
|
const createFactoryComponent = (factory, ...arguments_) => {
|
|
79
63
|
if (typeof factory !== "function")
|
|
@@ -148,28 +132,26 @@ export function createPiExtensionUiBridge(host) {
|
|
|
148
132
|
let settled = false;
|
|
149
133
|
let surface;
|
|
150
134
|
let overlay;
|
|
151
|
-
const
|
|
152
|
-
if (settled)
|
|
153
|
-
return;
|
|
154
|
-
settled = true;
|
|
155
|
-
if (activeCancel === cancelCustom)
|
|
156
|
-
activeCancel = undefined;
|
|
157
|
-
overlay?.hide();
|
|
158
|
-
if (surface !== undefined)
|
|
159
|
-
closeSurface(surface);
|
|
160
|
-
resolve(value);
|
|
161
|
-
};
|
|
162
|
-
const cancelCustom = () => {
|
|
135
|
+
const close = (settle) => {
|
|
163
136
|
if (settled)
|
|
164
137
|
return;
|
|
165
138
|
settled = true;
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
overlay
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
139
|
+
overlayCancels.delete(cancelCustom);
|
|
140
|
+
// Invariant: remove this dialog or overlay, not the topmost one; another may have opened above it.
|
|
141
|
+
if (overlay !== undefined)
|
|
142
|
+
overlay.hide();
|
|
143
|
+
else if (surface !== undefined)
|
|
144
|
+
dialogs.remove(surface);
|
|
145
|
+
settle();
|
|
146
|
+
if (overlay === undefined) {
|
|
147
|
+
try {
|
|
148
|
+
surface?.dispose?.();
|
|
149
|
+
}
|
|
150
|
+
catch { /* Rationale: a settled dialog's dispose failure must not leak. */ }
|
|
151
|
+
}
|
|
172
152
|
};
|
|
153
|
+
const done = (value) => close(() => resolve(value));
|
|
154
|
+
const cancelCustom = () => close(() => Reflect.apply(resolve, undefined, []));
|
|
173
155
|
let created;
|
|
174
156
|
try {
|
|
175
157
|
created = Reflect.apply(factory, undefined, [tui, piTheme(), keybindings, done]);
|
|
@@ -187,19 +169,18 @@ export function createPiExtensionUiBridge(host) {
|
|
|
187
169
|
return;
|
|
188
170
|
}
|
|
189
171
|
surface = withPiDialogCancel(componentPort(component), cancelCustom);
|
|
190
|
-
activeCancel = cancelCustom;
|
|
191
172
|
if (options?.overlay) {
|
|
192
173
|
const overlayOptions = typeof options.overlayOptions === "function" ? options.overlayOptions() : options.overlayOptions;
|
|
174
|
+
overlayCancels.add(cancelCustom);
|
|
193
175
|
overlay = host.showOverlay(surface, overlayOptions);
|
|
194
176
|
options.onHandle?.(publicOverlayHandle(overlay));
|
|
195
177
|
}
|
|
196
178
|
else
|
|
197
|
-
|
|
179
|
+
dialogs.push({ surface, blocked: undefined, cancel: cancelCustom });
|
|
198
180
|
}).catch(error => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
closeSurface(surface);
|
|
181
|
+
overlayCancels.delete(cancelCustom);
|
|
182
|
+
if (surface !== undefined && overlay === undefined)
|
|
183
|
+
dialogs.remove(surface);
|
|
203
184
|
reject(error);
|
|
204
185
|
});
|
|
205
186
|
}),
|
|
@@ -251,11 +232,9 @@ export function createPiExtensionUiBridge(host) {
|
|
|
251
232
|
setToolsExpanded: expanded => host.setToolsExpanded(expanded),
|
|
252
233
|
};
|
|
253
234
|
const reset = () => {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
activeSurface?.dispose?.();
|
|
258
|
-
activeSurface = undefined;
|
|
235
|
+
dialogs.cancelAll();
|
|
236
|
+
for (const cancel of [...overlayCancels])
|
|
237
|
+
cancel();
|
|
259
238
|
host.setInputSurface(null);
|
|
260
239
|
host.setProgramStatusBlocked(undefined);
|
|
261
240
|
};
|
|
@@ -276,6 +255,46 @@ export function createPiExtensionUiBridge(host) {
|
|
|
276
255
|
},
|
|
277
256
|
};
|
|
278
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Pinned Pi's extension dialog stack over the shell's single input slot. The last entry is visible; closing it shows
|
|
260
|
+
* the previous one with its program status, and a covered dialog stays answerable, so no dialog promise is left pending.
|
|
261
|
+
*/
|
|
262
|
+
function createExtensionDialogStack(host) {
|
|
263
|
+
const dialogs = [];
|
|
264
|
+
const showTop = () => {
|
|
265
|
+
const top = dialogs.at(-1);
|
|
266
|
+
host.setInputSurface(top?.surface ?? null);
|
|
267
|
+
host.setProgramStatusBlocked(top?.blocked);
|
|
268
|
+
host.runtime.requestRender();
|
|
269
|
+
};
|
|
270
|
+
return {
|
|
271
|
+
push(dialog) {
|
|
272
|
+
dialogs.push(dialog);
|
|
273
|
+
showTop();
|
|
274
|
+
},
|
|
275
|
+
/** Only removing the visible dialog changes the slot; a retained last surface stays painted without its status. */
|
|
276
|
+
remove(surface, retainSurface = false) {
|
|
277
|
+
const index = dialogs.findIndex(dialog => dialog.surface === surface);
|
|
278
|
+
if (index === -1)
|
|
279
|
+
return;
|
|
280
|
+
dialogs.splice(index, 1);
|
|
281
|
+
if (index !== dialogs.length)
|
|
282
|
+
return;
|
|
283
|
+
if (!retainSurface || dialogs.length > 0)
|
|
284
|
+
return showTop();
|
|
285
|
+
host.setProgramStatusBlocked(undefined);
|
|
286
|
+
host.runtime.requestRender();
|
|
287
|
+
},
|
|
288
|
+
isOnly: (surface) => dialogs.length === 1 && dialogs[0].surface === surface,
|
|
289
|
+
/** Rationale: unlike pinned Pi, which drops stacked dialogs unresolved, A1 settles each as cancelled, top first. */
|
|
290
|
+
cancelAll() {
|
|
291
|
+
for (const dialog of [...dialogs].reverse())
|
|
292
|
+
dialog.cancel();
|
|
293
|
+
for (const dialog of dialogs.splice(0))
|
|
294
|
+
dialog.surface.dispose?.();
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
279
298
|
function extensionError(surface, error) {
|
|
280
299
|
return `Extension ${surface} failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
281
300
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provenance: @earendil-works/pi-coding-agent 1.
|
|
2
|
+
* Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
|
|
3
3
|
* packages/coding-agent/src/core/keybindings.ts.
|
|
4
4
|
* Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
|
|
5
5
|
* resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provenance: @earendil-works/pi-coding-agent 1.
|
|
2
|
+
* Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
|
|
3
3
|
* packages/coding-agent/src/core/keybindings.ts.
|
|
4
4
|
* Modifications: Mechanical source port with Node import prefixes, public package-root agent-directory
|
|
5
5
|
* resolution, and an opt-in bare-A1 input profile including Ctrl+L level cycling, unbound model
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sourcePackage": "@earendil-works/pi-coding-agent",
|
|
3
|
-
"sourceVersion": "1.
|
|
3
|
+
"sourceVersion": "1.4.0",
|
|
4
4
|
"upstreamRepository": "https://github.com/earendil-works/pi.git",
|
|
5
|
-
"upstreamCommit": "
|
|
5
|
+
"upstreamCommit": "4a080252f06caf63a525d7873c5d94d3c23887e0",
|
|
6
6
|
"sourcePath": "dist/modes/interactive/assets/clankolas.png",
|
|
7
7
|
"sourceSha256": "169acd0dfe6fbb8d8742ed24a3fc654fd0b2e2d4223c733249c5493723f1b72d",
|
|
8
8
|
"license": "MIT",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provenance: @earendil-works/pi-coding-agent 1.
|
|
2
|
+
* Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/countdown-timer.ts.
|
|
4
4
|
* Modifications: Mechanical source port with ECMAScript private fields; imports remain on the public
|
|
5
5
|
* Pi TUI package root.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provenance: @earendil-works/pi-coding-agent 1.
|
|
2
|
+
* Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/earendil-announcement.ts.
|
|
4
4
|
* Modifications: Mechanical pinned source port with private imports remapped to public package-root
|
|
5
5
|
* types/APIs and A1-owned theme boundaries. The unchanged image is loaded lazily from its attributed,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Provenance: @earendil-works/pi-coding-agent 1.
|
|
2
|
+
* Provenance: @earendil-works/pi-coding-agent 1.4.0 (MIT), commit 4a080252f06caf63a525d7873c5d94d3c23887e0,
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/extension-editor.ts.
|
|
4
4
|
* Modifications: Mechanical port: remap pi-tui to the root public singleton, use owned
|
|
5
5
|
* keybindings/theme and external-editor seams, preserve editor layout, hints, focus, submission,
|