aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-modmgr.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/module-modmgr.js')
-rw-r--r--modules/core/module-modmgr.js34
1 files changed, 34 insertions, 0 deletions
diff --git a/modules/core/module-modmgr.js b/modules/core/module-modmgr.js
index 1104883..32bb2cc 100644
--- a/modules/core/module-modmgr.js
+++ b/modules/core/module-modmgr.js
@@ -5,6 +5,7 @@
return {
'modules': 'modules — Open the module manager GUI',
'listmods': 'listmods — List all loaded modules with status',
+ 'modules-list': 'modules-list [core|ext] — List all available modules from the module index (46 total)',
'loadmod': 'loadmod <url> — Load a module from a URL',
'removemod': 'removemod <name> — Remove a loaded module by name',
'startup-modules': 'startup-modules — Open the startup modules selector',
@@ -36,5 +37,38 @@
this.terminal.print(`${status} ${m.name}${badge}`);
});
};
+ this.commands['modules-list'] = async (args) => {
+ try {
+ const filter = (args[0] || '').toLowerCase();
+ const resp = await fetch('/spaces/newos4/modules-index.json?v=' + (localStorage.getItem('webx11_cache_ver') || ''));
+ if (!resp.ok) return this.terminal.print('Failed to load module index', 'error');
+ const idx = await resp.json();
+ let mods = Object.values(idx.modules);
+ if (filter === 'core' || filter === 'ext') mods = mods.filter(m => m.type === filter);
+ if (filter === 'infra') mods = mods.filter(m => m.layer === 'infrastructure');
+ const loaded = this.terminal.moduleManager.modules || {};
+ const loadedCount = Object.keys(loaded).length;
+ const byLayer = {};
+ mods.forEach(m => {
+ const l = m.layer || m.type || 'other';
+ if (!byLayer[l]) byLayer[l] = [];
+ byLayer[l].push(m);
+ });
+ const layerSummary = Object.entries(byLayer).map(([l, ms]) => `${ms.length} ${l}`).join(', ');
+ this.terminal.print(`📦 Module Index (${mods.length} modules: ${layerSummary} — ${loadedCount} loaded)`, 'header');
+ for (const [layer, layerMods] of Object.entries(byLayer)) {
+ this.terminal.print(` ── ${layer.toUpperCase()} (${layerMods.length}) ──`, 'info');
+ for (const m of layerMods) {
+ const isLoaded = loaded[m.class] ? '✓' : ' ';
+ const layerTag = m.layer === 'infrastructure' ? '[infra]' : m.type === 'core' ? '[core]' : '[ext]';
+ const cmdHint = m.commands.length > 0 ? ` ${m.commands.slice(0, 4).join(', ')}${m.commands.length > 4 ? '...' : ''}` : '';
+ const desc = m.description ? ` — ${m.description.substring(0, 60)}` : '';
+ this.terminal.print(` ${isLoaded} ${layerTag} ${m.name}${cmdHint}${desc}`, '');
+ }
+ }
+ } catch (e) {
+ this.terminal.print(`modules-list error: ${e.message}`, 'error');
+ }
+ };
}
}