aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-fs.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/module-fs.js')
-rw-r--r--modules/core/module-fs.js52
1 files changed, 51 insertions, 1 deletions
diff --git a/modules/core/module-fs.js b/modules/core/module-fs.js
index 160dccc..c2f29c4 100644
--- a/modules/core/module-fs.js
+++ b/modules/core/module-fs.js
@@ -351,15 +351,65 @@ class FileSystemModule {
setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 2000);
this.terminal.print('Exported VFS to webx11-filesystem-' + dateStr + '.json', 'success');
};
+ this.commands['vfs-size'] = () => {
+ try {
+ const json = JSON.stringify(this.terminal.fs.root);
+ const totalSize = (json.length / 1024 / 1024).toFixed(2);
+ const root = this.terminal.fs.root;
+ const sizeMap = [];
+ function walk(node, path) {
+ if (!node || !node.content) return;
+ for (const [name, child] of Object.entries(node.content)) {
+ const fullPath = path + '/' + name;
+ if (child.type === 'file') {
+ const size = (child.content ? child.content.length : 0);
+ sizeMap.push({ path: fullPath, size, sizeKB: (size / 1024).toFixed(1) });
+ } else if (child.type === 'dir') {
+ walk(child, fullPath);
+ }
+ }
+ }
+ walk(root, '');
+ sizeMap.sort((a, b) => b.size - a.size);
+ const totalFiles = sizeMap.length;
+ const top5 = sizeMap.slice(0, 5);
+ this.terminal.print('📊 VFS Size Report', 'text-muted');
+ this.terminal.print(' Total: ' + totalSize + ' MB across ' + totalFiles + ' files');
+ this.terminal.print(' Largest:');
+ top5.forEach((f, i) => {
+ this.terminal.print(' ' + (i + 1) + '. ' + f.path + ' — ' + f.sizeKB + ' KB');
+ });
+ // Show system dir sizes
+ const sysDirs = ['/_snapshots', '/_sessions', '/.trash'];
+ for (const dir of sysDirs) {
+ const dirNode = this.terminal.fs.readDir(dir);
+ if (dirNode) {
+ const cnt = dirNode.length;
+ // estimate dir size
+ const dirSize = JSON.stringify(dirNode).length;
+ this.terminal.print(' ' + dir + ': ' + cnt + ' files, ~' + (dirSize / 1024).toFixed(1) + ' KB', dirSize > 102400 ? 'warning' : 'text-muted');
+ }
+ }
+ } catch (e) {
+ this.terminal.print('vfs-size error: ' + e.message, 'error');
+ }
+ };
// Session commands (save/load/export/import)
this.commands['session-save'] = (args) => {
if (!args[0]) return this.terminal.print('Usage: session-save <name>', 'warning');
const name = args[0].replace(/[^a-zA-Z0-9_-]/g, '_');
+ // Strip system dirs to avoid recursive bloat in snapshots
+ const fsRoot = JSON.parse(JSON.stringify(this.terminal.fs.root));
+ if (fsRoot && fsRoot.content) {
+ delete fsRoot.content['_sessions'];
+ delete fsRoot.content['_snapshots'];
+ delete fsRoot.content['.trash'];
+ }
const snapshot = {
type: 'session',
savedAt: new Date().toISOString(),
- fsRoot: this.terminal.fs.root,
+ fsRoot: fsRoot,
currentPath: this.terminal.fs.currentPath,
version: 1
};