diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/core/core-bundle.js | 52 | ||||
| -rw-r--r-- | modules/core/module-debug-supervisor.js | 52 | ||||
| -rw-r--r-- | modules/core/module-loader.js | 2 |
3 files changed, 105 insertions, 1 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js index 449a80c..025572c 100644 --- a/modules/core/core-bundle.js +++ b/modules/core/core-bundle.js @@ -19859,6 +19859,58 @@ class DebugSupervisorModule { } this._scheduleSave(); + + // v4.6.38 (A5): auto-file fatal/error-class failures, max 3 per day, deduped by hash. + if (classification.severity === 'fatal' || classification.severity === 'error') { + this._maybeAutoFile({ hash, message, source, type: classification.type, severity: classification.severity }); + } + } + + _maybeAutoFile(e) { + try { this._maybeAutoFileInner(e); } catch (_e) {} + } + + _maybeAutoFileInner(e) { + try { if (localStorage.getItem('webx11_autoreport') === 'off') return; } catch (_e) {} + + const today = new Date().toISOString().slice(0, 10); + let state = { day: today, count: 0, hashes: [] }; + try { + const raw = JSON.parse(localStorage.getItem('webx11_autoreport_day') || 'null'); + if (raw && raw.day === today && Array.isArray(raw.hashes)) state = raw; + } catch (_e) {} + + if (state.count >= 3) return; // daily quota + if (state.hashes.indexOf(e.hash) !== -1) return; // one report per distinct error + state.count++; + state.hashes.push(e.hash); + try { localStorage.setItem('webx11_autoreport_day', JSON.stringify(state)); } catch (_e) {} + + const payload = { + title: 'Auto: ' + String(e.message || 'unknown error').slice(0, 120), + body: 'Automatically filed by the debug supervisor (no user action).', + diagnostics: { + version: (typeof window !== 'undefined' && window.NEWOS4_VERSION) || 'unknown', + url: (typeof location !== 'undefined') ? location.href : '', + ua: (typeof navigator !== 'undefined') ? navigator.userAgent : '', + auto: true, + errors: [{ + message: String(e.message || '').slice(0, 300), + source: String(e.source || '').slice(0, 200), + type: e.type, + severity: e.severity, + count: 1, + }], + }, + }; + try { + // /api/debug/* is excluded from the fetch interceptor, so a failure here cannot loop. + fetch('/spaces/newos4/api/debug/report.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }).catch(function () {}); + } catch (_e) {} } // ── Clustering (Jaccard similarity) ── diff --git a/modules/core/module-debug-supervisor.js b/modules/core/module-debug-supervisor.js index ffe08a8..959d162 100644 --- a/modules/core/module-debug-supervisor.js +++ b/modules/core/module-debug-supervisor.js @@ -315,6 +315,58 @@ class DebugSupervisorModule { } this._scheduleSave(); + + // v4.6.38 (A5): auto-file fatal/error-class failures, max 3 per day, deduped by hash. + if (classification.severity === 'fatal' || classification.severity === 'error') { + this._maybeAutoFile({ hash, message, source, type: classification.type, severity: classification.severity }); + } + } + + _maybeAutoFile(e) { + try { this._maybeAutoFileInner(e); } catch (_e) {} + } + + _maybeAutoFileInner(e) { + try { if (localStorage.getItem('webx11_autoreport') === 'off') return; } catch (_e) {} + + const today = new Date().toISOString().slice(0, 10); + let state = { day: today, count: 0, hashes: [] }; + try { + const raw = JSON.parse(localStorage.getItem('webx11_autoreport_day') || 'null'); + if (raw && raw.day === today && Array.isArray(raw.hashes)) state = raw; + } catch (_e) {} + + if (state.count >= 3) return; // daily quota + if (state.hashes.indexOf(e.hash) !== -1) return; // one report per distinct error + state.count++; + state.hashes.push(e.hash); + try { localStorage.setItem('webx11_autoreport_day', JSON.stringify(state)); } catch (_e) {} + + const payload = { + title: 'Auto: ' + String(e.message || 'unknown error').slice(0, 120), + body: 'Automatically filed by the debug supervisor (no user action).', + diagnostics: { + version: (typeof window !== 'undefined' && window.NEWOS4_VERSION) || 'unknown', + url: (typeof location !== 'undefined') ? location.href : '', + ua: (typeof navigator !== 'undefined') ? navigator.userAgent : '', + auto: true, + errors: [{ + message: String(e.message || '').slice(0, 300), + source: String(e.source || '').slice(0, 200), + type: e.type, + severity: e.severity, + count: 1, + }], + }, + }; + try { + // /api/debug/* is excluded from the fetch interceptor, so a failure here cannot loop. + fetch('/spaces/newos4/api/debug/report.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(payload), + }).catch(function () {}); + } catch (_e) {} } // ── Clustering (Jaccard similarity) ── diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 05a63e9..f9b4c9b 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -4,7 +4,7 @@ // Core module bundle loaded synchronously in main.html. // This loader only handles version cache-busting, splash, terminal init, and optional ext modules. - const LATEST_VER = 'v4.6.37'; + const LATEST_VER = 'v4.6.38'; const CACHE = '?v=' + LATEST_VER; const stored = localStorage.getItem('webx11_cache_ver'); if (stored !== LATEST_VER) { |