MCPcopy Create free account
hub / github.com/SethGammon/Citadel / sweepLockdirs

Function sweepLockdirs

scripts/state-hygiene.js:111–144  ·  view source on GitHub ↗

* Recursively sweep stale *.lock directories under the planning dir. * Symlinks are never followed or deleted. Plain files named *.lock are * intentionally left alone (session-end.lock is a regular file).

(dir, nowMs, dryRun, result, depth)

Source from the content-addressed store, hash-verified

109 * intentionally left alone (session-end.lock is a regular file).
110 */
111function sweepLockdirs(dir, nowMs, dryRun, result, depth) {
112 if (depth > MAX_LOCK_SCAN_DEPTH) return;
113 let entries = [];
114 try {
115 entries = fs.readdirSync(dir, { withFileTypes: true });
116 } catch {
117 return; // dir missing or unreadable
118 }
119 for (const entry of entries) {
120 if (entry.isSymbolicLink()) continue; // never follow symlinks
121 if (!entry.isDirectory()) continue;
122 const entryPath = path.join(dir, entry.name);
123 if (entry.name.endsWith('.lock')) {
124 try {
125 const st = fs.lstatSync(entryPath);
126 if (st.isSymbolicLink() || !st.isDirectory()) continue;
127 if (nowMs - st.mtimeMs < LOCKDIR_STALE_MS) continue; // fresh, maybe live
128 if (dryRun) {
129 result.lockdirs++;
130 result.removed.push(entryPath);
131 continue;
132 }
133 fs.rmSync(entryPath, { recursive: true, force: true });
134 result.lockdirs++;
135 result.removed.push(entryPath);
136 } catch (err) {
137 result.errors++;
138 result.failed.push({ path: entryPath, error: String(err && err.message || err) });
139 }
140 } else {
141 sweepLockdirs(entryPath, nowMs, dryRun, result, depth + 1);
142 }
143 }
144}
145
146/**
147 * Run the hygiene sweep.

Callers 1

cleanStateFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected