diff --git a/src/node/runtime/SSHRuntime.ts b/src/node/runtime/SSHRuntime.ts index 22588e873..13a358c42 100644 --- a/src/node/runtime/SSHRuntime.ts +++ b/src/node/runtime/SSHRuntime.ts @@ -18,6 +18,7 @@ import { RuntimeError as RuntimeErrorClass } from "./Runtime"; import { EXIT_CODE_ABORTED, EXIT_CODE_TIMEOUT } from "@/common/constants/exitCodes"; import { log } from "@/node/services/log"; import { checkInitHookExists, createLineBufferedLoggers, getInitHookEnv } from "./initHook"; +import { NON_INTERACTIVE_ENV_VARS } from "@/common/constants/env"; import { streamProcessToLogger } from "./streamProcess"; import { expandTildeForSSH, cdCommandForSSH } from "./tildeExpansion"; import { getProjectName } from "@/node/utils/runtime/helpers"; @@ -106,11 +107,10 @@ export class SSHRuntime implements Runtime { // Add cd command if cwd is specified parts.push(cdCommandForSSH(options.cwd)); - // Add environment variable exports - if (options.env) { - for (const [key, value] of Object.entries(options.env)) { - parts.push(`export ${key}=${shescape.quote(value)}`); - } + // Add environment variable exports (user env first, then non-interactive overrides) + const envVars = { ...options.env, ...NON_INTERACTIVE_ENV_VARS }; + for (const [key, value] of Object.entries(envVars)) { + parts.push(`export ${key}=${shescape.quote(value)}`); } // Add the actual command diff --git a/tests/runtime/runtime.test.ts b/tests/runtime/runtime.test.ts index 4a862711a..10cf943aa 100644 --- a/tests/runtime/runtime.test.ts +++ b/tests/runtime/runtime.test.ts @@ -113,6 +113,21 @@ describeIntegration("Runtime integration tests", () => { expect(result.stdout.trim()).toBe("test-value"); }); + test.concurrent("sets NON_INTERACTIVE_ENV_VARS to prevent prompts", async () => { + const runtime = createRuntime(); + await using workspace = await TestWorkspace.create(runtime, type); + + // Verify GIT_TERMINAL_PROMPT is set to 0 (prevents credential prompts) + const result = await execBuffered( + runtime, + 'echo "GIT_TERMINAL_PROMPT=$GIT_TERMINAL_PROMPT GIT_EDITOR=$GIT_EDITOR"', + { cwd: workspace.path, timeout: 30 } + ); + + expect(result.stdout).toContain("GIT_TERMINAL_PROMPT=0"); + expect(result.stdout).toContain("GIT_EDITOR=true"); + }); + test.concurrent("handles empty output", async () => { const runtime = createRuntime(); await using workspace = await TestWorkspace.create(runtime, type);