/* CDP runner: attach to running chrome (real time, no virtual time), poll the drive page status until DONE/ERROR, then report. usage: node tools/cdp_run.mjs [port] [timeoutSec] */ const port = process.argv[2] || '9333'; const timeoutMs = (parseInt(process.argv[3] || '120', 10)) * 1000; const targets = await (await fetch(`http://127.0.0.1:${port}/json`)).json(); const page = targets.find(t => t.type === 'page'); if (!page) { console.log('no page'); process.exit(1); } const ws = new WebSocket(page.webSocketDebuggerUrl); let id = 0; const pending = new Map(); function send(method, params = {}) { return new Promise((res, rej) => { const mid = ++id; pending.set(mid, { res, rej }); ws.send(JSON.stringify({ id: mid, method, params })); }); } ws.onmessage = (ev) => { const msg = JSON.parse(ev.data); if (msg.id && pending.has(msg.id)) { const { res, rej } = pending.get(msg.id); pending.delete(msg.id); msg.error ? rej(new Error(msg.error.message)) : res(msg.result); } }; await new Promise(r => { ws.onopen = r; }); async function evalJs(expr) { const r = await send('Runtime.evaluate', { expression: expr, returnByValue: true }); return r.result ? r.result.value : undefined; } const t0 = Date.now(); let last = ''; while (Date.now() - t0 < timeoutMs) { await new Promise(r => setTimeout(r, 2000)); const s = await evalJs(`(document.getElementById('status')||{}).textContent || ''`); if (s !== last) { console.log('----\n' + s); last = s; } if (/DONE|DRIVE_ERROR/.test(s)) break; } console.log('\n===== FINAL ====='); console.log(await evalJs(`(document.getElementById('status')||{}).textContent || ''`)); ws.close();