xdg.ts
1 /** 2 * XDG Base Directory utilities for Claude CLI Native Installer 3 * 4 * Implements the XDG Base Directory specification for organizing 5 * native installer components across appropriate system directories. 6 * 7 * @see https://specifications.freedesktop.org/basedir-spec/latest/ 8 */ 9 10 import { homedir as osHomedir } from 'os' 11 import { join } from 'path' 12 13 type EnvLike = Record<string, string | undefined> 14 15 type XDGOptions = { 16 env?: EnvLike 17 homedir?: string 18 } 19 20 function resolveOptions(options?: XDGOptions): { env: EnvLike; home: string } { 21 return { 22 env: options?.env ?? process.env, 23 home: options?.homedir ?? process.env.HOME ?? osHomedir(), 24 } 25 } 26 27 /** 28 * Get XDG state home directory 29 * Default: ~/.local/state 30 * @param options Optional env and homedir overrides for testing 31 */ 32 export function getXDGStateHome(options?: XDGOptions): string { 33 const { env, home } = resolveOptions(options) 34 return env.XDG_STATE_HOME ?? join(home, '.local', 'state') 35 } 36 37 /** 38 * Get XDG cache home directory 39 * Default: ~/.cache 40 * @param options Optional env and homedir overrides for testing 41 */ 42 export function getXDGCacheHome(options?: XDGOptions): string { 43 const { env, home } = resolveOptions(options) 44 return env.XDG_CACHE_HOME ?? join(home, '.cache') 45 } 46 47 /** 48 * Get XDG data home directory 49 * Default: ~/.local/share 50 * @param options Optional env and homedir overrides for testing 51 */ 52 export function getXDGDataHome(options?: XDGOptions): string { 53 const { env, home } = resolveOptions(options) 54 return env.XDG_DATA_HOME ?? join(home, '.local', 'share') 55 } 56 57 /** 58 * Get user bin directory (not technically XDG but follows the convention) 59 * Default: ~/.local/bin 60 * @param options Optional homedir override for testing 61 */ 62 export function getUserBinDir(options?: XDGOptions): string { 63 const { home } = resolveOptions(options) 64 return join(home, '.local', 'bin') 65 }