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

Function _fsWorkspaceId

src/adapters/scripts/_runtimePaths.js:304–341  ·  view source on GitHub ↗
(projectDir)

Source from the content-addressed store, hash-verified

302}
303
304function _fsWorkspaceId(projectDir) {
305 // Whole body is wrapped: the documented contract is "returns null on ANY
306 // read/write error" so the session-start/-end hooks degrade gracefully
307 // rather than crash. throwIfNoEntry:false only suppresses ENOENT; EACCES/EIO
308 // and friends still throw, so a bare lstat/mkdir here must not escape
309 // (Bugbot PR #557 round-2 — an unguarded lstat could crash the hook).
310 try {
311 const dir = path.join(_fsWorkspaceRoot(projectDir), '.evolver');
312 const file = path.join(dir, 'workspace-id');
313 // Read first, with symlink guards.
314 const existing = _readWsIdGuarded(dir, file);
315 if (existing) return existing;
316 // If the file exists but the guards rejected it (symlink / bad format),
317 // refuse rather than create over it.
318 if (fs.lstatSync(file, { throwIfNoEntry: false })) return null;
319 // Missing — create atomically. Refuse a symlinked .evolver dir (O_NOFOLLOW
320 // only guards the final component, not intermediate dirs).
321 const dirStat = fs.lstatSync(dir, { throwIfNoEntry: false });
322 if (dirStat && dirStat.isSymbolicLink()) return null;
323 fs.mkdirSync(dir, { recursive: true });
324 const payload = require('crypto').randomBytes(16).toString('hex');
325 const flags = fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL |
326 (fs.constants.O_NOFOLLOW || 0);
327 let fd;
328 try {
329 fd = fs.openSync(file, flags, 0o600);
330 } catch (e) {
331 // Lost a race — re-read WITH the same symlink guards (paths.js does the
332 // same). A bare readFileSync here would follow a symlink swapped in
333 // after our dir lstat (Bugbot PR #557).
334 if (e && e.code === 'EEXIST') return _readWsIdGuarded(dir, file);
335 return null; // ELOOP/EMLINK from O_NOFOLLOW hitting a symlink — refuse.
336 }
337 try { fs.writeSync(fd, payload + '\n', 0, 'utf8'); } finally { fs.closeSync(fd); }
338 try { fs.chmodSync(file, 0o600); } catch { /* best-effort */ }
339 return payload;
340 } catch { return null; }
341}
342
343// Resolve the current workspace id — the forge-resistant tag the session-end
344// writer stamps on every memory-graph entry (`workspace_id`). This is the

Callers 1

resolveWorkspaceIdFunction · 0.85

Calls 2

_fsWorkspaceRootFunction · 0.85
_readWsIdGuardedFunction · 0.85

Tested by

no test coverage detected