aboutsummaryrefslogtreecommitdiff
path: root/modules/core
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core')
-rw-r--r--modules/core/core-bundle.js52
-rw-r--r--modules/core/module-debug-supervisor.js52
-rw-r--r--modules/core/module-loader.js2
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) {