fix(terminal): drop native ARGV0 for bun-pty via env -u

bun-pty merges the OS environ into PTY children, so deleting ARGV0 from the
JS env object alone left the AppImage path in the shell. Wrap Linux PTY
spawns with env -u ARGV0, clear native ARGV0 under Bun via libc unsetenv,
and always clear process.env even when no login-shell snapshot exists.

Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
Cursor Agent
2026-08-03 09:12:35 +00:00
co-authored by Serhii Dziupin
parent be38fb8cf4
commit 5defd1af75
8 changed files with 138 additions and 13 deletions
@@ -156,6 +156,10 @@ describe('terminal runtime', () => {
expect(harness.processes[0].options.env.NODE_CHANNEL_FD).toBe('');
expect(harness.processes[0].options.env).not.toHaveProperty('ARGV0');
expect(harness.processes[0].options.env).not.toHaveProperty('ELECTRON_RUN_AS_NODE');
if (process.platform === 'linux') {
expect(harness.processes[0].shell).toMatch(/\/env$/);
expect(harness.processes[0].args.slice(0, 3)).toEqual(['-u', 'ARGV0', expect.any(String)]);
}
harness.processes[0].emitData('\u001b[?2031h\u001b]10;?\u0007\u001b]11;?\u0007');
expect(harness.processes[0].writes).toEqual(['\u001b]10;rgb:1b1b/1b1b/1b1b\u001b\\', '\u001b]11;rgb:fafa/f8f8/f0f0\u001b\\']);
@@ -184,6 +188,11 @@ describe('terminal runtime', () => {
await harness.routes.post.get('/api/terminal/create')({ body: { sessionId: 'term-argv0', cwd: '/repo', cols: 80, rows: 24 } }, response);
expect(response.statusCode).toBe(200);
expect(harness.processes[0].options.env).not.toHaveProperty('ARGV0');
if (process.platform === 'linux') {
expect(harness.processes[0].shell).toMatch(/\/env$/);
expect(harness.processes[0].args[0]).toBe('-u');
expect(harness.processes[0].args[1]).toBe('ARGV0');
}
} finally {
if (previousArgv0 === undefined) delete process.env.ARGV0;
else process.env.ARGV0 = previousArgv0;
@@ -216,14 +225,24 @@ describe('terminal runtime', () => {
const created = createResponse();
await harness.routes.post.get('/api/terminal/create')({ body: { sessionId: 'term-shell', cwd: '/repo', shell: 'zsh', loginShell: true } }, created);
expect(created.statusCode).toBe(200);
expect(harness.processes[0].shell).toBe('/bin/zsh');
expect(harness.processes[0].args).toEqual(['-l']);
if (process.platform === 'linux') {
expect(harness.processes[0].shell).toMatch(/\/env$/);
expect(harness.processes[0].args).toEqual(['-u', 'ARGV0', '/bin/zsh', '-l']);
} else {
expect(harness.processes[0].shell).toBe('/bin/zsh');
expect(harness.processes[0].args).toEqual(['-l']);
}
const restarted = createResponse();
await harness.routes.post.get('/api/terminal/:sessionId/restart')({ params: { sessionId: 'term-shell' }, body: { shell: 'bash', loginShell: true } }, restarted);
expect(restarted.statusCode).toBe(200);
expect(harness.processes[1].shell).toBe('/bin/bash');
expect(harness.processes[1].args).toEqual(['-l']);
if (process.platform === 'linux') {
expect(harness.processes[1].shell).toMatch(/\/env$/);
expect(harness.processes[1].args).toEqual(['-u', 'ARGV0', '/bin/bash', '-l']);
} else {
expect(harness.processes[1].shell).toBe('/bin/bash');
expect(harness.processes[1].args).toEqual(['-l']);
}
} finally { await harness.runtime.shutdown(); }
});