mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-10 00:31:22 +00:00
* fix: ensure bypassPermissions on custom CLI backend args When users override cliBackends.claude-cli.args (e.g. to add --verbose or change --output-format), the override array replaces the default entirely. The normalization step only re-added --permission-mode bypassPermissions when the legacy --dangerously-skip-permissions flag was present — if neither flag existed, it did nothing. This causes cron and heartbeat runs to silently fail with "exec denied: Cron runs cannot wait for interactive exec approval" because the CLI subprocess launches in interactive permission mode. Fix: always inject --permission-mode bypassPermissions when no explicit permission-mode flag is found in the resolved args, regardless of whether the legacy flag was present. * test(anthropic): add claude-cli permission normalization coverage * fix(test-utils): include video generation providers * fix: preserve claude-cli bypassPermissions on custom args (#61114) (thanks @cathrynlavery) --------- Co-authored-by: Shadow <hi@shadowing.dev> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import type { CliBackendConfig } from "openclaw/plugin-sdk/cli-backend";
|
|
|
|
export const CLAUDE_CLI_BACKEND_ID = "claude-cli";
|
|
|
|
export const CLAUDE_CLI_MODEL_ALIASES: Record<string, string> = {
|
|
opus: "opus",
|
|
"opus-4.6": "opus",
|
|
"opus-4.5": "opus",
|
|
"opus-4": "opus",
|
|
"claude-opus-4-6": "opus",
|
|
"claude-opus-4-5": "opus",
|
|
"claude-opus-4": "opus",
|
|
sonnet: "sonnet",
|
|
"sonnet-4.6": "sonnet",
|
|
"sonnet-4.5": "sonnet",
|
|
"sonnet-4.1": "sonnet",
|
|
"sonnet-4.0": "sonnet",
|
|
"claude-sonnet-4-6": "sonnet",
|
|
"claude-sonnet-4-5": "sonnet",
|
|
"claude-sonnet-4-1": "sonnet",
|
|
"claude-sonnet-4-0": "sonnet",
|
|
haiku: "haiku",
|
|
"haiku-3.5": "haiku",
|
|
"claude-haiku-3-5": "haiku",
|
|
};
|
|
|
|
export const CLAUDE_CLI_SESSION_ID_FIELDS = [
|
|
"session_id",
|
|
"sessionId",
|
|
"conversation_id",
|
|
"conversationId",
|
|
] as const;
|
|
|
|
export const CLAUDE_CLI_CLEAR_ENV = ["ANTHROPIC_API_KEY", "ANTHROPIC_API_KEY_OLD"] as const;
|
|
|
|
const CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG = "--dangerously-skip-permissions";
|
|
const CLAUDE_PERMISSION_MODE_ARG = "--permission-mode";
|
|
const CLAUDE_BYPASS_PERMISSIONS_MODE = "bypassPermissions";
|
|
|
|
export function isClaudeCliProvider(providerId: string): boolean {
|
|
return providerId.trim().toLowerCase() === CLAUDE_CLI_BACKEND_ID;
|
|
}
|
|
|
|
export function normalizeClaudePermissionArgs(args?: string[]): string[] | undefined {
|
|
if (!args) {
|
|
return args;
|
|
}
|
|
const normalized: string[] = [];
|
|
let hasPermissionMode = false;
|
|
for (let i = 0; i < args.length; i += 1) {
|
|
const arg = args[i];
|
|
if (arg === CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG) {
|
|
continue;
|
|
}
|
|
if (arg === CLAUDE_PERMISSION_MODE_ARG) {
|
|
hasPermissionMode = true;
|
|
normalized.push(arg);
|
|
const maybeValue = args[i + 1];
|
|
if (typeof maybeValue === "string") {
|
|
normalized.push(maybeValue);
|
|
i += 1;
|
|
}
|
|
continue;
|
|
}
|
|
if (arg.startsWith(`${CLAUDE_PERMISSION_MODE_ARG}=`)) {
|
|
hasPermissionMode = true;
|
|
}
|
|
normalized.push(arg);
|
|
}
|
|
if (!hasPermissionMode) {
|
|
normalized.push(CLAUDE_PERMISSION_MODE_ARG, CLAUDE_BYPASS_PERMISSIONS_MODE);
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
export function normalizeClaudeBackendConfig(config: CliBackendConfig): CliBackendConfig {
|
|
return {
|
|
...config,
|
|
args: normalizeClaudePermissionArgs(config.args),
|
|
resumeArgs: normalizeClaudePermissionArgs(config.resumeArgs),
|
|
};
|
|
}
|