diff options
| author | Agando <roduccomm@gmail.com> | 2026-06-17 06:01:20 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-06-17 06:01:20 +0200 |
| commit | cebacc27a48168e666679018f8e27156d12d4527 (patch) | |
| tree | b306d33b67b9d8c84bd9b9c16b1e91ee217628a6 /modules/core/module-fs.js | |
| parent | 6aa24b976952a698c673d350977721b27193183d (diff) | |
auto: 2026-06-17_06:01 changes
Diffstat (limited to 'modules/core/module-fs.js')
| -rw-r--r-- | modules/core/module-fs.js | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/modules/core/module-fs.js b/modules/core/module-fs.js index 309010d..ab8fd99 100644 --- a/modules/core/module-fs.js +++ b/modules/core/module-fs.js @@ -403,24 +403,18 @@ class FileSystemModule { 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 = { + // v2: metadata-only — VFS is persisted independently in localStorage + const manifest = { type: 'session', + version: 2, savedAt: new Date().toISOString(), - fsRoot: fsRoot, currentPath: this.terminal.fs.currentPath, - version: 1 + terminalLines: this.terminal._historyBuffer ? this.terminal._historyBuffer.slice(-50) : [] }; const filePath = '_sessions/' + name + '.json'; this.terminal.fs.mkdirRecursive('_sessions'); - this.terminal.fs.writeFile(filePath, JSON.stringify(snapshot, null, 2)); - this.terminal.print('Session saved: ' + name, 'success'); + this.terminal.fs.writeFile(filePath, JSON.stringify(manifest)); + this.terminal.print('Session saved: ' + name + ' (' + (manifest.terminalLines.length || 0) + ' history lines)', 'success'); }; this.commands['session-load'] = (args) => { if (!args[0]) return this.terminal.print('Usage: session-load <name>', 'warning'); @@ -429,11 +423,28 @@ class FileSystemModule { if (content === null) return this.terminal.print('Session not found: ' + args[0], 'error'); try { const session = JSON.parse(content); - if (!session || session.type !== 'session' || !session.fsRoot) { + if (!session || session.type !== 'session') { return this.terminal.print('Invalid session file: ' + args[0], 'error'); } - this.terminal.fs.root = session.fsRoot; - this.terminal.fs.currentPath = session.currentPath || []; + if (session.version === 2) { + // v2: metadata-only restore — keep existing VFS, just restore path + terminal history + this.terminal.fs.currentPath = session.currentPath || []; + if (session.terminalLines && Array.isArray(session.terminalLines) && this.terminal._historyBuffer) { + this.terminal._historyBuffer = session.terminalLines.slice(-50); + // Re-render last few lines for context + this.terminal.outputContainer.innerHTML = ''; + session.terminalLines.forEach(line => { + const text = typeof line === 'string' ? line : (line.l || ''); + const type = typeof line === 'object' ? (line.t || '') : ''; + this.terminal.print(text, type); + }); + } + } else { + // v1: full VFS restore (legacy) + if (!session.fsRoot) return this.terminal.print('Invalid session file', 'error'); + this.terminal.fs.root = session.fsRoot; + this.terminal.fs.currentPath = session.currentPath || []; + } this.terminal.fs.saveToStorage(); this.terminal.updatePrompt(); this.terminal.print('Session loaded: ' + args[0] + ' (' + new Date(session.savedAt).toLocaleString() + ')', 'success'); @@ -453,8 +464,13 @@ class FileSystemModule { const content = JSON.parse(this.terminal.fs.readFile('_sessions/' + f.name)); const label = f.name.replace('.json', ''); const date = content.savedAt ? new Date(content.savedAt).toLocaleString() : 'unknown'; - const fileCount = content.fsRoot ? Object.keys(content.fsRoot.content || {}).length : 0; - this.terminal.print(' ' + label + ' (' + fileCount + ' items, ' + date + ')'); + if (content.version === 2) { + const lines = content.terminalLines ? content.terminalLines.length : 0; + this.terminal.print(' ' + label + ' (' + lines + ' history lines, ' + date + ')'); + } else { + const fileCount = content.fsRoot ? Object.keys(content.fsRoot.content || {}).length : 0; + this.terminal.print(' ' + label + ' (' + fileCount + ' items, ' + date + ')'); + } } catch (e) { this.terminal.print(' ' + f.name.replace('.json', '') + ' (corrupt)'); } @@ -497,12 +513,30 @@ class FileSystemModule { reader.onload = (evt) => { try { const session = JSON.parse(evt.target.result); - if (!session || session.type !== 'session' || !session.fsRoot) { + if (!session || session.type !== 'session') { this.terminal.print('Invalid session file (not a valid session export)', 'error'); return; } - this.terminal.fs.root = session.fsRoot; - this.terminal.fs.currentPath = session.currentPath || []; + if (session.version === 2) { + // v2: metadata-only — keep existing VFS, restore path + this.terminal.fs.currentPath = session.currentPath || []; + if (session.terminalLines && Array.isArray(session.terminalLines) && this.terminal._historyBuffer) { + this.terminal._historyBuffer = session.terminalLines.slice(-50); + this.terminal.outputContainer.innerHTML = ''; + session.terminalLines.forEach(line => { + const text = typeof line === 'string' ? line : (line.l || ''); + const type = typeof line === 'object' ? (line.t || '') : ''; + this.terminal.print(text, type); + }); + } + } else { + if (!session.fsRoot) { + this.terminal.print('Invalid session file (not a valid session export)', 'error'); + return; + } + this.terminal.fs.root = session.fsRoot; + this.terminal.fs.currentPath = session.currentPath || []; + } this.terminal.fs.saveToStorage(); this.terminal.updatePrompt(); this.terminal.print('Session imported: ' + file.name + ' (' + (session.savedAt ? new Date(session.savedAt).toLocaleString() : 'unknown date') + ')', 'success'); |