Something went wrong. Try again.
this post sux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152/* * BiDi probe — talks WebDriver BiDi to a Firefox-family browser started with * --remote-debugging-port 9222. Installs the sux zip (if asked), finds the * bsky.app tab, reloads it, captures console output, and inspects the live * page state (interceptor flag, __suxDiag, feed DOM anchors, xrpc calls). * * node scripts/bidi-probe.mjs [--install] */const PORT = 9222;const ZIP = new URL("../web-ext-artifacts/sux_jev_feed_filter-0.1.0.zip", import.meta.url).pathname;const DO_INSTALL = process.argv.includes("--install");
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const ws = new WebSocket(`ws://localhost:${PORT}/session`);let seq = 0;const pending = new Map();const events = [];
function send(method, params = {}, sessionId = null, timeoutMs = 20000) { const id = ++seq; const msg = { id, method, params }; if (sessionId) msg.sessionId = sessionId; ws.send(JSON.stringify(msg)); return new Promise((resolve, reject) => { const t = setTimeout(() => { pending.delete(id); reject(new Error(`timeout: ${method}`)); }, timeoutMs); pending.set(id, { resolve, reject, t }); });}
await new Promise((res, rej) => { ws.onopen = res; ws.onerror = () => rej(new Error("could not connect — is Twilight running with --remote-debugging-port 9222?"));});
ws.onmessage = (ev) => { const msg = JSON.parse(ev.data); if (msg.id && pending.has(msg.id)) { const p = pending.get(msg.id); pending.delete(msg.id); clearTimeout(p.t); if (msg.type === "success") p.resolve(msg.result); else p.reject(new Error(`${msg.error.error}: ${msg.error.message}`)); } else if (msg.type === "event") { events.push(msg); }};
const out = {};const { sessionId } = await send("session.new", { capabilities: {} });out.session = sessionId;await send("session.subscribe", { events: ["log.entryAdded"] }, sessionId).catch(() => {});
if (DO_INSTALL) { try { const r = await send( "webExtension.install", { extensionData: { type: "path", path: ZIP } }, sessionId, 30000 ); out.install = { ok: true, extension: r.extension }; } catch (e) { out.install = { ok: false, error: e.message }; }}
// find the bsky.app tab, creating one if absentlet tree = await send("browsingContext.getTree", {}, sessionId);let ctx = tree.contexts.find((c) => (c.url || "").includes("bsky.app"));if (!ctx) { ctx = await send("browsingContext.create", { type: "tab", url: "https://bsky.app/" }, sessionId); await sleep(9000);}out.context = { id: ctx.context, url: ctx.url || "" };
// reload to re-run the content script, then let it workawait send("browsingContext.reload", { context: ctx.context, ignoreCache: true }, sessionId).catch((e) => { out.reloadError = e.message;});await sleep(10000);
async function evalIn(expression) { const r = await send( "script.evaluate", { expression, target: { context: ctx.context }, awaitPromise: true, resultOwnership: "none" }, sessionId ); if (r.result.type === "object" && "value" in r.result) return r.result.value; if ("value" in r.result) return r.result.value; return r.result;}
out.probe = await evalIn(`(() => { const norm = (href) => { if (!href) return null; const h = href.replace(/^https?:\\/\\/[^/]+/i, "").split("?")[0].split("#")[0]; const m = h.match(/^\\/profile\\/([^/]+)\\/post\\/([^/]+)\\/?$/); return m ? "profile/" + m[1].toLowerCase() + "/post/" + m[2] : null; }; const anchors = Array.from(document.querySelectorAll('a[href*="/post/"]')); const valid = anchors.filter((a) => norm(a.getAttribute("href"))); const itemContainer = (anchor) => { let node = anchor.parentElement; for (let depth = 0; node && node !== document.body && depth < 12; depth++) { const parent = node.parentElement; if (parent) { const sib = parent.querySelectorAll('a[href*="/post/"]'); for (let i = 0; i < sib.length; i++) if (!node.contains(sib[i])) return node; } node = parent; } return anchor.parentElement; }; const first = valid.slice(0, 5).map((a) => { const c = itemContainer(a); return { href: a.getAttribute("href").slice(0, 90), container: c.tagName + "." + String(c.className).split(" ").slice(0, 3).join("."), depth: (() => { let d = 0, n = a; while (n && n !== document.body) { d++; n = n.parentElement; } return d; })(), }; }); const xrpc = performance.getEntriesByType("resource").map((r) => r.name).filter((n) => n.includes("/xrpc/")).map((n) => n.split("?")[0].slice(-60)).slice(-12); return { url: location.href, ready: document.readyState, interceptor: !!window.__suxInterceptor, diag: window.__suxDiag || null, anchorCount: anchors.length, validAnchors: valid.length, firstContainers: first, xrpcCalls: xrpc, feedText: (document.body.innerText || "").slice(0, 200), };})()`);
await sleep(1500);out.console = events .filter((e) => e.method === "log.entryAdded") .map((e) => e.params) .filter((p) => p.text && (p.text.includes("sux") || p.level === "error")) .slice(-30) .map((p) => `[${p.level}] ${p.text} (${p.source?.realm || ""})`);
console.log(JSON.stringify(out, null, 2));try { await send("session.end", {}, sessionId, 5000); } catch { /* leave session */ }ws.close();process.exit(0);