// SPDX-License-Identifier: Apache-2.0 // Read a page: open it in a read tab (it can look but never write), print its text, headings and links. // // npm install webpilot-si # in this folder (see package.json) // export WEBPILOT_URL=http://localhost:8931 WEBPILOT_TOKEN=cbu_... // node read_page.ts # Node 22.18+ runs TypeScript as is (or: npx tsx read_page.ts) // node read_page.ts https://example.com // // Page content is untrusted data: this script prints it and never acts on instructions found in it. import { WebPilot } from "webpilot-si"; const url = process.argv[2] ?? "https://en.wikipedia.org/wiki/Web_browser"; const wp = new WebPilot(); // WEBPILOT_URL and WEBPILOT_TOKEN from the environment const tab = await wp.open(url); // mode "read" is the default try { const snap = await tab.snapshot(); console.log(`${tab.id}: ${snap.title} (${snap.url})`); console.log(`${snap.elements.length} interactive elements, e.g.:`); for (const e of snap.elements.slice(0, 5)) console.log(` ${e.ref.padStart(5)} ${e.role.padEnd(10)} ${e.name.slice(0, 60)}`); console.log("\n" + (await tab.readText()).slice(0, 800)); const meta = await tab.extract("meta"); console.log("\nheadings:\n " + (meta.data.headings ?? []).slice(0, 8).join("\n ")); const links = await tab.extract("links", { limit: 200 }); console.log(`\n${links.data.length} links; the first three:`); for (const link of links.data.slice(0, 3)) console.log(` ${JSON.stringify(link.text.slice(0, 40))} -> ${link.href}`); // Without a tab at all: the server fetches the page and returns its main content as Markdown. const read = await wp.read(url, { maxChars: 300 }); console.log(`\nread (via ${read.via}): ${read.content.slice(0, 200)}`); } finally { await tab.close(); // tabs outlive your program: close the ones you opened }