mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(coding-agent): skip npm audit and fund output when installing pi packages (#11469)
`pi install`, `pi remove` and `pi update --extensions` run npm without `--no-audit`, so npm prints its "N vulnerabilities … run `npm audit fix`" advice after every install. pi gives users no way to clear that warning, and following it causes harm. In `~/.pi/agent/npm`, `npm audit fix` runs without `--legacy-peer-deps`, so npm installs the host-provided `@earendil-works/pi-*` peers there: a second copy of pi. The comment above `getNpmInstallArgs` warns against exactly that. The change adds `--no-audit --no-fund` wherever pi already passes `--legacy-peer-deps` to npm: - `getNpmInstallArgs` (npm package installs and updates) - `getGitDependencyInstallArgs` (dependency installs for git packages) - npm uninstall pi's managed self-update (`runManagedNpmCi`) already passes both flags. bun and pnpm arguments are unchanged. I did not edit `CHANGELOG.md`, per CONTRIBUTING.md. **Testing** - Updated the expected npm argument arrays in `test/package-manager.test.ts`. With the source change reverted, 11 tests fail; with it, all 132 pass. - `npm run check` passes. - Ran the built CLI by hand with `PI_CODING_AGENT_DIR=/tmp/pa pi install npm:lodash@4.17.20`: - Before the change, the output ended with npm's "To address all issues, run: npm audit fix" block. - After, it shows only "added 1 package" and "Installed npm:lodash@4.17.20". Fixes #11409 Requested by @badlogic Co-authored-by: triagent <triagent@localhost>
This commit is contained in:
parent
deb12d78eb
commit
5fb9a0b110
2 changed files with 67 additions and 22 deletions
|
|
@ -1858,7 +1858,7 @@ export class DefaultPackageManager implements PackageManager {
|
|||
"--config.strict-dep-builds=false",
|
||||
];
|
||||
case "npm":
|
||||
return ["install", "--omit=dev", "--legacy-peer-deps"];
|
||||
return ["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"];
|
||||
default:
|
||||
return ["install"];
|
||||
}
|
||||
|
|
@ -1891,7 +1891,8 @@ export class DefaultPackageManager implements PackageManager {
|
|||
"--config.strict-dep-builds=false",
|
||||
];
|
||||
}
|
||||
return ["install", ...specs, "--prefix", installRoot, "--legacy-peer-deps"];
|
||||
// npm audit fix would run without --legacy-peer-deps and install pi peers, so skip audit advice.
|
||||
return ["install", ...specs, "--prefix", installRoot, "--legacy-peer-deps", "--no-audit", "--no-fund"];
|
||||
}
|
||||
|
||||
private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
|
||||
|
|
@ -1914,7 +1915,7 @@ export class DefaultPackageManager implements PackageManager {
|
|||
}
|
||||
const args = ["uninstall", source.name, "--prefix", installRoot];
|
||||
if (packageManagerName !== "pnpm") {
|
||||
args.push("--legacy-peer-deps");
|
||||
args.push("--legacy-peer-deps", "--no-audit", "--no-fund");
|
||||
}
|
||||
await this.runNpmCommand(args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -756,6 +756,8 @@ Content`,
|
|||
"--prefix",
|
||||
realpathSync(join(agentDir, "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
],
|
||||
undefined,
|
||||
);
|
||||
|
|
@ -769,7 +771,15 @@ Content`,
|
|||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["uninstall", "@scope/pkg", "--prefix", realpathSync(join(agentDir, "npm")), "--legacy-peer-deps"],
|
||||
[
|
||||
"uninstall",
|
||||
"@scope/pkg",
|
||||
"--prefix",
|
||||
realpathSync(join(agentDir, "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
],
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
|
@ -793,12 +803,12 @@ Content`,
|
|||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "@scope/pkg", "--prefix", realNpmRoot, "--legacy-peer-deps"],
|
||||
["install", "@scope/pkg", "--prefix", realNpmRoot, "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
undefined,
|
||||
);
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["uninstall", "@scope/pkg", "--prefix", realNpmRoot, "--legacy-peer-deps"],
|
||||
["uninstall", "@scope/pkg", "--prefix", realNpmRoot, "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
|
@ -849,9 +859,13 @@ Content`,
|
|||
|
||||
await packageManager.install(source);
|
||||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("npm", ["install", "--omit=dev", "--legacy-peer-deps"], {
|
||||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
{
|
||||
cwd: targetDir,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("should remove a newly created checkout when git clone fails", async () => {
|
||||
|
|
@ -915,9 +929,13 @@ Content`,
|
|||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("git", ["clean", "-fdx"], { cwd: targetDir });
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("npm", ["install", "--omit=dev", "--legacy-peer-deps"], {
|
||||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
{
|
||||
cwd: targetDir,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("should reconcile an existing git checkout to its update target when installing without a ref", async () => {
|
||||
|
|
@ -1066,9 +1084,13 @@ Content`,
|
|||
|
||||
await packageManager.update(source);
|
||||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("npm", ["install", "--omit=dev", "--legacy-peer-deps"], {
|
||||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
{
|
||||
cwd: targetDir,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("should repair missing git package dependencies when the checkout is already current", async () => {
|
||||
|
|
@ -1093,9 +1115,13 @@ Content`,
|
|||
|
||||
await packageManager.update(source);
|
||||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("npm", ["install", "--omit=dev", "--legacy-peer-deps"], {
|
||||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
{
|
||||
cwd: targetDir,
|
||||
},
|
||||
);
|
||||
expect(runCommandSpy).not.toHaveBeenCalledWith("git", ["clean", "-fdx"], { cwd: targetDir });
|
||||
});
|
||||
|
||||
|
|
@ -1127,9 +1153,13 @@ Content`,
|
|||
|
||||
await expect(packageManager.update(source)).rejects.toThrow("simulated clean failure");
|
||||
|
||||
expect(runCommandSpy).toHaveBeenCalledWith("npm", ["install", "--omit=dev", "--legacy-peer-deps"], {
|
||||
cwd: targetDir,
|
||||
});
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "--omit=dev", "--legacy-peer-deps", "--no-audit", "--no-fund"],
|
||||
{
|
||||
cwd: targetDir,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("should disable peer installation through wrapped pnpm when updating git dependencies", async () => {
|
||||
|
|
@ -2506,7 +2536,15 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||
);
|
||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||
"npm",
|
||||
["install", "example@^1.0.0", "--prefix", realpathSync(join(tempDir, ".pi", "npm")), "--legacy-peer-deps"],
|
||||
[
|
||||
"install",
|
||||
"example@^1.0.0",
|
||||
"--prefix",
|
||||
realpathSync(join(tempDir, ".pi", "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
],
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
|
@ -2572,6 +2610,8 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||
"--prefix",
|
||||
realpathSync(join(agentDir, "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
]);
|
||||
mkdirSync(managedPath, { recursive: true });
|
||||
writeFileSync(
|
||||
|
|
@ -2689,6 +2729,8 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||
"--prefix",
|
||||
realpathSync(join(agentDir, "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
],
|
||||
undefined,
|
||||
);
|
||||
|
|
@ -2702,6 +2744,8 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||
"--prefix",
|
||||
realpathSync(join(tempDir, ".pi", "npm")),
|
||||
"--legacy-peer-deps",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
],
|
||||
undefined,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue