fix: code/cli acpx reliability 20260304 (#34020)

* agents: switch claude-cli defaults to bypassPermissions

* agents: add claude-cli default args coverage

* agents: emit watchdog stall system event for cli runs

* agents: test cli watchdog stall system event

* acpx: fallback to sessions new when ensure returns no ids

* acpx tests: mock sessions new fallback path

* acpx tests: cover ensure-empty fallback flow

* skills: clarify claude print mode without pty

* docs: update cli-backends claude default args

* docs: refresh cli live test default args

* gateway tests: align live claude args defaults

* changelog: credit claude/acpx reliability fixes

* Agents: normalize legacy Claude permission flag overrides

* Tests: cover legacy Claude permission override normalization

* Changelog: note legacy Claude permission flag auto-normalization

* ACPX: fail fast when ensure/new return no session IDs

* ACPX tests: support empty sessions new fixture output

* ACPX tests: assert ensureSession failure when IDs missing

* CLI runner: scope watchdog heartbeat wake to session

* CLI runner tests: assert session-scoped watchdog wake

* Update CHANGELOG.md
This commit is contained in:
Vincent Koc
2026-03-03 22:15:28 -08:00
committed by GitHub
parent dfb4cb87f9
commit 4d183af0cf
12 changed files with 362 additions and 30 deletions

View File

@@ -33,14 +33,19 @@ const CLAUDE_MODEL_ALIASES: Record<string, string> = {
"claude-haiku-3-5": "haiku",
};
const CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG = "--dangerously-skip-permissions";
const CLAUDE_PERMISSION_MODE_ARG = "--permission-mode";
const CLAUDE_BYPASS_PERMISSIONS_MODE = "bypassPermissions";
const DEFAULT_CLAUDE_BACKEND: CliBackendConfig = {
command: "claude",
args: ["-p", "--output-format", "json", "--dangerously-skip-permissions"],
args: ["-p", "--output-format", "json", "--permission-mode", "bypassPermissions"],
resumeArgs: [
"-p",
"--output-format",
"json",
"--dangerously-skip-permissions",
"--permission-mode",
"bypassPermissions",
"--resume",
"{sessionId}",
],
@@ -147,6 +152,48 @@ function mergeBackendConfig(base: CliBackendConfig, override?: CliBackendConfig)
};
}
function normalizeClaudePermissionArgs(args?: string[]): string[] | undefined {
if (!args) {
return args;
}
const normalized: string[] = [];
let sawLegacySkip = false;
let hasPermissionMode = false;
for (let i = 0; i < args.length; i += 1) {
const arg = args[i];
if (arg === CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG) {
sawLegacySkip = true;
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 (sawLegacySkip && !hasPermissionMode) {
normalized.push(CLAUDE_PERMISSION_MODE_ARG, CLAUDE_BYPASS_PERMISSIONS_MODE);
}
return normalized;
}
function normalizeClaudeBackendConfig(config: CliBackendConfig): CliBackendConfig {
return {
...config,
args: normalizeClaudePermissionArgs(config.args),
resumeArgs: normalizeClaudePermissionArgs(config.resumeArgs),
};
}
export function resolveCliBackendIds(cfg?: OpenClawConfig): Set<string> {
const ids = new Set<string>([
normalizeBackendKey("claude-cli"),
@@ -169,11 +216,12 @@ export function resolveCliBackendConfig(
if (normalized === "claude-cli") {
const merged = mergeBackendConfig(DEFAULT_CLAUDE_BACKEND, override);
const command = merged.command?.trim();
const config = normalizeClaudeBackendConfig(merged);
const command = config.command?.trim();
if (!command) {
return null;
}
return { id: normalized, config: { ...merged, command } };
return { id: normalized, config: { ...config, command } };
}
if (normalized === "codex-cli") {
const merged = mergeBackendConfig(DEFAULT_CODEX_BACKEND, override);