@timurproko/a1 0.2.7-dev.1255 → 0.2.7-dev.1264
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/session-shell/prompt-submission.d.ts +1 -1
- package/dist/app/session-shell/prompt-submission.js +9 -9
- package/dist/app/session-shell/resource-labels.d.ts +2 -0
- package/dist/app/session-shell/resource-labels.js +158 -0
- package/dist/app/session-shell/session-prompt-history.d.ts +29 -0
- package/dist/app/session-shell/session-prompt-history.js +80 -0
- package/dist/app/session-shell/session-selectors.d.ts +46 -0
- package/dist/app/session-shell/session-selectors.js +269 -0
- package/dist/app/session-shell/session-shell-root.d.ts +6 -28
- package/dist/app/session-shell/session-shell-root.js +26 -220
- package/dist/app/session-shell/session-shell.d.ts +3 -23
- package/dist/app/session-shell/session-shell.js +54 -365
- package/dist/app/session-shell/session-viewport-controller.d.ts +2 -10
- package/dist/app/session-shell/session-viewport-controller.js +40 -318
- package/dist/app/session-shell/settings-bindings.d.ts +1 -1
- package/dist/app/session-shell/settings-bindings.js +2 -2
- package/dist/app/session-shell/viewport-pointer.d.ts +83 -0
- package/dist/app/session-shell/viewport-pointer.js +361 -0
- package/dist/composition/owned-ui.js +63 -59
- package/dist/contracts/owned-ui/index.d.ts +1 -1
- package/dist/contracts/owned-ui/index.js +1 -1
- package/dist/contracts/owned-ui/validation.d.ts +1 -11
- package/dist/contracts/owned-ui/validation.js +8 -104
- package/dist/contracts/presentation/index.d.ts +1 -1
- package/dist/contracts/presentation/terminal.d.ts +0 -6
- package/dist/features/owned-ui/settings-app.js +13 -208
- package/dist/features/owned-ui/settings-model-dialog.d.ts +41 -0
- package/dist/features/owned-ui/settings-model-dialog.js +194 -0
- package/dist/foundation/release/automatic-update.js +1 -8
- package/dist/foundation/release/dependency-layer.js +3 -3
- package/dist/foundation/release/latest-release.js +1 -1
- package/dist/foundation/release/managed-path.d.ts +10 -0
- package/dist/foundation/release/managed-path.js +26 -0
- package/dist/foundation/release/release-gc.js +6 -8
- package/dist/foundation/release/restart-certification.js +3 -4
- package/dist/foundation/release/update-activation.js +1 -1
- package/dist/foundation/release/update-execution-lease.js +1 -7
- package/dist/foundation/release/update-installer.d.ts +45 -0
- package/dist/foundation/release/update-installer.js +57 -0
- package/dist/foundation/release/update-recovery.js +2 -9
- package/dist/foundation/release/update.d.ts +4 -23
- package/dist/foundation/release/update.js +160 -179
- package/dist/integrations/pi/components/bracketed-paste.d.ts +33 -0
- package/dist/integrations/pi/components/bracketed-paste.js +123 -0
- package/dist/integrations/pi/components/owned-editor-ux.js +46 -140
- package/dist/integrations/pi/engine/adapter.d.ts +1 -8
- package/dist/integrations/pi/engine/adapter.js +6 -49
- package/dist/integrations/pi/engine/host.js +1 -1
- package/dist/integrations/pi/engine/repository-metadata.d.ts +49 -0
- package/dist/integrations/pi/engine/repository-metadata.js +189 -0
- package/dist/integrations/pi/engine/session-runtime.d.ts +6 -12
- package/dist/integrations/pi/engine/session-runtime.js +21 -178
- package/dist/integrations/pi/engine/view-state.d.ts +21 -2
- package/dist/integrations/pi/engine/view-state.js +129 -1
- package/dist/integrations/pi/engine/workflow-runner.d.ts +0 -1
- package/dist/integrations/pi/engine/workflow-runner.js +254 -365
- package/dist/integrations/pi/engine/workflow-share.d.ts +9 -0
- package/dist/integrations/pi/engine/workflow-share.js +168 -0
- package/dist/integrations/pi/engine/workflow-support.d.ts +0 -14
- package/dist/integrations/pi/engine/workflow-support.js +0 -47
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +9 -19
- package/dist/integrations/pi/tui-runtime/adapter.js +35 -144
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +4 -4
- package/dist/integrations/pi/tui-runtime/index.d.ts +0 -1
- package/dist/integrations/pi/tui-runtime/overlay-geometry.d.ts +2 -2
- package/dist/integrations/pi/tui-runtime/presentation-adapter.d.ts +2 -2
- package/dist/ui/components/transcript-viewport-frame.d.ts +120 -0
- package/dist/ui/components/transcript-viewport-frame.js +314 -0
- package/dist/ui/components/transcript-viewport-types.d.ts +147 -0
- package/dist/ui/components/transcript-viewport.d.ts +2 -147
- package/dist/ui/components/transcript-viewport.js +87 -315
- package/package.json +3 -3
- package/dist/integrations/pi/engine/diagnostics-state.d.ts +0 -9
- package/dist/integrations/pi/engine/diagnostics-state.js +0 -34
- package/dist/integrations/pi/engine/usage-view.d.ts +0 -4
- package/dist/integrations/pi/engine/usage-view.js +0 -56
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +0 -22
- /package/dist/{integrations/pi/tui-runtime/contracts.js → ui/components/transcript-viewport-types.js} +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentSession, AgentSessionRuntime } from "../startup-public.js";
|
|
2
|
+
import type { PiWorkflowHost, PiWorkflowRequest, PiWorkflowResult } from "./workflows.js";
|
|
3
|
+
export interface PiShareCall {
|
|
4
|
+
readonly request: PiWorkflowRequest;
|
|
5
|
+
readonly session: AgentSession;
|
|
6
|
+
readonly runtime: AgentSessionRuntime;
|
|
7
|
+
readonly host: PiWorkflowHost;
|
|
8
|
+
}
|
|
9
|
+
export declare function runShareWorkflow({ request, session, runtime, host }: PiShareCall): Promise<PiWorkflowResult>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pinned Pi's `/share` workflow: the Radius artifact route with a gist fallback. The runner loads
|
|
3
|
+
* this module on the first `/share`, so its network clients stay off the startup path.
|
|
4
|
+
*/
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
import { readFile, rm } from "node:fs/promises";
|
|
7
|
+
import { tmpdir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { PRODUCT_IDENTITY } from "../../../product-identity.js";
|
|
10
|
+
import { isRecord, requireCapability, stringProperty } from "./message-values.js";
|
|
11
|
+
import { commandMissing, errorMessage, isAbortError, workflowResult } from "./workflow-support.js";
|
|
12
|
+
// Provenance: the pinned engine's modes/interactive/session-share.ts Radius route and the model
|
|
13
|
+
// runtime's DEFAULT_RADIUS_GATEWAY; neither is in the public API, so each upgrade re-checks them.
|
|
14
|
+
const RADIUS_SHARE_GATEWAY = "https://radius.pi.dev";
|
|
15
|
+
const RADIUS_AUTH_MIN_VALIDITY_MS = 5 * 60_000;
|
|
16
|
+
export async function runShareWorkflow({ request, session, runtime, host }) {
|
|
17
|
+
const signal = request.signal;
|
|
18
|
+
if (signal?.aborted)
|
|
19
|
+
return shareCancelled(request);
|
|
20
|
+
const destination = runtime.services.settingsManager?.getSessionShareDestination?.() ?? "auto";
|
|
21
|
+
if (destination !== "gist") {
|
|
22
|
+
const radius = await shareViaRadius({ request, session, runtime, host });
|
|
23
|
+
if (radius !== undefined)
|
|
24
|
+
return radius;
|
|
25
|
+
if (destination === "radius")
|
|
26
|
+
return workflowResult(request.command, "failed", "Radius authentication is not configured. Run '/login radius' first.");
|
|
27
|
+
}
|
|
28
|
+
request.onProgress?.("Creating gist…");
|
|
29
|
+
try {
|
|
30
|
+
await host.runCommand("gh", ["auth", "status"], signal === undefined ? undefined : { signal });
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (signal?.aborted || isAbortError(error))
|
|
34
|
+
return shareCancelled(request);
|
|
35
|
+
const message = commandMissing(error)
|
|
36
|
+
? "GitHub CLI (gh) is not installed. Install it from https://cli.github.com/"
|
|
37
|
+
: "GitHub CLI is not logged in. Run 'gh auth login' first.";
|
|
38
|
+
return workflowResult(request.command, "failed", message);
|
|
39
|
+
}
|
|
40
|
+
const temporary = join(tmpdir(), `${PRODUCT_IDENTITY.filesystem.temporaryPrefix}pi-session-${process.pid}.html`);
|
|
41
|
+
try {
|
|
42
|
+
try {
|
|
43
|
+
await requireCapability(session.exportToHtml, "exportToHtml").call(session, temporary);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return workflowResult(request.command, "failed", `Failed to export session: ${errorMessage(error, "Unknown error")}`);
|
|
47
|
+
}
|
|
48
|
+
if (signal?.aborted)
|
|
49
|
+
return shareCancelled(request);
|
|
50
|
+
let gist;
|
|
51
|
+
try {
|
|
52
|
+
gist = await host.runCommand("gh", ["gist", "create", "--public=false", temporary], signal === undefined ? undefined : { signal });
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (signal?.aborted || isAbortError(error))
|
|
56
|
+
return shareCancelled(request);
|
|
57
|
+
return workflowResult(request.command, "failed", `Failed to create gist: ${shareCommandFailureDetail(error)}`);
|
|
58
|
+
}
|
|
59
|
+
if (signal?.aborted)
|
|
60
|
+
return shareCancelled(request);
|
|
61
|
+
const gistUrl = gist.stdout.trim();
|
|
62
|
+
const gistId = gistUrl.split("/").at(-1);
|
|
63
|
+
if (!gistId)
|
|
64
|
+
return workflowResult(request.command, "failed", "Failed to parse gist ID from gh output");
|
|
65
|
+
return workflowResult(request.command, "completed", `Share URL: ${shareViewerUrl(gistId)}`, gistUrl);
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
await rm(temporary, { force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function shareCancelled(request) {
|
|
72
|
+
return workflowResult(request.command, "cancelled", "Share cancelled", undefined, "status");
|
|
73
|
+
}
|
|
74
|
+
// Protocol: the pinned Radius `/share` route. Undefined means Radius has no provider or credential,
|
|
75
|
+
// so the caller may fall back to a gist; any other outcome, including an upload failure, is final.
|
|
76
|
+
async function shareViaRadius({ request, session, runtime, host }) {
|
|
77
|
+
const signal = request.signal;
|
|
78
|
+
const models = runtime.services.modelRuntime;
|
|
79
|
+
if (models.getProvider?.("radius") === undefined)
|
|
80
|
+
return undefined;
|
|
81
|
+
const token = radiusAuthCredential(await models.getAuth("radius", { minOAuthValidityMs: RADIUS_AUTH_MIN_VALIDITY_MS }));
|
|
82
|
+
if (!token)
|
|
83
|
+
return undefined;
|
|
84
|
+
if (signal?.aborted)
|
|
85
|
+
return shareCancelled(request);
|
|
86
|
+
request.onProgress?.("Uploading to Radius…");
|
|
87
|
+
const temporary = join(tmpdir(), `${PRODUCT_IDENTITY.filesystem.temporaryPrefix}pi-session-${process.pid}.jsonl`);
|
|
88
|
+
let body;
|
|
89
|
+
try {
|
|
90
|
+
requireCapability(session.exportToJsonl, "exportToJsonl").call(session, temporary);
|
|
91
|
+
body = withRadiusShareTrailingEntry(await readFile(temporary, "utf8"), session.state ?? {}, randomUUID().slice(0, 8));
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
return workflowResult(request.command, "failed", `Failed to export session: ${errorMessage(error, "Unknown error")}`);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
await rm(temporary, { force: true });
|
|
98
|
+
}
|
|
99
|
+
const url = new URL("/v1/artifacts", RADIUS_SHARE_GATEWAY);
|
|
100
|
+
url.searchParams.set("visibility", "organization");
|
|
101
|
+
url.searchParams.set("title", "Pi session");
|
|
102
|
+
try {
|
|
103
|
+
const response = await (host.fetch ?? fetch)(url, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/x-ndjson" },
|
|
106
|
+
body,
|
|
107
|
+
...(signal === undefined ? {} : { signal }),
|
|
108
|
+
});
|
|
109
|
+
const json = await response.json().catch(() => null);
|
|
110
|
+
if (signal?.aborted)
|
|
111
|
+
return shareCancelled(request);
|
|
112
|
+
const artifact = isRecord(json) && isRecord(json.artifact) ? json.artifact : undefined;
|
|
113
|
+
const shareUrl = artifact === undefined ? undefined : stringProperty(artifact, "canonical_url");
|
|
114
|
+
if (!response.ok || shareUrl === undefined) {
|
|
115
|
+
const detail = (isRecord(json) ? stringProperty(json, "error") : undefined) || response.statusText || String(response.status);
|
|
116
|
+
return workflowResult(request.command, "failed", `Failed to upload Radius artifact: ${detail}`);
|
|
117
|
+
}
|
|
118
|
+
return workflowResult(request.command, "completed", `Share URL: ${shareUrl}`);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (signal?.aborted || isAbortError(error))
|
|
122
|
+
return shareCancelled(request);
|
|
123
|
+
return workflowResult(request.command, "failed", `Failed to upload Radius artifact: ${errorMessage(error, "Unknown error")}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function shareCommandFailureDetail(error) {
|
|
127
|
+
// Compatibility: Pi reports a failed child's stderr, not execFile's command wrapper.
|
|
128
|
+
if (isRecord(error) && (typeof error.code === "number" || typeof error.signal === "string") && typeof error.stderr === "string") {
|
|
129
|
+
return error.stderr.trim() || "Unknown error";
|
|
130
|
+
}
|
|
131
|
+
return errorMessage(error, "Unknown error");
|
|
132
|
+
}
|
|
133
|
+
function shareViewerUrl(gistId) {
|
|
134
|
+
const baseUrl = process.env.PI_SHARE_VIEWER_URL || "https://pi.dev/session/";
|
|
135
|
+
return `${baseUrl}#${gistId}`;
|
|
136
|
+
}
|
|
137
|
+
/** The bearer token in a model-runtime auth result: an API key or an `Authorization: Bearer` header. */
|
|
138
|
+
function radiusAuthCredential(auth) {
|
|
139
|
+
const resolved = isRecord(auth) && isRecord(auth.auth) ? auth.auth : undefined;
|
|
140
|
+
if (resolved === undefined)
|
|
141
|
+
return undefined;
|
|
142
|
+
if (typeof resolved.apiKey === "string" && resolved.apiKey)
|
|
143
|
+
return resolved.apiKey;
|
|
144
|
+
const headers = isRecord(resolved.headers) ? resolved.headers : {};
|
|
145
|
+
const authorization = Object.entries(headers).find(([name]) => name.toLowerCase() === "authorization")?.[1];
|
|
146
|
+
return typeof authorization === "string" ? /^Bearer\s+(.+)$/iu.exec(authorization)?.[1] : undefined;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Append the pinned `pi.share` trailing entry (system prompt and tool schemas for the session viewer)
|
|
150
|
+
* to a branch JSONL export. It chains to the last exported entry and reuses the header timestamp.
|
|
151
|
+
*/
|
|
152
|
+
function withRadiusShareTrailingEntry(jsonl, state, id) {
|
|
153
|
+
const lines = jsonl.split("\n").filter(line => line.length > 0);
|
|
154
|
+
const header = lines[0] === undefined ? undefined : JSON.parse(lines[0]);
|
|
155
|
+
const last = lines.length > 1 ? JSON.parse(lines.at(-1)) : undefined;
|
|
156
|
+
const entry = {
|
|
157
|
+
type: "custom",
|
|
158
|
+
customType: "pi.share",
|
|
159
|
+
id,
|
|
160
|
+
parentId: isRecord(last) && typeof last.id === "string" ? last.id : null,
|
|
161
|
+
timestamp: isRecord(header) && typeof header.timestamp === "string" ? header.timestamp : new Date().toISOString(),
|
|
162
|
+
data: {
|
|
163
|
+
systemPrompt: state.systemPrompt,
|
|
164
|
+
tools: (state.tools ?? []).filter(isRecord).map(tool => ({ name: tool.name, description: tool.description, parameters: tool.parameters })),
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
return `${[...lines, JSON.stringify(entry)].join("\n")}\n`;
|
|
168
|
+
}
|
|
@@ -12,22 +12,8 @@ export declare function workflowLoginNotification(event: unknown): PiWorkflowLog
|
|
|
12
12
|
export declare function workflowResult(command: PiWorkflowRequest["command"], outcome: PiWorkflowResult["outcome"], message: string, detail?: string, messageKind?: PiWorkflowResult["messageKind"], messages?: readonly PiWorkflowMessage[]): PiWorkflowResult;
|
|
13
13
|
export declare function workflowConfirmation(command: PiWorkflowRequest["command"], message: string, detail?: string): PiWorkflowResult;
|
|
14
14
|
export declare function errorMessage(error: unknown, fallback: string): string;
|
|
15
|
-
export declare function shareCommandFailureDetail(error: unknown): string;
|
|
16
15
|
export declare function commandMissing(error: unknown): boolean;
|
|
17
16
|
export declare function isAbortError(error: unknown): boolean;
|
|
18
|
-
export declare function shareViewerUrl(gistId: string): string;
|
|
19
|
-
export declare const RADIUS_SHARE_GATEWAY = "https://radius.pi.dev";
|
|
20
|
-
export declare const RADIUS_AUTH_MIN_VALIDITY_MS: number;
|
|
21
|
-
/** The bearer token in a model-runtime auth result: an API key or an `Authorization: Bearer` header. */
|
|
22
|
-
export declare function radiusAuthCredential(auth: unknown): string | undefined;
|
|
23
|
-
/**
|
|
24
|
-
* Append the pinned `pi.share` trailing entry (system prompt and tool schemas for the session viewer)
|
|
25
|
-
* to a branch JSONL export. It chains to the last exported entry and reuses the header timestamp.
|
|
26
|
-
*/
|
|
27
|
-
export declare function withRadiusShareTrailingEntry(jsonl: string, state: {
|
|
28
|
-
readonly systemPrompt?: unknown;
|
|
29
|
-
readonly tools?: readonly unknown[];
|
|
30
|
-
}, id: string): string;
|
|
31
17
|
export declare function workflowOptions(value: unknown, idKey: string, labelKey: string): readonly PiWorkflowOption[];
|
|
32
18
|
export declare function pathArgument(value: string): string | undefined;
|
|
33
19
|
export declare function pinnedHotkeySummary(): string;
|
|
@@ -262,59 +262,12 @@ export function workflowConfirmation(command, message, detail) {
|
|
|
262
262
|
export function errorMessage(error, fallback) {
|
|
263
263
|
return error instanceof Error ? error.message : fallback;
|
|
264
264
|
}
|
|
265
|
-
export function shareCommandFailureDetail(error) {
|
|
266
|
-
// Compatibility: Pi reports a failed child's stderr, not execFile's command wrapper.
|
|
267
|
-
if (isRecord(error) && (typeof error.code === "number" || typeof error.signal === "string") && typeof error.stderr === "string") {
|
|
268
|
-
return error.stderr.trim() || "Unknown error";
|
|
269
|
-
}
|
|
270
|
-
return errorMessage(error, "Unknown error");
|
|
271
|
-
}
|
|
272
265
|
export function commandMissing(error) {
|
|
273
266
|
return isRecord(error) && error.code === "ENOENT";
|
|
274
267
|
}
|
|
275
268
|
export function isAbortError(error) {
|
|
276
269
|
return isRecord(error) && (error.name === "AbortError" || error.code === "ABORT_ERR");
|
|
277
270
|
}
|
|
278
|
-
export function shareViewerUrl(gistId) {
|
|
279
|
-
const baseUrl = process.env.PI_SHARE_VIEWER_URL || "https://pi.dev/session/";
|
|
280
|
-
return `${baseUrl}#${gistId}`;
|
|
281
|
-
}
|
|
282
|
-
// Provenance: the pinned engine's modes/interactive/session-share.ts Radius route and the model
|
|
283
|
-
// runtime's DEFAULT_RADIUS_GATEWAY; neither is in the public API, so each upgrade re-checks them.
|
|
284
|
-
export const RADIUS_SHARE_GATEWAY = "https://radius.pi.dev";
|
|
285
|
-
export const RADIUS_AUTH_MIN_VALIDITY_MS = 5 * 60_000;
|
|
286
|
-
/** The bearer token in a model-runtime auth result: an API key or an `Authorization: Bearer` header. */
|
|
287
|
-
export function radiusAuthCredential(auth) {
|
|
288
|
-
const resolved = isRecord(auth) && isRecord(auth.auth) ? auth.auth : undefined;
|
|
289
|
-
if (resolved === undefined)
|
|
290
|
-
return undefined;
|
|
291
|
-
if (typeof resolved.apiKey === "string" && resolved.apiKey)
|
|
292
|
-
return resolved.apiKey;
|
|
293
|
-
const headers = isRecord(resolved.headers) ? resolved.headers : {};
|
|
294
|
-
const authorization = Object.entries(headers).find(([name]) => name.toLowerCase() === "authorization")?.[1];
|
|
295
|
-
return typeof authorization === "string" ? /^Bearer\s+(.+)$/iu.exec(authorization)?.[1] : undefined;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Append the pinned `pi.share` trailing entry (system prompt and tool schemas for the session viewer)
|
|
299
|
-
* to a branch JSONL export. It chains to the last exported entry and reuses the header timestamp.
|
|
300
|
-
*/
|
|
301
|
-
export function withRadiusShareTrailingEntry(jsonl, state, id) {
|
|
302
|
-
const lines = jsonl.split("\n").filter(line => line.length > 0);
|
|
303
|
-
const header = lines[0] === undefined ? undefined : JSON.parse(lines[0]);
|
|
304
|
-
const last = lines.length > 1 ? JSON.parse(lines.at(-1)) : undefined;
|
|
305
|
-
const entry = {
|
|
306
|
-
type: "custom",
|
|
307
|
-
customType: "pi.share",
|
|
308
|
-
id,
|
|
309
|
-
parentId: isRecord(last) && typeof last.id === "string" ? last.id : null,
|
|
310
|
-
timestamp: isRecord(header) && typeof header.timestamp === "string" ? header.timestamp : new Date().toISOString(),
|
|
311
|
-
data: {
|
|
312
|
-
systemPrompt: state.systemPrompt,
|
|
313
|
-
tools: (state.tools ?? []).filter(isRecord).map(tool => ({ name: tool.name, description: tool.description, parameters: tool.parameters })),
|
|
314
|
-
},
|
|
315
|
-
};
|
|
316
|
-
return `${[...lines, JSON.stringify(entry)].join("\n")}\n`;
|
|
317
|
-
}
|
|
318
271
|
export function workflowOptions(value, idKey, labelKey) {
|
|
319
272
|
if (!Array.isArray(value))
|
|
320
273
|
return [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ProgramStatus, type WheelScrollLines } from "@earendil-works/pi-tui";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TerminalComponentPort, TerminalInputListener, TerminalOverlayHandle, TerminalOverlayOptions, TerminalPreInputListener, TerminalRuntimeOptions, TerminalRuntimeState, TerminalStopOptions, TerminalViewport } from "../../../contracts/presentation/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Re-encodes one key report decoded by pi-tui in the legacy form, so a kitty-keyboard terminal
|
|
5
5
|
* and a legacy terminal produce the same owned-screen action. Releases decode
|
|
@@ -15,19 +15,14 @@ export declare class PiTuiRuntimeError extends Error {
|
|
|
15
15
|
/** Bridges neutral presentation ports to one Pi TUI instance and owns terminal restoration on stop. */
|
|
16
16
|
export declare class PiTuiRuntimeAdapter {
|
|
17
17
|
#private;
|
|
18
|
-
constructor(options:
|
|
19
|
-
get state():
|
|
18
|
+
constructor(options: TerminalRuntimeOptions);
|
|
19
|
+
get state(): TerminalRuntimeState;
|
|
20
20
|
get active(): boolean;
|
|
21
21
|
get mode(): "regular" | "fullscreen";
|
|
22
22
|
get fullRedraws(): number;
|
|
23
|
-
viewport():
|
|
24
|
-
scrollState(id?: string): PiTuiScrollState;
|
|
25
|
-
scrollBy(lines: number, id?: string): void;
|
|
26
|
-
scrollToTop(id?: string): void;
|
|
27
|
-
scrollToBottom(id?: string): void;
|
|
23
|
+
viewport(): TerminalViewport;
|
|
28
24
|
start(): void;
|
|
29
|
-
|
|
30
|
-
showOverlay(component: PiTuiComponentPort, options?: PiTuiOverlayOptions): PiTuiOverlayHandle;
|
|
25
|
+
showOverlay(component: TerminalComponentPort, options?: TerminalOverlayOptions): TerminalOverlayHandle;
|
|
31
26
|
hasOverlay(): boolean;
|
|
32
27
|
/** Keyboard capture is independent of a passive overlay's visible pointer region. */
|
|
33
28
|
hasFocusedOverlay(): boolean;
|
|
@@ -44,30 +39,25 @@ export declare class PiTuiRuntimeAdapter {
|
|
|
44
39
|
* renderer keeps scheduling but nothing it paints reaches the terminal.
|
|
45
40
|
*/
|
|
46
41
|
freezePresentation(): void;
|
|
47
|
-
get presentationFrozen(): boolean;
|
|
48
42
|
/**
|
|
49
43
|
* Keeps asynchronous replacement-surface construction atomic at the terminal. Renderers may
|
|
50
44
|
* compose while held, but their writes are dropped until the final forced repaint on release.
|
|
51
45
|
*/
|
|
52
46
|
beginPresentationHold(): () => void;
|
|
53
47
|
get presentationHeld(): boolean;
|
|
54
|
-
addPreInputListener(listener:
|
|
55
|
-
addInputListener(listener:
|
|
48
|
+
addPreInputListener(listener: TerminalPreInputListener): () => void;
|
|
49
|
+
addInputListener(listener: TerminalInputListener): () => void;
|
|
56
50
|
switchMode(mode: "regular" | "fullscreen"): boolean;
|
|
57
51
|
setHardwareCursor(enabled: boolean): void;
|
|
58
|
-
getHardwareCursor(): boolean;
|
|
59
52
|
setClearOnShrink(enabled: boolean): void;
|
|
60
53
|
setWheelScrollLines(lines: WheelScrollLines): void;
|
|
61
|
-
getClearOnShrink(): boolean;
|
|
62
54
|
setTerminalProgress(active: boolean): void;
|
|
63
55
|
setProgramStatus(status: ProgramStatus): void;
|
|
64
56
|
setTitle(title: string): void;
|
|
65
|
-
/** Shows a bounded fullscreen acknowledgement without changing root layout geometry. */
|
|
66
|
-
showFlash(message: string, durationMs?: number): void;
|
|
67
57
|
writeAfterStop(text: string): void;
|
|
68
58
|
invalidate(): void;
|
|
69
59
|
requestRender(force?: boolean): void;
|
|
70
60
|
renderNow(force?: boolean): void;
|
|
71
|
-
stop(options?:
|
|
72
|
-
dispose(options?:
|
|
61
|
+
stop(options?: TerminalStopOptions): Promise<void>;
|
|
62
|
+
dispose(options?: TerminalStopOptions): Promise<void>;
|
|
73
63
|
}
|
|
@@ -128,7 +128,7 @@ export class PiTuiRuntimeAdapter {
|
|
|
128
128
|
#rootBridge;
|
|
129
129
|
#bridges = new WeakMap();
|
|
130
130
|
#mountedComponents = new Set();
|
|
131
|
-
#
|
|
131
|
+
#scrollIds = new Set();
|
|
132
132
|
#overlayGeometry;
|
|
133
133
|
#overlayDisposers = new Set();
|
|
134
134
|
#overlayInputCoordination = new Map();
|
|
@@ -222,53 +222,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
222
222
|
rows: Math.max(1, this.#terminal.rows),
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
|
-
scrollState(id) {
|
|
226
|
-
if (id === undefined) {
|
|
227
|
-
if (!(this.#tui instanceof TuiAltScreen)) {
|
|
228
|
-
throw new Error("Pi TUI application scrolling is available only in fullscreen mode");
|
|
229
|
-
}
|
|
230
|
-
return {
|
|
231
|
-
scrollTop: this.#tui.viewportTop,
|
|
232
|
-
viewportHeight: this.viewport().rows,
|
|
233
|
-
followingEnd: this.#tui.isFollowingOutput,
|
|
234
|
-
scrollbarVisible: false,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
const scrollView = this.#requireScrollView(id);
|
|
238
|
-
return {
|
|
239
|
-
scrollTop: scrollView.scrollTop,
|
|
240
|
-
viewportHeight: scrollView.viewportHeight,
|
|
241
|
-
followingEnd: scrollView.isFollowingEnd,
|
|
242
|
-
scrollbarVisible: scrollView.isScrollbarVisible,
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
scrollBy(lines, id) {
|
|
246
|
-
this.#assertRunning("scroll");
|
|
247
|
-
if (id === undefined)
|
|
248
|
-
this.#requireFullscreen().scrollBy(lines);
|
|
249
|
-
else {
|
|
250
|
-
this.#requireScrollView(id).scrollBy(lines);
|
|
251
|
-
this.#tui.requestRender();
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
scrollToTop(id) {
|
|
255
|
-
this.#assertRunning("scroll");
|
|
256
|
-
if (id === undefined)
|
|
257
|
-
this.#requireFullscreen().scrollToTop();
|
|
258
|
-
else {
|
|
259
|
-
this.#requireScrollView(id).scrollToStart();
|
|
260
|
-
this.#tui.requestRender();
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
scrollToBottom(id) {
|
|
264
|
-
this.#assertRunning("scroll");
|
|
265
|
-
if (id === undefined)
|
|
266
|
-
this.#requireFullscreen().scrollToBottom();
|
|
267
|
-
else {
|
|
268
|
-
this.#requireScrollView(id).scrollToEnd();
|
|
269
|
-
this.#tui.requestRender();
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
225
|
start() {
|
|
273
226
|
if (this.#state === "running")
|
|
274
227
|
return;
|
|
@@ -286,12 +239,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
286
239
|
throw new PiTuiRuntimeError("start", error);
|
|
287
240
|
}
|
|
288
241
|
}
|
|
289
|
-
setFocus(component) {
|
|
290
|
-
this.#assertRunning("focus");
|
|
291
|
-
if (this.#overlayInputCoordination.size > 0)
|
|
292
|
-
this.#overlayGeometry?.invalidate();
|
|
293
|
-
this.#tui.setFocus(this.#bridgeFor(component));
|
|
294
|
-
}
|
|
295
242
|
showOverlay(component, options) {
|
|
296
243
|
this.#assertRunning("overlay");
|
|
297
244
|
if (this.#bridges.has(component))
|
|
@@ -340,9 +287,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
340
287
|
this.#assertRunning("presentation freeze");
|
|
341
288
|
this.#presentationFrozen = true;
|
|
342
289
|
}
|
|
343
|
-
get presentationFrozen() {
|
|
344
|
-
return this.#presentationFrozen;
|
|
345
|
-
}
|
|
346
290
|
/**
|
|
347
291
|
* Keeps asynchronous replacement-surface construction atomic at the terminal. Renderers may
|
|
348
292
|
* compose while held, but their writes are dropped until the final forced repaint on release.
|
|
@@ -394,7 +338,7 @@ export class PiTuiRuntimeAdapter {
|
|
|
394
338
|
previous.clear();
|
|
395
339
|
if (previous instanceof TuiAltScreen)
|
|
396
340
|
previous.setLayoutRoot(undefined);
|
|
397
|
-
this.#
|
|
341
|
+
this.#scrollIds.clear();
|
|
398
342
|
const next = this.#createTui(mode, hardwareCursor);
|
|
399
343
|
next.setClearOnShrink(clearOnShrink);
|
|
400
344
|
this.#mountTui(next);
|
|
@@ -417,9 +361,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
417
361
|
if (this.active)
|
|
418
362
|
this.#tui.requestRender();
|
|
419
363
|
}
|
|
420
|
-
getHardwareCursor() {
|
|
421
|
-
return this.#tui.getShowHardwareCursor();
|
|
422
|
-
}
|
|
423
364
|
setClearOnShrink(enabled) {
|
|
424
365
|
this.#tui.setClearOnShrink(enabled);
|
|
425
366
|
}
|
|
@@ -428,9 +369,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
428
369
|
if (this.#tui instanceof TuiAltScreen)
|
|
429
370
|
this.#tui.setWheelScrollLines(lines);
|
|
430
371
|
}
|
|
431
|
-
getClearOnShrink() {
|
|
432
|
-
return this.#tui.getClearOnShrink();
|
|
433
|
-
}
|
|
434
372
|
setTerminalProgress(active) {
|
|
435
373
|
if (this.#terminalProgress === active)
|
|
436
374
|
return;
|
|
@@ -443,11 +381,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
443
381
|
setTitle(title) {
|
|
444
382
|
this.#terminal.setTitle(title);
|
|
445
383
|
}
|
|
446
|
-
/** Shows a bounded fullscreen acknowledgement without changing root layout geometry. */
|
|
447
|
-
showFlash(message, durationMs) {
|
|
448
|
-
this.#assertRunning("flash");
|
|
449
|
-
this.#requireFullscreen().flash(message, durationMs);
|
|
450
|
-
}
|
|
451
384
|
writeAfterStop(text) {
|
|
452
385
|
if (this.#state !== "stopped")
|
|
453
386
|
throw new Error("terminal output requires a stopped Pi TUI runtime");
|
|
@@ -580,7 +513,7 @@ export class PiTuiRuntimeAdapter {
|
|
|
580
513
|
if (node.type === "component")
|
|
581
514
|
return this.#mount(node.component);
|
|
582
515
|
if (node.type === "scroll") {
|
|
583
|
-
if (this.#
|
|
516
|
+
if (this.#scrollIds.has(node.id))
|
|
584
517
|
throw new TypeError(`duplicate Pi TUI scroll layout id: ${node.id}`);
|
|
585
518
|
const options = {
|
|
586
519
|
...(node.follow === undefined ? {} : { follow: node.follow }),
|
|
@@ -591,9 +524,8 @@ export class PiTuiRuntimeAdapter {
|
|
|
591
524
|
...(node.scrollbarThumbStyle === undefined ? {} : { scrollbarThumbStyle: node.scrollbarThumbStyle }),
|
|
592
525
|
...(node.scrollbarHideDelayMs === undefined ? {} : { scrollbarHideDelayMs: node.scrollbarHideDelayMs }),
|
|
593
526
|
};
|
|
594
|
-
|
|
595
|
-
this.#
|
|
596
|
-
return scrollView;
|
|
527
|
+
this.#scrollIds.add(node.id);
|
|
528
|
+
return new ScrollView(this.#buildLayout(node.child), options);
|
|
597
529
|
}
|
|
598
530
|
const children = node.children.map(entry => ({
|
|
599
531
|
component: this.#buildLayout(entry.node),
|
|
@@ -610,19 +542,6 @@ export class PiTuiRuntimeAdapter {
|
|
|
610
542
|
};
|
|
611
543
|
return node.direction === "vertical" ? new VStack(children, options) : new HStack(children, options);
|
|
612
544
|
}
|
|
613
|
-
#requireFullscreen() {
|
|
614
|
-
if (!(this.#tui instanceof TuiAltScreen)) {
|
|
615
|
-
throw new Error("Pi TUI application scrolling is available only in fullscreen mode");
|
|
616
|
-
}
|
|
617
|
-
return this.#tui;
|
|
618
|
-
}
|
|
619
|
-
#requireScrollView(id) {
|
|
620
|
-
this.#requireFullscreen();
|
|
621
|
-
const scrollView = this.#scrollViews.get(id);
|
|
622
|
-
if (!scrollView)
|
|
623
|
-
throw new TypeError(`unknown Pi TUI scroll layout id: ${id}`);
|
|
624
|
-
return scrollView;
|
|
625
|
-
}
|
|
626
545
|
#assertRunning(operation) {
|
|
627
546
|
if (!this.active)
|
|
628
547
|
throw new Error(`Pi TUI ${operation} requires a running runtime`);
|
|
@@ -683,12 +602,33 @@ export class PiTuiRuntimeAdapter {
|
|
|
683
602
|
this.#disposeRoot();
|
|
684
603
|
}
|
|
685
604
|
}
|
|
686
|
-
|
|
687
|
-
|
|
605
|
+
/**
|
|
606
|
+
* Forwards every terminal member to `terminal` unless `overrides` replaces it.
|
|
607
|
+
* Invariant: the size and keyboard getters stay live; spreading the inner terminal would freeze them.
|
|
608
|
+
*/
|
|
609
|
+
function forwardingTerminal(terminal, overrides = {}) {
|
|
688
610
|
return {
|
|
689
611
|
get columns() { return terminal.columns; },
|
|
690
612
|
get rows() { return terminal.rows; },
|
|
691
613
|
get kittyProtocolActive() { return terminal.kittyProtocolActive; },
|
|
614
|
+
start: overrides.start ?? ((onInput, onResize) => terminal.start(onInput, onResize)),
|
|
615
|
+
stop: overrides.stop ?? (() => terminal.stop()),
|
|
616
|
+
drainInput: overrides.drainInput ?? ((maxMs, idleMs) => terminal.drainInput(maxMs, idleMs)),
|
|
617
|
+
write: overrides.write ?? (data => terminal.write(data)),
|
|
618
|
+
moveBy: overrides.moveBy ?? (lines => terminal.moveBy(lines)),
|
|
619
|
+
hideCursor: overrides.hideCursor ?? (() => terminal.hideCursor()),
|
|
620
|
+
showCursor: overrides.showCursor ?? (() => terminal.showCursor()),
|
|
621
|
+
clearLine: overrides.clearLine ?? (() => terminal.clearLine()),
|
|
622
|
+
clearFromCursor: overrides.clearFromCursor ?? (() => terminal.clearFromCursor()),
|
|
623
|
+
clearScreen: overrides.clearScreen ?? (() => terminal.clearScreen()),
|
|
624
|
+
setTitle: overrides.setTitle ?? (title => terminal.setTitle(title)),
|
|
625
|
+
setProgress: overrides.setProgress ?? (active => terminal.setProgress(active)),
|
|
626
|
+
setProgramStatus: overrides.setProgramStatus ?? (status => terminal.setProgramStatus?.(status)),
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function coordinatedInputTerminal(terminal, coordinator, setSink, frameMouse) {
|
|
630
|
+
const mouse = frameMouse ? new MouseReportInput(data => coordinator.accept(data)) : undefined;
|
|
631
|
+
return forwardingTerminal(terminal, {
|
|
692
632
|
start(onInput, onResize) {
|
|
693
633
|
setSink(onInput);
|
|
694
634
|
terminal.start(data => mouse === undefined ? coordinator.accept(data) : mouse.accept(data), () => {
|
|
@@ -703,27 +643,10 @@ function coordinatedInputTerminal(terminal, coordinator, setSink, frameMouse) {
|
|
|
703
643
|
setSink(undefined);
|
|
704
644
|
terminal.stop();
|
|
705
645
|
},
|
|
706
|
-
|
|
707
|
-
write: data => terminal.write(data),
|
|
708
|
-
moveBy: lines => terminal.moveBy(lines),
|
|
709
|
-
hideCursor: () => terminal.hideCursor(),
|
|
710
|
-
showCursor: () => terminal.showCursor(),
|
|
711
|
-
clearLine: () => terminal.clearLine(),
|
|
712
|
-
clearFromCursor: () => terminal.clearFromCursor(),
|
|
713
|
-
clearScreen: () => terminal.clearScreen(),
|
|
714
|
-
setTitle: title => terminal.setTitle(title),
|
|
715
|
-
setProgress: active => terminal.setProgress(active),
|
|
716
|
-
setProgramStatus: status => terminal.setProgramStatus?.(status),
|
|
717
|
-
};
|
|
646
|
+
});
|
|
718
647
|
}
|
|
719
648
|
function diagnosticTerminal(terminal, trace) {
|
|
720
|
-
return {
|
|
721
|
-
get columns() { return terminal.columns; },
|
|
722
|
-
get rows() { return terminal.rows; },
|
|
723
|
-
get kittyProtocolActive() { return terminal.kittyProtocolActive; },
|
|
724
|
-
start: (onInput, onResize) => terminal.start(onInput, onResize),
|
|
725
|
-
stop: () => terminal.stop(),
|
|
726
|
-
drainInput: (maxMs, idleMs) => terminal.drainInput(maxMs, idleMs),
|
|
649
|
+
return forwardingTerminal(terminal, {
|
|
727
650
|
write(data) {
|
|
728
651
|
trace("write-start");
|
|
729
652
|
try {
|
|
@@ -733,25 +656,10 @@ function diagnosticTerminal(terminal, trace) {
|
|
|
733
656
|
trace("write-end");
|
|
734
657
|
}
|
|
735
658
|
},
|
|
736
|
-
|
|
737
|
-
hideCursor: () => terminal.hideCursor(),
|
|
738
|
-
showCursor: () => terminal.showCursor(),
|
|
739
|
-
clearLine: () => terminal.clearLine(),
|
|
740
|
-
clearFromCursor: () => terminal.clearFromCursor(),
|
|
741
|
-
clearScreen: () => terminal.clearScreen(),
|
|
742
|
-
setTitle: title => terminal.setTitle(title),
|
|
743
|
-
setProgress: active => terminal.setProgress(active),
|
|
744
|
-
setProgramStatus: status => terminal.setProgramStatus?.(status),
|
|
745
|
-
};
|
|
659
|
+
});
|
|
746
660
|
}
|
|
747
661
|
function frozenGateTerminal(terminal, frozen) {
|
|
748
|
-
return {
|
|
749
|
-
get columns() { return terminal.columns; },
|
|
750
|
-
get rows() { return terminal.rows; },
|
|
751
|
-
get kittyProtocolActive() { return terminal.kittyProtocolActive; },
|
|
752
|
-
start: (onInput, onResize) => terminal.start(onInput, onResize),
|
|
753
|
-
stop: () => terminal.stop(),
|
|
754
|
-
drainInput: (maxMs, idleMs) => terminal.drainInput(maxMs, idleMs),
|
|
662
|
+
return forwardingTerminal(terminal, {
|
|
755
663
|
write: data => { if (!frozen())
|
|
756
664
|
terminal.write(data); },
|
|
757
665
|
moveBy: lines => { if (!frozen())
|
|
@@ -766,17 +674,11 @@ function frozenGateTerminal(terminal, frozen) {
|
|
|
766
674
|
terminal.clearFromCursor(); },
|
|
767
675
|
clearScreen: () => { if (!frozen())
|
|
768
676
|
terminal.clearScreen(); },
|
|
769
|
-
|
|
770
|
-
setProgress: active => terminal.setProgress(active),
|
|
771
|
-
setProgramStatus: status => terminal.setProgramStatus?.(status),
|
|
772
|
-
};
|
|
677
|
+
});
|
|
773
678
|
}
|
|
774
679
|
function preInputTerminal(terminal, route, frameMouse) {
|
|
775
680
|
let mouse;
|
|
776
|
-
return {
|
|
777
|
-
get columns() { return terminal.columns; },
|
|
778
|
-
get rows() { return terminal.rows; },
|
|
779
|
-
get kittyProtocolActive() { return terminal.kittyProtocolActive; },
|
|
681
|
+
return forwardingTerminal(terminal, {
|
|
780
682
|
start(onInput, onResize) {
|
|
781
683
|
const deliver = (data) => {
|
|
782
684
|
const routed = route(data);
|
|
@@ -790,18 +692,7 @@ function preInputTerminal(terminal, route, frameMouse) {
|
|
|
790
692
|
});
|
|
791
693
|
},
|
|
792
694
|
stop: () => { mouse?.reset(); terminal.stop(); },
|
|
793
|
-
|
|
794
|
-
write: data => terminal.write(data),
|
|
795
|
-
moveBy: lines => terminal.moveBy(lines),
|
|
796
|
-
hideCursor: () => terminal.hideCursor(),
|
|
797
|
-
showCursor: () => terminal.showCursor(),
|
|
798
|
-
clearLine: () => terminal.clearLine(),
|
|
799
|
-
clearFromCursor: () => terminal.clearFromCursor(),
|
|
800
|
-
clearScreen: () => terminal.clearScreen(),
|
|
801
|
-
setTitle: title => terminal.setTitle(title),
|
|
802
|
-
setProgress: active => terminal.setProgress(active),
|
|
803
|
-
setProgramStatus: status => terminal.setProgramStatus?.(status),
|
|
804
|
-
};
|
|
695
|
+
});
|
|
805
696
|
}
|
|
806
697
|
function toOverlayOptions(options) {
|
|
807
698
|
if (options === undefined)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { TerminalPort } from "../../../contracts/presentation/index.js";
|
|
2
2
|
export declare const PINNED_PI_TUI_DAMAGE_GRAMMAR = "@earendil-works/pi-tui@1.5.0:tui-alt-screen-one-write-v1";
|
|
3
3
|
import type { TerminalDamageDecision, TerminalDamageDecisionReason, TerminalDamageFrameDescriptor, TerminalDamageFrameSafety } from "../../../contracts/presentation/index.js";
|
|
4
4
|
export type PiTuiDamageFrameDescriptor = TerminalDamageFrameDescriptor;
|
|
@@ -34,11 +34,11 @@ export interface DamageAwareTerminalOptions {
|
|
|
34
34
|
* viewport metadata authorizes a shift; bytes are inspected only to validate
|
|
35
35
|
* and preserve Pi's complete row paint and cursor syntax.
|
|
36
36
|
*/
|
|
37
|
-
export declare class DamageAwareTerminalAdapter implements
|
|
37
|
+
export declare class DamageAwareTerminalAdapter implements TerminalPort {
|
|
38
38
|
#private;
|
|
39
|
-
readonly inner:
|
|
39
|
+
readonly inner: TerminalPort;
|
|
40
40
|
readonly options: DamageAwareTerminalOptions;
|
|
41
|
-
constructor(inner:
|
|
41
|
+
constructor(inner: TerminalPort, options: DamageAwareTerminalOptions);
|
|
42
42
|
get columns(): number;
|
|
43
43
|
get rows(): number;
|
|
44
44
|
get kittyProtocolActive(): boolean;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export type { PiTuiComponentPort, PiTuiInputDiagnosticsEvent, PiTuiInputDiagnosticsPhase, PiTuiInputListener, PiTuiInputListenerResult, PiTuiLayoutEntry, PiTuiLayoutNode, PiTuiOverlayAnchor, PiTuiOverlayHandle, PiTuiOverlayMargin, PiTuiOverlayOptions, PiTuiOverlayUnfocusOptions, PiTuiPointerSurface, PiTuiPreInputListener, PiTuiRuntimeAdapterOptions, PiTuiRuntimeState, PiTuiScrollState, PiTuiSizeValue, PiTuiStopOptions, PiTuiTerminalPort, PiTuiViewport, } from "./contracts.js";
|
|
2
1
|
export { samePointerSurfaces } from "./overlay-geometry.js";
|
|
3
2
|
export { PI_TERMINAL_RUNTIME } from "./runtime-factory.js";
|
|
4
3
|
export { DamageAwareTerminalAdapter, PINNED_PI_TUI_DAMAGE_GRAMMAR, paintTerminalCanvasFrame, rebaseTerminalDefaultBackground, } from "./damage-aware-terminal.js";
|