/ utils / deepLink / terminalPreference.ts
terminalPreference.ts
 1  /**
 2   * Terminal preference capture for deep link handling.
 3   *
 4   * Separate from terminalLauncher.ts so interactiveHelpers.tsx can import
 5   * this without pulling the full launcher module into the startup path
 6   * (which would defeat LODESTONE tree-shaking).
 7   */
 8  
 9  import { getGlobalConfig, saveGlobalConfig } from '../config.js'
10  import { logForDebugging } from '../debug.js'
11  
12  /**
13   * Map TERM_PROGRAM env var values (lowercased) to the `app` name used by
14   * launchMacosTerminal's switch cases. TERM_PROGRAM values are what terminals
15   * self-report; they don't always match the .app bundle name (e.g.,
16   * "iTerm.app" → "iTerm", "Apple_Terminal" → "Terminal").
17   */
18  const TERM_PROGRAM_TO_APP: Record<string, string> = {
19    iterm: 'iTerm',
20    'iterm.app': 'iTerm',
21    ghostty: 'Ghostty',
22    kitty: 'kitty',
23    alacritty: 'Alacritty',
24    wezterm: 'WezTerm',
25    apple_terminal: 'Terminal',
26  }
27  
28  /**
29   * Capture the current terminal from TERM_PROGRAM and store it for the deep
30   * link handler to use later. The handler runs headless (LaunchServices/xdg)
31   * where TERM_PROGRAM is unset, so without this it falls back to a static
32   * priority list that picks whatever is installed first — often not the
33   * terminal the user actually uses.
34   *
35   * Called fire-and-forget from interactive startup, same as
36   * updateGithubRepoPathMapping.
37   */
38  export function updateDeepLinkTerminalPreference(): void {
39    // Only detectMacosTerminal reads the stored value — skip the write on
40    // other platforms.
41    if (process.platform !== 'darwin') return
42  
43    const termProgram = process.env.TERM_PROGRAM
44    if (!termProgram) return
45  
46    const app = TERM_PROGRAM_TO_APP[termProgram.toLowerCase()]
47    if (!app) return
48  
49    const config = getGlobalConfig()
50    if (config.deepLinkTerminal === app) return
51  
52    saveGlobalConfig(current => ({ ...current, deepLinkTerminal: app }))
53    logForDebugging(`Stored deep link terminal preference: ${app}`)
54  }