aboutsummaryrefslogtreecommitdiff
path: root/modules/core/terminal.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/terminal.js')
-rw-r--r--modules/core/terminal.js60
1 files changed, 47 insertions, 13 deletions
diff --git a/modules/core/terminal.js b/modules/core/terminal.js
index 647060a..1aad5bb 100644
--- a/modules/core/terminal.js
+++ b/modules/core/terminal.js
@@ -857,10 +857,19 @@
}
_autoRestoreSession() {
try {
+ const lastReset = parseInt(localStorage.getItem('webx11_last_reset') || '0', 10);
this.fs.mkdirRecursive('_sessions');
const autoSession = this.fs.readFile('_sessions/_auto.json');
if (autoSession) {
const data = JSON.parse(autoSession);
+ const savedAt = data.savedAt || 0;
+ // v4.5.47: skip restoring backups created before the last reset
+ if (lastReset && savedAt && savedAt < lastReset) {
+ this.fs.deleteFile('_sessions/_auto.json');
+ this.fs.deleteFile('_sessions/_auto-context.json');
+ this.print('↻ Skipped stale auto-session backup (older than last reset)', 'info');
+ return;
+ }
if (data && data.fsRoot) {
this.fs.root = data.fsRoot;
this.fs.currentPath = data.currentPath || [];
@@ -873,6 +882,9 @@
localStorage.setItem('webx11_ai_context', aiCtx);
}
} catch (e) {}
+ // v4.5.47: delete backup after successful restore so reset-mem doesn't get resurrected
+ this.fs.deleteFile('_sessions/_auto.json');
+ this.fs.deleteFile('_sessions/_auto-context.json');
}
}
} catch (e) {
@@ -1145,6 +1157,14 @@
this._safeRegister('WorldModelModule', 'world model');
this._safeRegister('ServerMonitorModule', 'server monitor');
this._safeRegister('SimpleGUIModule', 'simple GUI builder');
+ // v4.5.47: Critical ext modules promoted to boot path
+ this._safeRegister('EditorModule', 'editor');
+ this._safeRegister('ShellModule', 'shell');
+ this._safeRegister('AliasModule', 'aliases');
+ this._safeRegister('FinderModule', 'finder');
+ this._safeRegister('FileManagerModule', 'file manager');
+ this._safeRegister('DiffModule', 'diff');
+ this._safeRegister('BusyBoxModule', 'busybox');
}
_initRegisteredModules() {
for (const [name, mod] of Object.entries(this.moduleManager.modules)) {
@@ -1221,21 +1241,35 @@
} catch (e) {}
}
async _loadExtModules(filterKeys) {
- const autoLoadKeys = filterKeys || ['calc', 'voice', 'cron', 'theme', 'wpm', 'mindmap', 'webdav', 'skill-pack-core', 'editor', 'diff', 'alias', 'finder', 'filemgr', 'cryptogzip', 'shell', 'tutorial', 'busybox', 'floating', 'console'];
+ const autoLoadKeys = filterKeys || ['calc', 'voice', 'cron', 'theme', 'wpm', 'mindmap', 'webdav', 'skill-pack-core', 'cryptogzip', 'tutorial', 'floating', 'console'];
const cacheVer = localStorage.getItem('webx11_cache_ver') || '2026-05-27-14';
- try {
- const res = await fetch('packages.json?v=' + cacheVer);
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
- const index = await res.json();
- for (const key of autoLoadKeys) {
- const pkg = index.packages[key];
- if (pkg) {
- const url = pkg.url + (pkg.url.includes('?') ? '&v=' : '?v=') + cacheVer;
- await this.moduleManager.loadModuleFromURL(url);
- }
+ let index = null;
+ let lastErr = null;
+ // v4.5.47: retry packages.json fetch up to 3 times
+ for (let attempt = 1; attempt <= 3; attempt++) {
+ try {
+ const res = await fetch('packages.json?v=' + cacheVer);
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
+ index = await res.json();
+ lastErr = null;
+ break;
+ } catch (err) {
+ lastErr = err;
+ if (attempt < 3) await new Promise(r => setTimeout(r, 300 * attempt));
+ }
+ }
+
+ if (!index) {
+ this.print(`Failed to auto-load ext modules: ${lastErr ? lastErr.message : 'unknown error'}`, 'error');
+ return;
+ }
+
+ for (const key of autoLoadKeys) {
+ const pkg = index.packages[key];
+ if (pkg) {
+ const url = pkg.url + (pkg.url.includes('?') ? '&v=' : '?v=') + cacheVer;
+ await this.moduleManager.loadModuleFromURL(url);
}
- } catch (err) {
- this.print(`Failed to auto-load ext modules: ${err.message}`, 'error');
}
}
async reloadPersistedModules() {