Filter noisy package updates and skip native installs
This commit is contained in:
@@ -4,7 +4,7 @@ import { existsSync, lstatSync, mkdtempSync, mkdirSync, readFileSync, writeFileS
|
|||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { join, resolve } from "node:path";
|
import { join, resolve } from "node:path";
|
||||||
|
|
||||||
import { seedBundledWorkspacePackages } from "../src/pi/package-ops.js";
|
import { installPackageSources, seedBundledWorkspacePackages } from "../src/pi/package-ops.js";
|
||||||
|
|
||||||
function createBundledWorkspace(appRoot: string, packageNames: string[]): void {
|
function createBundledWorkspace(appRoot: string, packageNames: string[]): void {
|
||||||
for (const packageName of packageNames) {
|
for (const packageName of packageNames) {
|
||||||
@@ -18,6 +18,17 @@ function createBundledWorkspace(appRoot: string, packageNames: string[]): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeSettings(agentDir: string, settings: Record<string, unknown>): void {
|
||||||
|
mkdirSync(agentDir, { recursive: true });
|
||||||
|
writeFileSync(resolve(agentDir, "settings.json"), JSON.stringify(settings, null, 2) + "\n", "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeFakeNpmScript(root: string, body: string): string {
|
||||||
|
const scriptPath = resolve(root, "fake-npm.mjs");
|
||||||
|
writeFileSync(scriptPath, body, "utf8");
|
||||||
|
return scriptPath;
|
||||||
|
}
|
||||||
|
|
||||||
test("seedBundledWorkspacePackages links bundled packages into the Feynman npm prefix", () => {
|
test("seedBundledWorkspacePackages links bundled packages into the Feynman npm prefix", () => {
|
||||||
const appRoot = mkdtempSync(join(tmpdir(), "feynman-bundle-"));
|
const appRoot = mkdtempSync(join(tmpdir(), "feynman-bundle-"));
|
||||||
const homeRoot = mkdtempSync(join(tmpdir(), "feynman-home-"));
|
const homeRoot = mkdtempSync(join(tmpdir(), "feynman-home-"));
|
||||||
@@ -54,3 +65,83 @@ test("seedBundledWorkspacePackages preserves existing installed packages", () =>
|
|||||||
assert.equal(readFileSync(resolve(existingPackageDir, "package.json"), "utf8"), '{"name":"pi-subagents","version":"user"}\n');
|
assert.equal(readFileSync(resolve(existingPackageDir, "package.json"), "utf8"), '{"name":"pi-subagents","version":"user"}\n');
|
||||||
assert.equal(lstatSync(existingPackageDir).isSymbolicLink(), false);
|
assert.equal(lstatSync(existingPackageDir).isSymbolicLink(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("installPackageSources filters noisy npm chatter but preserves meaningful output", async () => {
|
||||||
|
const root = mkdtempSync(join(tmpdir(), "feynman-package-ops-"));
|
||||||
|
const workingDir = resolve(root, "project");
|
||||||
|
const agentDir = resolve(root, "agent");
|
||||||
|
mkdirSync(workingDir, { recursive: true });
|
||||||
|
|
||||||
|
const scriptPath = writeFakeNpmScript(root, [
|
||||||
|
`console.log("npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead");`,
|
||||||
|
'console.log("changed 343 packages in 9s");',
|
||||||
|
'console.log("59 packages are looking for funding");',
|
||||||
|
'console.log("run `npm fund` for details");',
|
||||||
|
'console.error("visible stderr line");',
|
||||||
|
'console.log("visible stdout line");',
|
||||||
|
"process.exit(0);",
|
||||||
|
].join("\n"));
|
||||||
|
|
||||||
|
writeSettings(agentDir, {
|
||||||
|
npmCommand: [process.execPath, scriptPath],
|
||||||
|
});
|
||||||
|
|
||||||
|
let stdout = "";
|
||||||
|
let stderr = "";
|
||||||
|
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
|
||||||
|
const originalStderrWrite = process.stderr.write.bind(process.stderr);
|
||||||
|
(process.stdout.write as unknown as (chunk: string | Uint8Array) => boolean) = ((chunk: string | Uint8Array) => {
|
||||||
|
stdout += chunk.toString();
|
||||||
|
return true;
|
||||||
|
}) as typeof process.stdout.write;
|
||||||
|
(process.stderr.write as unknown as (chunk: string | Uint8Array) => boolean) = ((chunk: string | Uint8Array) => {
|
||||||
|
stderr += chunk.toString();
|
||||||
|
return true;
|
||||||
|
}) as typeof process.stderr.write;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await installPackageSources(workingDir, agentDir, ["npm:test-visible-package"]);
|
||||||
|
assert.deepEqual(result.installed, ["npm:test-visible-package"]);
|
||||||
|
assert.deepEqual(result.skipped, []);
|
||||||
|
} finally {
|
||||||
|
process.stdout.write = originalStdoutWrite;
|
||||||
|
process.stderr.write = originalStderrWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
const combined = `${stdout}\n${stderr}`;
|
||||||
|
assert.match(combined, /visible stdout line/);
|
||||||
|
assert.match(combined, /visible stderr line/);
|
||||||
|
assert.doesNotMatch(combined, /node-domexception/);
|
||||||
|
assert.doesNotMatch(combined, /changed 343 packages/);
|
||||||
|
assert.doesNotMatch(combined, /packages are looking for funding/);
|
||||||
|
assert.doesNotMatch(combined, /npm fund/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("installPackageSources skips native packages on unsupported Node majors before invoking npm", async () => {
|
||||||
|
const root = mkdtempSync(join(tmpdir(), "feynman-package-ops-"));
|
||||||
|
const workingDir = resolve(root, "project");
|
||||||
|
const agentDir = resolve(root, "agent");
|
||||||
|
const markerPath = resolve(root, "npm-invoked.txt");
|
||||||
|
mkdirSync(workingDir, { recursive: true });
|
||||||
|
|
||||||
|
const scriptPath = writeFakeNpmScript(root, [
|
||||||
|
`import { writeFileSync } from "node:fs";`,
|
||||||
|
`writeFileSync(${JSON.stringify(markerPath)}, "invoked\\n", "utf8");`,
|
||||||
|
"process.exit(0);",
|
||||||
|
].join("\n"));
|
||||||
|
|
||||||
|
writeSettings(agentDir, {
|
||||||
|
npmCommand: [process.execPath, scriptPath],
|
||||||
|
});
|
||||||
|
|
||||||
|
const originalVersion = process.versions.node;
|
||||||
|
Object.defineProperty(process.versions, "node", { value: "25.0.0", configurable: true });
|
||||||
|
try {
|
||||||
|
const result = await installPackageSources(workingDir, agentDir, ["npm:@kaiserlich-dev/pi-session-search"]);
|
||||||
|
assert.deepEqual(result.installed, []);
|
||||||
|
assert.deepEqual(result.skipped, ["npm:@kaiserlich-dev/pi-session-search"]);
|
||||||
|
assert.equal(existsSync(markerPath), false);
|
||||||
|
} finally {
|
||||||
|
Object.defineProperty(process.versions, "node", { value: originalVersion, configurable: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user