fix(tools): make live-view auto-spawn serve for zero-config watching

The viewer now starts obscura serve itself if nothing is
listening, so any way of launching it works: running the tool
alone, through the obscura-serve wrapper, or indirectly when the
MCP bridge spawns serve for an agent session. The bridge also
starts the viewer alongside serve so any MCP or Playwright client
automatically gets a live tab at http://localhost:8080 without
extra steps.
This commit is contained in:
Suydev committed 2026-08-23 13:46:38 +04:00
1 parent 598a6d55d1
commit e78d011efe
1 file changed
+32
+32
View File
@@ -21,6 +21,7 @@
// back off when it is idle, so watching feels live without burning CPU. // back off when it is idle, so watching feels live without burning CPU.
import http from "node:http"; import http from "node:http";
import { spawn } from "node:child_process";
const cdpPort = process.argv[2] ?? 9222; const cdpPort = process.argv[2] ?? 9222;
const httpPort = Number(process.argv[3] ?? 8080); const httpPort = Number(process.argv[3] ?? 8080);
@@ -28,6 +29,36 @@ const FAST_MS = 250; // capture cadence right after a visible change
const IDLE_MS = 1500; // capture cadence while nothing changes const IDLE_MS = 1500; // capture cadence while nothing changes
const MIN_FRAME_BYTES = 100; // ignore blank placeholder frames const MIN_FRAME_BYTES = 100; // ignore blank placeholder frames
async function ensureServe() {
try {
const r = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);
if (r.ok) return;
} catch {}
// try spawning obscura directly (works in normal installs and in proot ubuntu)
try {
const child = spawn("obscura", ["serve", "--port", String(cdpPort)], {
stdio: "ignore",
detached: true,
});
child.unref();
} catch {}
// fallback for Termux proot setups where obscura lives inside ubuntu
try {
const child = spawn("proot-distro", ["login", "ubuntu", "--", "/usr/local/bin/obscura", "serve", "--port", String(cdpPort)], {
stdio: "ignore",
detached: true,
});
child.unref();
} catch {}
for (let i = 0; i < 30; i++) {
await new Promise((r) => setTimeout(r, 1000));
try {
const r = await fetch(`http://127.0.0.1:${cdpPort}/json/version`);
if (r.ok) return;
} catch {}
}
}
const clients = new Set(); const clients = new Set();
let latest = null; let latest = null;
let sessionId = null; let sessionId = null;
@@ -144,6 +175,7 @@ async function ensureAttached(call) {
} }
async function connect() { async function connect() {
await ensureServe();
const gen = ++generation; const gen = ++generation;
sessionId = null; sessionId = null;
ws = new WebSocket(`ws://127.0.0.1:${cdpPort}/devtools/browser`); ws = new WebSocket(`ws://127.0.0.1:${cdpPort}/devtools/browser`);