aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.html6
-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
4 files changed, 108 insertions, 4 deletions
diff --git a/main.html b/main.html
index 4bd5701..1a0c622 100644
--- a/main.html
+++ b/main.html
@@ -1349,13 +1349,13 @@
</script>
<!-- v4.5.63: A2A scratchpad fixes + agent-register arg fix -->
-<script src="modules/core/core-bundle.js?v=v4.6.37"></script>
+<script src="modules/core/core-bundle.js?v=v4.6.38"></script>
<!-- Async dependency-ordered module loader now only initializes terminal and loads optional ext modules -->
-<script src="modules/core/module-loader.js?v=v4.6.37"></script>
+<script src="modules/core/module-loader.js?v=v4.6.38"></script>
<!-- Critical ext bundle loads AFTER webx11 exists so registerModule calls work -->
-<script src="modules/ext/critical-ext-bundle.js?v=v4.6.37"></script>
+<script src="modules/ext/critical-ext-bundle.js?v=v4.6.38"></script>
<script>
// ═══ ONE TRUE VERSION SOURCE ═══
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) {