From 2963d46d758bec6cc35161c4b60265fa006771d9 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Wed, 1 Apr 2026 13:14:54 -0400 Subject: [PATCH] fix(cli): avoid login shells for lifecycle commands --- src/commands/project.ts | 4 ++-- tests/project-lifecycle-processes.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/commands/project.ts b/src/commands/project.ts index 3d66c149..60416536 100644 --- a/src/commands/project.ts +++ b/src/commands/project.ts @@ -2141,9 +2141,9 @@ export function wrapLifecyclePersistentCommand(opts: { ' done < "$fifo" ) &', "reader_pid=$!", "if command -v python3 >/dev/null 2>&1; then", - ' python3 -c \'import os, sys; os.setsid(); os.execvp("sh", ["sh", "-lc", sys.argv[1]])\' "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &', + ' python3 -c \'import os, sys; os.setsid(); os.execvp("sh", ["sh", "-c", sys.argv[1]])\' "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &', "else", - ' sh -lc "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &', + ' sh -c "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &', "fi", "cmd_pid=$!", 'wait "$cmd_pid"', diff --git a/tests/project-lifecycle-processes.test.ts b/tests/project-lifecycle-processes.test.ts index f4c1e8b3..809e9520 100644 --- a/tests/project-lifecycle-processes.test.ts +++ b/tests/project-lifecycle-processes.test.ts @@ -137,6 +137,21 @@ test("wrapLifecyclePersistentCommand uses external kill for process-group cleanu ); }); +test("wrapLifecyclePersistentCommand avoids login-shell execution", () => { + const script = wrapLifecyclePersistentCommand({ + command: "bun run proxy", + logPath: "/tmp/event-agent.log", + serviceName: "proxy", + }); + + expect(script).toContain('os.execvp("sh", ["sh", "-c", sys.argv[1]])'); + expect(script).toContain('sh -c "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &'); + expect(script).not.toContain('os.execvp("sh", ["sh", "-lc", sys.argv[1]])'); + expect(script).not.toContain( + 'sh -lc "$HACK_LIFECYCLE_COMMAND" >"$fifo" 2>&1 &' + ); +}); + async function createLifecycleProjectDir(): Promise { const root = await mkdtemp(join(tmpdir(), "hack-lifecycle-processes-")); tempDirs.add(root);