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

Function findEvolverRoot

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

Source from the content-addressed store, hash-verified

163}
164
165function findEvolverRoot() {
166 if (process.env.EVOLVER_ROOT) {
167 const explicit = process.env.EVOLVER_ROOT;
168 if (fs.existsSync(path.join(explicit, 'package.json')) &&
169 isEvolverPackageJson(path.join(explicit, 'package.json'))) {
170 return explicit;
171 }
172 }
173
174 // Dev/repo layout: this file lives at src/adapters/scripts/_runtimePaths.js,
175 // so `../../..` is the package root.
176 const repoRoot = path.resolve(__dirname, '..', '..', '..');
177 if (fs.existsSync(path.join(repoRoot, 'package.json')) &&
178 isEvolverPackageJson(path.join(repoRoot, 'package.json'))) {
179 return repoRoot;
180 }
181
182 // npm-global / npm-local install layout. The hook script may have been
183 // copied out of the package into `.claude/hooks/` etc., breaking relative
184 // walks. Use require.resolve to find the installed package authoritatively.
185 //
186 // SECURITY: do NOT include `process.cwd()` here. A hostile workspace can
187 // place its own `node_modules/@evomap/evolver/package.json`, which would
188 // be selected here and control `findMemoryGraph()` -> the memory graph
189 // contents become attacker-controlled prompt-injection material in
190 // `evolver-session-start.js`'s `additionalContext`. Restrict to trusted,
191 // user/system-scoped install roots (built in `_buildInstallSearchPaths`).
192 try {
193 // Allowlist of trusted user/system-scoped install roots. Built by
194 // _buildInstallSearchPaths() above so the list is one source of truth
195 // (Apple Silicon Homebrew, Linuxbrew, NVM / fnm / Volta / asdf,
196 // and Windows %APPDATA%\npm + %ProgramFiles%\nodejs install layouts).
197 // process.cwd() is intentionally excluded: a hostile workspace can plant
198 // its own node_modules/@evomap/evolver/package.json which would then
199 // control findMemoryGraph() and feed attacker-controlled content into
200 // evolver-session-start.js's additionalContext.
201 const pkgJson = require.resolve('@evomap/evolver/package.json', {
202 paths: _buildInstallSearchPaths(),
203 });
204 if (pkgJson && isEvolverPackageJson(pkgJson)) {
205 return path.dirname(pkgJson);
206 }
207 } catch { /* not installed via npm */ }
208
209 const homeSkills = path.join(os.homedir(), 'skills', 'evolver');
210 if (fs.existsSync(path.join(homeSkills, 'package.json')) &&
211 isEvolverPackageJson(path.join(homeSkills, 'package.json'))) {
212 return homeSkills;
213 }
214
215 return null;
216}
217
218// Resolve the user's PROJECT directory — the workspace the agent is actually
219// working in — for git-diff collection and workspace tagging.

Callers 6

adapters.test.jsFile · 0.85
resolveWorkspaceIdFunction · 0.85
loadHubFetchFunction · 0.85
mainFunction · 0.85
runInjectionFunction · 0.85
mainFunction · 0.85

Calls 2

isEvolverPackageJsonFunction · 0.85
_buildInstallSearchPathsFunction · 0.85

Tested by

no test coverage detected