@timurproko/a1 0.1.8-dev.157 → 0.1.8-dev.214
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 +32 -0
- package/bin/cli.js +2 -2
- package/bin/sync-pi-tui-proxy.js +1 -1
- package/bin/ui.js +18 -3
- package/dist/cli/dispatch.js +3 -3
- package/dist/cli/packages.js +1 -1
- package/dist/cli/version-stats.js +3 -3
- package/dist/composition/owned-ui.d.ts +4 -1
- package/dist/composition/owned-ui.js +9 -6
- package/dist/composition/settings-route-host.js +6 -4
- package/dist/contracts/agent-engine/capability-ports.d.ts +2 -2
- package/dist/contracts/agent-engine/domain-validation.js +22 -4
- package/dist/contracts/agent-engine/domain.d.ts +17 -0
- package/dist/contracts/owned-ui/model.d.ts +8 -0
- package/dist/contracts/owned-ui/validation.js +11 -0
- package/dist/features/launch/development-launch.js +1 -1
- package/dist/features/owned-ui/customization.d.ts +2 -0
- package/dist/features/owned-ui/customization.js +2 -0
- package/dist/features/owned-ui/diagnostics.d.ts +1 -0
- package/dist/features/owned-ui/diagnostics.js +1 -0
- package/dist/features/owned-ui/index.d.ts +1 -0
- package/dist/features/owned-ui/index.js +1 -0
- package/dist/features/owned-ui/project-trust-prompt.d.ts +25 -0
- package/dist/features/owned-ui/project-trust-prompt.js +149 -0
- package/dist/features/owned-ui/settings-app.js +69 -44
- package/dist/features/workspace/reducer.d.ts +1 -0
- package/dist/features/workspace/reducer.js +1 -0
- package/dist/features/workspace/router.d.ts +1 -0
- package/dist/features/workspace/router.js +1 -0
- package/dist/features/workspace/store.d.ts +1 -0
- package/dist/features/workspace/store.js +1 -0
- package/dist/foundation/launch-guardian/main.js +1 -1
- package/dist/foundation/native-host-protocol/codec.d.ts +2 -0
- package/dist/foundation/native-host-protocol/codec.js +2 -0
- package/dist/foundation/process-containment/linux-process-inspector.d.ts +1 -0
- package/dist/foundation/process-containment/linux-process-inspector.js +1 -0
- package/dist/foundation/process-containment/native-guardian-containment.d.ts +1 -0
- package/dist/foundation/process-containment/native-guardian-containment.js +1 -0
- package/dist/foundation/process-containment/windows-process-inspector.d.ts +1 -0
- package/dist/foundation/process-containment/windows-process-inspector.js +1 -0
- package/dist/foundation/protocol/client.d.ts +1 -0
- package/dist/foundation/protocol/client.js +1 -0
- package/dist/foundation/protocol/messages.d.ts +1 -0
- package/dist/foundation/protocol/messages.js +1 -0
- package/dist/foundation/release/bootstrap.js +6 -6
- package/dist/foundation/release/cohort-state.d.ts +1 -0
- package/dist/foundation/release/cohort-state.js +1 -0
- package/dist/foundation/release/release-gc.js +1 -1
- package/dist/foundation/release/release.js +1 -1
- package/dist/foundation/release/update-transaction.d.ts +1 -0
- package/dist/foundation/release/update-transaction.js +1 -0
- package/dist/foundation/release/update.js +12 -12
- package/dist/foundation/storage/control-store.d.ts +1 -0
- package/dist/foundation/storage/control-store.js +1 -0
- package/dist/foundation/structured-agent-runtime/backpressure.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/backpressure.js +1 -0
- package/dist/foundation/structured-agent-runtime/commands.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/commands.js +1 -0
- package/dist/foundation/structured-agent-runtime/reconnection.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/reconnection.js +1 -0
- package/dist/foundation/structured-agent-runtime/state.d.ts +1 -0
- package/dist/foundation/structured-agent-runtime/state.js +1 -0
- package/dist/foundation/supervision/main.js +1 -1
- package/dist/foundation/supervision/server.d.ts +1 -0
- package/dist/foundation/supervision/server.js +4 -6
- package/dist/integrations/pi/components/conformance.d.ts +1 -0
- package/dist/integrations/pi/components/conformance.js +1 -0
- package/dist/integrations/pi/components/shell-components.d.ts +1 -0
- package/dist/integrations/pi/components/shell-components.js +1 -0
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +10 -0
- package/dist/integrations/pi/components/shell-footer-status.d.ts +1 -1
- package/dist/integrations/pi/components/shell-footer-status.js +19 -13
- package/dist/integrations/pi/components/shell-presenters-info.d.ts +36 -0
- package/dist/integrations/pi/components/shell-presenters-info.js +78 -0
- package/dist/integrations/pi/components/shell-presenters-transcript.d.ts +3 -36
- package/dist/integrations/pi/components/shell-presenters-transcript.js +88 -128
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +11 -1
- package/dist/integrations/pi/components/shell-shared-facade.js +1 -1
- package/dist/integrations/pi/engine/adapter.d.ts +22 -4
- package/dist/integrations/pi/engine/adapter.js +220 -70
- package/dist/integrations/pi/engine/conformance.d.ts +2 -0
- package/dist/integrations/pi/engine/conformance.js +2 -0
- package/dist/integrations/pi/engine/http-dispatcher.d.ts +4 -0
- package/dist/integrations/pi/engine/http-dispatcher.js +25 -0
- package/dist/integrations/pi/engine/index.d.ts +3 -0
- package/dist/integrations/pi/engine/index.js +3 -0
- package/dist/integrations/pi/engine/model-auth-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/model-auth-integration.js +1 -0
- package/dist/integrations/pi/engine/package-integration.js +1 -1
- package/dist/integrations/pi/engine/project-trust-preflight.d.ts +22 -0
- package/dist/integrations/pi/engine/project-trust-preflight.js +50 -0
- package/dist/integrations/pi/engine/resource-extension-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/resource-extension-integration.js +1 -0
- package/dist/integrations/pi/engine/runtime-integration.d.ts +16 -1
- package/dist/integrations/pi/engine/runtime-integration.js +34 -4
- package/dist/integrations/pi/engine/session-integration.d.ts +1 -0
- package/dist/integrations/pi/engine/session-integration.js +2 -1
- package/dist/integrations/pi/engine/settings-effects.d.ts +66 -0
- package/dist/integrations/pi/engine/settings-effects.js +249 -0
- package/dist/integrations/pi/engine/settings-integration.d.ts +14 -26
- package/dist/integrations/pi/engine/settings-integration.js +102 -108
- package/dist/integrations/pi/engine/workflow-controllers.d.ts +2 -1
- package/dist/integrations/pi/engine/workflow-controllers.js +1 -0
- package/dist/integrations/pi/session-ui/clipboard-image.d.ts +11 -0
- package/dist/integrations/pi/session-ui/clipboard-image.js +29 -0
- package/dist/integrations/pi/session-ui/index.d.ts +1 -0
- package/dist/integrations/pi/session-ui/index.js +1 -0
- package/dist/integrations/pi/session-ui/prompt-chips.js +6 -2
- package/dist/integrations/pi/session-ui/session-shell-root.d.ts +39 -4
- package/dist/integrations/pi/session-ui/session-shell-root.js +215 -80
- package/dist/integrations/pi/session-ui/session-shell.d.ts +10 -1
- package/dist/integrations/pi/session-ui/session-shell.js +256 -45
- package/dist/integrations/pi/session-ui/session-viewport-controller.d.ts +5 -0
- package/dist/integrations/pi/session-ui/session-viewport-controller.js +76 -11
- package/dist/integrations/pi/session-ui/stream-presentation-coalescer.d.ts +29 -0
- package/dist/integrations/pi/session-ui/stream-presentation-coalescer.js +79 -0
- package/dist/integrations/pi/session-ui/system-clipboard.d.ts +9 -0
- package/dist/integrations/pi/session-ui/system-clipboard.js +38 -9
- package/dist/integrations/pi/tui-runtime/adapter.d.ts +6 -0
- package/dist/integrations/pi/tui-runtime/adapter.js +166 -8
- package/dist/integrations/pi/tui-runtime/contracts.d.ts +25 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.d.ts +63 -0
- package/dist/integrations/pi/tui-runtime/damage-aware-terminal.js +240 -0
- package/dist/integrations/pi/tui-runtime/index.d.ts +2 -0
- package/dist/integrations/pi/tui-runtime/index.js +2 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.d.ts +39 -0
- package/dist/integrations/pi/tui-runtime/input-presentation-coordinator.js +139 -0
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/ui/apps/host.js +5 -9
- package/dist/ui/apps/registry.d.ts +1 -0
- package/dist/ui/apps/registry.js +1 -0
- package/dist/ui/components/dialog-panel.js +5 -3
- package/dist/ui/components/frame.d.ts +1 -0
- package/dist/ui/components/frame.js +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/line-input.d.ts +1 -6
- package/dist/ui/components/line-input.js +4 -9
- package/dist/ui/components/list-view.d.ts +0 -6
- package/dist/ui/components/list-view.js +14 -7
- package/dist/ui/components/progress-status.d.ts +2 -0
- package/dist/ui/components/progress-status.js +4 -0
- package/dist/ui/components/scrollbar.js +1 -1
- package/dist/ui/components/shortcuts.d.ts +1 -0
- package/dist/ui/components/shortcuts.js +1 -0
- package/dist/ui/components/spans.d.ts +2 -5
- package/dist/ui/components/spans.js +28 -8
- package/dist/ui/components/surface.d.ts +0 -5
- package/dist/ui/components/surface.js +1 -5
- package/dist/ui/components/text-selection.d.ts +10 -1
- package/dist/ui/components/text-selection.js +96 -29
- package/dist/ui/components/text.js +3 -3
- package/dist/ui/components/transcript-viewport.d.ts +42 -0
- package/dist/ui/components/transcript-viewport.js +287 -39
- package/dist/ui/settings/sections.d.ts +6 -19
- package/dist/ui/settings/sections.js +17 -15
- package/dist/ui/settings/session.d.ts +8 -18
- package/dist/ui/settings/session.js +60 -52
- package/dist/ui/settings/store.d.ts +1 -0
- package/dist/ui/settings/store.js +2 -1
- package/docs/architecture/code-documentation.md +77 -0
- package/docs/architecture/project-structure.md +15 -1
- package/docs/architecture/ui-reference-provenance.md +23 -3
- package/docs/ci-release-runbook.md +98 -7
- package/docs/manual-owned-ui-checkpoint.md +28 -1
- package/docs/manual-terminal-colour-check.md +4 -3
- package/docs/repository-governance-live-acceptance.md +77 -0
- package/package.json +11 -3
|
@@ -96,18 +96,18 @@ export function createUpdateLifecycleCoordinator(environment = process.env, file
|
|
|
96
96
|
await removeEndpointArtifacts(owner.paths.endpointMetadataPath, owner.paths.endpoint);
|
|
97
97
|
return { priorActiveVersion };
|
|
98
98
|
}
|
|
99
|
-
//
|
|
99
|
+
// Rationale: leaving sessions alone is the expected outcome, and saying so mid-update tears
|
|
100
100
|
// the progress bar; only ending a session (below) is worth interrupting it for.
|
|
101
101
|
if (plan === "leave-running")
|
|
102
102
|
return { priorActiveVersion };
|
|
103
|
-
//
|
|
103
|
+
// Rationale: say whose work is ending before it ends.
|
|
104
104
|
const live = endpoint.ownership.liveInstanceIds.length;
|
|
105
105
|
if (live > 0) {
|
|
106
106
|
output.stderr(`${PRODUCT_TEXT.diagnostic(`ending ${live === 1 ? "one session" : `${live} sessions`} that run from the installation being replaced; a session started by an installed release would have been left alone.`)}\n`);
|
|
107
107
|
}
|
|
108
108
|
const identity = await requestUpdateShutdown(endpoint, targetVersion, 2_000);
|
|
109
109
|
if (!identity.accepted && processIsAlive(endpoint.pid)) {
|
|
110
|
-
//
|
|
110
|
+
// Security: explicit update consent permits bounded cleanup of an authenticated
|
|
111
111
|
// older owner that predates the update-shutdown message.
|
|
112
112
|
const cleanup = await cleanupVerifiedOwner(endpoint, { allowLiveInstances: true, reason: "legacy-mutable-install" });
|
|
113
113
|
if (!cleanup.terminated)
|
|
@@ -133,7 +133,7 @@ export function createUpdateLifecycleCoordinator(environment = process.env, file
|
|
|
133
133
|
await rename(probe, packageRoot);
|
|
134
134
|
}
|
|
135
135
|
catch (error) {
|
|
136
|
-
//
|
|
136
|
+
// Invariant: best-effort rollback runs if the first rename succeeded and the second did not.
|
|
137
137
|
await rename(probe, packageRoot).catch(() => { });
|
|
138
138
|
throw new Error(PRODUCT_TEXT.diagnostic(`package remains locked after verified shutdown: ${errorMessage(error)}`));
|
|
139
139
|
}
|
|
@@ -214,7 +214,7 @@ function createUpdateProgress(output, enabled) {
|
|
|
214
214
|
draw();
|
|
215
215
|
if (creepTo <= current)
|
|
216
216
|
return;
|
|
217
|
-
//
|
|
217
|
+
// Rationale: creep asymptotically toward (but never reach) the next milestone so
|
|
218
218
|
// long opaque phases such as npm install still show visible motion. The
|
|
219
219
|
// ceiling stays a whole point below the milestone: settling on `creepTo`
|
|
220
220
|
// itself would render as that milestone and make arriving at it invisible,
|
|
@@ -225,7 +225,7 @@ function createUpdateProgress(output, enabled) {
|
|
|
225
225
|
}, PROGRESS_TICK_MS);
|
|
226
226
|
timer.unref?.();
|
|
227
227
|
},
|
|
228
|
-
//
|
|
228
|
+
// Rationale: the bar exists to say the update is still moving. Once it has finished
|
|
229
229
|
// there is a better line to occupy that row — the one naming what is now
|
|
230
230
|
// installed — so the bar gives the row back rather than leaving a full
|
|
231
231
|
// meter above a message that already implies it.
|
|
@@ -283,7 +283,7 @@ async function resolveRequestedPreview(runner, requested, output) {
|
|
|
283
283
|
const versions = (Array.isArray(published) ? published : [published]).filter((value) => typeof value === "string");
|
|
284
284
|
const exact = versions.find(version => version === requested);
|
|
285
285
|
if (exact !== undefined) {
|
|
286
|
-
//
|
|
286
|
+
// Rationale: naming a release here would install it through the preview path, which is a
|
|
287
287
|
// different command with a different meaning.
|
|
288
288
|
if (!exact.includes("-dev.")) {
|
|
289
289
|
output.stderr(`${PRODUCT_TEXT.diagnostic(`${exact} is a release, not a preview; run ${PRODUCT_TEXT.commandName} update to move to the current release.`)}\n`);
|
|
@@ -336,7 +336,7 @@ export async function runSelfUpdate(options) {
|
|
|
336
336
|
if (resolved.version === null)
|
|
337
337
|
return resolved.exitCode;
|
|
338
338
|
const targetVersion = resolved.version;
|
|
339
|
-
//
|
|
339
|
+
// Rationale: no full stop after a version: it already ends in a dot-separated identifier,
|
|
340
340
|
// and a trailing one reads as part of the version rather than as punctuation.
|
|
341
341
|
output.stdout(`${PRODUCT_TEXT.commandName} update: ${runningVersion} → ${targetVersion}\n`);
|
|
342
342
|
const progress = createUpdateProgress(output, options.progress ?? (options.output === undefined && process.stdout.isTTY === true));
|
|
@@ -375,7 +375,7 @@ export async function runSelfUpdate(options) {
|
|
|
375
375
|
output.stdout(`${PRODUCT_TEXT.commandName} is up to date — no update needed.\n`);
|
|
376
376
|
return 0;
|
|
377
377
|
}
|
|
378
|
-
//
|
|
378
|
+
// Rationale: the bar first appears here so a no-change run never flashes it.
|
|
379
379
|
progress.set(3, 15);
|
|
380
380
|
const cohortState = await new CohortStateStore(paths.dataDir).read();
|
|
381
381
|
transaction = await transactionStore.begin({
|
|
@@ -403,7 +403,7 @@ export async function runSelfUpdate(options) {
|
|
|
403
403
|
}
|
|
404
404
|
transaction = await transactionStore.advance("package-installed");
|
|
405
405
|
}
|
|
406
|
-
// npm 12 blocks install scripts unless allowScripts covers the package, so
|
|
406
|
+
// Compatibility: npm 12 blocks install scripts unless allowScripts covers the package, so
|
|
407
407
|
// the postinstall that points the #pi-tui proxy at the tree npm just built
|
|
408
408
|
// may never have run. Run the shipped script directly: the proxy must be
|
|
409
409
|
// correct before the release store copies this tree. A failure is reported
|
|
@@ -417,7 +417,7 @@ export async function runSelfUpdate(options) {
|
|
|
417
417
|
output.stderr(`${PRODUCT_TEXT.diagnostic(`could not point the #pi-tui proxy at the installed tree: ${errorMessage(error)}`)}\n`);
|
|
418
418
|
}
|
|
419
419
|
progress.set(70, 75);
|
|
420
|
-
//
|
|
420
|
+
// Concurrency: ownership can be reacquired after an interrupted installation (for
|
|
421
421
|
// example, if bare A1 is launched before the update is resumed). Recheck
|
|
422
422
|
// immediately before activation so recovery cannot start a second cohort.
|
|
423
423
|
await measure("ownership-release", async () => { await lifecycle.shutdownVerifiedOwners(targetVersion); });
|
|
@@ -530,7 +530,7 @@ async function rollbackPriorCohort(dataDir, environment, priorReleaseId) {
|
|
|
530
530
|
}
|
|
531
531
|
const release = await readMaterializedRelease(prior.releaseRoot);
|
|
532
532
|
const paths = resolveProductPaths(environment);
|
|
533
|
-
//
|
|
533
|
+
// Invariant: rollback re-points the active reference and starts the prior cohort on its own endpoint;
|
|
534
534
|
// a cohort that survived the update keeps serving the work it already had.
|
|
535
535
|
await startSupervisor(release, environment);
|
|
536
536
|
await waitForVerifiedEndpoint(resolveCohortEndpoint(paths, release.releaseId, environment).endpointMetadataPath, release, 8_000);
|
|
@@ -14,6 +14,7 @@ export interface StoredWorkspaceAgent {
|
|
|
14
14
|
readonly agent: ManagedAgentDescriptor;
|
|
15
15
|
readonly presentation: WorkspaceAgentPresentation;
|
|
16
16
|
}
|
|
17
|
+
/** Owns WAL-backed control persistence and reconciles prior-boot records before current use. */
|
|
17
18
|
export declare class ControlStore {
|
|
18
19
|
#private;
|
|
19
20
|
readonly bootNonce: string | null;
|
|
@@ -6,6 +6,7 @@ import { assertManagedAgentDescriptor, assertRecoveryAuthority, assertTerminalSe
|
|
|
6
6
|
import { assertLaunchInstance, assertLaunchInstanceOutcome, assertNativeProcessIdentity, assertProcessContainmentIdentity, } from "../lifecycle/index.js";
|
|
7
7
|
export const DEFAULT_WORKSPACE_ID = "workspace-default";
|
|
8
8
|
const INITIAL_WORKSPACE_ID = DEFAULT_WORKSPACE_ID;
|
|
9
|
+
/** Owns WAL-backed control persistence and reconciles prior-boot records before current use. */
|
|
9
10
|
export class ControlStore {
|
|
10
11
|
bootNonce;
|
|
11
12
|
database;
|
|
@@ -33,6 +33,7 @@ export type StructuredBackpressureReleaseResult = {
|
|
|
33
33
|
readonly code: "unknown-lease" | "invalid-request";
|
|
34
34
|
readonly diagnostic: string;
|
|
35
35
|
};
|
|
36
|
+
/** Issues bounded resource leases and selects the negotiated backpressure action on exhaustion. */
|
|
36
37
|
export declare class StructuredBackpressureController {
|
|
37
38
|
#private;
|
|
38
39
|
readonly adapterId: string;
|
|
@@ -38,6 +38,7 @@ export type StructuredCommandOutcomeResult = {
|
|
|
38
38
|
readonly code: string;
|
|
39
39
|
readonly diagnostic: string;
|
|
40
40
|
};
|
|
41
|
+
/** Tracks structured commands by correlation identity through one idempotent terminal outcome. */
|
|
41
42
|
export declare class StructuredCommandTracker {
|
|
42
43
|
#private;
|
|
43
44
|
readonly agentId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertStructuredCapability, assertWorkspaceCommand, } from "../../contracts/workspace/index.js";
|
|
2
|
+
/** Tracks structured commands by correlation identity through one idempotent terminal outcome. */
|
|
2
3
|
export class StructuredCommandTracker {
|
|
3
4
|
agentId;
|
|
4
5
|
#capability;
|
|
@@ -30,6 +30,7 @@ export type StructuredReconnectionResult = {
|
|
|
30
30
|
readonly code: string;
|
|
31
31
|
readonly diagnostic: string;
|
|
32
32
|
};
|
|
33
|
+
/** Accepts a recovery boundary once after validating negotiated identity, proof, and protocol continuity. */
|
|
33
34
|
export declare class StructuredReconnectionManager {
|
|
34
35
|
#private;
|
|
35
36
|
constructor(capability: StructuredCapabilityContract);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { WORKSPACE_CONTRACT_VERSION, assertRecoveryAuthority, assertStructuredAgentSnapshot, assertStructuredCapability, } from "../../contracts/workspace/index.js";
|
|
2
2
|
import { StructuredEventReducer } from "./state.js";
|
|
3
|
+
/** Accepts a recovery boundary once after validating negotiated identity, proof, and protocol continuity. */
|
|
3
4
|
export class StructuredReconnectionManager {
|
|
4
5
|
#capability;
|
|
5
6
|
#acceptedBoundaries = new Set();
|
|
@@ -44,6 +44,7 @@ export type StructuredSnapshotApplyResult = {
|
|
|
44
44
|
readonly code: string;
|
|
45
45
|
readonly diagnostic: string;
|
|
46
46
|
};
|
|
47
|
+
/** Applies ordered structured events and snapshots while exposing gaps as explicit resynchronization. */
|
|
47
48
|
export declare class StructuredEventReducer {
|
|
48
49
|
#private;
|
|
49
50
|
readonly agentId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertStructuredAgentSnapshot, assertStructuredCapability, assertWorkspaceEvent, } from "../../contracts/workspace/index.js";
|
|
2
|
+
/** Applies ordered structured events and snapshots while exposing gaps as explicit resynchronization. */
|
|
2
3
|
export class StructuredEventReducer {
|
|
3
4
|
agentId;
|
|
4
5
|
#capability;
|
|
@@ -19,7 +19,7 @@ export async function runSupervisor() {
|
|
|
19
19
|
throw new Error(PRODUCT_TEXT.diagnostic("supervisor must be launched from a verified immutable release"));
|
|
20
20
|
const release = await readCertifiedReleaseManifest({ releaseRoot, releaseId, contentDigest }, resolve(paths.dataDir, "releases"));
|
|
21
21
|
await assertImmutableExecutionRoot(release, paths.dataDir);
|
|
22
|
-
//
|
|
22
|
+
// Protocol: one endpoint per cohort: a superseded cohort keeps serving what it already has while the
|
|
23
23
|
// installed release listens on its own address.
|
|
24
24
|
paths = { ...productPaths, ...resolveCohortEndpoint(productPaths, release.releaseId) };
|
|
25
25
|
const bootNonce = randomUUID();
|
|
@@ -2,6 +2,7 @@ import { type SupervisorSnapshot } from "../lifecycle/index.js";
|
|
|
2
2
|
import { type MaterializedRelease } from "../release/index.js";
|
|
3
3
|
import { ControlStore } from "../storage/index.js";
|
|
4
4
|
import { type ProductPaths } from "./paths.js";
|
|
5
|
+
/** Owns one release-cohort endpoint and the authenticated launch instances registered through it. */
|
|
5
6
|
export declare class SupervisorServer {
|
|
6
7
|
#private;
|
|
7
8
|
readonly store: ControlStore;
|
|
@@ -8,6 +8,7 @@ import { processIsAlive } from "../release/index.js";
|
|
|
8
8
|
import { ControlStore } from "../storage/index.js";
|
|
9
9
|
import { resolveProductPaths } from "./paths.js";
|
|
10
10
|
import { PRODUCT_IDENTITY, PRODUCT_TEXT } from "../../product-identity.js";
|
|
11
|
+
/** Owns one release-cohort endpoint and the authenticated launch instances registered through it. */
|
|
11
12
|
export class SupervisorServer {
|
|
12
13
|
store;
|
|
13
14
|
release;
|
|
@@ -90,10 +91,7 @@ export class SupervisorServer {
|
|
|
90
91
|
this.#supersededPoll = poll;
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
-
* Notices that another release has become the one new sessions start on. Nothing is
|
|
95
|
-
* interrupted by that: this cohort finishes what it is holding and then leaves.
|
|
96
|
-
*/
|
|
94
|
+
// Invariant: superseding a cohort never interrupts its held instances; it retires only when empty.
|
|
97
95
|
async #refreshCohortRole() {
|
|
98
96
|
if (this.#closing || !this.readActiveReleaseId)
|
|
99
97
|
return;
|
|
@@ -327,7 +325,7 @@ export class SupervisorServer {
|
|
|
327
325
|
this.#uncertainInstances.delete(stored.id);
|
|
328
326
|
this.#unbindOwner(stored.id, socket);
|
|
329
327
|
this.#mutated();
|
|
330
|
-
//
|
|
328
|
+
// Invariant: the last session on a superseded cohort has left; there is nothing here to keep.
|
|
331
329
|
if (this.#superseded && this.#instances.size === 0)
|
|
332
330
|
void this.retire();
|
|
333
331
|
}
|
|
@@ -421,7 +419,7 @@ export class SupervisorServer {
|
|
|
421
419
|
const deadline = Date.now() + timeoutMs;
|
|
422
420
|
while (Date.now() < deadline) {
|
|
423
421
|
if (this.#instances.size === 0) {
|
|
424
|
-
//
|
|
422
|
+
// Concurrency: allow the terminal command result to flush before closing owner sockets.
|
|
425
423
|
await new Promise(resolvePromise => setTimeout(resolvePromise, 25));
|
|
426
424
|
return this.#instances.size === 0;
|
|
427
425
|
}
|
|
@@ -10,6 +10,7 @@ export interface PiComponentConformanceReport {
|
|
|
10
10
|
readonly componentResults: readonly PiComponentConformanceResult[];
|
|
11
11
|
readonly componentFamilies: readonly string[];
|
|
12
12
|
}
|
|
13
|
+
/** Identifies the Pi presentation-conformance stage that failed against the pinned component surface. */
|
|
13
14
|
export declare class PiComponentConformanceError extends Error {
|
|
14
15
|
readonly stage: "theme" | "components";
|
|
15
16
|
constructor(stage: "theme" | "components", cause: unknown);
|
|
@@ -5,6 +5,7 @@ import { AssistantMessageComponent, ExtensionSelectorComponent, initTheme, Login
|
|
|
5
5
|
import { OWNED_UI_CONTRACT_VERSION } from "../../../contracts/owned-ui/index.js";
|
|
6
6
|
import { createTuiFacade, validatedAssistantMessage } from "./shell-components.js";
|
|
7
7
|
import { PRODUCT_IDENTITY } from "../../../product-identity.js";
|
|
8
|
+
/** Identifies the Pi presentation-conformance stage that failed against the pinned component surface. */
|
|
8
9
|
export class PiComponentConformanceError extends Error {
|
|
9
10
|
stage;
|
|
10
11
|
constructor(stage, cause) {
|
|
@@ -2,5 +2,6 @@ export * from "./shell-shared-facade.js";
|
|
|
2
2
|
export * from "./shell-editor-autocomplete.js";
|
|
3
3
|
export * from "./shell-selectors-dialogs.js";
|
|
4
4
|
export * from "./shell-presenters-transcript.js";
|
|
5
|
+
export * from "./shell-presenters-info.js";
|
|
5
6
|
export * from "./shell-footer-status.js";
|
|
6
7
|
export * from "./shell-extension-ui.js";
|
|
@@ -2,5 +2,6 @@ export * from "./shell-shared-facade.js";
|
|
|
2
2
|
export * from "./shell-editor-autocomplete.js";
|
|
3
3
|
export * from "./shell-selectors-dialogs.js";
|
|
4
4
|
export * from "./shell-presenters-transcript.js";
|
|
5
|
+
export * from "./shell-presenters-info.js";
|
|
5
6
|
export * from "./shell-footer-status.js";
|
|
6
7
|
export * from "./shell-extension-ui.js";
|
|
@@ -158,6 +158,16 @@ export function createPiShellEditor(options) {
|
|
|
158
158
|
setSubmitHandler: handler => { submitHandler = handler; },
|
|
159
159
|
setInterruptHandler: handler => { interruptHandler = handler; },
|
|
160
160
|
setAutocompleteCommands,
|
|
161
|
+
setPaddingX(padding) {
|
|
162
|
+
editor.setPaddingX(padding);
|
|
163
|
+
editor.invalidate();
|
|
164
|
+
tui.requestRender();
|
|
165
|
+
},
|
|
166
|
+
setAutocompleteMaxVisible(maxVisible) {
|
|
167
|
+
editor.setAutocompleteMaxVisible(maxVisible);
|
|
168
|
+
editor.invalidate();
|
|
169
|
+
tui.requestRender();
|
|
170
|
+
},
|
|
161
171
|
addAutocompleteProvider(factory) {
|
|
162
172
|
if (typeof factory !== "function")
|
|
163
173
|
throw new TypeError("extension autocomplete factory must be a function");
|
|
@@ -2,6 +2,6 @@ import type { OwnedUiSessionViewModel } from "../../../contracts/owned-ui/index.
|
|
|
2
2
|
import { type PiShellViewComponentPort, type PiShellStatusPort, type PiShellQueuedInputPort, type PiShellHeaderPort, type PiShellResourceEntry, type PiShellLoadedResourcesPort, type PiShellHeaderOptions, type PiShellEditorOptions } from "./shell-shared-facade.js";
|
|
3
3
|
export declare function createPiShellHeader(options?: PiShellHeaderOptions): PiShellHeaderPort;
|
|
4
4
|
export declare function createPiShellLoadedResources(resources: readonly PiShellResourceEntry[], initialExpanded?: boolean): PiShellLoadedResourcesPort;
|
|
5
|
-
export declare function createPiShellStatus(view: OwnedUiSessionViewModel, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellStatusPort;
|
|
5
|
+
export declare function createPiShellStatus(view: OwnedUiSessionViewModel, formatProgressStatus: (message: string) => string, runtime?: Pick<PiShellEditorOptions, "getColumns" | "getRows" | "requestRender">): PiShellStatusPort;
|
|
6
6
|
export declare function createPiShellFooter(view: OwnedUiSessionViewModel, cwd: string): PiShellViewComponentPort;
|
|
7
7
|
export declare function createPiQueuedInputStatus(submissions: readonly string[], presentation?: "pinned" | "custom-viewport"): PiShellQueuedInputPort;
|
|
@@ -67,20 +67,21 @@ export function createPiShellLoadedResources(resources, initialExpanded = false)
|
|
|
67
67
|
invalidate() { },
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
export function createPiShellStatus(view, runtime) {
|
|
70
|
+
export function createPiShellStatus(view, formatProgressStatus, runtime) {
|
|
71
71
|
ensureTheme();
|
|
72
72
|
const statusUi = createTuiFacade(runtime ?? { getColumns: () => 80, getRows: () => 24, requestRender() { } });
|
|
73
73
|
let workingOverride;
|
|
74
|
-
let
|
|
75
|
-
let
|
|
74
|
+
let outputPad = PINNED_PI_LAYOUT.outputPad;
|
|
75
|
+
let component = statusComponent(view, statusUi, workingOverride, outputPad, formatProgressStatus);
|
|
76
|
+
let signature = statusSignature(view, workingOverride, outputPad);
|
|
76
77
|
const rebuild = () => {
|
|
77
|
-
const nextSignature = statusSignature(view, workingOverride);
|
|
78
|
+
const nextSignature = statusSignature(view, workingOverride, outputPad);
|
|
78
79
|
if (nextSignature === signature)
|
|
79
80
|
return;
|
|
80
81
|
if (component !== undefined && "dispose" in component && typeof component.dispose === "function")
|
|
81
82
|
component.dispose();
|
|
82
83
|
signature = nextSignature;
|
|
83
|
-
component = statusComponent(view, statusUi, workingOverride);
|
|
84
|
+
component = statusComponent(view, statusUi, workingOverride, outputPad, formatProgressStatus);
|
|
84
85
|
};
|
|
85
86
|
return {
|
|
86
87
|
render: width => component?.render(width) ?? [],
|
|
@@ -93,6 +94,10 @@ export function createPiShellStatus(view, runtime) {
|
|
|
93
94
|
workingOverride = message;
|
|
94
95
|
rebuild();
|
|
95
96
|
},
|
|
97
|
+
setOutputPad(padding) {
|
|
98
|
+
outputPad = padding;
|
|
99
|
+
rebuild();
|
|
100
|
+
},
|
|
96
101
|
dispose() {
|
|
97
102
|
if (component !== undefined && "dispose" in component && typeof component.dispose === "function")
|
|
98
103
|
component.dispose();
|
|
@@ -121,19 +126,20 @@ export function createPiQueuedInputStatus(submissions, presentation = "pinned")
|
|
|
121
126
|
},
|
|
122
127
|
};
|
|
123
128
|
}
|
|
124
|
-
function statusComponent(view, ui, workingOverride) {
|
|
125
|
-
if (view.lifecycle === "busy")
|
|
126
|
-
return new WorkingStatusIndicator(ui, workingOverride ?? view.status.workingMessage ?? "Working
|
|
129
|
+
function statusComponent(view, ui, workingOverride, outputPad, formatProgressStatus) {
|
|
130
|
+
if (view.lifecycle === "busy") {
|
|
131
|
+
return new WorkingStatusIndicator(ui, formatProgressStatus(workingOverride ?? view.status.workingMessage ?? "Working"));
|
|
132
|
+
}
|
|
127
133
|
if (view.lifecycle === "failed") {
|
|
128
|
-
return new Text(piTheme().fg("error", view.status.diagnostics.at(-1) ?? "Session failed"),
|
|
134
|
+
return new Text(piTheme().fg("error", view.status.diagnostics.at(-1) ?? "Session failed"), outputPad, 0);
|
|
129
135
|
}
|
|
130
136
|
if (view.status.workingMessage !== null) {
|
|
131
|
-
return new Text(piTheme().fg("muted", view.status.workingMessage),
|
|
137
|
+
return new Text(piTheme().fg("muted", view.status.workingMessage), outputPad, 0);
|
|
132
138
|
}
|
|
133
139
|
return undefined;
|
|
134
140
|
}
|
|
135
|
-
function statusSignature(view, workingOverride) {
|
|
136
|
-
return `${view.lifecycle}\u0000${workingOverride ?? ""}\u0000${view.status.workingMessage ?? ""}\u0000${view.status.diagnostics.at(-1) ?? ""}`;
|
|
141
|
+
function statusSignature(view, workingOverride, outputPad) {
|
|
142
|
+
return `${outputPad}\u0000${view.lifecycle}\u0000${workingOverride ?? ""}\u0000${view.status.workingMessage ?? ""}\u0000${view.status.diagnostics.at(-1) ?? ""}`;
|
|
137
143
|
}
|
|
138
144
|
function queuedInputText(submissions, presentation) {
|
|
139
145
|
if (submissions.length === 0)
|
|
@@ -144,7 +150,7 @@ function queuedInputText(submissions, presentation) {
|
|
|
144
150
|
}
|
|
145
151
|
const messages = submissions.map(submission => theme.fg("dim", `Steering: ${submission.replaceAll("\n", " ⏎ ")}`));
|
|
146
152
|
const dequeueHint = theme.fg("dim", "↳ Alt+Up to edit all queued messages");
|
|
147
|
-
//
|
|
153
|
+
// Compatibility: the custom viewport matches Pi's interactive queue presentation while the
|
|
148
154
|
// comparison shell remains byte-for-byte compatible with its pinned fixture.
|
|
149
155
|
return ["", ...messages, dequeueHint].join("\n");
|
|
150
156
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type PiShellComponentPort } from "./shell-shared-facade.js";
|
|
2
|
+
export interface PiShellSessionInfoPresentation {
|
|
3
|
+
readonly sessionName?: string;
|
|
4
|
+
readonly stats: {
|
|
5
|
+
readonly sessionFile?: string;
|
|
6
|
+
readonly sessionId: string;
|
|
7
|
+
readonly userMessages: number;
|
|
8
|
+
readonly assistantMessages: number;
|
|
9
|
+
readonly toolCalls: number;
|
|
10
|
+
readonly toolResults: number;
|
|
11
|
+
readonly totalMessages: number;
|
|
12
|
+
readonly tokens: {
|
|
13
|
+
readonly input: number;
|
|
14
|
+
readonly output: number;
|
|
15
|
+
readonly cacheRead: number;
|
|
16
|
+
readonly cacheWrite: number;
|
|
17
|
+
readonly total: number;
|
|
18
|
+
};
|
|
19
|
+
readonly cost: number;
|
|
20
|
+
};
|
|
21
|
+
readonly cacheWaste: {
|
|
22
|
+
readonly missedTokens: number;
|
|
23
|
+
readonly missedCost: number;
|
|
24
|
+
readonly missCount: number;
|
|
25
|
+
};
|
|
26
|
+
readonly usageBreakdown: readonly {
|
|
27
|
+
readonly key: string;
|
|
28
|
+
readonly cost: number;
|
|
29
|
+
readonly tokens: number;
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
32
|
+
export declare function renderPiShellStatusText(message: string, width: number, outputPad?: 0 | 1): readonly string[];
|
|
33
|
+
export declare function createPiShellSessionInfo(presentation: PiShellSessionInfoPresentation): PiShellComponentPort;
|
|
34
|
+
export declare function createPiShellCollapsedChangelog(): PiShellComponentPort;
|
|
35
|
+
export declare function createPiShellChangelog(markdown: string): PiShellComponentPort;
|
|
36
|
+
export declare function createPiShellHotkeys(): PiShellComponentPort;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DynamicBorder, getMarkdownTheme } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Container, Markdown, Spacer, Text } from "#pi-tui";
|
|
3
|
+
import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
|
|
4
|
+
import { PINNED_PI_LAYOUT, piTheme } from "./theme.js";
|
|
5
|
+
import { componentPort, ensureTheme, formatSessionTokens } from "./shell-shared-facade.js";
|
|
6
|
+
export function renderPiShellStatusText(message, width, outputPad = PINNED_PI_LAYOUT.outputPad) {
|
|
7
|
+
ensureTheme();
|
|
8
|
+
return new Text(piTheme().fg("dim", message), outputPad, 0).render(width);
|
|
9
|
+
}
|
|
10
|
+
export function createPiShellSessionInfo(presentation) {
|
|
11
|
+
ensureTheme();
|
|
12
|
+
const { stats, sessionName, cacheWaste, usageBreakdown } = presentation;
|
|
13
|
+
let info = `${piTheme().bold("Session Info")}\n\n`;
|
|
14
|
+
if (sessionName)
|
|
15
|
+
info += `${piTheme().fg("dim", "Name:")} ${sessionName}\n`;
|
|
16
|
+
info += `${piTheme().fg("dim", "File:")} ${stats.sessionFile ?? "In-memory"}\n${piTheme().fg("dim", "ID:")} ${stats.sessionId}\n\n`;
|
|
17
|
+
info += `${piTheme().bold("Messages")}\n${piTheme().fg("dim", "Total:")} ${stats.totalMessages}\n${piTheme().fg("dim", "User:")} ${stats.userMessages}\n`;
|
|
18
|
+
info += `${piTheme().fg("dim", "Assistant:")} ${stats.assistantMessages}\n${piTheme().fg("dim", "Tools:")} ${stats.toolCalls} calls, ${stats.toolResults} results\n\n`;
|
|
19
|
+
info += `${piTheme().bold("Tokens")}\n`;
|
|
20
|
+
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
21
|
+
const promptTokens = input + cacheRead + cacheWrite;
|
|
22
|
+
info += `${piTheme().fg("dim", "Input:")} ${promptTokens.toLocaleString()}\n`;
|
|
23
|
+
if (promptTokens > 0 && (cacheRead > 0 || cacheWrite > 0)) {
|
|
24
|
+
info += ` ${piTheme().fg("dim", "Cached:")} ${cacheRead.toLocaleString()} ${piTheme().fg("dim", `(${((cacheRead / promptTokens) * 100).toFixed(1)}%)`)}\n`;
|
|
25
|
+
const written = cacheWrite > 0 ? ` ${piTheme().fg("dim", `(${cacheWrite.toLocaleString()} written to cache)`)}` : "";
|
|
26
|
+
info += ` ${piTheme().fg("dim", "Uncached:")} ${(input + cacheWrite).toLocaleString()}${written}\n`;
|
|
27
|
+
}
|
|
28
|
+
info += `${piTheme().fg("dim", "Output:")} ${stats.tokens.output.toLocaleString()}\n${piTheme().fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
|
|
29
|
+
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
30
|
+
info += `\n${piTheme().bold("Cost")}\n${piTheme().fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
|
|
31
|
+
if (usageBreakdown.length > 1)
|
|
32
|
+
for (const entry of usageBreakdown)
|
|
33
|
+
info += `\n ${piTheme().fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${piTheme().fg("dim", `(${formatSessionTokens(entry.tokens)} tokens)`)}`;
|
|
34
|
+
if (cacheWaste.missedTokens > 0) {
|
|
35
|
+
const detail = `${cacheWaste.missedTokens.toLocaleString()} tokens, ${cacheWaste.missCount === 1 ? "1 miss" : `${cacheWaste.missCount} misses`}`;
|
|
36
|
+
info += cacheWaste.missedCost >= 0.0001 ? `\n${piTheme().fg("dim", "Cache Re-billed:")} $${cacheWaste.missedCost.toFixed(3)} ${piTheme().fg("dim", `(${detail})`)}` : `\n${piTheme().fg("dim", "Cache Re-billed:")} ${detail}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const container = new Container();
|
|
40
|
+
container.addChild(new Spacer(1));
|
|
41
|
+
container.addChild(new Text(info, 1, 0));
|
|
42
|
+
return componentPort(container);
|
|
43
|
+
}
|
|
44
|
+
export function createPiShellCollapsedChangelog() {
|
|
45
|
+
ensureTheme();
|
|
46
|
+
const container = new Container();
|
|
47
|
+
container.addChild(new Spacer(1));
|
|
48
|
+
container.addChild(new DynamicBorder());
|
|
49
|
+
container.addChild(new Text(`${piTheme().bold(piTheme().fg("accent", "What's New"))}\n${piTheme().fg("muted", "Run /changelog to view the full release notes.")}`, 1, 0));
|
|
50
|
+
container.addChild(new DynamicBorder());
|
|
51
|
+
return componentPort(container);
|
|
52
|
+
}
|
|
53
|
+
export function createPiShellChangelog(markdown) {
|
|
54
|
+
ensureTheme();
|
|
55
|
+
const container = new Container();
|
|
56
|
+
container.addChild(new Spacer(1));
|
|
57
|
+
container.addChild(new DynamicBorder());
|
|
58
|
+
container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "What's New")), 1, 0));
|
|
59
|
+
container.addChild(new Spacer(1));
|
|
60
|
+
container.addChild(new Markdown(markdown.trim() || "No changelog entries found.", 1, 1, getMarkdownTheme()));
|
|
61
|
+
container.addChild(new DynamicBorder());
|
|
62
|
+
return componentPort(container);
|
|
63
|
+
}
|
|
64
|
+
export function createPiShellHotkeys() {
|
|
65
|
+
ensureTheme();
|
|
66
|
+
const keys = new KeybindingsManager();
|
|
67
|
+
const display = (action) => keys.getKeys(action).map(key => key.split("+").map(part => part.charAt(0).toUpperCase() + part.slice(1)).join("+")).join("/");
|
|
68
|
+
const row = (actions, description) => `| ${actions.map(action => `\`${display(action)}\``).join(" / ")} | ${description} |`;
|
|
69
|
+
const markdown = ["**Navigation**", "| Key | Action |", "|-----|--------|", row(["tui.editor.cursorUp", "tui.editor.cursorDown", "tui.editor.cursorLeft", "tui.editor.cursorRight"], "Move cursor / browse history"), row(["tui.editor.cursorWordLeft", "tui.editor.cursorWordRight"], "Move by word"), row(["tui.editor.cursorLineStart"], "Start of line"), row(["tui.editor.cursorLineEnd"], "End of line"), row(["tui.editor.jumpForward"], "Jump forward to character"), row(["tui.editor.jumpBackward"], "Jump backward to character"), row(["tui.editor.pageUp", "tui.editor.pageDown"], "Scroll by page"), "", "**Editing**", "| Key | Action |", "|-----|--------|", row(["tui.input.submit"], "Send message"), row(["tui.input.newLine"], `New line${process.platform === "win32" ? " (Ctrl+Enter on Windows Terminal)" : ""}`), row(["tui.editor.deleteWordBackward"], "Delete word backwards"), row(["tui.editor.deleteWordForward"], "Delete word forwards"), row(["tui.editor.deleteToLineStart"], "Delete to start of line"), row(["tui.editor.deleteToLineEnd"], "Delete to end of line"), row(["tui.editor.yank"], "Paste the most-recently-deleted text"), row(["tui.editor.yankPop"], "Cycle through the deleted text after pasting"), row(["tui.editor.undo"], "Undo"), "", "**Other**", "| Key | Action |", "|-----|--------|", row(["tui.input.tab"], "Path completion / accept autocomplete"), row(["app.interrupt"], "Cancel autocomplete / abort streaming"), row(["app.clear"], "Clear editor (first) / exit (second)"), row(["app.exit"], "Exit (when editor is empty)"), row(["app.suspend"], "Suspend to background"), row(["app.thinking.cycle"], "Cycle thinking level"), row(["app.model.cycleForward", "app.model.cycleBackward"], "Cycle models"), row(["app.model.select"], "Open model selector"), row(["app.tools.expand"], "Toggle tool output expansion"), row(["app.thinking.toggle"], "Toggle thinking block visibility"), row(["app.editor.external"], "Edit message in external editor"), row(["app.message.copy"], "Copy last assistant message"), row(["app.message.followUp"], "Queue follow-up message"), row(["app.message.dequeue"], "Restore queued messages"), row(["app.clipboard.pasteImage"], "Paste image or text from clipboard"), "| `/` | Slash commands |", "| `!` | Run bash command |", "| `!!` | Run bash command (excluded from context) |"].join("\n");
|
|
70
|
+
const container = new Container();
|
|
71
|
+
container.addChild(new Spacer(1));
|
|
72
|
+
container.addChild(new DynamicBorder());
|
|
73
|
+
container.addChild(new Text(piTheme().bold(piTheme().fg("accent", "Keyboard Shortcuts")), 1, 0));
|
|
74
|
+
container.addChild(new Spacer(1));
|
|
75
|
+
container.addChild(new Markdown(markdown, 1, 1, getMarkdownTheme()));
|
|
76
|
+
container.addChild(new DynamicBorder());
|
|
77
|
+
return componentPort(container);
|
|
78
|
+
}
|
|
@@ -1,43 +1,10 @@
|
|
|
1
1
|
import { AssistantMessageComponent } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type MermaidRenderingMode } from "./upstream/components/mermaid.js";
|
|
2
3
|
import type { OwnedUiTranscriptBlock } from "../../../contracts/owned-ui/index.js";
|
|
3
4
|
import { type PiShellSubmittedPromptComposer } from "./submitted-prompt-adapter.js";
|
|
4
5
|
export type { PiShellSubmittedPromptComposer } from "./submitted-prompt-adapter.js";
|
|
5
|
-
import { type
|
|
6
|
-
export
|
|
7
|
-
readonly sessionName?: string;
|
|
8
|
-
readonly stats: {
|
|
9
|
-
readonly sessionFile?: string;
|
|
10
|
-
readonly sessionId: string;
|
|
11
|
-
readonly userMessages: number;
|
|
12
|
-
readonly assistantMessages: number;
|
|
13
|
-
readonly toolCalls: number;
|
|
14
|
-
readonly toolResults: number;
|
|
15
|
-
readonly totalMessages: number;
|
|
16
|
-
readonly tokens: {
|
|
17
|
-
readonly input: number;
|
|
18
|
-
readonly output: number;
|
|
19
|
-
readonly cacheRead: number;
|
|
20
|
-
readonly cacheWrite: number;
|
|
21
|
-
readonly total: number;
|
|
22
|
-
};
|
|
23
|
-
readonly cost: number;
|
|
24
|
-
};
|
|
25
|
-
readonly cacheWaste: {
|
|
26
|
-
readonly missedTokens: number;
|
|
27
|
-
readonly missedCost: number;
|
|
28
|
-
readonly missCount: number;
|
|
29
|
-
};
|
|
30
|
-
readonly usageBreakdown: readonly {
|
|
31
|
-
readonly key: string;
|
|
32
|
-
readonly cost: number;
|
|
33
|
-
readonly tokens: number;
|
|
34
|
-
}[];
|
|
35
|
-
}
|
|
36
|
-
export declare function renderPiShellStatusText(message: string, width: number): readonly string[];
|
|
37
|
-
export declare function createPiShellSessionInfo(presentation: PiShellSessionInfoPresentation): PiShellComponentPort;
|
|
38
|
-
export declare function createPiShellChangelog(markdown: string): PiShellComponentPort;
|
|
39
|
-
export declare function createPiShellHotkeys(): PiShellComponentPort;
|
|
40
|
-
export declare function createPiShellTranscriptComponent(initial: OwnedUiTranscriptBlock, cwd: string, extensions?: PiShellExtensionRendererResolver, submittedPrompt?: PiShellSubmittedPromptComposer): PiShellTranscriptComponentPort;
|
|
6
|
+
import { type PiShellExtensionRendererResolver, type PiShellImageAssetResolver, type PiShellTranscriptComponentPort } from "./shell-shared-facade.js";
|
|
7
|
+
export declare function createPiShellTranscriptComponent(initial: OwnedUiTranscriptBlock, cwd: string, extensions?: PiShellExtensionRendererResolver, submittedPrompt?: PiShellSubmittedPromptComposer, initialOutputPad?: 0 | 1, initialHideThinkingBlock?: boolean, initialMermaidRenderingMode?: MermaidRenderingMode, initialShowImages?: boolean, initialImageWidthCells?: number, imageAssets?: PiShellImageAssetResolver): PiShellTranscriptComponentPort;
|
|
41
8
|
export declare function renderPiShellTranscriptBlock(block: OwnedUiTranscriptBlock, width: number, cwd: string): readonly string[];
|
|
42
9
|
/**
|
|
43
10
|
* Pinned Pi's CLI prints startup diagnostics with `reportDiagnostics` before
|