chore(vendor): import pi 1.3.0

Imported as a linear vendor commit so forge rebases do not replay the upstream root tree.

git-subtree-dir: third_party/pi

git-subtree-split: 71023aec1546d6d677a65669c5665c0927ce0dd0
This commit is contained in:
2026-10-15 17:58:48 -04:00
parent 719370c8f7
commit 6081e3e325
1743 changed files with 205460 additions and 131705 deletions

View File

@@ -6,6 +6,7 @@ import { type Component, Container, type Focusable, type TUI } from "../../tui/s
import { TuiMainScreen } from "../../tui/src/tui-main-screen.ts";
import { VirtualTerminal } from "../../tui/test/virtual-terminal.ts";
import type { AutocompleteProviderFactory } from "../src/core/extensions/types.ts";
import type { QuietStartup } from "../src/core/settings-manager.ts";
import type { SourceInfo } from "../src/core/source-info.ts";
import type { AuthSelectorProvider } from "../src/modes/interactive/components/oauth-selector.ts";
import { InteractiveMode } from "../src/modes/interactive/interactive-mode.ts";
@@ -299,6 +300,84 @@ describe("InteractiveMode.showExtensionCustom", () => {
ui.stop();
}
});
// Regression test for #10648: closing a lower overlay removed the topmost overlay instead.
test.each([
{ lowerKind: "capturing", nonCapturing: false },
{ lowerKind: "non-capturing", nonCapturing: true },
])(
"closing a lower $lowerKind overlay custom UI removes its own overlay, not the topmost one",
async ({ nonCapturing }) => {
const terminal = new VirtualTerminal(80, 24);
const ui: TUI = new TuiMainScreen(terminal);
const editorContainer = new Container();
const editor = new TestFocusableComponent("EDITOR");
const lower = new TestFocusableComponent("LOWER");
const upper = new TestFocusableComponent("UPPER");
let closeLower: (value: string) => void = () => {
throw new Error("closeLower was not initialized");
};
let closeUpper: (value: string) => void = () => {
throw new Error("closeUpper was not initialized");
};
const fakeThis = {
editor,
editorContainer,
keybindings: {},
ui,
disposeActiveSelector: vi.fn(),
};
const showExtensionCustom = <T>(
factory: (tui: TUI, theme: unknown, keybindings: unknown, done: (result: T) => void) => Component,
options?: { overlay?: boolean; overlayOptions?: { nonCapturing?: boolean } },
): Promise<T> =>
(InteractiveMode as any).prototype.showExtensionCustom.call(fakeThis, factory, options) as Promise<T>;
editorContainer.addChild(editor);
ui.addChild(editorContainer);
ui.setFocus(editor);
ui.start();
try {
const lowerPromise = showExtensionCustom<string>(
(_tui, _theme, _keybindings, done) => {
closeLower = done;
return lower;
},
{ overlay: true, overlayOptions: { nonCapturing } },
);
await flushTui(ui, terminal);
const upperPromise = showExtensionCustom<string>(
(_tui, _theme, _keybindings, done) => {
closeUpper = done;
return upper;
},
{ overlay: true },
);
await flushTui(ui, terminal);
expect(upper.focused).toBe(true);
closeLower("lower closed");
await expect(lowerPromise).resolves.toBe("lower closed");
await flushTui(ui, terminal);
const viewport = terminal.getViewport().join("\n");
expect(viewport).toContain("UPPER");
expect(viewport).not.toContain("LOWER");
terminal.sendInput("x");
await flushTui(ui, terminal);
expect(upper.inputs).toEqual(["x"]);
expect(lower.inputs).toEqual([]);
closeUpper("upper closed");
await expect(upperPromise).resolves.toBe("upper closed");
await flushTui(ui, terminal);
expect(ui.hasOverlay()).toBe(false);
expect(editor.focused).toBe(true);
} finally {
ui.stop();
}
},
);
});
describe("InteractiveMode.createExtensionUIContext addAutocompleteProvider", () => {
@@ -486,9 +565,10 @@ describe("InteractiveMode.createBaseAutocompleteProvider", () => {
sessionManager: { getCwd: () => "/tmp" },
fdPath: null,
getLoginProviderOptions: () => [
{ id: "anthropic", name: "Anthropic", authType: "oauth" },
{ id: "anthropic", name: "Anthropic", authType: "api_key" },
{ id: "anthropic", name: "Anthropic", authType: "oauth", subscription: true },
{ id: "anthropic", name: "Anthropic", authType: "api_key", subscription: true },
{ id: "openai", name: "OpenAI", authType: "api_key" },
{ id: "radius", name: "Radius", authType: "oauth", subscription: false },
],
};
@@ -505,6 +585,13 @@ describe("InteractiveMode.createBaseAutocompleteProvider", () => {
description: "Anthropic · subscription/API key",
},
]);
// OAuth sign-in without a subscription, such as Radius, is an account.
const radiusLine = "/login radius";
const radiusSuggestions = await provider.getSuggestions([radiusLine], 0, radiusLine.length, {
signal: new AbortController().signal,
});
expect(radiusSuggestions?.items).toEqual([{ value: "radius", label: "radius", description: "Radius · account" }]);
});
});
describe("InteractiveMode.showLoadedResources", () => {
@@ -513,7 +600,7 @@ describe("InteractiveMode.showLoadedResources", () => {
});
function createShowLoadedResourcesThis(options: {
quietStartup: boolean;
quietStartup: QuietStartup;
verbose?: boolean;
toolOutputExpanded?: boolean;
cwd?: string;
@@ -561,6 +648,7 @@ describe("InteractiveMode.showLoadedResources", () => {
(InteractiveMode as any).prototype.formatExtensionDisplayPath.call(fakeThis, p),
formatContextPath: (p: string) => (InteractiveMode as any).prototype.formatContextPath.call(fakeThis, p),
getStartupExpansionState: () => (InteractiveMode as any).prototype.getStartupExpansionState.call(fakeThis),
shouldShowStartupDetails: () => (InteractiveMode as any).prototype.shouldShowStartupDetails.call(fakeThis),
buildScopeGroups: () => [],
formatScopeGroups: () => "resource-list",
isPackageSource: (sourceInfo?: SourceInfo) =>
@@ -1232,6 +1320,28 @@ describe("InteractiveMode.showLoadedResources", () => {
expect(fakeThis.loadedResourcesContainer.children).toHaveLength(0);
});
test("hides resource listing but keeps the startup header with header-only quiet startup", () => {
const fakeThis = createShowLoadedResourcesThis({
quietStartup: "header",
skills: [{ filePath: "/tmp/skill/SKILL.md", name: "commit" }],
});
(InteractiveMode as any).prototype.showLoadedResources.call(fakeThis, {
force: false,
});
expect(fakeThis.loadedResourcesContainer.children).toHaveLength(0);
expect((InteractiveMode as any).prototype.shouldShowStartupHeader.call(fakeThis)).toBe(true);
expect((InteractiveMode as any).prototype.shouldShowStartupDetails.call(fakeThis)).toBe(false);
});
test("hides the startup header with full quiet startup unless verbose", () => {
const quiet = createShowLoadedResourcesThis({ quietStartup: true });
expect((InteractiveMode as any).prototype.shouldShowStartupHeader.call(quiet)).toBe(false);
const verbose = createShowLoadedResourcesThis({ quietStartup: "header", verbose: true });
expect((InteractiveMode as any).prototype.shouldShowStartupDetails.call(verbose)).toBe(true);
});
test("still shows diagnostics on quiet startup when requested", () => {
const fakeThis = createShowLoadedResourcesThis({
quietStartup: true,