From 7c03cc01de94a4b64e3c4de39f6d44e401b7db60 Mon Sep 17 00:00:00 2001 From: Agando Date: Sun, 18 Oct 2026 17:01:52 +0200 Subject: newOS4 v4.6.37: bug-report pipeline (report.php, bug command, HTML generator, telemetry-loop fix) --- modules/core/module-system.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'modules/core/module-system.js') diff --git a/modules/core/module-system.js b/modules/core/module-system.js index 9dee38c..1a9ad05 100644 --- a/modules/core/module-system.js +++ b/modules/core/module-system.js @@ -15,6 +15,7 @@ 'errors': 'errors [n] — Show last n ERROR log entries (default: 20)', 'doctor': 'doctor — Run all health checks, rank issues, show top 3 warnings', 'bug-report': 'bug-report — Generate a markdown bug report to /tmp/ for debugging', + 'bug': 'bug — File a structured bug report (stored server-side, visible in BUG-REPORT.html)', 'preview': 'preview <file.html> — Render an HTML file from the VFS in a preview pane', 'reset': 'reset [mem|vfs|config|all] — Global reset command (default: mem)', 'factory-reset': 'factory-reset — Alias for reset all', @@ -305,6 +306,48 @@ } }; + // v4.6.37: bug — file a structured report to the backend (Part A) + this.commands['bug'] = async (args) => { + const title = (args || []).join(' ').trim() || 'Untitled bug report'; + const diag = { + version: window.NEWOS4_VERSION || 'unknown', + url: location.href, + ua: navigator.userAgent, + online: navigator.onLine, + modules: Object.keys(this.terminal.moduleManager.modules).length, + errors: [], + }; + try { + const raw = JSON.parse(localStorage.getItem('webx11_debug_db') || '[]'); + const list = Array.isArray(raw) ? raw : (raw.errors || []); + diag.errors = list.slice(-20).map(e => ({ + message: String(e.message || e.msg || '').slice(0, 300), + source: String(e.source || e.url || '').slice(0, 200), + count: Number(e.count) || 1, + })); + } catch (_e) {} + try { + diag.recent_commands = JSON.parse(localStorage.getItem('webx11_command_history') || '[]') + .slice(-10) + .map(c => String(c).replace(/(password|token|secret|api[_-]?key)\S*/ig, '$1:[redacted]')); + } catch (_e) {} + + this.terminal.print('📮 Filing bug report…', 'info'); + let res = null, err = null; + try { + const r = await fetch('/spaces/newos4/api/debug/report.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ title, diagnostics: diag }), + }); + res = await r.json(); + if (!r.ok) err = res.error || ('HTTP ' + r.status); + } catch (e) { err = e.message; } + if (err) { this.terminal.print('❌ Report failed: ' + err, 'error'); return; } + this.terminal.print('✅ Report filed: ' + res.id + (res.duplicate ? ' (already known)' : ''), 'success'); + this.terminal.print(' View: /spaces/newos4/downloads/bugs/BUG-REPORT.html', 'info'); + }; + this.commands['preview'] = (args) => this.terminal.openPreview(args); // v4.5.64: reset — unified reset command superseding factory-reset, reset-vfs, reset-mem, config-reset -- cgit v1.2.3