diff --git a/src/tmux-manager.ts b/src/tmux-manager.ts index acfecb3a..2be5daa9 100644 --- a/src/tmux-manager.ts +++ b/src/tmux-manager.ts @@ -780,7 +780,11 @@ export function buildSpawnCommand(options: { // SERVER process's env — empty in containers and system systemd units, leaving // the pane command ending in a dangling `&&` ("syntax error: unexpected end of // file", pane dead on arrival). Resolve it in Node and quote the result. - return shellescape(resolveLocalShell()); + // -i -l: interactive login shell, so the resolved shell sources the user's rc + // files (~/.zshrc, ~/.bashrc, etc.) instead of running as a bare non-interactive + // child of the non-interactive `bash -c` that launches the pane — without this, + // aliases, PATH additions, and tool init (zoxide, nvm, etc.) are silently dropped. + return `${shellescape(resolveLocalShell())} -i -l`; } /** diff --git a/test/shell-session-launch.test.ts b/test/shell-session-launch.test.ts index e3a1ba42..078ad48a 100644 --- a/test/shell-session-launch.test.ts +++ b/test/shell-session-launch.test.ts @@ -88,6 +88,14 @@ describe('shell-mode spawn command (issue #208)', () => { expect(cmd.trim()).not.toBe(''); }); + it('launches an interactive login shell, so rc files (~/.zshrc, ~/.bashrc, etc.) are sourced', () => { + // Without -i -l, the resolved shell runs as a bare non-interactive child of + // the non-interactive `bash -c` that launches the pane, silently dropping + // aliases, PATH additions, and tool init (zoxide, nvm, etc.). + const cmd = buildSpawnCommand({ mode: 'shell', sessionId: 'abc123de-0000-0000-0000-000000000000' }); + expect(cmd.trim().endsWith('-i -l')).toBe(true); + }); + it('produces a launch command that parses after the outer sh -c expansion layer', () => { const cmd = buildSpawnCommand({ mode: 'shell', sessionId: 'abc123de-0000-0000-0000-000000000000' }); // Mirrors tmux-manager: `… bash -c ${JSON.stringify(launchCmd)}` handed to `sh -c`.