import { join } from 'node:path'; import { homedir, platform } from 'node:os'; export type ShellType = 'zsh' | 'bash' | 'fish' | 'powershell' | 'unknown'; export function detectShell(): ShellType { const shell = process.env['SHELL'] ?? ''; if (shell.includes('zsh')) return 'zsh'; if (shell.includes('bash')) return 'bash'; if (shell.includes('fish')) return 'fish'; if (platform() === 'win32') return 'powershell'; return 'unknown'; } export function getShellProfilePath(): string | null { const home = homedir(); if (platform() === 'win32') { return join(home, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1'); } const shell = detectShell(); switch (shell) { // Both of these deliberately avoid the interactive-only rc files. // Debian's default .bashrc returns early for non-interactive shells, so a // PATH line appended to it never runs for `bash -lc`, systemd units, or // agent seats — an install could report success and still leave `mosaic` // unreachable. .profile is read by login shells and sources .bashrc for // interactive ones, so one line covers both; .zshenv is zsh's equivalent. case 'zsh': { const zdotdir = process.env['ZDOTDIR'] ?? home; return join(zdotdir, '.zshenv'); } case 'bash': return join(home, '.profile'); case 'fish': return join(home, '.config', 'fish', 'config.fish'); default: return join(home, '.profile'); } }