/ src / utils / systemDirectories.ts
systemDirectories.ts
 1  import { homedir } from 'os'
 2  import { join } from 'path'
 3  import { logForDebugging } from './debug.js'
 4  import { getPlatform, type Platform } from './platform.js'
 5  
 6  export type SystemDirectories = {
 7    HOME: string
 8    DESKTOP: string
 9    DOCUMENTS: string
10    DOWNLOADS: string
11    [key: string]: string // Index signature for compatibility with Record<string, string>
12  }
13  
14  type EnvLike = Record<string, string | undefined>
15  
16  type SystemDirectoriesOptions = {
17    env?: EnvLike
18    homedir?: string
19    platform?: Platform
20  }
21  
22  /**
23   * Get cross-platform system directories
24   * Handles differences between Windows, macOS, Linux, and WSL
25   * @param options Optional overrides for testing (env, homedir, platform)
26   */
27  export function getSystemDirectories(
28    options?: SystemDirectoriesOptions,
29  ): SystemDirectories {
30    const platform = options?.platform ?? getPlatform()
31    const homeDir = options?.homedir ?? homedir()
32    const env = options?.env ?? process.env
33  
34    // Default paths used by most platforms
35    const defaults: SystemDirectories = {
36      HOME: homeDir,
37      DESKTOP: join(homeDir, 'Desktop'),
38      DOCUMENTS: join(homeDir, 'Documents'),
39      DOWNLOADS: join(homeDir, 'Downloads'),
40    }
41  
42    switch (platform) {
43      case 'windows': {
44        // Windows: Use USERPROFILE if available (handles localized folder names)
45        const userProfile = env.USERPROFILE || homeDir
46        return {
47          HOME: homeDir,
48          DESKTOP: join(userProfile, 'Desktop'),
49          DOCUMENTS: join(userProfile, 'Documents'),
50          DOWNLOADS: join(userProfile, 'Downloads'),
51        }
52      }
53  
54      case 'linux':
55      case 'wsl': {
56        // Linux/WSL: Check XDG Base Directory specification first
57        return {
58          HOME: homeDir,
59          DESKTOP: env.XDG_DESKTOP_DIR || defaults.DESKTOP,
60          DOCUMENTS: env.XDG_DOCUMENTS_DIR || defaults.DOCUMENTS,
61          DOWNLOADS: env.XDG_DOWNLOAD_DIR || defaults.DOWNLOADS,
62        }
63      }
64  
65      case 'macos':
66      default: {
67        // macOS and unknown platforms use standard paths
68        if (platform === 'unknown') {
69          logForDebugging(`Unknown platform detected, using default paths`)
70        }
71        return defaults
72      }
73    }
74  }