aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-neural-vfs.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-14 06:00:14 +0200
committerAgando <roduccomm@gmail.com>2026-06-14 06:00:14 +0200
commit3dda77c60c19ebe810ac86e35a5c510c737b7b39 (patch)
treebfa0ac2c5e96249f7a5010df8bde039e416915bf /modules/core/module-neural-vfs.js
parentde713efd619360e29b9bfc4b99d30d2a86b96caf (diff)
auto: 2026-06-14_06:00 changes
Diffstat (limited to 'modules/core/module-neural-vfs.js')
-rw-r--r--modules/core/module-neural-vfs.js76
1 files changed, 66 insertions, 10 deletions
diff --git a/modules/core/module-neural-vfs.js b/modules/core/module-neural-vfs.js
index 2e5b9ac..f9bc7f4 100644
--- a/modules/core/module-neural-vfs.js
+++ b/modules/core/module-neural-vfs.js
@@ -21,6 +21,10 @@ class NeuralVFSModule {
this._treeFiles = 5;
this._treeConcepts = 15;
this._resolveFiles = 20;
+ this._excludePatterns = [];
+ this._excludeDirs = [];
+ this._excludeFiles = [];
+ this._includeOnly = [];
this._loadConfig();
// Auto-sync state
this._dirtyPaths = new Set();
@@ -46,10 +50,10 @@ class NeuralVFSModule {
}
}
_loadConfig() {
- try { const c = localStorage.getItem('webx11_nvfs_config'); if (c) { const p = JSON.parse(c); if (p.fuzzyLimit) this._fuzzyLimit = p.fuzzyLimit; if (p.treeFiles) this._treeFiles = p.treeFiles; if (p.treeConcepts) this._treeConcepts = p.treeConcepts; if (p.resolveFiles) this._resolveFiles = p.resolveFiles; } } catch (e) {}
+ try { const c = localStorage.getItem('webx11_nvfs_config'); if (c) { const p = JSON.parse(c); if (p.fuzzyLimit) this._fuzzyLimit = p.fuzzyLimit; if (p.treeFiles) this._treeFiles = p.treeFiles; if (p.treeConcepts) this._treeConcepts = p.treeConcepts; if (p.resolveFiles) this._resolveFiles = p.resolveFiles; if (Array.isArray(p.excludePatterns)) this._excludePatterns = p.excludePatterns; if (Array.isArray(p.excludeDirs)) this._excludeDirs = p.excludeDirs; if (Array.isArray(p.excludeFiles)) this._excludeFiles = p.excludeFiles; if (Array.isArray(p.includeOnly)) this._includeOnly = p.includeOnly; } } catch (e) {}
}
_saveConfig() {
- localStorage.setItem('webx11_nvfs_config', JSON.stringify({ fuzzyLimit: this._fuzzyLimit, treeFiles: this._treeFiles, treeConcepts: this._treeConcepts, resolveFiles: this._resolveFiles }));
+ localStorage.setItem('webx11_nvfs_config', JSON.stringify({ fuzzyLimit: this._fuzzyLimit, treeFiles: this._treeFiles, treeConcepts: this._treeConcepts, resolveFiles: this._resolveFiles, excludePatterns: this._excludePatterns, excludeDirs: this._excludeDirs, excludeFiles: this._excludeFiles, includeOnly: this._includeOnly }));
}
getHelpInfo() {
@@ -58,7 +62,7 @@ class NeuralVFSModule {
'nvfs-status': 'nvfs-status — Show semantic index stats and last scan time',
'nvfs-resolve': 'nvfs-resolve <concept> — Find files related to a concept',
'nvfs-tree': 'nvfs-tree [concept] — Show concept-to-file mapping as a tree',
- 'nvfs-config': 'nvfs-config [key] [value] — View or set Neural VFS config (fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index, deep-model)',
+ 'nvfs-config': 'nvfs-config [key] [value] — View or set Neural VFS config (fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index, deep-model, exclude-patterns, exclude-dirs, exclude-files, include-only)',
'nvfs-alias': 'nvfs-alias list|add|remove|clear — Manage concept aliases',
'nvfs-sync': 'nvfs-sync [--deep] — Incremental background sync (auto-sync dirty files)',
'nvfs-save': 'nvfs-save — Force-save current in-memory index to VFS (survives refresh)',
@@ -233,6 +237,7 @@ class NeuralVFSModule {
if (!entries) return;
for (const entry of entries) {
const fullPath = path === '/' ? '/' + entry.name : path + '/' + entry.name;
+ if (this._isExcluded(fullPath)) continue;
if (entry.type === 'file') {
if (this._isSystemFile(fullPath)) continue;
list.push({ path: fullPath, node: { type: 'file', content: fs.readFile(fullPath) || '' } });
@@ -385,7 +390,7 @@ class NeuralVFSModule {
// ── Nvfs Config ──
nvfsConfig(args) {
- if (args.length === 0) {
+ const listConfig = () => {
this.terminal.print('=== Neural VFS Config ===', 'info');
this.terminal.print(`fuzzy-limit: ${this._fuzzyLimit} (default: 10)`, '');
this.terminal.print(`tree-files: ${this._treeFiles} (default: 5)`, '');
@@ -393,17 +398,21 @@ class NeuralVFSModule {
this.terminal.print(`resolve-files: ${this._resolveFiles} (default: 20)`, '');
this.terminal.print(`deep-index: ${this._deepIndexEnabled ? 'on' : 'off'} (LLM-assisted concept extraction)`, '');
this.terminal.print(`deep-model: ${this._deepModel} (model for deep indexing)`, '');
+ this.terminal.print(`exclude-patterns: ${this._excludePatterns.length ? this._excludePatterns.join(', ') : '(none)'}`, '');
+ this.terminal.print(`exclude-dirs: ${this._excludeDirs.length ? this._excludeDirs.join(', ') : '(none)'}`, '');
+ this.terminal.print(`exclude-files: ${this._excludeFiles.length ? this._excludeFiles.join(', ') : '(none)'}`, '');
+ this.terminal.print(`include-only: ${this._includeOnly.length ? this._includeOnly.join(', ') : '(all)'}`, '');
this.terminal.print('Usage: nvfs-config <key> <value>', 'info');
- this.terminal.print('Keys: fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index (on|off), deep-model <name>', 'info');
- return;
- }
+ this.terminal.print('Keys: fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index (on|off), deep-model, exclude-patterns, exclude-dirs, exclude-files, include-only', 'info');
+ this.terminal.print('Lists are comma-separated. Use "+item" to append, "-item" to remove, or a plain comma list to replace.', 'info');
+ };
+ if (args.length === 0) { listConfig(); return; }
const key = args[0];
if (key === 'deep-index') {
const val = args[1];
if (val !== 'on' && val !== 'off') return this.terminal.print('deep-index must be "on" or "off"', 'warning');
this._deepIndexEnabled = val === 'on';
localStorage.setItem('webx11_nvfs_deep', this._deepIndexEnabled ? 'true' : 'false');
- // If turning off mid-queue, abort pending deep work
if (!this._deepIndexEnabled && this._deepIndexing) {
this._deepQueue = [];
this._deepIndexing = false;
@@ -424,13 +433,38 @@ class NeuralVFSModule {
this.terminal.print(`nvfs-config deep-model set to ${val}`, 'success');
return;
}
+ // List-type config keys
+ const listKeys = {
+ 'exclude-patterns': '_excludePatterns',
+ 'exclude-dirs': '_excludeDirs',
+ 'exclude-files': '_excludeFiles',
+ 'include-only': '_includeOnly'
+ };
+ if (listKeys[key]) {
+ const raw = args.slice(1).join(' ').trim();
+ if (!raw) { this.terminal.print(`${key}: ${this[listKeys[key]].join(', ') || '(empty)'}`, 'info'); return; }
+ let current = this[listKeys[key]];
+ if (raw.startsWith('+')) {
+ const add = raw.slice(1).split(',').map(s => s.trim()).filter(Boolean);
+ current = [...new Set([...current, ...add])];
+ } else if (raw.startsWith('-')) {
+ const rem = raw.slice(1).split(',').map(s => s.trim()).filter(Boolean);
+ current = current.filter(c => !rem.includes(c));
+ } else {
+ current = raw.split(',').map(s => s.trim()).filter(Boolean);
+ }
+ this[listKeys[key]] = current;
+ this._saveConfig();
+ this.terminal.print(`${key}: ${current.join(', ')}`, 'success');
+ return;
+ }
const val = parseInt(args[1]);
if (isNaN(val) || val < 1 || val > 200) return this.terminal.print('Value must be 1-200', 'warning');
if (key === 'fuzzy-limit') { this._fuzzyLimit = val; }
else if (key === 'tree-files') { this._treeFiles = val; }
else if (key === 'tree-concepts') { this._treeConcepts = val; }
else if (key === 'resolve-files') { this._resolveFiles = val; }
- else { return this.terminal.print(`Unknown key: ${key}. Valid: fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index (on|off), deep-model <name>`, 'warning'); }
+ else { return this.terminal.print(`Unknown key: ${key}. Valid: fuzzy-limit, tree-files, tree-concepts, resolve-files, deep-index (on|off), deep-model, exclude-patterns, exclude-dirs, exclude-files, include-only`, 'warning'); }
this._saveConfig();
this.terminal.print(`nvfs-config ${key} set to ${val}`, 'success');
}
@@ -497,6 +531,28 @@ class NeuralVFSModule {
return false;
}
+ _isExcluded(path) {
+ const normalized = path.startsWith('/') ? path : '/' + path;
+ // Explicit file or directory names
+ const excludeNames = ['agents', 'leases', 'agent-registry', 'lease-system'];
+ const parts = normalized.split('/').filter(Boolean);
+ for (const part of parts) {
+ if (excludeNames.includes(part.toLowerCase())) return true;
+ if (this._excludeDirs.includes(part)) return true;
+ if (this._excludeFiles.includes(part)) return true;
+ }
+ if (this._excludePatterns.some(p => {
+ try { return new RegExp(p).test(normalized); } catch (e) { return normalized.includes(p); }
+ })) return true;
+ if (this._includeOnly.length > 0) {
+ const isIncluded = this._includeOnly.some(p => {
+ try { return new RegExp(p).test(normalized); } catch (e) { return normalized.includes(p); }
+ });
+ if (!isIncluded) return true;
+ }
+ return false;
+ }
+
_contentHash(str) {
if (!str) return '';
let hash = 5381;
@@ -713,7 +769,7 @@ class NeuralVFSModule {
// ── Enum helpers for autocomplete ──
_getNvfsConfigKeys() {
- return ['fuzzy-limit', 'tree-files', 'tree-concepts', 'resolve-files', 'deep-index', 'deep-model'];
+ return ['fuzzy-limit', 'tree-files', 'tree-concepts', 'resolve-files', 'deep-index', 'deep-model', 'exclude-patterns', 'exclude-dirs', 'exclude-files', 'include-only'];
}
_getNvfsAliasActions() {