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.js52
1 files changed, 52 insertions, 0 deletions
diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js
index d2d3103..3ab25b1 100644
--- a/modules/core/virtual-fs.js
+++ b/modules/core/virtual-fs.js
@@ -3,6 +3,7 @@ class VirtualFileSystem {
this.root = { type: 'dir', content: {} };
this.currentPath = [];
this._ready = this.loadFromStorage();
+ this._conceptCache = null;
}
_u8ToBase64(u8) {
let s = '';
@@ -82,6 +83,27 @@ class VirtualFileSystem {
} catch (e) { console.error('FS save error:', e); }
}, 2000);
}
+ 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) {
@@ -130,6 +152,18 @@ 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);
@@ -161,6 +195,24 @@ 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];