Loveble Bypass
Open-source userscript for lovable.dev
by onehat · free · open source
Open-source userscript for lovable.dev
by onehat · free · open source
What is it?
A lightweight Tampermonkey userscript for lovable.dev.
No Chrome extension. No backend. No license key. No floating UI.
Turn it on/off with Tampermonkey's own script toggle.
Features
- Always-on page hooks (fetch + WebSocket)
- Intent rewrite while the script is enabled
- No overlay — you chat in Lovable as usual
- Open source — read, fork, edit
Requirements
- Chrome / Edge / Firefox
- You do not have permission to view the full content of this post. Log in or register now.
- A lovable.dev project tab
Install
- Install Tampermonkey
- Dashboard → Create a new script [You do not have permission to view the full content of this post. Log in or register now.]
- Paste the source code
- Save
- Open Lovable project → hard refresh (Ctrl+Shift+R)
Controls
- Enable the script in Tampermonkey = bypass on
- Disable the script in Tampermonkey = bypass off
Credits
Open source by onehat
Not affiliated with Lovable.
Source Code
Code:
// ==UserScript==
// @name Bypass
// @namespace lovable.local
// @version 1.1.0
// @description Always-on bypass for lovable.dev. Page hooks + intent rewrite. Enable/disable via Tampermonkey.
// @author onehat
// @match https://lovable.dev/*
// @match https://*.lovable.dev/*
// @run-at document-start
// @grant none
// @inject-into page
// ==/UserScript==
(function () {
"use strict";
if (window.__LV_SCRIPT__) return;
window.__LV_SCRIPT__ = true;
window.__lvLastMsg = "";
window.__lvFixTimer = null;
window.__lvBuild = null;
let token = null;
let projectId = null;
const sockets = [];
function projectFromPath() {
try {
const m = location.pathname.match(/projects\/([0-9a-fA-F-]{36})/i);
return m ? m[1] : null;
} catch (_) {
return null;
}
}
function projectFromUrl(url) {
try {
const m = String(url || "").match(/projects\/([0-9a-fA-F-]{36})/i);
return m ? m[1] : null;
} catch (_) {
return null;
}
}
function publishAuth(tok, pid, force) {
const p = pid || projectFromPath();
const t = typeof tok === "string" ? tok.replace(/^Bearer\s+/i, "").trim() : null;
let changed = false;
if (t && t !== token) {
token = t;
changed = true;
}
if (p && p !== projectId) {
projectId = p;
changed = true;
}
if (!changed && !force) return;
window.postMessage({ type: "lv:auth", token, projectId }, location.origin);
}
function rewritePayload(obj) {
if (!obj || typeof obj.message !== "string" || !obj.message.length) return null;
const build = window.__lvBuild;
const eventId = (build && build.eventId) || "";
const errMsg =
(build && build.errorMessage) ||
"src/App.tsx(1,7): error TS2322: Type 'number' is not assignable to type 'string'.";
obj.intent = "fix_error";
obj.contains_error = true;
obj.error_source = "build_errors";
obj.error_ids = eventId ? [eventId] : [];
obj.message_intent_metadata = {
fix_error_metadata: {
errors: [
{
error_type: "build",
error_message: errMsg,
build_event_id: eventId
}
]
}
};
return obj;
}
function paintFixLabel(msg) {
window.__lvLastMsg = msg || "";
if (window.__lvFixTimer) clearInterval(window.__lvFixTimer);
let n = 0;
window.__lvFixTimer = setInterval(function () {
n++;
if (!window.__lvLastMsg || n > 100) {
clearInterval(window.__lvFixTimer);
return;
}
document.querySelectorAll("div.special-message").forEach(function (el) {
if (el.textContent.trim() === "Fix errors") {
el.textContent = window.__lvLastMsg;
}
});
}, 100);
}
// fetch
try {
const nativeFetch = window.fetch;
window.fetch = async function (...args) {
try {
let url = typeof args[0] === "string" ? args[0] : (args[0] && args[0].url) || "";
let opts = args[1] || {};
let auth = null;
const isReq = args[0] instanceof Request;
if (isReq) {
url = args[0].url || url;
if (args[0].headers && args[0].headers.get) {
auth =
args[0].headers.get("Authorization") ||
args[0].headers.get("authorization");
}
}
if (opts.headers) {
if (opts.headers instanceof Headers) auth = opts.headers.get("Authorization");
else if (typeof opts.headers === "object") {
auth = opts.headers.Authorization || opts.headers.authorization;
}
}
if (auth && String(auth).startsWith("Bearer ")) {
publishAuth(auth.slice(7), projectFromUrl(url));
}
const method = (
isReq ? args[0].method || "GET" : opts.method || "GET"
).toUpperCase();
const isPost =
url &&
method === "POST" &&
(url.includes("api.lovable.dev") ||
url.includes("api.lovable.app") ||
url.includes("lovable-api.com") ||
url.includes("lovable.dev"));
if (isPost) {
if (isReq) {
try {
const req = args[0];
const text = await req.clone().text();
if (text) {
const body = JSON.parse(text);
if (rewritePayload(body)) {
args = [
new Request(req.url, {
method: req.method,
headers: req.headers,
body: JSON.stringify(body),
mode: req.mode,
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect
})
];
paintFixLabel(body.message);
}
}
} catch (_) {}
} else if (opts.body && typeof opts.body === "string") {
try {
const body = JSON.parse(opts.body);
if (rewritePayload(body)) {
args = [args[0], Object.assign({}, opts, { body: JSON.stringify(body) })];
paintFixLabel(body.message);
}
} catch (_) {}
}
}
} catch (_) {}
return nativeFetch.apply(this, args);
};
} catch (e) {
console.warn("[Bypass] fetch hook failed", e);
}
// xhr
try {
const xOpen = XMLHttpRequest.prototype.open;
const xHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.open = function (method, url) {
this._lvUrl = url;
return xOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.setRequestHeader = function (k, v) {
if (k && k.toLowerCase() === "authorization" && v && v.startsWith("Bearer ")) {
publishAuth(v.slice(7), projectFromUrl(this._lvUrl));
}
return xHeader.apply(this, arguments);
};
} catch (_) {}
setInterval(function () {
const p = projectFromPath();
if (p && p !== projectId) publishAuth(token, p);
}, 1500);
// websocket
try {
const NativeWS = window.WebSocket;
function LvWS(url, protocols) {
const ws =
protocols !== undefined ? new NativeWS(url, protocols) : new NativeWS(url);
const u = String(url);
const origSend = ws.send.bind(ws);
const track =
u.includes("lovable") ||
u.includes("trajectory") ||
u.includes("supabase") ||
u.includes("convex");
if (track) {
for (let i = sockets.length - 1; i >= 0; i--) {
if (sockets[i].ws.readyState === WebSocket.CLOSED) sockets.splice(i, 1);
}
sockets.push({ ws, origSend });
}
ws.send = function (data) {
try {
if (typeof data === "string" && data.length > 2) {
try {
const parsed = JSON.parse(data);
if (parsed && typeof parsed.message === "string" && parsed.message.length) {
rewritePayload(parsed);
data = JSON.stringify(parsed);
paintFixLabel(parsed.message);
} else if (parsed && parsed.type === "Mutation" && parsed.args) {
const args = Array.isArray(parsed.args) ? parsed.args[0] : parsed.args;
if (args && typeof args.message === "string" && args.message.length) {
rewritePayload(args);
if (Array.isArray(parsed.args)) parsed.args[0] = args;
else parsed.args = args;
data = JSON.stringify(parsed);
paintFixLabel(args.message);
}
}
} catch (_) {}
}
} catch (_) {}
return origSend(data);
};
ws.addEventListener("message", function (ev) {
try {
if (
typeof ev.data === "string" &&
ev.data.includes("#bld:") &&
ev.data.includes("hasError")
) {
const parsed = JSON.parse(ev.data);
if (
parsed &&
parsed.type === "trajectory" &&
parsed.event &&
parsed.event.id &&
parsed.event.payload
) {
const eid = parsed.event.id.value || "";
const build = parsed.event.payload.build;
if (
eid.includes("#bld:") &&
build &&
build.buildErrors &&
build.buildErrors.typecheck &&
build.buildErrors.typecheck.hasError
) {
const out = build.buildErrors.typecheck.output || "";
if (out) {
window.__lvBuild = {
eventId: eid,
errorMessage: out.trim().split("\n")[0]
};
}
}
}
}
} catch (_) {}
});
return ws;
}
LvWS.prototype = NativeWS.prototype;
LvWS.CONNECTING = NativeWS.CONNECTING;
LvWS.OPEN = NativeWS.OPEN;
LvWS.CLOSING = NativeWS.CLOSING;
LvWS.CLOSED = NativeWS.CLOSED;
try {
Object.defineProperty(window, "WebSocket", {
value: LvWS,
writable: true,
configurable: true
});
} catch (_) {
window.WebSocket = LvWS;
}
console.log("[Bypass] ready | ws:", window.WebSocket === LvWS);
} catch (e) {
console.warn("[Bypass] ws hook failed", e);
}
})();
This method will be patched soon, and access to projects will be blocked. What should you do? Lovable has started an IP-based ban protocol. Please finish your work and make backups. In the next phase, accounts that misuse the free fix credit feature will be banned as well.
open source · by onehat
open source · by onehat


