FN-8413: add ACP SDK to published CLI dependencies
Ensure packed Fusion installs the ACP SDK required by the vendored Claude CLI extension. - Declare the compatible ACP SDK version in the CLI runtime dependencies. - Guard published-manifest dependency coverage and clean-install resolution with tests. - Add a patch changeset for the published package fix. Files changed: .changeset/fn-8413-pi-claude-cli-acp-sdk-dep.md | 7 ++ packages/cli/package.json | 1 + packages/cli/src/__tests__/package-config.test.ts | 26 +++++++ .../pi-claude-cli-publish-resolve.smoke.test.ts | 81 ++++++++++++++++++++++ pnpm-lock.yaml | 3 + 5 files changed, 118 insertions(+) Fusion-Task-Id: FN-8413 Fusion-Task-Lineage: c3cb8cc1-0be8-4196-b43e-eacd5837105d Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-8413-pi-claude-cli-acp-sdk-dep.md
Normal file
7
.changeset/fn-8413-pi-claude-cli-acp-sdk-dep.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@runfusion/fusion": patch
|
||||
---
|
||||
|
||||
summary: Install @agentclientprotocol/sdk with @runfusion/fusion so the Claude CLI pi extension can load.
|
||||
category: fix
|
||||
dev: FN-8413 / issue #2355 — nested dist/pi-claude-cli/package.json declared the SDK but npm only installs root dependencies; pin remains 0.24.0 (do not bump to 1.x).
|
||||
@@ -63,6 +63,7 @@
|
||||
"test:pre-release": "pnpm test:slow-cli && pnpm test:build-exe"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "0.24.0",
|
||||
"@earendil-works/pi-ai": "0.80.10",
|
||||
"@earendil-works/pi-coding-agent": "0.80.10",
|
||||
"claude-code-cli-acp": "0.1.1",
|
||||
|
||||
@@ -167,6 +167,32 @@ describe("CLI package.json publishing config", () => {
|
||||
assertRuntimeDepsAreNotOptionalPeers(applyPrepackTransform(pkg), "published manifest");
|
||||
});
|
||||
|
||||
/*
|
||||
FNXC:PublishBoundary 2026-07-19-21:20:
|
||||
FN-8413 / issue #2355 requires the root published manifest to carry every
|
||||
third-party dependency used by the raw TypeScript pi-claude-cli extension.
|
||||
The nested private dist/pi-claude-cli/package.json is inert during npm
|
||||
install, so keep the SDK pinned to the driver's compatible 0.24.0 API here
|
||||
and after prepack rather than relying on the workspace dependency.
|
||||
*/
|
||||
it("keeps raw pi-claude-cli runtime dependencies on the published root manifest", () => {
|
||||
const piClaudeCliPkg = loadPackageJson("pi-claude-cli");
|
||||
const publishedPkg = applyPrepackTransform(pkg);
|
||||
|
||||
expect(pkg.dependencies).toHaveProperty("@agentclientprotocol/sdk", "0.24.0");
|
||||
expect(publishedPkg.dependencies).toHaveProperty("@agentclientprotocol/sdk", "0.24.0");
|
||||
|
||||
for (const [name, specifier] of Object.entries(piClaudeCliPkg.dependencies ?? {})) {
|
||||
if (name.startsWith("@fusion/") || typeof specifier !== "string" || specifier.includes("workspace:")) {
|
||||
continue;
|
||||
}
|
||||
expect(
|
||||
pkg.dependencies,
|
||||
`raw pi-claude-cli dependency ${name} must be installed from the published root manifest`,
|
||||
).toHaveProperty(name, specifier);
|
||||
}
|
||||
});
|
||||
|
||||
it("defines test:docs-index as a single-file docs README index lane", () => {
|
||||
const script = pkg.scripts?.["test:docs-index"];
|
||||
const parts = script?.trim().split(/\s+/) ?? [];
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { createRequire } from "node:module";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const cliRoot = join(__dirname, "..", "..");
|
||||
const shouldRun =
|
||||
process.env.FUSION_TEST_PI_CLAUDE_PUBLISH_RESOLVE === "1" ||
|
||||
process.env.FUSION_TEST_PI_CLAUDE_PUBLISH_RESOLVE === "true";
|
||||
|
||||
function run(command: string, args: string[], cwd: string): void {
|
||||
const result = spawnSync(command, args, { cwd, encoding: "utf8", stdio: "pipe" });
|
||||
if (result.status !== 0) {
|
||||
throw new Error(
|
||||
`${command} ${args.join(" ")} failed (exit ${result.status}):\n${result.stderr || result.stdout}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:PublishBoundary 2026-07-19-21:20:
|
||||
FN-8413 / issue #2355 reproduces the real npm install boundary because the
|
||||
private nested dist/pi-claude-cli/package.json cannot install dependencies for
|
||||
raw TypeScript extension files. Pack and install with plain npm, then resolve
|
||||
from acp-driver.ts to prove the root SDK pin remains the driver's compatible
|
||||
0.24.0 API instead of silently relying on workspace hoisting or upgrading to 1.x.
|
||||
*/
|
||||
describe.skipIf(!shouldRun)("pi-claude-cli published package resolution", () => {
|
||||
it("resolves the ACP SDK from the packed raw extension after a clean npm install", () => {
|
||||
const driverPath = join(cliRoot, "dist", "pi-claude-cli", "src", "acp-driver.ts");
|
||||
if (!existsSync(driverPath)) {
|
||||
run("pnpm", ["run", "build:package"], cliRoot);
|
||||
}
|
||||
expect(existsSync(driverPath), "CLI build must stage the raw pi-claude-cli driver").toBe(true);
|
||||
|
||||
const smokeDir = mkdtempSync(join(tmpdir(), "fusion-pi-claude-resolve-"));
|
||||
try {
|
||||
const packDir = join(smokeDir, "tarballs");
|
||||
const installDir = join(smokeDir, "install");
|
||||
mkdirSync(installDir, { recursive: true });
|
||||
run("pnpm", ["pack", "--pack-destination", packDir], cliRoot);
|
||||
|
||||
const tarball = readdirSync(packDir).find(
|
||||
(file) => file.startsWith("runfusion-fusion-") && file.endsWith(".tgz"),
|
||||
);
|
||||
expect(tarball, "pnpm pack must produce the @runfusion/fusion tarball").toBeDefined();
|
||||
|
||||
writeFileSync(
|
||||
join(installDir, "package.json"),
|
||||
JSON.stringify({ name: "fusion-pi-claude-resolve-smoke", version: "0.0.0", private: true }),
|
||||
);
|
||||
run(
|
||||
"npm",
|
||||
["install", "--no-audit", "--no-fund", "--ignore-scripts", join(packDir, tarball!)],
|
||||
installDir,
|
||||
);
|
||||
|
||||
const installedRoot = join(installDir, "node_modules", "@runfusion", "fusion");
|
||||
const installedPackage = JSON.parse(readFileSync(join(installedRoot, "package.json"), "utf8"));
|
||||
expect(installedPackage.dependencies).toHaveProperty("@agentclientprotocol/sdk", "0.24.0");
|
||||
|
||||
const installedDriver = join(installedRoot, "dist", "pi-claude-cli", "src", "acp-driver.ts");
|
||||
expect(existsSync(installedDriver), "packed package must retain the raw extension driver").toBe(true);
|
||||
expect(createRequire(installedDriver).resolve("@agentclientprotocol/sdk")).toContain(
|
||||
"@agentclientprotocol/sdk",
|
||||
);
|
||||
} finally {
|
||||
rmSync(smokeDir, { recursive: true, force: true });
|
||||
}
|
||||
}, 300_000);
|
||||
});
|
||||
3
pnpm-lock.yaml
generated
3
pnpm-lock.yaml
generated
@@ -50,6 +50,9 @@ importers:
|
||||
|
||||
packages/cli:
|
||||
dependencies:
|
||||
'@agentclientprotocol/sdk':
|
||||
specifier: 0.24.0
|
||||
version: 0.24.0(zod@4.3.6)
|
||||
'@earendil-works/pi-ai':
|
||||
specifier: 0.80.10
|
||||
version: 0.80.10(@modelcontextprotocol/sdk@1.28.0(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)
|
||||
|
||||
Reference in New Issue
Block a user