Add a bundled Claude Code ACP runtime with model discovery and CLI distribution integration. - Add the Claude ACP runtime plugin, bridge, tool forwarding, and tests. - Register Claude model discovery and cached picker support in the dashboard. - Stage the plugin in CLI and desktop packaging with its pinned dependency. - Add workspace, lockfile, and release metadata. Files changed: .changeset/fn-8224-claude-acp-runtime.md | 7 + packages/cli/package.json | 1 + packages/cli/src/__tests__/bundle-output.test.ts | 32 +- .../cli/src/plugins/staged-bundled-plugin-ids.ts | 1 + packages/cli/tsup.config.ts | 40 +- .../core/src/plugins/bundled-plugin-install.ts | 2 + packages/dashboard/package.json | 3 +- packages/dashboard/src/claude-model-cache.ts | 185 +++++++ packages/dashboard/src/routes.ts | 1 + .../dashboard/src/routes/register-model-routes.ts | 11 + packages/dashboard/src/runtime-provider-probes.ts | 15 + packages/dashboard/vitest.config.ts | 4 + packages/desktop/scripts/workspace-tools.ts | 1 + plugins/fusion-plugin-claude-runtime/README.md | 7 + plugins/fusion-plugin-claude-runtime/manifest.json | 1 + plugins/fusion-plugin-claude-runtime/package.json | 1 + .../src/__tests__/cli-spawn.test.ts | 3 + .../src/__tests__/index.test.ts | 3 + .../src/__tests__/provider.test.ts | 8 + .../src/__tests__/runtime-adapter.test.ts | 7 + .../src/__tests__/tool-bridge.test.ts | 79 +++ .../src/acp-settings.ts | 21 + .../src/acp/VENDORED.md | 30 ++ .../src/acp/cli-spawn.ts | 188 +++++++ .../src/acp/control-handler.ts | 302 ++++++++++++ .../src/acp/event-bridge.ts | 308 ++++++++++++ .../src/acp/fs-capabilities.ts | 263 ++++++++++ .../fusion-plugin-claude-runtime/src/acp/index.ts | 16 + .../src/acp/path-jail.ts | 229 +++++++++ .../src/acp/process-manager.ts | 177 +++++++ .../src/acp/prompt-builder.ts | 87 ++++ .../src/acp/provider.ts | 542 +++++++++++++++++++++ .../src/acp/runtime-adapter.ts | 190 ++++++++ .../src/acp/sanitize.ts | 81 +++ .../src/acp/tool-mapping.ts | 47 ++ .../fusion-plugin-claude-runtime/src/acp/types.ts | 189 +++++++ .../fusion-plugin-claude-runtime/src/cli-spawn.ts | 31 ++ plugins/fusion-plugin-claude-runtime/src/index.ts | 95 ++++ .../src/mcp-forwarding.ts | 114 +++++ .../src/mcp-schema-server.cjs | 155 ++++++ plugins/fusion-plugin-claude-runtime/src/probe.ts | 8 + .../fusion-plugin-claude-runtime/src/provider.ts | 8 + .../src/runtime-adapter.ts | 424 ++++++++++++++++ .../src/skill-loader.ts | 290 +++++++++++ .../src/tool-bridge.ts | 264 ++++++++++ plugins/fusion-plugin-claude-runtime/src/types.ts | 142 ++++++ plugins/fusion-plugin-claude-runtime/tsconfig.json | 10 + .../fusion-plugin-claude-runtime/vitest.config.ts | 22 + pnpm-lock.yaml | 131 ++++- pnpm-workspace.yaml | 1 + 50 files changed, 4753 insertions(+), 24 deletions(-) Fusion-Task-Id: FN-8224 Fusion-Task-Lineage: 4e626913-32bb-4baa-a142-816c7f4ee7c4 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
96 lines
3.4 KiB
TypeScript
96 lines
3.4 KiB
TypeScript
import { definePlugin } from "@fusion/plugin-sdk";
|
|
import type { FusionPlugin } from "@fusion/plugin-sdk";
|
|
import { killAllProcesses } from "./acp/index.js";
|
|
import { probeClaudeBinary } from "./probe.js";
|
|
import { discoverClaudeProviderModels } from "./provider.js";
|
|
import { ClaudeRuntimeAdapter } from "./runtime-adapter.js";
|
|
|
|
/*
|
|
FNXC:ClaudeAcpRuntime 2026-07-17-12:00:
|
|
FN-8224 adds a first-class Claude ACP runtime. It composes the reviewed,
|
|
identity-pinned claude-code-cli-acp bridge, mirrors the bundled Grok runtime,
|
|
and is additive to the existing experimental pi-claude-cli Route A.
|
|
*/
|
|
|
|
/*
|
|
FNXC:ProcessLifecycle 2026-07-16-07:00:
|
|
The dashboard backfill worker repeatedly evaluates this plugin through
|
|
`vi.resetModules()` while retaining the process singleton. Install one exit
|
|
listener per Claude lifecycle owner and use the process-shared registry in the
|
|
ACP manager so it reaps children from every evaluation. Do not appease this
|
|
with `setMaxListeners`; the listener must stay bounded.
|
|
*/
|
|
const PROCESS_EXIT_HOOK_KEY = Symbol.for("fusion.plugin.claude-runtime.exitCleanup");
|
|
const processWithExitHook = process as typeof process & { [key: symbol]: boolean | undefined };
|
|
if (!processWithExitHook[PROCESS_EXIT_HOOK_KEY]) {
|
|
process.on("exit", killAllProcesses);
|
|
processWithExitHook[PROCESS_EXIT_HOOK_KEY] = true;
|
|
}
|
|
|
|
const plugin: FusionPlugin = definePlugin({
|
|
manifest: {
|
|
id: "fusion-plugin-claude-runtime",
|
|
name: "Claude Runtime Plugin",
|
|
version: "0.1.0",
|
|
description: "Claude CLI runtime support for Fusion (ACP agent stdio)",
|
|
runtime: {
|
|
runtimeId: "claude",
|
|
name: "Claude Runtime",
|
|
version: "0.1.0",
|
|
},
|
|
},
|
|
state: "installed",
|
|
hooks: {
|
|
onLoad: (ctx) => {
|
|
ctx.logger.info(
|
|
"Claude Runtime Plugin loaded — transport=ACP (claude-code-cli-acp); probe uses claude --version",
|
|
);
|
|
},
|
|
},
|
|
runtime: {
|
|
metadata: {
|
|
runtimeId: "claude",
|
|
name: "Claude Runtime",
|
|
version: "0.1.0",
|
|
},
|
|
factory: async () => new ClaudeRuntimeAdapter(),
|
|
},
|
|
cliProviders: [
|
|
{
|
|
providerId: "claude-cli",
|
|
displayName: "Claude CLI",
|
|
binaryName: "claude",
|
|
providerType: "cli",
|
|
statusRoute: "/providers/claude-cli/status",
|
|
authRoute: "/auth/claude-cli",
|
|
actions: [
|
|
{ actionId: "enable", label: "Enable", actionType: "enable", method: "POST", route: "/auth/claude-cli" },
|
|
{ actionId: "disable", label: "Disable", actionType: "disable", method: "POST", route: "/auth/claude-cli" },
|
|
{ actionId: "test", label: "Test", actionType: "test", method: "GET", route: "/providers/claude-cli/status" }
|
|
],
|
|
probe: async () => {
|
|
const status = await probeClaudeBinary();
|
|
return {
|
|
available: status.available,
|
|
authenticated: status.authenticated,
|
|
binaryPath: status.binaryPath,
|
|
binaryName: status.binaryName,
|
|
version: status.version,
|
|
reason: status.reason,
|
|
};
|
|
},
|
|
discoverModels: discoverClaudeProviderModels,
|
|
runtime: {
|
|
runtimeId: "claude",
|
|
createAdapter: async () => new ClaudeRuntimeAdapter(),
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
export default plugin;
|
|
export { probeClaudeBinary } from "./probe.js";
|
|
export { discoverClaudeProviderModels } from "./provider.js";
|
|
export { ClaudeRuntimeAdapter } from "./runtime-adapter.js";
|
|
export type { ClaudeBinaryStatus } from "./types.js";
|