@timurproko/a1 0.1.1-dev.8 → 0.1.4
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 +60 -62
- package/bin/cli.js +14 -2
- package/bin/module-identity.js +132 -0
- package/bin/ui.js +10 -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/src/cli/capabilities.d.ts +15 -0
- package/dist/src/cli/capabilities.js +7 -0
- package/dist/src/cli/dispatch.d.ts +9 -3
- package/dist/src/cli/dispatch.js +104 -16
- package/dist/src/cli/index.d.ts +2 -0
- package/dist/src/cli/index.js +2 -0
- package/dist/src/cli/packages.d.ts +23 -0
- package/dist/src/cli/packages.js +84 -0
- package/dist/src/foundation/agent-engine-contracts/index.d.ts +1 -0
- package/dist/src/foundation/agent-engine-contracts/index.js +1 -0
- package/dist/src/foundation/agent-engine-contracts/package-ports.d.ts +54 -0
- package/dist/src/foundation/agent-engine-contracts/package-ports.js +31 -0
- package/dist/src/foundation/pi-component-adapter/shell-editor-autocomplete.js +1 -1
- package/dist/src/foundation/pi-component-adapter/shell-extension-ui.js +1 -1
- package/dist/src/foundation/pi-component-adapter/shell-footer-status.js +1 -1
- package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.d.ts +15 -0
- package/dist/src/foundation/pi-component-adapter/shell-presenters-transcript.js +34 -1
- package/dist/src/foundation/pi-component-adapter/shell-selectors-dialogs.js +1 -1
- package/dist/src/foundation/pi-component-adapter/shell-shared-facade.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/shell-shared-facade.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.d.ts +2 -2
- package/dist/src/foundation/pi-component-adapter/upstream/adjacent/core/keybindings.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/countdown-timer.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/custom-entry.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/daxnuts.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/extension-editor.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/first-time-setup.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/mermaid.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/owned-editor.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/session-footer.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/session-footer.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/status-indicator.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/tree-selector.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/components/trust-selector.js +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.d.ts +1 -1
- package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.js +1 -1
- package/dist/src/foundation/pi-engine-adapter/adapter.d.ts +8 -1
- package/dist/src/foundation/pi-engine-adapter/adapter.js +28 -1
- package/dist/src/foundation/pi-engine-adapter/index.d.ts +1 -0
- package/dist/src/foundation/pi-engine-adapter/index.js +1 -0
- package/dist/src/foundation/pi-engine-adapter/package-integration.d.ts +13 -0
- package/dist/src/foundation/pi-engine-adapter/package-integration.js +112 -0
- package/dist/src/foundation/pi-engine-adapter/runtime-integration.d.ts +18 -1
- package/dist/src/foundation/pi-engine-adapter/runtime-integration.js +37 -2
- package/dist/src/foundation/pi-owned-ui-integration/session-shell.js +14 -2
- package/dist/src/foundation/pi-tui-runtime-adapter/adapter.js +1 -1
- package/dist/src/foundation/release/release.js +26 -2
- package/dist/src/foundation/release/update.d.ts +11 -1
- package/dist/src/foundation/release/update.js +106 -5
- package/docs/architecture/toolchain.md +3 -3
- package/docs/ci-release-runbook.md +81 -33
- package/docs/features/launch-profiles.md +2 -0
- package/package.json +10 -3
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { configurationRootForProfile, initializeProductProfile, resolveLaunchProfilePaths } from "../features/launch/index.js";
|
|
2
|
+
import { PRODUCT_TEXT } from "../product-identity.js";
|
|
3
|
+
export async function runPackageCommand(request, environment) {
|
|
4
|
+
const stdout = environment.stdout ?? (message => process.stdout.write(message));
|
|
5
|
+
const stderr = environment.stderr ?? (message => process.stderr.write(message));
|
|
6
|
+
const cwd = environment.cwd ?? process.cwd();
|
|
7
|
+
const processEnvironment = environment.environment ?? process.env;
|
|
8
|
+
const paths = resolveLaunchProfilePaths({ environment: processEnvironment });
|
|
9
|
+
const profileRoot = configurationRootForProfile("a1", paths);
|
|
10
|
+
if (profileRoot === null)
|
|
11
|
+
throw new Error(PRODUCT_TEXT.diagnostic("has no profile root for package commands"));
|
|
12
|
+
try {
|
|
13
|
+
await (environment.initializeProfile ?? initializeProductProfile)(profileRoot);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
stderr(`${PRODUCT_TEXT.diagnostic(`could not prepare its profile at ${profileRoot}: ${message(error)}`)}\n`);
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
const port = environment.createPort({
|
|
20
|
+
profileRoot,
|
|
21
|
+
cwd,
|
|
22
|
+
onProgress: progress => stdout(`${progress.message}\n`),
|
|
23
|
+
});
|
|
24
|
+
const outcome = await runVerb(port, request);
|
|
25
|
+
const rendered = renderPackageOutcome(outcome, profileRoot);
|
|
26
|
+
(outcome.status === "completed" ? stdout : stderr)(rendered);
|
|
27
|
+
return outcome.status === "completed" ? 0 : 1;
|
|
28
|
+
}
|
|
29
|
+
async function runVerb(port, request) {
|
|
30
|
+
if (request.verb === "list")
|
|
31
|
+
return await port.list();
|
|
32
|
+
if (request.verb === "refresh-models")
|
|
33
|
+
return await port.refreshModels();
|
|
34
|
+
if (request.verb === "update")
|
|
35
|
+
return await port.update(request.source ?? undefined);
|
|
36
|
+
if (request.source === null)
|
|
37
|
+
throw new Error(PRODUCT_TEXT.diagnostic(`requires a source for ${request.verb}`));
|
|
38
|
+
return request.verb === "install" ? await port.install(request.source) : await port.remove(request.source);
|
|
39
|
+
}
|
|
40
|
+
export function renderPackageOutcome(outcome, profileRoot) {
|
|
41
|
+
const name = PRODUCT_TEXT.displayName;
|
|
42
|
+
if (outcome.status === "failed") {
|
|
43
|
+
return `${PRODUCT_TEXT.diagnostic(`could not ${describeOperation(outcome.operation)}: ${outcome.detail ?? "unknown failure"}`)}\n`;
|
|
44
|
+
}
|
|
45
|
+
if (outcome.status === "not-found") {
|
|
46
|
+
return `${PRODUCT_TEXT.diagnostic(`found no package matching ${outcome.source ?? "that source"} in ${profileRoot}.`)}\n`;
|
|
47
|
+
}
|
|
48
|
+
switch (outcome.operation) {
|
|
49
|
+
case "install":
|
|
50
|
+
return `${name} installed ${outcome.source} into ${profileRoot}.\n`
|
|
51
|
+
+ `Restart ${PRODUCT_TEXT.commandName} for a running session to load it.\n`;
|
|
52
|
+
case "remove":
|
|
53
|
+
return `${name} removed ${outcome.source} from ${profileRoot}.\n`;
|
|
54
|
+
case "update":
|
|
55
|
+
return outcome.source === null
|
|
56
|
+
? `${name} updated the packages in ${profileRoot}.\n`
|
|
57
|
+
: `${name} updated ${outcome.source}.\n`;
|
|
58
|
+
case "refresh-models":
|
|
59
|
+
return `${name} refreshed the model catalogs in ${profileRoot}.\n`;
|
|
60
|
+
case "list":
|
|
61
|
+
return renderPackageList(outcome, profileRoot);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function renderPackageList(outcome, profileRoot) {
|
|
65
|
+
if (outcome.packages.length === 0)
|
|
66
|
+
return `${PRODUCT_TEXT.displayName} has no packages installed in ${profileRoot}.\n`;
|
|
67
|
+
const lines = [`Packages installed for ${PRODUCT_TEXT.commandName} in ${profileRoot}:`];
|
|
68
|
+
for (const entry of outcome.packages) {
|
|
69
|
+
lines.push(` ${entry.source}${entry.filtered ? " (partly enabled)" : ""}`);
|
|
70
|
+
if (entry.installedPath !== null)
|
|
71
|
+
lines.push(` ${entry.installedPath}`);
|
|
72
|
+
}
|
|
73
|
+
return `${lines.join("\n")}\n`;
|
|
74
|
+
}
|
|
75
|
+
function describeOperation(operation) {
|
|
76
|
+
if (operation === "refresh-models")
|
|
77
|
+
return "refresh the model catalogs";
|
|
78
|
+
if (operation === "list")
|
|
79
|
+
return "list installed packages";
|
|
80
|
+
return `${operation} the package`;
|
|
81
|
+
}
|
|
82
|
+
function message(error) {
|
|
83
|
+
return (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim();
|
|
84
|
+
}
|
|
@@ -2,6 +2,7 @@ export * from "./capability-ports.js";
|
|
|
2
2
|
export * from "./domain.js";
|
|
3
3
|
export * from "./domain-validation.js";
|
|
4
4
|
export * from "./model.js";
|
|
5
|
+
export * from "./package-ports.js";
|
|
5
6
|
export * from "./ports.js";
|
|
6
7
|
export * from "./validation.js";
|
|
7
8
|
export * from "./serialization.js";
|
|
@@ -2,6 +2,7 @@ export * from "./capability-ports.js";
|
|
|
2
2
|
export * from "./domain.js";
|
|
3
3
|
export * from "./domain-validation.js";
|
|
4
4
|
export * from "./model.js";
|
|
5
|
+
export * from "./package-ports.js";
|
|
5
6
|
export * from "./ports.js";
|
|
6
7
|
export * from "./validation.js";
|
|
7
8
|
export * from "./serialization.js";
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension packages are managed outside any session: the command that installs
|
|
3
|
+
* one runs before the runtime exists, against a profile root chosen by the caller
|
|
4
|
+
* rather than by whatever session happens to be open. So this port stands apart
|
|
5
|
+
* from the session-scoped service ports and names only what a package operation
|
|
6
|
+
* needs — a root, a source, and an outcome a caller can render without knowing
|
|
7
|
+
* which engine performed it.
|
|
8
|
+
*/
|
|
9
|
+
export type AgentPackageOperation = "install" | "remove" | "update" | "refresh-models" | "list";
|
|
10
|
+
/**
|
|
11
|
+
* Why an operation ended, kept separate from the prose so callers can branch on
|
|
12
|
+
* it. `not-found` is the one failure an engine can state structurally — the source
|
|
13
|
+
* is not configured in this profile — rather than only in a message.
|
|
14
|
+
*/
|
|
15
|
+
export type AgentPackageStatus = "completed" | "not-found" | "failed";
|
|
16
|
+
export interface AgentPackageDescriptor {
|
|
17
|
+
readonly source: string;
|
|
18
|
+
readonly installedPath: string | null;
|
|
19
|
+
/** True when the profile enables only part of what the package provides. */
|
|
20
|
+
readonly filtered: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface AgentPackageOutcome {
|
|
23
|
+
readonly operation: AgentPackageOperation;
|
|
24
|
+
readonly status: AgentPackageStatus;
|
|
25
|
+
readonly source: string | null;
|
|
26
|
+
readonly packages: readonly AgentPackageDescriptor[];
|
|
27
|
+
readonly detail: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface AgentPackageProgress {
|
|
30
|
+
readonly operation: AgentPackageOperation;
|
|
31
|
+
readonly message: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AgentPackagesPort {
|
|
34
|
+
readonly capabilities: {
|
|
35
|
+
readonly install: boolean;
|
|
36
|
+
readonly remove: boolean;
|
|
37
|
+
readonly update: boolean;
|
|
38
|
+
readonly refreshModels: boolean;
|
|
39
|
+
};
|
|
40
|
+
/** Absolute profile root every operation of this port acts on. */
|
|
41
|
+
readonly profileRoot: string;
|
|
42
|
+
list(): Promise<AgentPackageOutcome>;
|
|
43
|
+
install(source: string): Promise<AgentPackageOutcome>;
|
|
44
|
+
remove(source: string): Promise<AgentPackageOutcome>;
|
|
45
|
+
update(source?: string): Promise<AgentPackageOutcome>;
|
|
46
|
+
refreshModels(): Promise<AgentPackageOutcome>;
|
|
47
|
+
}
|
|
48
|
+
export interface AgentPackagesPortInput {
|
|
49
|
+
readonly profileRoot: string;
|
|
50
|
+
readonly cwd: string;
|
|
51
|
+
readonly onProgress?: (progress: AgentPackageProgress) => void;
|
|
52
|
+
}
|
|
53
|
+
export declare function assertAgentPackagesPort(port: AgentPackagesPort): void;
|
|
54
|
+
export declare function agentPackageOutcome(operation: AgentPackageOperation, status: AgentPackageStatus, detail?: string | null, source?: string | null, packages?: readonly AgentPackageDescriptor[]): AgentPackageOutcome;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension packages are managed outside any session: the command that installs
|
|
3
|
+
* one runs before the runtime exists, against a profile root chosen by the caller
|
|
4
|
+
* rather than by whatever session happens to be open. So this port stands apart
|
|
5
|
+
* from the session-scoped service ports and names only what a package operation
|
|
6
|
+
* needs — a root, a source, and an outcome a caller can render without knowing
|
|
7
|
+
* which engine performed it.
|
|
8
|
+
*/
|
|
9
|
+
export function assertAgentPackagesPort(port) {
|
|
10
|
+
if (typeof port?.capabilities !== "object" || port.capabilities === null)
|
|
11
|
+
throw new TypeError("packages port capabilities are required");
|
|
12
|
+
if (typeof port.profileRoot !== "string" || port.profileRoot.length === 0)
|
|
13
|
+
throw new TypeError("packages port requires an absolute profile root");
|
|
14
|
+
for (const operation of ["list", "install", "remove", "update", "refreshModels"]) {
|
|
15
|
+
if (typeof port[operation] !== "function")
|
|
16
|
+
throw new TypeError(`packages port requires ${operation}`);
|
|
17
|
+
}
|
|
18
|
+
for (const capability of ["install", "remove", "update", "refreshModels"]) {
|
|
19
|
+
if (typeof port.capabilities[capability] !== "boolean")
|
|
20
|
+
throw new TypeError(`packages capability ${capability} must be explicit`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function agentPackageOutcome(operation, status, detail, source, packages = []) {
|
|
24
|
+
return Object.freeze({
|
|
25
|
+
operation,
|
|
26
|
+
status,
|
|
27
|
+
source: source ?? null,
|
|
28
|
+
packages: Object.freeze([...packages]),
|
|
29
|
+
detail: detail ?? null,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSelectListTheme } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { CombinedAutocompleteProvider, setKeybindings, } from "
|
|
2
|
+
import { CombinedAutocompleteProvider, setKeybindings, } from "#pi-tui";
|
|
3
3
|
import { KeybindingsManager } from "./upstream/adjacent/core/keybindings.js";
|
|
4
4
|
import { OwnedEditor } from "./upstream/components/owned-editor.js";
|
|
5
5
|
import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExtensionInputComponent, ExtensionSelectorComponent, getSelectListTheme, } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { ExtensionEditorComponent, } from "./upstream/components/extension-editor.js";
|
|
3
|
-
import { setKeybindings, Text, } from "
|
|
3
|
+
import { setKeybindings, Text, } from "#pi-tui";
|
|
4
4
|
import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
|
|
5
5
|
import { PINNED_PI_LAYOUT, applyPiTheme, applyPiThemeInstance, getAvailablePiThemes, loadPiTheme, piTheme, } from "./theme.js";
|
|
6
6
|
import { componentPort, createTuiFacade, ensureTheme, isRecord, } from "./shell-shared-facade.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { rawKeyHint, VERSION } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { Spacer, Text, } from "
|
|
2
|
+
import { Spacer, Text, } from "#pi-tui";
|
|
3
3
|
import { SessionFooter } from "./upstream/components/session-footer.js";
|
|
4
4
|
import { WorkingStatusIndicator } from "./upstream/components/status-indicator.js";
|
|
5
5
|
import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
@@ -37,6 +37,21 @@ export declare function createPiShellChangelog(markdown: string): PiShellCompone
|
|
|
37
37
|
export declare function createPiShellHotkeys(): PiShellComponentPort;
|
|
38
38
|
export declare function createPiShellTranscriptComponent(initial: OwnedUiTranscriptBlock, cwd: string, extensions?: PiShellExtensionRendererResolver): PiShellTranscriptComponentPort;
|
|
39
39
|
export declare function renderPiShellTranscriptBlock(block: OwnedUiTranscriptBlock, width: number, cwd: string): readonly string[];
|
|
40
|
+
/**
|
|
41
|
+
* Pinned Pi's CLI prints startup diagnostics with `reportDiagnostics` before
|
|
42
|
+
* the banner: the whole line, prefix included, in chalk's basic ANSI severity
|
|
43
|
+
* colour — not the theme's tokens — with info lines dim and unprefixed.
|
|
44
|
+
*/
|
|
45
|
+
export declare function renderPiShellStartupDiagnostic(diagnostic: {
|
|
46
|
+
readonly severity: "info" | "warning" | "error";
|
|
47
|
+
readonly message: string;
|
|
48
|
+
}, width: number): readonly string[];
|
|
49
|
+
/**
|
|
50
|
+
* Pinned Pi's `showPackageUpdateNotification` banner: warning-coloured dynamic
|
|
51
|
+
* borders around a bold warning title, the muted update instruction with the
|
|
52
|
+
* accent command, and the package list.
|
|
53
|
+
*/
|
|
54
|
+
export declare function renderPiShellPackageUpdateNotice(packages: readonly string[], width: number): readonly string[];
|
|
40
55
|
type PiAssistantMessage = NonNullable<ConstructorParameters<typeof AssistantMessageComponent>[0]>;
|
|
41
56
|
export declare function validatedAssistantMessage(block: OwnedUiTranscriptBlock): PiAssistantMessage;
|
|
42
57
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AssistantMessageComponent, BashExecutionComponent, CompactionSummaryMessageComponent, CustomMessageComponent, DynamicBorder, getMarkdownTheme, parseSkillBlock, ToolExecutionComponent, UserMessageComponent, } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { SkillInvocationMessageComponent, } from "./upstream/components/skill-invocation-message.js";
|
|
3
|
-
import { Container, Markdown, Spacer, Text, } from "
|
|
3
|
+
import { Container, Markdown, Spacer, Text, } from "#pi-tui";
|
|
4
4
|
import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
|
|
5
5
|
import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
6
6
|
import { componentPort, createTuiFacade, ensureTheme, formatSessionTokens, isRecord, } from "./shell-shared-facade.js";
|
|
@@ -141,6 +141,39 @@ export function renderPiShellTranscriptBlock(block, width, cwd) {
|
|
|
141
141
|
ensureTheme();
|
|
142
142
|
return transcriptComponent(block, cwd, true).render(width);
|
|
143
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Pinned Pi's CLI prints startup diagnostics with `reportDiagnostics` before
|
|
146
|
+
* the banner: the whole line, prefix included, in chalk's basic ANSI severity
|
|
147
|
+
* colour — not the theme's tokens — with info lines dim and unprefixed.
|
|
148
|
+
*/
|
|
149
|
+
export function renderPiShellStartupDiagnostic(diagnostic, width) {
|
|
150
|
+
ensureTheme();
|
|
151
|
+
const escape = String.fromCharCode(27);
|
|
152
|
+
const chalk = diagnostic.severity === "error"
|
|
153
|
+
? { open: `${escape}[31m`, close: `${escape}[39m`, prefix: "Error: " }
|
|
154
|
+
: diagnostic.severity === "warning"
|
|
155
|
+
? { open: `${escape}[33m`, close: `${escape}[39m`, prefix: "Warning: " }
|
|
156
|
+
: { open: `${escape}[2m`, close: `${escape}[22m`, prefix: "" };
|
|
157
|
+
return new Text(`${chalk.open}${chalk.prefix}${diagnostic.message}${chalk.close}`, 0, 0).render(width);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Pinned Pi's `showPackageUpdateNotification` banner: warning-coloured dynamic
|
|
161
|
+
* borders around a bold warning title, the muted update instruction with the
|
|
162
|
+
* accent command, and the package list.
|
|
163
|
+
*/
|
|
164
|
+
export function renderPiShellPackageUpdateNotice(packages, width) {
|
|
165
|
+
ensureTheme();
|
|
166
|
+
const theme = piTheme();
|
|
167
|
+
const container = new Container();
|
|
168
|
+
container.addChild(new Spacer(1));
|
|
169
|
+
container.addChild(new DynamicBorder(text => theme.fg("warning", text)));
|
|
170
|
+
container.addChild(new Text(`${theme.bold(theme.fg("warning", "Package Updates Available"))}\n`
|
|
171
|
+
+ `${theme.fg("muted", "Package updates are available. Run ")}${theme.fg("accent", "pi update --extensions")}\n`
|
|
172
|
+
+ `${theme.fg("muted", "Packages:")}\n`
|
|
173
|
+
+ packages.map(name => `- ${name}`).join("\n"), 1, 0));
|
|
174
|
+
container.addChild(new DynamicBorder(text => theme.fg("warning", text)));
|
|
175
|
+
return container.render(width);
|
|
176
|
+
}
|
|
144
177
|
function transcriptComponent(block, cwd, expanded, extensions) {
|
|
145
178
|
switch (block.kind) {
|
|
146
179
|
case "user": {
|
|
@@ -3,7 +3,7 @@ import { DaxnutsComponent, } from "./upstream/components/daxnuts.js";
|
|
|
3
3
|
import { EarendilAnnouncementComponent, } from "./upstream/components/earendil-announcement.js";
|
|
4
4
|
import { SessionSelectorComponent, } from "./upstream/components/session-selector.js";
|
|
5
5
|
import { TreeSelectorComponent, } from "./upstream/components/tree-selector.js";
|
|
6
|
-
import { Box, Container, SelectList, Spacer, Text, } from "
|
|
6
|
+
import { Box, Container, SelectList, Spacer, Text, } from "#pi-tui";
|
|
7
7
|
import { ScopedModelsSelectorComponent, } from "./upstream/components/scoped-models-selector.js";
|
|
8
8
|
import { TrustSelectorComponent, } from "./upstream/components/trust-selector.js";
|
|
9
9
|
import { PINNED_PI_LAYOUT, piTheme, } from "./theme.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AutocompleteProvider, type Component, type TUI } from "
|
|
1
|
+
import { type AutocompleteProvider, type Component, type TUI } from "#pi-tui";
|
|
2
2
|
import type { OwnedUiSessionViewModel, OwnedUiThinkingLevel, OwnedUiTranscriptBlock } from "../owned-ui-contracts/index.js";
|
|
3
3
|
export interface PiShellComponentPort {
|
|
4
4
|
render(width: number): readonly string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { setKeybindings, } from "
|
|
1
|
+
import { setKeybindings, } from "#pi-tui";
|
|
2
2
|
import { KeybindingsManager, } from "./upstream/adjacent/core/keybindings.js";
|
|
3
3
|
import { ensurePiTheme, } from "./theme.js";
|
|
4
4
|
// Pinned from packages/coding-agent/src/core/slash-commands.ts at 914cf14.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Source-synchronized from Pi 0.84.2 packages/coding-agent/src/core/keybindings.ts. */
|
|
2
|
-
import { type Keybinding, type KeybindingsConfig, type KeyId, KeybindingsManager as TuiKeybindingsManager } from "
|
|
2
|
+
import { type Keybinding, type KeybindingsConfig, type KeyId, KeybindingsManager as TuiKeybindingsManager } from "#pi-tui";
|
|
3
3
|
export interface AppKeybindings {
|
|
4
4
|
"app.interrupt": true;
|
|
5
5
|
"app.clear": true;
|
|
@@ -45,7 +45,7 @@ export interface AppKeybindings {
|
|
|
45
45
|
"app.tree.filter.cycleBackward": true;
|
|
46
46
|
}
|
|
47
47
|
export type AppKeybinding = keyof AppKeybindings;
|
|
48
|
-
declare module "
|
|
48
|
+
declare module "#pi-tui" {
|
|
49
49
|
interface Keybindings extends AppKeybindings {
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Source-synchronized from Pi 0.84.2 packages/coding-agent/src/core/keybindings.ts. */
|
|
2
|
-
import { TUI_KEYBINDINGS, KeybindingsManager as TuiKeybindingsManager, } from "
|
|
2
|
+
import { TUI_KEYBINDINGS, KeybindingsManager as TuiKeybindingsManager, } from "#pi-tui";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Source-synchronized from Pi 0.84.2
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/countdown-timer.ts
|
|
4
4
|
*/
|
|
5
|
-
import type { TUI } from "
|
|
5
|
+
import type { TUI } from "#pi-tui";
|
|
6
6
|
export declare class CountdownTimer {
|
|
7
7
|
#private;
|
|
8
8
|
constructor(timeoutMs: number, tui: TUI | undefined, onTick: (seconds: number) => void, onExpire: () => void);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A heartfelt tribute to dax (@thdxr) for providing free Kimi K2.5 access via OpenCode.
|
|
5
5
|
*/
|
|
6
|
-
import type { Component, TUI } from "
|
|
6
|
+
import type { Component, TUI } from "#pi-tui";
|
|
7
7
|
export declare class DaxnutsComponent implements Component {
|
|
8
8
|
private ui;
|
|
9
9
|
private image;
|
package/dist/src/foundation/pi-component-adapter/upstream/components/earendil-announcement.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Mechanically adapted from Pi commit 914cf14
|
|
2
2
|
// packages/coding-agent/src/modes/interactive/components/earendil-announcement.ts (MIT).
|
|
3
3
|
// Local modifications: remap private imports to public package-root/owned theme boundaries and omit optional package-private imagery.
|
|
4
|
-
import { Container, Spacer, Text } from "
|
|
4
|
+
import { Container, Spacer, Text } from "#pi-tui";
|
|
5
5
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { piTheme } from "../theme/theme.js";
|
|
7
7
|
const BLOG_URL = "https://mariozechner.at/posts/2026-04-08-ive-sold-out/";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/extension-editor.ts (MIT).
|
|
4
4
|
* Modifications: root public pi-tui singleton, owned keybindings/theme seam, owned external-editor import.
|
|
5
5
|
*/
|
|
6
|
-
import { Container, type TUI } from "
|
|
6
|
+
import { Container, type TUI } from "#pi-tui";
|
|
7
7
|
import type { KeybindingsManager } from "../adjacent/core/keybindings.js";
|
|
8
8
|
export declare class ExtensionEditorComponent extends Container {
|
|
9
9
|
#private;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/extension-editor.ts (MIT).
|
|
4
4
|
* Modifications: root public pi-tui singleton, owned keybindings/theme seam, owned external-editor import.
|
|
5
5
|
*/
|
|
6
|
-
import { Container, Editor, Spacer, Text, } from "
|
|
6
|
+
import { Container, Editor, Spacer, Text, } from "#pi-tui";
|
|
7
7
|
import { DynamicBorder, getSelectListTheme } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
import { editInExternalEditor } from "../external-editor.js";
|
|
9
9
|
import { piTheme } from "../../theme.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Mechanically adapted from Pi commit 914cf14
|
|
2
2
|
// packages/coding-agent/src/modes/interactive/components/first-time-setup.ts (MIT).
|
|
3
3
|
// Local modifications: remap private imports to public package-root or owned theme boundaries.
|
|
4
|
-
import { Container, getKeybindings, Spacer, Text } from "
|
|
4
|
+
import { Container, getKeybindings, Spacer, Text } from "#pi-tui";
|
|
5
5
|
import { DynamicBorder, keyHint, rawKeyHint } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { piTheme } from "../theme/theme.js";
|
|
7
7
|
const APP_NAME = "pi";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Mechanically adapted from Pi commit 914cf14
|
|
2
2
|
// packages/coding-agent/src/modes/interactive/components/mermaid.ts (MIT).
|
|
3
3
|
// Local modifications: remap private imports to public package-root or owned theme boundaries.
|
|
4
|
-
import { Marked } from "
|
|
4
|
+
import { Marked } from "#pi-tui";
|
|
5
5
|
import { render } from "grok-mermaid";
|
|
6
6
|
const markdownParser = new Marked();
|
|
7
7
|
function isMermaid(token) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/custom-editor.ts (MIT).
|
|
4
4
|
* Modifications: A1-owned class name and A1-owned synchronized keybinding contract.
|
|
5
5
|
*/
|
|
6
|
-
import { Editor, type EditorOptions, type EditorTheme, type TUI } from "
|
|
6
|
+
import { Editor, type EditorOptions, type EditorTheme, type TUI } from "#pi-tui";
|
|
7
7
|
import type { AppKeybinding, KeybindingsManager } from "../adjacent/core/keybindings.js";
|
|
8
8
|
export declare class OwnedEditor extends Editor {
|
|
9
9
|
private readonly keybindings;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/custom-editor.ts (MIT).
|
|
4
4
|
* Modifications: A1-owned class name and A1-owned synchronized keybinding contract.
|
|
5
5
|
*/
|
|
6
|
-
import { Editor } from "
|
|
6
|
+
import { Editor } from "#pi-tui";
|
|
7
7
|
export class OwnedEditor extends Editor {
|
|
8
8
|
keybindings;
|
|
9
9
|
actionHandlers = new Map();
|
package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ interface ScopedModel {
|
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly name?: string;
|
|
10
10
|
}
|
|
11
|
-
import { Container, type Focusable, Input } from "
|
|
11
|
+
import { Container, type Focusable, Input } from "#pi-tui";
|
|
12
12
|
export interface ModelsConfig {
|
|
13
13
|
allModels: ScopedModel[];
|
|
14
14
|
enabledModelIds: string[] | null;
|
package/dist/src/foundation/pi-component-adapter/upstream/components/scoped-models-selector.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Container, fuzzyFilter, getKeybindings, Input, Key, matchesKey, Spacer, Text, } from "
|
|
1
|
+
import { Container, fuzzyFilter, getKeybindings, Input, Key, matchesKey, Spacer, Text, } from "#pi-tui";
|
|
2
2
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { getModelSearchText } from "../model-search.js";
|
|
4
4
|
import { piTheme } from "../theme/theme.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Component } from "
|
|
1
|
+
import { type Component } from "#pi-tui";
|
|
2
2
|
import type { OwnedUiSessionViewModel } from "../../../owned-ui-contracts/index.js";
|
|
3
3
|
export declare class SessionFooter implements Component {
|
|
4
4
|
private readonly getView;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Modifications: consumes neutral owned-UI view data rather than a concrete AgentSession.
|
|
5
5
|
*/
|
|
6
6
|
import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
7
|
-
import { truncateToWidth, visibleWidth } from "
|
|
7
|
+
import { truncateToWidth, visibleWidth } from "#pi-tui";
|
|
8
8
|
import { piTheme } from "../../theme.js";
|
|
9
9
|
export class SessionFooter {
|
|
10
10
|
getView;
|
package/dist/src/foundation/pi-component-adapter/upstream/components/session-selector-search.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/session-selector-search.ts
|
|
4
4
|
* Mechanical change: public SessionInfo type import.
|
|
5
5
|
*/
|
|
6
|
-
import { fuzzyMatch } from "
|
|
6
|
+
import { fuzzyMatch } from "#pi-tui";
|
|
7
7
|
function normalizeWhitespaceLower(text) {
|
|
8
8
|
return text.toLowerCase().replace(/\s+/g, " ").trim();
|
|
9
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Component, Container, type Focusable } from "
|
|
1
|
+
import { type Component, Container, type Focusable } from "#pi-tui";
|
|
2
2
|
import { KeybindingsManager } from "../adjacent/core/keybindings.js";
|
|
3
3
|
import { type SessionInfo } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
type SessionListProgress = (loaded: number, total: number) => void;
|
|
@@ -7,7 +7,7 @@ import { spawnSync } from "node:child_process";
|
|
|
7
7
|
import { existsSync, realpathSync } from "node:fs";
|
|
8
8
|
import { unlink } from "node:fs/promises";
|
|
9
9
|
import * as os from "node:os";
|
|
10
|
-
import { Container, getKeybindings, Input, Spacer, Text, truncateToWidth, visibleWidth, } from "
|
|
10
|
+
import { Container, getKeybindings, Input, Spacer, Text, truncateToWidth, visibleWidth, } from "#pi-tui";
|
|
11
11
|
import { KeybindingsManager } from "../adjacent/core/keybindings.js";
|
|
12
12
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
13
13
|
import { piTheme } from "../theme/theme.js";
|
package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Modified only to use A1's public pi-tui instance and owned theme boundary.
|
|
6
6
|
*/
|
|
7
|
-
import { Box, type MarkdownTheme } from "
|
|
7
|
+
import { Box, type MarkdownTheme } from "#pi-tui";
|
|
8
8
|
export interface SkillInvocationBlock {
|
|
9
9
|
readonly name: string;
|
|
10
10
|
readonly content: string;
|
package/dist/src/foundation/pi-component-adapter/upstream/components/skill-invocation-message.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Modified only to use A1's public pi-tui instance and owned theme boundary.
|
|
6
6
|
*/
|
|
7
|
-
import { Box, getKeybindings, Markdown, Text } from "
|
|
7
|
+
import { Box, getKeybindings, Markdown, Text } from "#pi-tui";
|
|
8
8
|
import { piTheme } from "../theme/theme.js";
|
|
9
9
|
export class SkillInvocationMessageComponent extends Box {
|
|
10
10
|
skillBlock;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Source-synchronized from Pi 0.84.2
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/status-indicator.ts
|
|
4
4
|
*/
|
|
5
|
-
import { type Component, Loader, type LoaderIndicatorOptions, type TUI } from "
|
|
5
|
+
import { type Component, Loader, type LoaderIndicatorOptions, type TUI } from "#pi-tui";
|
|
6
6
|
export type StatusIndicatorKind = "working" | "retry" | "compaction" | "branchSummary";
|
|
7
7
|
export declare class StatusIndicator extends Loader {
|
|
8
8
|
readonly kind: StatusIndicatorKind;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Source-synchronized from Pi 0.84.2
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/status-indicator.ts
|
|
4
4
|
*/
|
|
5
|
-
import { Loader } from "
|
|
5
|
+
import { Loader } from "#pi-tui";
|
|
6
6
|
import { keyText } from "@earendil-works/pi-coding-agent";
|
|
7
7
|
import { piTheme } from "../theme/theme.js";
|
|
8
8
|
import { CountdownTimer } from "./countdown-timer.js";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/tree-selector.ts
|
|
4
4
|
* Mechanical changes: public component/type imports and owned keybindings/theme helpers.
|
|
5
5
|
*/
|
|
6
|
-
import { type Component, Container, type Focusable } from "
|
|
6
|
+
import { type Component, Container, type Focusable } from "#pi-tui";
|
|
7
7
|
import { type SessionTreeNode } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
/** Filter mode for tree display */
|
|
9
9
|
export type FilterMode = "default" | "no-tools" | "user-only" | "labeled-only" | "all";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* packages/coding-agent/src/modes/interactive/components/tree-selector.ts
|
|
4
4
|
* Mechanical changes: public component/type imports and owned keybindings/theme helpers.
|
|
5
5
|
*/
|
|
6
|
-
import { Container, Input, Spacer, sliceByColumn, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "
|
|
6
|
+
import { Container, Input, Spacer, sliceByColumn, Text, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from "#pi-tui";
|
|
7
7
|
import { DynamicBorder } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
import { KeybindingsManager } from "../adjacent/core/keybindings.js";
|
|
9
9
|
import { piTheme } from "../theme/theme.js";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// packages/coding-agent/src/modes/interactive/components/trust-selector.ts (MIT).
|
|
3
3
|
// Local modifications: inject trust options and remap theme/import boundaries.
|
|
4
4
|
import { DynamicBorder, keyHint, rawKeyHint } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import { Container, getKeybindings, Spacer, Text } from "
|
|
5
|
+
import { Container, getKeybindings, Spacer, Text } from "#pi-tui";
|
|
6
6
|
import { piTheme } from "../theme/theme.js";
|
|
7
7
|
function formatDecision(trustPath, decision) {
|
|
8
8
|
if (decision === null)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync, watch } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { getAgentDir, initTheme, Theme, } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
import { getCapabilities } from "
|
|
4
|
+
import { getCapabilities } from "#pi-tui";
|
|
5
5
|
import { BUILTIN_THEME_RESOURCES, isBuiltinThemeName } from "../../resources/builtin-themes.js";
|
|
6
6
|
export const PINNED_PI_LAYOUT = Object.freeze({
|
|
7
7
|
editorPaddingX: 0,
|