elffuss-code / js /telemetry.js
KikoCis's picture
Elffuss Code — browser IDE with a local AI agent (WebGPU)
b30b7c5 verified
Raw
History Blame Contribute Delete
2.59 kB
// Buzón opt-in de errores/feedback. Apagado por defecto — la promesa de
// «nada sale de tu máquina» sigue siendo cierta salvo que el usuario decida
// lo contrario en Ajustes. Cuando está activo:
// - errores no capturados (window.onerror / unhandledrejection) y los
// puntos concretos del código que llaman a reportError() se mandan a
// /proxy/report (mismo origen, vía el proxy compartido de Elffuss)
// - sendFeedback() manda texto libre que el usuario escriba a propósito
// Nunca se manda código ni contenido del proyecto — solo el mensaje técnico,
// la pila, la URL y el user-agent. Sin cola ni reintentos: si el envío
// falla, se descarta sin más (evita que un fallo de red se convierta en
// almacenamiento sin límite).
let appName = 'elffuss';
let enabled = false;
let hooked = false;
const storageKey = () => 'elffuss.telemetry.' + appName;
export function isEnabled() { return enabled; }
export function setEnabled(v) {
enabled = !!v;
try { localStorage.setItem(storageKey(), enabled ? '1' : '0'); } catch { /* localStorage lleno/bloqueado */ }
if (enabled) hookGlobalErrors();
}
async function post(kind, message, opts = {}) {
if (!enabled) return;
try {
await fetch('/proxy/report', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
app: appName, kind, message: String(message ?? '').slice(0, 2000),
stack: String(opts.stack || '').slice(0, 4000),
url: location.href, userAgent: navigator.userAgent,
extra: String(opts.extra || '').slice(0, 2000),
}),
});
} catch { /* sin conexión o proxy caído: se descarta, no hay reintento */ }
}
export function reportError(message, opts = {}) { return post('error', message, opts); }
export function sendFeedback(text) { return post('feedback', text); }
function hookGlobalErrors() {
if (hooked) return;
hooked = true;
window.addEventListener('error', e => {
reportError(e.message || String(e.error) || 'error', { stack: e.error?.stack || '' });
});
window.addEventListener('unhandledrejection', e => {
const r = e.reason;
reportError('unhandledrejection: ' + (r?.message || r), { stack: r?.stack || '' });
});
}
// Llamar UNA vez al arrancar, con el nombre de la app (para distinguir
// elffuss-code de elffuss-claw en los informes) — lee la preferencia guardada.
export function init(name) {
appName = name || appName;
try { enabled = localStorage.getItem(storageKey()) === '1'; } catch { enabled = false; }
if (enabled) hookGlobalErrors();
}