import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import test from "node:test"; const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8")) as { dependencies: Record; files: string[]; pi: { extensions: string[]; skills?: string[] }; }; const filesIncludePackageDir = (files: string[], packageDir: string): boolean => files.some((entry) => entry === packageDir || entry.startsWith(`${packageDir}/`)); test("pi-web-search is the single search surface and reads credentials from auth.json", () => { const entries = packageJson.pi.extensions; assert.ok(entries.includes("./pi-web-search/index.ts"), "the bundle must load pi-web-search"); assert.equal( entries.includes("./extensions/search-config.ts"), false, "search keys come from auth.json — the env loader extension is retired", ); for (const retired of [ "./extensions/mcp.ts", "./extensions/tavily-override.ts", "./node_modules/@keenable/pi-search/src/index.ts", ]) { assert.equal(entries.includes(retired), false, `${retired} must no longer be loaded`); } }); test("pi-web-search ships as a maintained file: dependency without upstream search packages", () => { assert.equal(packageJson.dependencies["pi-web-search"], "file:./pi-web-search"); assert.ok(filesIncludePackageDir(packageJson.files, "pi-web-search")); assert.equal(packageJson.dependencies["@tavily/pi-extension"], undefined); assert.equal(packageJson.dependencies["@keenable/pi-search"], undefined); assert.equal(packageJson.dependencies["pi-mcp-adapter"], undefined, "Exa is a direct client now — no MCP adapter"); }); test("no extension in the bundle loads the MCP adapter or upstream search extensions", async () => { for (const entry of packageJson.pi.extensions.filter((e) => !e.startsWith("./node_modules/"))) { const source = await readFile(new URL(`../${entry.slice(2)}`, import.meta.url), "utf8"); assert.equal(source.includes("pi-mcp-adapter"), false, `${entry} must not import pi-mcp-adapter`); assert.equal(source.includes("@tavily/pi-extension"), false, `${entry} must not import @tavily/pi-extension`); } }); test("the keenable skill path is gone with the upstream package", () => { for (const skillPath of packageJson.pi.skills ?? []) { assert.equal(skillPath.includes("@keenable"), false); } });