#!/usr/bin/env node import { readFile } from 'node:fs/promises'; import net from 'node:net'; const PAGES_FILE = '/Users/inmanx/.cache/cdp/pages.json'; const SOCKET_ROOT = '/Users/inmanx/.cache/cdp'; const ORIGIN = 'http://127.0.0.1:8786'; function argument(name, fallback = '') { const index = process.argv.indexOf(name); return index >= 0 && process.argv[index + 1] ? process.argv[index + 1] : fallback; } function daemonRequest(socketPath, cmd, args = []) { return new Promise((resolve, reject) => { const socket = net.createConnection(socketPath); let buffer = ''; const timer = setTimeout(() => { socket.destroy(); reject(new Error(`CDP daemon ${cmd} timed out`)); }, 15_000); socket.on('connect', () => { socket.write(`${JSON.stringify({ id: 1, cmd, args })}\n`); }); socket.on('data', (chunk) => { buffer += chunk.toString(); const newline = buffer.indexOf('\n'); if (newline < 0) return; try { const response = JSON.parse(buffer.slice(0, newline)); clearTimeout(timer); socket.end(); if (!response.ok) reject(new Error(response.error || `CDP daemon ${cmd} failed`)); else resolve(response.result || ''); } catch (error) { clearTimeout(timer); socket.destroy(); reject(error); } }); socket.on('error', (error) => { clearTimeout(timer); reject(error); }); }); } const taskId = argument('--task-id'); const storageKey = argument('--storage-key'); const targetPrefix = argument('--target', 'DA600CC0'); if (!/^TASK-[A-Za-z0-9_-]+$/.test(taskId)) throw new Error('--task-id is required'); if (!/^ltjt_[A-Za-z0-9_-]+$/.test(storageKey)) throw new Error('--storage-key is required'); const pages = JSON.parse(await readFile(PAGES_FILE, 'utf8')); const page = pages.find((target) => target.targetId.startsWith(targetPrefix)); if (!page) throw new Error(`page target not found: ${targetPrefix}`); const socketPath = `${SOCKET_ROOT}/cdp-${page.targetId}.sock`; const evaluated = JSON.parse(await daemonRequest(socketPath, 'evalraw', [ 'Runtime.evaluate', JSON.stringify({ expression: `sessionStorage.getItem(${JSON.stringify(storageKey)})`, returnByValue: true }) ])); const rawResult = evaluated.result?.value; if (!rawResult) throw new Error('stored extension result is missing'); const result = JSON.parse(rawResult); if (!result.execution_id || result.status !== 'completed') throw new Error('stored extension result is not a completed durable result'); const cookieResult = JSON.parse(await daemonRequest(socketPath, 'evalraw', [ 'Network.getCookies', JSON.stringify({ urls: [`${ORIGIN}/`] }) ])); const cookies = (cookieResult.cookies || []).filter((cookie) => cookie.domain === '127.0.0.1' || cookie.domain === 'localhost'); if (!cookies.length) throw new Error('authenticated browser session cookie is missing'); const cookieHeader = cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; '); const csrfResponse = await fetch(`${ORIGIN}/api/auth/csrf`, { headers: { Cookie: cookieHeader }, cache: 'no-store' }); const csrfBody = await csrfResponse.json(); if (!csrfResponse.ok || !csrfBody.csrf_token) throw new Error(`CSRF request failed: HTTP ${csrfResponse.status}`); const response = await fetch(`${ORIGIN}/api/tasks/${encodeURIComponent(taskId)}/result`, { method: 'POST', headers: { Cookie: cookieHeader, 'Content-Type': 'application/json', 'X-CSRF-Token': csrfBody.csrf_token }, body: JSON.stringify({ connection_id: `task-owner-browser:${ORIGIN}`, execution_id: result.execution_id, result }) }); const body = await response.json(); if (!response.ok) throw new Error(body.message || body.error || `result persistence failed: HTTP ${response.status}`); process.stdout.write(`${JSON.stringify({ status: 'extension_result_persisted', http_status: response.status, task_id: body.task?.task_id || taskId, task_status: body.task?.status || '', task_stage: body.task?.stage || '', execution_id: result.execution_id, report_status: result.report?.status || '', requery_matched: result.report?.requery?.matched === true }, null, 2)}\n`);