Quote variable values with spaces in the displayed run command line

Values containing spaces (e.g. an env-passed SCENE="Glitz and glam")
rendered as bare, space-separated words in the run detail view,
indistinguishable from separate argv/env entries. Now anything outside
a safe bareword character set is quoted and escaped for display only -
actual execution is unaffected, since values are always passed as
discrete argv elements/env vars, never through a shell.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-17 03:01:53 +02:00
co-authored by Claude Sonnet 5
parent 23a4e2ebc0
commit 335e7624b4
+14 -2
View File
@@ -18,6 +18,15 @@ function stringifyValue(value: unknown, joinWith: string): string {
return String(value); return String(value);
} }
/** Quotes a value for the human-readable `redactedCommandLine` display only - the real
* invocation always passes values as discrete argv elements/env vars (see build note below),
* so this never affects execution. Without it, a value like "Glitz and glam" renders as three
* bare words indistinguishable from separate argv entries. */
function quoteForDisplay(value: string): string {
if (value !== "" && /^[a-zA-Z0-9_@%+=:,./-]+$/.test(value)) return value;
return `"${value.replace(/([$`"\\])/g, "\\$1")}"`;
}
/** Builds an argv-array invocation from validated variable values. Never produces a shell string. */ /** Builds an argv-array invocation from validated variable values. Never produces a shell string. */
export function buildInvocation( export function buildInvocation(
script: ScriptConfig, script: ScriptConfig,
@@ -43,7 +52,10 @@ export function buildInvocation(
const argName = variable.argName!; const argName = variable.argName!;
const value = stringifyValue(raw, variable.joinWith); const value = stringifyValue(raw, variable.joinWith);
argv.push(argName, value); argv.push(argName, value);
redactedArgv.push(argName, variable.secret ? REDACTED : value); redactedArgv.push(
argName,
variable.secret ? REDACTED : quoteForDisplay(value),
);
break; break;
} }
case "flag": { case "flag": {
@@ -57,7 +69,7 @@ export function buildInvocation(
const value = stringifyValue(raw, variable.joinWith); const value = stringifyValue(raw, variable.joinWith);
env[variable.envName!] = value; env[variable.envName!] = value;
redactedEnvAssignments.push( redactedEnvAssignments.push(
`${variable.envName}=${variable.secret ? REDACTED : value}`, `${variable.envName}=${variable.secret ? REDACTED : quoteForDisplay(value)}`,
); );
break; break;
} }