From 335e7624b4b62d3eaec1ee9f794ca4fa07bb4c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Mon, 17 Aug 2026 03:01:53 +0200 Subject: [PATCH] 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 --- src/lib/runner/build-args.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/lib/runner/build-args.ts b/src/lib/runner/build-args.ts index a1d9238..c29cdd7 100644 --- a/src/lib/runner/build-args.ts +++ b/src/lib/runner/build-args.ts @@ -18,6 +18,15 @@ function stringifyValue(value: unknown, joinWith: string): string { 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. */ export function buildInvocation( script: ScriptConfig, @@ -43,7 +52,10 @@ export function buildInvocation( const argName = variable.argName!; const value = stringifyValue(raw, variable.joinWith); argv.push(argName, value); - redactedArgv.push(argName, variable.secret ? REDACTED : value); + redactedArgv.push( + argName, + variable.secret ? REDACTED : quoteForDisplay(value), + ); break; } case "flag": { @@ -57,7 +69,7 @@ export function buildInvocation( const value = stringifyValue(raw, variable.joinWith); env[variable.envName!] = value; redactedEnvAssignments.push( - `${variable.envName}=${variable.secret ? REDACTED : value}`, + `${variable.envName}=${variable.secret ? REDACTED : quoteForDisplay(value)}`, ); break; }