MCPcopy Create free account
hub / github.com/EvoMap/evolver / _buildInstallSearchPaths

Function _buildInstallSearchPaths

src/adapters/scripts/_runtimePaths.js:65–163  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

63// prompt-injection reason as the original allowlist (see comment in
64// findEvolverRoot below).
65function _buildInstallSearchPaths() {
66 const home = os.homedir();
67 // Env-derived bases must be ABSOLUTE. A relative override (e.g. NVM_DIR='.nvm')
68 // or empty value would resolve against process.cwd() and let a hostile
69 // workspace plant a fake @evomap/evolver in the require.resolve allowlist —
70 // the prompt-injection surface PR #94 closed. isAbsolute is platform-matched
71 // (path.win32 recognises C:\ ...) so the guard holds on Windows too; a
72 // non-absolute override falls through to the trusted home/system default.
73 const _pathFlavor = process.platform === 'win32' ? path.win32 : path.posix;
74 const absEnv = (v) => (v && _pathFlavor.isAbsolute(v)) ? v : null;
75 const paths = [
76 // npm global with `npm config set prefix` overrides
77 path.join(home, '.npm-global', 'lib', 'node_modules'),
78 path.join(home, '.local', 'lib', 'node_modules'),
79 // System-wide (apt/yum nodejs, Intel Mac Homebrew)
80 '/usr/lib/node_modules',
81 '/usr/local/lib/node_modules',
82 // Apple Silicon Homebrew (default since macOS Big Sur on M1/M2/M3/M4 —
83 // the majority of Mac dev hardware sold since 2021). Without this
84 // entry, `npm install -g @evomap/evolver` on an Apple Silicon Mac
85 // lands at /opt/homebrew/lib/node_modules/@evomap/evolver and the
86 // hook scripts cannot find the package -> additionalContext is empty
87 // -> evolution memory never reaches the LLM.
88 '/opt/homebrew/lib/node_modules',
89 // Linuxbrew (Homebrew on Linux — niche but real).
90 '/home/linuxbrew/.linuxbrew/lib/node_modules',
91 ];
92 // Per-user Node version managers. Each manager has its own on-disk layout
93 // and its own base-dir env override; the version subdirectory is dynamic
94 // (e.g. `~/.nvm/versions/node/v22.15.0`) so we scan and append each
95 // version's node_modules. These were missing from the original hard-coded
96 // list even though NVM in particular is extremely common across all OSes.
97
98 // NVM. Globals are per-version under `<NVM_DIR>/versions/node/<ver>/lib`.
99 // NVM_DIR defaults to ~/.nvm but is frequently relocated.
100 const nvmDir = absEnv(process.env.NVM_DIR) || path.join(home, '.nvm');
101 _scanVersionedNodeModules(path.join(nvmDir, 'versions', 'node'), 'lib', paths);
102
103 // fnm. Each version lives under `<base>/node-versions/<ver>/installation/`,
104 // and fnm does NOT override the npm prefix, so globals are at
105 // `installation/lib/node_modules`. The base dir is XDG-first
106 // (`$XDG_DATA_HOME/fnm`, i.e. ~/.local/share/fnm on Linux and
107 // ~/Library/Application Support/fnm on macOS); `~/.fnm` is only the legacy
108 // fallback. `$FNM_DIR` overrides everything. Scan all candidate bases;
109 // _scanVersionedNodeModules silently skips the ones that don't exist.
110 const fnmSub = path.join('installation', 'lib');
111 const fnmBases = [];
112 if (absEnv(process.env.FNM_DIR)) fnmBases.push(process.env.FNM_DIR);
113 if (absEnv(process.env.XDG_DATA_HOME)) fnmBases.push(path.join(process.env.XDG_DATA_HOME, 'fnm'));
114 fnmBases.push(path.join(home, '.local', 'share', 'fnm')); // Linux XDG default
115 fnmBases.push(path.join(home, 'Library', 'Application Support', 'fnm')); // macOS default
116 fnmBases.push(path.join(home, '.fnm')); // legacy
117 for (const base of fnmBases) {
118 _scanVersionedNodeModules(path.join(base, 'node-versions'), fnmSub, paths);
119 }
120
121 // Volta does NOT store global packages alongside the Node image. It
122 // sandboxes each `npm install -g`'d package under

Callers 1

findEvolverRootFunction · 0.85

Calls 2

absEnvFunction · 0.85

Tested by

no test coverage detected