@blockrun/franklin 3.15.17 → 3.15.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/storage/hygiene.js +58 -0
- package/package.json +1 -1
package/dist/storage/hygiene.js
CHANGED
|
@@ -61,6 +61,10 @@ export function runDataHygiene() {
|
|
|
61
61
|
removeLegacyFiles();
|
|
62
62
|
}
|
|
63
63
|
catch { /* best effort */ }
|
|
64
|
+
try {
|
|
65
|
+
sweepOrphanToolResults();
|
|
66
|
+
}
|
|
67
|
+
catch { /* best effort */ }
|
|
64
68
|
}
|
|
65
69
|
function trimDataDir() {
|
|
66
70
|
const dir = path.join(BLOCKRUN_DIR, 'data');
|
|
@@ -132,3 +136,57 @@ function removeLegacyFiles() {
|
|
|
132
136
|
catch { /* ok */ }
|
|
133
137
|
}
|
|
134
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* `streaming-executor` writes large tool outputs to
|
|
141
|
+
* `~/.blockrun/tool-results/<sessionId>/<toolUseId>.txt`. When a session is
|
|
142
|
+
* pruned by `pruneOldSessions`, the meta + jsonl are deleted but the
|
|
143
|
+
* tool-results dir is left dangling. Verified on a real machine: 5 dirs,
|
|
144
|
+
* oldest from 4/14 (3 weeks past MAX_SESSIONS=20 retention).
|
|
145
|
+
*
|
|
146
|
+
* A tool-results dir is considered orphan when its name (the session id)
|
|
147
|
+
* has no `<sessionId>.meta.json` partner in the sessions/ dir. The active
|
|
148
|
+
* session is implicitly protected because its meta exists.
|
|
149
|
+
*/
|
|
150
|
+
function sweepOrphanToolResults() {
|
|
151
|
+
const toolResultsDir = path.join(BLOCKRUN_DIR, 'tool-results');
|
|
152
|
+
const sessionsDir = path.join(BLOCKRUN_DIR, 'sessions');
|
|
153
|
+
if (!fs.existsSync(toolResultsDir))
|
|
154
|
+
return;
|
|
155
|
+
const knownSessionIds = new Set();
|
|
156
|
+
if (fs.existsSync(sessionsDir)) {
|
|
157
|
+
try {
|
|
158
|
+
for (const f of fs.readdirSync(sessionsDir)) {
|
|
159
|
+
if (f.endsWith('.meta.json')) {
|
|
160
|
+
knownSessionIds.add(f.slice(0, -'.meta.json'.length));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Best-effort — if we can't read sessions/, skip the sweep so
|
|
166
|
+
// we never delete tool-results that might still belong to a
|
|
167
|
+
// live session.
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
let entries;
|
|
172
|
+
try {
|
|
173
|
+
entries = fs.readdirSync(toolResultsDir);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
for (const name of entries) {
|
|
179
|
+
if (knownSessionIds.has(name))
|
|
180
|
+
continue;
|
|
181
|
+
const dir = path.join(toolResultsDir, name);
|
|
182
|
+
try {
|
|
183
|
+
const stat = fs.statSync(dir);
|
|
184
|
+
if (!stat.isDirectory())
|
|
185
|
+
continue;
|
|
186
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Skip — best-effort cleanup.
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
package/package.json
CHANGED