fix(runner): support both portable provider layouts

This commit is contained in:
Dotta 2026-09-06 11:37:26 -05:00
parent 75289b06b1
commit 9421d65359
2 changed files with 42 additions and 13 deletions

View File

@ -634,10 +634,39 @@ it("derives the ACPX package authority only from the verified dist/cli layout",
).toThrow("ACPX sidecar must use the provider package dist/cli layout");
});
it("keeps a deployed ACPX package inside its pnpm-owned dependency root", async () => {
it("keeps a self-rooted pnpm deployment inside its dependency authority", async () => {
const deploymentRoot = await mkdtemp(
join(tmpdir(), "paperclip-deployed-provider-root-"),
);
const deployedPackageRoot = deploymentRoot;
await mkdir(join(deployedPackageRoot, "dist", "cli"), { recursive: true });
await mkdir(join(deploymentRoot, "node_modules", ".pnpm"), {
recursive: true,
});
try {
expect(
runnerdLaunchProfileInternals.acpxProviderPackageAuthority(
join(
deployedPackageRoot,
"dist",
"cli",
"acpx-runtime-sidecar.cjs",
),
deployedPackageRoot,
),
).toEqual({
root: deploymentRoot,
manifest: join(deployedPackageRoot, "package.json"),
});
} finally {
await rm(deploymentRoot, { recursive: true, force: true });
}
});
it("keeps a scoped npm-installed package inside its portable dependency root", async () => {
const deploymentRoot = await mkdtemp(
join(tmpdir(), "paperclip-npm-provider-root-"),
);
const deployedPackageRoot = join(
deploymentRoot,
"node_modules",
@ -645,9 +674,6 @@ it("keeps a deployed ACPX package inside its pnpm-owned dependency root", async
"paperclip-runner",
);
await mkdir(join(deployedPackageRoot, "dist", "cli"), { recursive: true });
await mkdir(join(deploymentRoot, "node_modules", ".pnpm"), {
recursive: true,
});
try {
expect(
runnerdLaunchProfileInternals.acpxProviderPackageAuthority(

View File

@ -1568,17 +1568,20 @@ function acpxProviderPackageAuthority(
}
const sidecarPackageRoot = resolve(cliDirectory, "../..");
// A local source build lives at <workspace>/packages/paperclip-runner and
// resolves dependencies from <workspace>/node_modules. A `pnpm deploy`
// package lives at <deploy>/node_modules/@paperclipai/paperclip-runner,
// beside <deploy>/node_modules/.pnpm. The provider verifier receives the
// directory that owns node_modules, so step out one more level only for the
// deployed shape.
// resolves dependencies from <workspace>/node_modules. `pnpm deploy` makes
// the package itself the deployment root and owns <deploy>/node_modules/.pnpm.
// The older npm-installed portable shape nests the scoped package at
// <deploy>/node_modules/@paperclipai/paperclip-runner. The verifier always
// receives the directory that owns node_modules, regardless of which
// portable shape launched the already-authenticated sidecar.
const sourceDependencyRoot = resolve(ownerPackageRoot, "../..");
const localDependencyRoot = existsSync(
resolve(sourceDependencyRoot, ".pnpm"),
)
? resolve(sourceDependencyRoot, "..")
: sourceDependencyRoot;
resolve(ownerPackageRoot, "node_modules", ".pnpm"),
)
? ownerPackageRoot
: basename(sourceDependencyRoot) === "node_modules"
? resolve(sourceDependencyRoot, "..")
: sourceDependencyRoot;
return sidecarPackageRoot === ownerPackageRoot
? {
root: localDependencyRoot,