aboutsummaryrefslogtreecommitdiff
path: root/modules/core/virtual-fs.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/virtual-fs.js')
-rw-r--r--modules/core/virtual-fs.js23
1 files changed, 20 insertions, 3 deletions
diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js
index 3a3e119..57c6578 100644
--- a/modules/core/virtual-fs.js
+++ b/modules/core/virtual-fs.js
@@ -510,6 +510,19 @@ class VirtualFileSystem {
}
return { dir, name: segs[segs.length - 1] };
}
+ // newOS4 patch: _resolvePath() validates intermediate segments only, so it returns a
+ // result for a leaf that does not exist. Mutating callers then acted on a phantom
+ // path and reported success (deleteCheckpoint printed 'Deleted checkpoint' and
+ // deleted nothing). _requireLeaf() refuses any resolved path whose leaf is absent.
+ _requireLeaf(resolved) {
+ if (!resolved) return null;
+ if (resolved.name) {
+ const node = (resolved.dir && resolved.dir.content) ? resolved.dir.content[resolved.name] : null;
+ if (!node) return null;
+ }
+ return resolved;
+ }
+
_resolveDir(path) {
if (this._isVirtualPath(path)) {
const r = this._resolveVirtualPath(path);
@@ -579,7 +592,7 @@ class VirtualFileSystem {
}
deleteFile(path) {
if (this._isVirtualPath(path)) return false;
- const resolved = this._resolvePath(path);
+ const resolved = this._requireLeaf(this._resolvePath(path));
if (!resolved || !resolved.name) return false;
const node = resolved.dir.content[resolved.name];
if (node && node.type === 'file') {
@@ -966,6 +979,10 @@ class VirtualFileSystem {
delete rootClone.content['_sessions'];
delete rootClone.content['_snapshots'];
delete rootClone.content['.trash'];
+ // newOS4 patch: module originals and the semantic index dominated every
+ // snapshot (one checkpoint reached 4.13MB) and grew on each new checkpoint.
+ delete rootClone.content['_mods'];
+ delete rootClone.content['.semantic_index'];
}
const data = {
version: 1,
@@ -1000,7 +1017,7 @@ class VirtualFileSystem {
// clone verbatim deletes every checkpoint, every agent session and the trash, so keep the
// live copies and re-attach them after the root swap.
const keep = {};
- for (const dir of ['_snapshots', '_sessions', '.trash']) {
+ for (const dir of ['_snapshots', '_sessions', '.trash', '_mods', '.semantic_index']) {
const node = this.root && this.root.content ? this.root.content[dir] : null;
if (node) keep[dir] = node;
}
@@ -1020,7 +1037,7 @@ class VirtualFileSystem {
}
deleteCheckpoint(name) {
const path = '/_snapshots/checkpoint-' + name + '.json';
- const resolved = this._resolvePath(path);
+ const resolved = this._requireLeaf(this._resolvePath(path));
if (resolved && resolved.name) {
delete resolved.dir.content[resolved.name];
this.saveToStorage();