aboutsummaryrefslogtreecommitdiff
path: root/modules/core/virtual-fs.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-08 18:01:06 +0200
committerAgando <roduccomm@gmail.com>2026-06-08 18:01:06 +0200
commitb562e1491513163921593985f3542d4ee8ae0e75 (patch)
treef768a2378d3c09b3685a7bf42a9fc4dec71ef31c /modules/core/virtual-fs.js
parentb9485bae5c2e62fa9c1b1c56d0f75be67cb47c37 (diff)
auto: 2026-06-08_18:00 changes
Diffstat (limited to 'modules/core/virtual-fs.js')
-rw-r--r--modules/core/virtual-fs.js109
1 files changed, 15 insertions, 94 deletions
diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js
index 95b031e..cb8020a 100644
--- a/modules/core/virtual-fs.js
+++ b/modules/core/virtual-fs.js
@@ -3,7 +3,6 @@ class VirtualFileSystem {
this.root = { type: 'dir', content: {} };
this.currentPath = [];
this._ready = this.loadFromStorage();
- this._conceptCache = null;
}
_u8ToBase64(u8) {
let s = '';
@@ -66,6 +65,17 @@ class VirtualFileSystem {
}
return false;
}
+ _emitChange(path) {
+ // Notify NeuralVFS via window event — zero coupling
+ // Skip internal index/system files to prevent re-trigger loops
+ if (!path) return;
+ const normalized = path.startsWith('/') ? path : '/' + path;
+ const sysPaths = ['/.semantic_index', '/.memory_graph', '/.trash', '/_snapshots', '/_sessions', '/logs', '/memory', '/system', '/_mods', '/backups'];
+ if (sysPaths.some(p => normalized.startsWith(p))) return;
+ if (typeof window !== 'undefined' && window.__nvfsMarkDirty) {
+ window.__nvfsMarkDirty(path);
+ }
+ }
saveToStorage() {
if (this._storageSavePending) return;
this._storageSavePending = true;
@@ -83,38 +93,6 @@ class VirtualFileSystem {
} catch (e) { console.error('FS save error:', e); }
}, 2000);
}
- _emitChange(path) {
- // Notify NeuralVFS via window event — zero coupling
- // Skip internal index/system files to prevent re-trigger loops
- if (!path) return;
- const normalized = path.startsWith('/') ? path : '/' + path;
- const sysPaths = ['/.semantic_index', '/.memory_graph', '/.trash', '/_snapshots', '/_sessions', '/logs', '/memory', '/system', '/_mods', '/backups'];
- if (sysPaths.some(p => normalized.startsWith(p))) return;
- if (typeof window !== 'undefined' && window.__nvfsMarkDirty) {
- window.__nvfsMarkDirty(path);
- }
- }
- getCurrentPath() {
- return '/' + this.currentPath.join('/');
- }
- setCurrentPath(path) {
- const segs = this._toAbsoluteSegments(path);
- if (segs === null) return false;
- this.currentPath = segs;
- return true;
- }
- _loadConceptIndex() {
- if (this._conceptCache) return this._conceptCache;
- try {
- const raw = this.readFile('/.semantic_index/map.json');
- if (raw) {
- this._conceptCache = JSON.parse(raw);
- return this._conceptCache;
- }
- } catch (e) {}
- return null;
- }
- _clearConceptCache() { this._conceptCache = null; }
getCurrentDir() {
let dir = this.root;
for (let part of this.currentPath) {
@@ -163,18 +141,6 @@ class VirtualFileSystem {
return dir;
}
ls(path) {
- // concept:// listing
- if (path && path.startsWith('concept://')) {
- const concept = path.replace('concept://', '').replace(/\/.*$/, '').toLowerCase();
- const index = this._loadConceptIndex();
- if (!index) return [];
- let matches = index[concept] || [];
- if (matches.length === 0) {
- const fuzzy = Object.keys(index).filter(k => k.includes(concept) || concept.includes(k));
- if (fuzzy.length > 0) matches = index[fuzzy[0]];
- }
- return (matches || []).map(m => ({ name: m.path.split('/').pop(), type: 'file', path: m.path, size: 0, concept: true }));
- }
let dir;
if (path) {
const resolved = this._resolvePath(path);
@@ -207,24 +173,6 @@ class VirtualFileSystem {
return true;
}
readFile(path) {
- // concept:// URI resolution
- if (path && path.startsWith('concept://')) {
- const concept = path.replace('concept://', '').replace(/\/.*$/, '').toLowerCase();
- try {
- const index = this._loadConceptIndex();
- if (!index) return 'No semantic index found. Run nvfs-index first.';
- let matches = index[concept];
- if (!matches) {
- const fuzzy = Object.keys(index).filter(k => k.includes(concept) || concept.includes(k));
- if (fuzzy.length > 0) matches = index[fuzzy[0]];
- }
- if (!matches || matches.length === 0) return `No files found for concept "${concept}"`;
- const first = matches[0];
- const content = this.readFile(first.path);
- if (content) return `--- ${first.path} (concept://${concept}) ---\n${content}`;
- return `Concept "${concept}" → ${matches.length} file(s):\n${matches.map(m => ` ${m.path} — ${m.summary || ''}`).join('\n')}`;
- } catch (e) { return `concept:// error: ${e.message}`; }
- }
const resolved = this._resolvePath(path);
if (!resolved || !resolved.name) return null;
const node = resolved.dir.content[resolved.name];
@@ -291,6 +239,9 @@ class VirtualFileSystem {
}
return false;
}
+ deleteDirRecursive(path) {
+ return this.trashDir(path);
+ }
mkdirRecursive(path) {
const segs = this._toAbsoluteSegments(path);
if (!segs) return false;
@@ -539,25 +490,15 @@ class VirtualFileSystem {
checkpoint(name) {
if (!name) name = new Date().toISOString();
const createdAt = new Date().toISOString();
- // Strip system dirs to avoid fractal bloat — snapshots/sessions/trash
- // don't belong inside a checkpoint of user data
- const root = JSON.parse(JSON.stringify(this.root));
- if (root && root.content) {
- delete root.content['_snapshots'];
- delete root.content['_sessions'];
- delete root.content['.trash'];
- }
const data = {
version: 1,
createdAt,
- root,
+ root: JSON.parse(JSON.stringify(this.root)),
currentPath: [...this.currentPath]
};
if (!this.readDir('/_snapshots')) {
this.mkdirRecursive('/_snapshots');
}
- // Strip _snapshots from the serialized data too (redundant safety)
- data.root = root;
this.fsWriteJSON('/_snapshots/checkpoint-' + name + '.json', data);
this.saveToStorage();
// Auto-manage: keep max 10 checkpoints, delete oldest
@@ -597,26 +538,6 @@ class VirtualFileSystem {
}
return false;
}
- // Reset VFS — wipes everything, removes localStorage keys
- reset() {
- this.root = { type: 'dir', content: {} };
- this.currentPath = [];
- this._conceptCache = null;
- try {
- localStorage.removeItem('webx11_filesystem_v2');
- localStorage.removeItem('webx11_filesystem');
- } catch (e) {}
- return true;
- }
- // Empty trash — permanently delete all trashed files
- emptyTrash() {
- if (this.root.content['.trash']) {
- delete this.root.content['.trash'];
- this.saveToStorage();
- return true;
- }
- return false;
- }
// Old-compat aliases for agent tools and SkillsModule
read(path) { return this.readFile(path); }
write(path, content) { return this.writeFile(path, content); }