fix(coding-agent): disable managed extension peer resolution
closes #4907
This commit is contained in:
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed managed npm extension updates to avoid package managers installing or resolving pi host packages as peer dependencies ([#4907](https://github.com/earendil-works/pi/issues/4907)).
|
||||||
|
|
||||||
## [0.75.5] - 2026-05-23
|
## [0.75.5] - 2026-05-23
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
@@ -1706,13 +1706,25 @@ export class DefaultPackageManager implements PackageManager {
|
|||||||
|
|
||||||
private getNpmInstallArgs(specs: string[], installRoot: string): string[] {
|
private getNpmInstallArgs(specs: string[], installRoot: string): string[] {
|
||||||
const packageManagerName = this.getPackageManagerName();
|
const packageManagerName = this.getPackageManagerName();
|
||||||
|
// Extension packages run inside pi and resolve pi APIs through loader aliases/virtual modules.
|
||||||
|
// Disable peer dependency resolution for managed installs (npm's --legacy-peer-deps, and
|
||||||
|
// equivalent bun/pnpm settings) so package managers do not install or solve host-provided
|
||||||
|
// @earendil-works/pi-* peers. Stale auto-installed pi peers can otherwise block updates.
|
||||||
if (packageManagerName === "bun") {
|
if (packageManagerName === "bun") {
|
||||||
return ["install", ...specs, "--cwd", installRoot];
|
return ["install", ...specs, "--cwd", installRoot, "--omit=peer"];
|
||||||
}
|
}
|
||||||
if (packageManagerName === "pnpm") {
|
if (packageManagerName === "pnpm") {
|
||||||
return ["install", ...specs, "--prefix", installRoot, "--config.strict-dep-builds=false"];
|
return [
|
||||||
|
"install",
|
||||||
|
...specs,
|
||||||
|
"--prefix",
|
||||||
|
installRoot,
|
||||||
|
"--config.auto-install-peers=false",
|
||||||
|
"--config.strict-peer-dependencies=false",
|
||||||
|
"--config.strict-dep-builds=false",
|
||||||
|
];
|
||||||
}
|
}
|
||||||
return ["install", ...specs, "--prefix", installRoot];
|
return ["install", ...specs, "--prefix", installRoot, "--legacy-peer-deps"];
|
||||||
}
|
}
|
||||||
|
|
||||||
private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
|
private async installNpm(source: NpmSource, scope: SourceScope, temporary: boolean): Promise<void> {
|
||||||
|
|||||||
@@ -693,7 +693,17 @@ Content`,
|
|||||||
|
|
||||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||||
"mise",
|
"mise",
|
||||||
["exec", "node@20", "--", "npm", "install", "@scope/pkg", "--prefix", join(agentDir, "npm")],
|
[
|
||||||
|
"exec",
|
||||||
|
"node@20",
|
||||||
|
"--",
|
||||||
|
"npm",
|
||||||
|
"install",
|
||||||
|
"@scope/pkg",
|
||||||
|
"--prefix",
|
||||||
|
join(agentDir, "npm"),
|
||||||
|
"--legacy-peer-deps",
|
||||||
|
],
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -714,7 +724,7 @@ Content`,
|
|||||||
|
|
||||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||||
"mise",
|
"mise",
|
||||||
["exec", "bun@1", "--", "bun", "install", "@scope/pkg", "--cwd", join(agentDir, "npm")],
|
["exec", "bun@1", "--", "bun", "install", "@scope/pkg", "--cwd", join(agentDir, "npm"), "--omit=peer"],
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -953,6 +963,8 @@ Content`,
|
|||||||
"pnpm-pkg",
|
"pnpm-pkg",
|
||||||
"--prefix",
|
"--prefix",
|
||||||
join(agentDir, "npm"),
|
join(agentDir, "npm"),
|
||||||
|
"--config.auto-install-peers=false",
|
||||||
|
"--config.strict-peer-dependencies=false",
|
||||||
"--config.strict-dep-builds=false",
|
"--config.strict-dep-builds=false",
|
||||||
]);
|
]);
|
||||||
mkdirSync(join(packagePath, "extensions"), { recursive: true });
|
mkdirSync(join(packagePath, "extensions"), { recursive: true });
|
||||||
@@ -2005,7 +2017,7 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||||||
);
|
);
|
||||||
expect(runCommandSpy).toHaveBeenCalledWith(
|
expect(runCommandSpy).toHaveBeenCalledWith(
|
||||||
"npm",
|
"npm",
|
||||||
["install", "example@latest", "--prefix", join(tempDir, ".pi", "npm")],
|
["install", "example@latest", "--prefix", join(tempDir, ".pi", "npm"), "--legacy-peer-deps"],
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -2044,7 +2056,13 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||||||
.mockImplementation(async (...callArgs: unknown[]) => {
|
.mockImplementation(async (...callArgs: unknown[]) => {
|
||||||
const [command, args] = callArgs as [string, string[]];
|
const [command, args] = callArgs as [string, string[]];
|
||||||
expect(command).toBe("npm");
|
expect(command).toBe("npm");
|
||||||
expect(args).toEqual(["install", "legacy-pkg@latest", "--prefix", join(agentDir, "npm")]);
|
expect(args).toEqual([
|
||||||
|
"install",
|
||||||
|
"legacy-pkg@latest",
|
||||||
|
"--prefix",
|
||||||
|
join(agentDir, "npm"),
|
||||||
|
"--legacy-peer-deps",
|
||||||
|
]);
|
||||||
mkdirSync(managedPath, { recursive: true });
|
mkdirSync(managedPath, { recursive: true });
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
join(managedPath, "package.json"),
|
join(managedPath, "package.json"),
|
||||||
@@ -2154,13 +2172,27 @@ export default function(api) { api.registerTool({ name: "test", description: "te
|
|||||||
expect(runCommandSpy).toHaveBeenNthCalledWith(
|
expect(runCommandSpy).toHaveBeenNthCalledWith(
|
||||||
1,
|
1,
|
||||||
"npm",
|
"npm",
|
||||||
["install", "user-old@latest", "user-unknown@latest", "--prefix", join(agentDir, "npm")],
|
[
|
||||||
|
"install",
|
||||||
|
"user-old@latest",
|
||||||
|
"user-unknown@latest",
|
||||||
|
"--prefix",
|
||||||
|
join(agentDir, "npm"),
|
||||||
|
"--legacy-peer-deps",
|
||||||
|
],
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
expect(runCommandSpy).toHaveBeenNthCalledWith(
|
expect(runCommandSpy).toHaveBeenNthCalledWith(
|
||||||
2,
|
2,
|
||||||
"npm",
|
"npm",
|
||||||
["install", "project-old@latest", "project-missing@latest", "--prefix", join(tempDir, ".pi", "npm")],
|
[
|
||||||
|
"install",
|
||||||
|
"project-old@latest",
|
||||||
|
"project-missing@latest",
|
||||||
|
"--prefix",
|
||||||
|
join(tempDir, ".pi", "npm"),
|
||||||
|
"--legacy-peer-deps",
|
||||||
|
],
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
expect(updateGitSpy).toHaveBeenCalledTimes(4);
|
expect(updateGitSpy).toHaveBeenCalledTimes(4);
|
||||||
|
|||||||
Reference in New Issue
Block a user