| 53 | |
| 54 | // Terminal detection |
| 55 | async function detectTerminal(): Promise<SupportedTerminal | null> { |
| 56 | const termProgram = process.env['TERM_PROGRAM']; |
| 57 | |
| 58 | // Check VS Code and its forks - check forks first to avoid false positives |
| 59 | // Check for Cursor-specific indicators |
| 60 | if ( |
| 61 | process.env['CURSOR_TRACE_ID'] || |
| 62 | process.env['VSCODE_GIT_ASKPASS_MAIN']?.toLowerCase().includes('cursor') |
| 63 | ) { |
| 64 | return 'cursor'; |
| 65 | } |
| 66 | // Check for Windsurf-specific indicators |
| 67 | if ( |
| 68 | process.env['VSCODE_GIT_ASKPASS_MAIN']?.toLowerCase().includes('windsurf') |
| 69 | ) { |
| 70 | return 'windsurf'; |
| 71 | } |
| 72 | // Check VS Code last since forks may also set VSCODE env vars |
| 73 | if (termProgram === 'vscode' || process.env['VSCODE_GIT_IPC_HANDLE']) { |
| 74 | return 'vscode'; |
| 75 | } |
| 76 | |
| 77 | // Check parent process name |
| 78 | if (os.platform() !== 'win32') { |
| 79 | try { |
| 80 | const { stdout } = await execAsync('ps -o comm= -p $PPID'); |
| 81 | const parentName = stdout.trim(); |
| 82 | |
| 83 | // Check forks before VS Code to avoid false positives |
| 84 | if (parentName.includes('windsurf') || parentName.includes('Windsurf')) |
| 85 | return 'windsurf'; |
| 86 | if (parentName.includes('cursor') || parentName.includes('Cursor')) |
| 87 | return 'cursor'; |
| 88 | if (parentName.includes('code') || parentName.includes('Code')) |
| 89 | return 'vscode'; |
| 90 | } catch (error) { |
| 91 | // Continue detection even if process check fails |
| 92 | console.debug('Parent process detection failed:', error); |
| 93 | } |
| 94 | } |
| 95 | |
| 96 | return null; |
| 97 | } |
| 98 | |
| 99 | // Backup file helper |
| 100 | async function backupFile(filePath: string): Promise<void> { |