Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
363
extensions/anthropic/cli-shared.ts
Normal file
363
extensions/anthropic/cli-shared.ts
Normal file
@@ -0,0 +1,363 @@
|
||||
/**
|
||||
* Shared Claude CLI backend normalization. It sanitizes command args, maps
|
||||
* thinking levels, and keeps OpenClaw-managed CLI runs isolated from shell env.
|
||||
*/
|
||||
import type {
|
||||
CliBackendConfig,
|
||||
CliBackendNormalizeConfigContext,
|
||||
CliBackendResolveExecutionArgsContext,
|
||||
} from "openclaw/plugin-sdk/cli-backend";
|
||||
import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { CLAUDE_CLI_BACKEND_ID } from "./cli-constants.js";
|
||||
export {
|
||||
CLAUDE_CLI_BACKEND_ID,
|
||||
CLAUDE_CLI_DEFAULT_ALLOWLIST_REFS,
|
||||
CLAUDE_CLI_DEFAULT_MODEL_REF,
|
||||
CLAUDE_CLI_MODEL_ALIASES,
|
||||
CLAUDE_CLI_SESSION_ID_FIELDS,
|
||||
} from "./cli-constants.js";
|
||||
|
||||
// Claude Code honors provider-routing, auth, and config-root env before
|
||||
// consulting its local login state, so inherited shell overrides must not
|
||||
// steer OpenClaw-managed Claude CLI runs toward a different provider,
|
||||
// endpoint, token source, plugin/config tree, or telemetry bootstrap mode.
|
||||
/** Environment variables removed before launching OpenClaw-managed Claude CLI runs. */
|
||||
export const CLAUDE_CLI_CLEAR_ENV = [
|
||||
"ANTHROPIC_API_KEY",
|
||||
"ANTHROPIC_API_KEY_OLD",
|
||||
"ANTHROPIC_API_TOKEN",
|
||||
"ANTHROPIC_AUTH_TOKEN",
|
||||
"ANTHROPIC_BASE_URL",
|
||||
"ANTHROPIC_CUSTOM_HEADERS",
|
||||
"ANTHROPIC_OAUTH_TOKEN",
|
||||
"ANTHROPIC_UNIX_SOCKET",
|
||||
"CLAUDE_CONFIG_DIR",
|
||||
"CLAUDE_CODE_API_KEY_FILE_DESCRIPTOR",
|
||||
"CLAUDE_CODE_ENTRYPOINT",
|
||||
"CLAUDE_CODE_OAUTH_REFRESH_TOKEN",
|
||||
"CLAUDE_CODE_OAUTH_SCOPES",
|
||||
"CLAUDE_CODE_OAUTH_TOKEN",
|
||||
"CLAUDE_CODE_OAUTH_TOKEN_FILE_DESCRIPTOR",
|
||||
"CLAUDE_CODE_PLUGIN_CACHE_DIR",
|
||||
"CLAUDE_CODE_PLUGIN_SEED_DIR",
|
||||
"CLAUDE_CODE_REMOTE",
|
||||
"CLAUDE_CODE_USE_COWORK_PLUGINS",
|
||||
"CLAUDE_CODE_USE_BEDROCK",
|
||||
"CLAUDE_CODE_USE_FOUNDRY",
|
||||
"CLAUDE_CODE_USE_VERTEX",
|
||||
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"OTEL_EXPORTER_OTLP_HEADERS",
|
||||
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
|
||||
"OTEL_EXPORTER_OTLP_LOGS_HEADERS",
|
||||
"OTEL_EXPORTER_OTLP_LOGS_PROTOCOL",
|
||||
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
|
||||
"OTEL_EXPORTER_OTLP_METRICS_HEADERS",
|
||||
"OTEL_EXPORTER_OTLP_METRICS_PROTOCOL",
|
||||
"OTEL_EXPORTER_OTLP_PROTOCOL",
|
||||
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
|
||||
"OTEL_EXPORTER_OTLP_TRACES_HEADERS",
|
||||
"OTEL_EXPORTER_OTLP_TRACES_PROTOCOL",
|
||||
"OTEL_LOGS_EXPORTER",
|
||||
"OTEL_METRICS_EXPORTER",
|
||||
"OTEL_SDK_DISABLED",
|
||||
"OTEL_TRACES_EXPORTER",
|
||||
] as const;
|
||||
|
||||
const CLAUDE_LEGACY_SKIP_PERMISSIONS_ARG = "--dangerously-skip-permissions";
|
||||
const CLAUDE_PERMISSION_MODE_ARG = "--permission-mode";
|
||||
const CLAUDE_SETTING_SOURCES_ARG = "--setting-sources";
|
||||
const CLAUDE_EFFORT_ARG = "--effort";
|
||||
const CLAUDE_BARE_ARG = "--bare";
|
||||
const CLAUDE_SAFE_MODE_ARG = "--safe-mode";
|
||||
const CLAUDE_TOOLS_ARG = "--tools";
|
||||
const CLAUDE_DISALLOWED_TOOLS_ARG = "--disallowedTools";
|
||||
const CLAUDE_MCP_CONFIG_ARG = "--mcp-config";
|
||||
const CLAUDE_STRICT_MCP_CONFIG_ARG = "--strict-mcp-config";
|
||||
const CLAUDE_NO_SESSION_PERSISTENCE_ARG = "--no-session-persistence";
|
||||
const CLAUDE_MAX_TURNS_ARG = "--max-turns";
|
||||
const CLAUDE_SESSION_ID_ARG = "--session-id";
|
||||
const CLAUDE_RESUME_ARG = "--resume";
|
||||
const CLAUDE_RESUME_SESSION_AT_ARG = "--resume-session-at";
|
||||
const CLAUDE_RESUME_SHORT_ARG = "-r";
|
||||
const CLAUDE_CONTINUE_ARG = "--continue";
|
||||
const CLAUDE_CONTINUE_SHORT_ARG = "-c";
|
||||
const CLAUDE_FORK_SESSION_ARG = "--fork-session";
|
||||
const CLAUDE_SAFE_SETTING_SOURCES = "user";
|
||||
const CLAUDE_BYPASS_PERMISSION_MODE = "bypassPermissions";
|
||||
const CLAUDE_DEFAULT_PERMISSION_MODE = "default";
|
||||
const CLAUDE_NO_TOOLS_VALUE = "";
|
||||
const CLAUDE_DENY_MCP_TOOLS_VALUE = "mcp__*";
|
||||
|
||||
type ClaudeCliEffort = "low" | "medium" | "high" | "xhigh" | "max";
|
||||
|
||||
/** Explicit thinking opt-out for Claude CLI routes unsupported by Claude Code. */
|
||||
export const CLAUDE_CLI_OFF_THINKING_PROFILE = {
|
||||
levels: [{ id: "off" }],
|
||||
defaultLevel: "off",
|
||||
} as const;
|
||||
|
||||
/** Return whether a provider id refers to the Claude CLI backend. */
|
||||
export function isClaudeCliProvider(providerId: string): boolean {
|
||||
return normalizeOptionalLowercaseString(providerId) === CLAUDE_CLI_BACKEND_ID;
|
||||
}
|
||||
|
||||
function isOpenClawRequestedYolo(context?: CliBackendNormalizeConfigContext): boolean {
|
||||
const agentExec = context?.agentId
|
||||
? context.config?.agents?.list?.find((agent) => agent.id === context.agentId)?.tools?.exec
|
||||
: undefined;
|
||||
const exec = agentExec ?? context?.config?.tools?.exec;
|
||||
const security = exec?.security ?? "full";
|
||||
const ask = exec?.ask ?? "off";
|
||||
return security === "full" && ask === "off";
|
||||
}
|
||||
|
||||
/** Resolve Claude permission mode from OpenClaw exec security settings. */
|
||||
export function resolveClaudePermissionMode(context?: CliBackendNormalizeConfigContext): {
|
||||
mode?: string;
|
||||
overrideExisting: boolean;
|
||||
} {
|
||||
return isOpenClawRequestedYolo(context)
|
||||
? { mode: CLAUDE_BYPASS_PERMISSION_MODE, overrideExisting: false }
|
||||
: { overrideExisting: false };
|
||||
}
|
||||
|
||||
/** Normalize Claude permission arguments, removing legacy skip-permissions flags. */
|
||||
export function normalizeClaudePermissionArgs(
|
||||
args?: string[],
|
||||
options?: { mode?: string; overrideExisting?: boolean },
|
||||
): string[] | undefined {
|
||||
if (!args) {
|
||||
return options?.mode ? [CLAUDE_PERMISSION_MODE_ARG, options.mode] : 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) {
|
||||
const maybeValue = args[i + 1];
|
||||
if (
|
||||
typeof maybeValue === "string" &&
|
||||
maybeValue.trim().length > 0 &&
|
||||
!maybeValue.startsWith("-")
|
||||
) {
|
||||
hasPermissionMode = true;
|
||||
if (!options?.overrideExisting) {
|
||||
normalized.push(arg);
|
||||
normalized.push(maybeValue);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith(`${CLAUDE_PERMISSION_MODE_ARG}=`)) {
|
||||
const maybeValue = arg.slice(`${CLAUDE_PERMISSION_MODE_ARG}=`.length).trim();
|
||||
if (maybeValue.length > 0 && !maybeValue.startsWith("-")) {
|
||||
hasPermissionMode = true;
|
||||
if (!options?.overrideExisting) {
|
||||
normalized.push(`${CLAUDE_PERMISSION_MODE_ARG}=${maybeValue}`);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
normalized.push(arg);
|
||||
}
|
||||
if (options?.mode && (!hasPermissionMode || options.overrideExisting)) {
|
||||
normalized.push(CLAUDE_PERMISSION_MODE_ARG, options.mode);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/** Ensure Claude CLI setting sources stay restricted to user settings. */
|
||||
export function normalizeClaudeSettingSourcesArgs(args?: string[]): string[] | undefined {
|
||||
if (!args) {
|
||||
return args;
|
||||
}
|
||||
const normalized: string[] = [];
|
||||
let hasSettingSources = false;
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
const arg = args[i];
|
||||
if (arg === CLAUDE_SETTING_SOURCES_ARG) {
|
||||
const maybeValue = args[i + 1];
|
||||
if (
|
||||
typeof maybeValue === "string" &&
|
||||
maybeValue.trim().length > 0 &&
|
||||
!maybeValue.startsWith("-")
|
||||
) {
|
||||
hasSettingSources = true;
|
||||
normalized.push(arg, CLAUDE_SAFE_SETTING_SOURCES);
|
||||
i += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith(`${CLAUDE_SETTING_SOURCES_ARG}=`)) {
|
||||
hasSettingSources = true;
|
||||
normalized.push(`${CLAUDE_SETTING_SOURCES_ARG}=${CLAUDE_SAFE_SETTING_SOURCES}`);
|
||||
continue;
|
||||
}
|
||||
normalized.push(arg);
|
||||
}
|
||||
if (!hasSettingSources) {
|
||||
normalized.push(CLAUDE_SETTING_SOURCES_ARG, CLAUDE_SAFE_SETTING_SOURCES);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/** Map OpenClaw thinking levels to Claude CLI effort flags for a model id. */
|
||||
export function mapClaudeCliThinkingLevelToEffort(
|
||||
thinkingLevel?: string | null,
|
||||
): ClaudeCliEffort | undefined {
|
||||
switch (normalizeOptionalLowercaseString(thinkingLevel)) {
|
||||
case "minimal":
|
||||
case "low":
|
||||
return "low";
|
||||
case "adaptive":
|
||||
case "medium":
|
||||
return "medium";
|
||||
case "high":
|
||||
return "high";
|
||||
case "xhigh":
|
||||
return "xhigh";
|
||||
case "max":
|
||||
return "max";
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function stripClaudeEffortArgs(args: readonly string[]): string[] {
|
||||
const normalized: string[] = [];
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
const arg = args[i] ?? "";
|
||||
if (arg === CLAUDE_EFFORT_ARG) {
|
||||
const maybeValue = args[i + 1];
|
||||
if (
|
||||
typeof maybeValue === "string" &&
|
||||
maybeValue.trim().length > 0 &&
|
||||
!maybeValue.startsWith("-")
|
||||
) {
|
||||
i += 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (arg.startsWith(`${CLAUDE_EFFORT_ARG}=`)) {
|
||||
continue;
|
||||
}
|
||||
normalized.push(arg);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const CLAUDE_SIDE_QUESTION_VARIADIC_VALUE_ARGS = new Set([
|
||||
"--allowedTools",
|
||||
"--allowed-tools",
|
||||
CLAUDE_DISALLOWED_TOOLS_ARG,
|
||||
"--disallowed-tools",
|
||||
CLAUDE_TOOLS_ARG,
|
||||
CLAUDE_MCP_CONFIG_ARG,
|
||||
]);
|
||||
|
||||
const CLAUDE_SIDE_QUESTION_VALUE_ARGS = new Set([
|
||||
CLAUDE_PERMISSION_MODE_ARG,
|
||||
CLAUDE_SESSION_ID_ARG,
|
||||
CLAUDE_RESUME_ARG,
|
||||
CLAUDE_RESUME_SESSION_AT_ARG,
|
||||
CLAUDE_RESUME_SHORT_ARG,
|
||||
CLAUDE_MAX_TURNS_ARG,
|
||||
]);
|
||||
|
||||
const CLAUDE_SIDE_QUESTION_BARE_ARGS = new Set([
|
||||
CLAUDE_CONTINUE_ARG,
|
||||
CLAUDE_CONTINUE_SHORT_ARG,
|
||||
CLAUDE_FORK_SESSION_ARG,
|
||||
CLAUDE_BARE_ARG,
|
||||
CLAUDE_SAFE_MODE_ARG,
|
||||
CLAUDE_STRICT_MCP_CONFIG_ARG,
|
||||
CLAUDE_NO_SESSION_PERSISTENCE_ARG,
|
||||
]);
|
||||
|
||||
function stripClaudeSideQuestionConflictingArgs(args: readonly string[]): string[] {
|
||||
const normalized: string[] = [];
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
const arg = args[i] ?? "";
|
||||
const equalsIndex = arg.indexOf("=");
|
||||
const argName = equalsIndex > 0 ? arg.slice(0, equalsIndex) : arg;
|
||||
if (CLAUDE_SIDE_QUESTION_BARE_ARGS.has(argName)) {
|
||||
continue;
|
||||
}
|
||||
if (CLAUDE_SIDE_QUESTION_VARIADIC_VALUE_ARGS.has(argName)) {
|
||||
if (equalsIndex < 0) {
|
||||
while (typeof args[i + 1] === "string" && !args[i + 1]?.startsWith("-")) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (CLAUDE_SIDE_QUESTION_VALUE_ARGS.has(argName)) {
|
||||
if (equalsIndex < 0) {
|
||||
const maybeValue = args[i + 1];
|
||||
if (typeof maybeValue === "string" && !maybeValue.startsWith("-")) {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
normalized.push(arg);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function resolveClaudeCliSideQuestionExecutionArgs(baseArgs: readonly string[]): string[] {
|
||||
return [
|
||||
...stripClaudeSideQuestionConflictingArgs(stripClaudeEffortArgs(baseArgs)),
|
||||
CLAUDE_SAFE_MODE_ARG,
|
||||
CLAUDE_TOOLS_ARG,
|
||||
CLAUDE_NO_TOOLS_VALUE,
|
||||
CLAUDE_DISALLOWED_TOOLS_ARG,
|
||||
CLAUDE_DENY_MCP_TOOLS_VALUE,
|
||||
CLAUDE_STRICT_MCP_CONFIG_ARG,
|
||||
CLAUDE_NO_SESSION_PERSISTENCE_ARG,
|
||||
CLAUDE_MAX_TURNS_ARG,
|
||||
"1",
|
||||
CLAUDE_PERMISSION_MODE_ARG,
|
||||
CLAUDE_DEFAULT_PERMISSION_MODE,
|
||||
];
|
||||
}
|
||||
|
||||
/** Resolve final Claude CLI execution args for one backend invocation. */
|
||||
export function resolveClaudeCliExecutionArgs(
|
||||
context: CliBackendResolveExecutionArgsContext,
|
||||
): string[] {
|
||||
if (context.executionMode === "side-question") {
|
||||
return resolveClaudeCliSideQuestionExecutionArgs(context.baseArgs);
|
||||
}
|
||||
const effort = mapClaudeCliThinkingLevelToEffort(context.thinkingLevel);
|
||||
if (!effort) {
|
||||
return [...context.baseArgs];
|
||||
}
|
||||
return [...stripClaudeEffortArgs(context.baseArgs), CLAUDE_EFFORT_ARG, effort];
|
||||
}
|
||||
|
||||
/** Normalize Claude CLI backend config before registration or execution. */
|
||||
export function normalizeClaudeBackendConfig(
|
||||
config: CliBackendConfig,
|
||||
context?: CliBackendNormalizeConfigContext,
|
||||
): CliBackendConfig {
|
||||
const output = config.output ?? "jsonl";
|
||||
const input = config.input ?? "stdin";
|
||||
const permission = resolveClaudePermissionMode(context);
|
||||
return {
|
||||
...config,
|
||||
args: normalizeClaudePermissionArgs(normalizeClaudeSettingSourcesArgs(config.args), permission),
|
||||
resumeArgs: normalizeClaudePermissionArgs(
|
||||
normalizeClaudeSettingSourcesArgs(config.resumeArgs),
|
||||
permission,
|
||||
),
|
||||
output,
|
||||
liveSession:
|
||||
config.liveSession ?? (output === "jsonl" && input === "stdin" ? "claude-stdio" : undefined),
|
||||
input,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user