fix: normalize claude cli fallback config

This commit is contained in:
Peter Steinberger
2026-04-05 07:09:03 +01:00
parent f039bbf2aa
commit 37cc06f1fd
4 changed files with 49 additions and 12 deletions

View File

@@ -331,7 +331,7 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
expect(resolved?.config.resumeArgs).toContain("bypassPermissions");
});
it("keeps bundle MCP enabled for override-only claude-cli config when the plugin registry is absent", () => {
it("normalizes override-only claude-cli config when the plugin registry is absent", () => {
const registry = createEmptyPluginRegistry();
setActivePluginRegistry(registry);
@@ -342,6 +342,7 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
"claude-cli": {
command: "/usr/local/bin/claude",
args: ["-p", "--output-format", "json"],
resumeArgs: ["-p", "--output-format", "json", "--resume", "{sessionId}"],
},
},
},
@@ -352,6 +353,22 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
expect(resolved).not.toBeNull();
expect(resolved?.bundleMcp).toBe(true);
expect(resolved?.config.args).toEqual([
"-p",
"--output-format",
"json",
"--permission-mode",
"bypassPermissions",
]);
expect(resolved?.config.resumeArgs).toEqual([
"-p",
"--output-format",
"json",
"--resume",
"{sessionId}",
"--permission-mode",
"bypassPermissions",
]);
});
});

View File

@@ -1,3 +1,7 @@
import {
CLAUDE_CLI_BACKEND_ID,
normalizeClaudeBackendConfig,
} from "../../extensions/anthropic/api.js";
import type { OpenClawConfig } from "../config/config.js";
import type { CliBackendConfig } from "../config/types.js";
import { resolveRuntimeCliBackends } from "../plugins/cli-backends.runtime.js";
@@ -10,12 +14,20 @@ export type ResolvedCliBackend = {
pluginId?: string;
};
function resolveFallbackBundleMcpCapability(provider: string): boolean {
// Claude CLI consumes explicit MCP config overlays even when the runtime
// plugin registry is not initialized yet (for example direct runner tests or
// narrow non-gateway entrypoints).
return provider === "claude-cli";
}
type FallbackCliBackendPolicy = {
bundleMcp: boolean;
normalizeConfig?: (config: CliBackendConfig) => CliBackendConfig;
};
const FALLBACK_CLI_BACKEND_POLICIES: Record<string, FallbackCliBackendPolicy> = {
[CLAUDE_CLI_BACKEND_ID]: {
// Claude CLI consumes explicit MCP config overlays even when the runtime
// plugin registry is not initialized yet (for example direct runner tests
// or narrow non-gateway entrypoints).
bundleMcp: true,
normalizeConfig: normalizeClaudeBackendConfig,
},
};
function normalizeBackendKey(key: string): string {
return normalizeProviderId(key);
@@ -96,6 +108,7 @@ export function resolveCliBackendConfig(
cfg?: OpenClawConfig,
): ResolvedCliBackend | null {
const normalized = normalizeBackendKey(provider);
const fallbackPolicy = FALLBACK_CLI_BACKEND_POLICIES[normalized];
const configured = cfg?.agents?.defaults?.cliBackends ?? {};
const override = pickBackendConfig(configured, normalized);
const registered = resolveRegisteredBackend(normalized);
@@ -117,13 +130,16 @@ export function resolveCliBackendConfig(
if (!override) {
return null;
}
const command = override.command?.trim();
const config = fallbackPolicy?.normalizeConfig
? fallbackPolicy.normalizeConfig(override)
: override;
const command = config.command?.trim();
if (!command) {
return null;
}
return {
id: normalized,
config: { ...override, command },
bundleMcp: resolveFallbackBundleMcpCapability(normalized),
config: { ...config, command },
bundleMcp: fallbackPolicy?.bundleMcp,
};
}