feat(acp): bundle into CLI, on-demand install, S1 safety + evidence (U8)
Wires the ACP runtime plugin into the published CLI (RUNTIME_PLUGIN_IDS in tsup.config) and the on-demand BUILTIN_PLUGINS catalog (experimental), matching the untrusted-subprocess security posture. Adds the Risk S1 default-policy safety: an acpAllowUnrestricted acknowledgement (default false) — without it, a blanket allow on a sensitive category is escalated to approval rather than auto-approved under the allow-all default policy, applied in both the permission floor and fs write gating. Adds docs/acp-contract.md (launch/readiness + failure taxonomy), a README with the AGENTS.md-required upstream evidence (SDK repo/docs/release/integrity), a bundle-output test for the staged plugin, and a @runfusion/fusion minor changeset. Package green at 179 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -260,6 +260,23 @@ describe("CLI bundle output", () => {
|
||||
expect(manifest.name?.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("dist/plugins/fusion-plugin-acp-runtime/ is staged with the acp runtime manifest", () => {
|
||||
const stagedRoot = join(cliRoot, "dist", "plugins", "fusion-plugin-acp-runtime");
|
||||
const manifestPath = join(stagedRoot, "manifest.json");
|
||||
|
||||
expect(existsSync(manifestPath)).toBe(true);
|
||||
const manifest = JSON.parse(readFileSync(manifestPath, "utf-8")) as {
|
||||
id?: string;
|
||||
runtime?: { runtimeId?: string };
|
||||
};
|
||||
expect(manifest.id).toBe("fusion-plugin-acp-runtime");
|
||||
// The runtime is selected by runtimeId; assert it is "acp".
|
||||
expect(manifest.runtime?.runtimeId).toBe("acp");
|
||||
expect(existsSync(join(stagedRoot, "bundled.js"))).toBe(true);
|
||||
// v1 ships no mcp-schema-server.cjs (MCP forwarding deferred, KTD5).
|
||||
expect(existsSync(join(stagedRoot, "mcp-schema-server.cjs"))).toBe(false);
|
||||
});
|
||||
|
||||
it("pi-claude-cli source imports child process helpers from node:child_process", () => {
|
||||
const processManagerSource = readFileSync(join(cliRoot, "dist", "pi-claude-cli", "src", "process-manager.ts"), "utf-8");
|
||||
|
||||
|
||||
@@ -57,6 +57,14 @@ export const BUILTIN_PLUGINS: BuiltinPluginCatalogEntry[] = [
|
||||
path: "./plugins/fusion-plugin-droid-runtime",
|
||||
experimental: true,
|
||||
},
|
||||
{
|
||||
id: "fusion-plugin-acp-runtime",
|
||||
name: "ACP Runtime",
|
||||
description: "Runtime provider that drives any external Agent Client Protocol agent over JSON-RPC/stdio.",
|
||||
category: "runtime",
|
||||
path: "./plugins/fusion-plugin-acp-runtime",
|
||||
experimental: true,
|
||||
},
|
||||
{
|
||||
id: "fusion-plugin-dependency-graph",
|
||||
name: "Dependency Graph",
|
||||
|
||||
@@ -14,6 +14,7 @@ const RUNTIME_PLUGIN_IDS = [
|
||||
"fusion-plugin-paperclip-runtime",
|
||||
"fusion-plugin-cursor-runtime",
|
||||
"fusion-plugin-droid-runtime",
|
||||
"fusion-plugin-acp-runtime",
|
||||
] as const;
|
||||
|
||||
const RUNTIME_PLUGINS_WITH_MCP_SCHEMA_SERVER = new Set([
|
||||
|
||||
Reference in New Issue
Block a user