#!/usr/bin/env node // 🤖 tools/marketing-shots/web-check.mjs — headless screenshot of the seeded // demo space, so you can eyeball that it matches the marketing web frame before // capturing native. // // Mints a fresh sign-in link for Cass, opens the space in headless Chromium, // switches to the Lit Room theme (warm cream, as in team-web.png), opens the // flagship "The commons 🌱" thread, and writes a 2x screenshot. // // Usage: node tools/marketing-shots/web-check.mjs [output.png] [--thread "The commons"] // default output: tools/marketing-shots/web-check.png // Requires the demo server to be running (`./tools/dev shots up`) and // .demo-state.json to exist (seed-team.mjs). Playwright is resolved from the // npx cache (override with $LCHAT_PLAYWRIGHT). import { readState, mintDeviceLink } from "./demo-lib.mjs"; const PW = process.env.LCHAT_PLAYWRIGHT || "/Users/paulcampbell/.npm/_npx/e41f203b7505f1fb/node_modules/playwright/index.mjs"; function arg(name, def) { const i = process.argv.indexOf(`--${name}`); return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : def; } const out = process.argv[2] && !process.argv[2].startsWith("--") ? process.argv[2] : "tools/marketing-shots/web-check.png"; const threadName = arg("thread", "The commons"); async function main() { const s = readState(); if (!s) { console.error("web-check: no .demo-state.json — run seed-team.mjs first."); process.exit(1); } const link = await mintDeviceLink(s.base, s.adminToken, s.cass, s.base, "You"); const { chromium } = await import(PW); const browser = await chromium.launch(); const ctx = await browser.newContext({ viewport: { width: 1280, height: 1024 }, deviceScaleFactor: 2 }); const page = await ctx.newPage(); // Sign in via the add-device link (join.js claims it + stores keys). The link // shows a confirm card first; "Sign in here in the browser" completes it. await page.goto(link, { waitUntil: "networkidle" }); await page.getByText("Sign in here in the browser").click(); await page.waitForSelector("#thread-list .thread-row", { timeout: 20000 }); // Pick the Lit Room theme + light appearance, matching the web frame. await page.evaluate(() => { localStorage.setItem("lchat_theme", "litroom"); localStorage.setItem("lchat_appearance", "light"); }); await page.reload({ waitUntil: "networkidle" }); // Open the flagship thread from the list. await page.waitForSelector("#thread-list .thread-row", { timeout: 20000 }); const row = page.locator(".thread-row", { hasText: threadName }).first(); await row.click(); await page.waitForTimeout(1500); // let the feed fold + render await page.screenshot({ path: out }); console.error(`web-check: wrote ${out}`); await browser.close(); } main().catch((e) => { console.error("web-check:", e.message); process.exit(1); });