eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1#!/usr/bin/env node
2// 🤖 tools/marketing-shots/web-check.mjs — headless screenshot of the seeded
3// demo space, so you can eyeball that it matches the marketing web frame before
4// capturing native.
5//
6// Mints a fresh sign-in link for Cass, opens the space in headless Chromium,
7// switches to the Lit Room theme (warm cream, as in team-web.png), opens the
8// flagship "The commons 🌱" thread, and writes a 2x screenshot.
9//
10// Usage: node tools/marketing-shots/web-check.mjs [output.png] [--thread "The commons"]
11// default output: tools/marketing-shots/web-check.png
12// Requires the demo server to be running (`./tools/dev shots up`) and
13// .demo-state.json to exist (seed-team.mjs). Playwright is resolved from the
14// npx cache (override with $LCHAT_PLAYWRIGHT).
15
16import { readState, mintDeviceLink } from "./demo-lib.mjs";
17
18const PW =
19 process.env.LCHAT_PLAYWRIGHT ||
20 "/Users/paulcampbell/.npm/_npx/e41f203b7505f1fb/node_modules/playwright/index.mjs";
21
22function arg(name, def) {
23 const i = process.argv.indexOf(`--${name}`);
24 return i >= 0 && i + 1 < process.argv.length ? process.argv[i + 1] : def;
25}
26
27const out =
28 process.argv[2] && !process.argv[2].startsWith("--")
29 ? process.argv[2]
30 : "tools/marketing-shots/web-check.png";
31const threadName = arg("thread", "The commons");
32
33async function main() {
34 const s = readState();
35 if (!s) {
36 console.error("web-check: no .demo-state.json — run seed-team.mjs first.");
37 process.exit(1);
38 }
39 const link = await mintDeviceLink(s.base, s.adminToken, s.cass, s.base, "You");
40
41 const { chromium } = await import(PW);
42 const browser = await chromium.launch();
43 const ctx = await browser.newContext({ viewport: { width: 1280, height: 1024 }, deviceScaleFactor: 2 });
44 const page = await ctx.newPage();
45
46 // Sign in via the add-device link (join.js claims it + stores keys). The link
47 // shows a confirm card first; "Sign in here in the browser" completes it.
48 await page.goto(link, { waitUntil: "networkidle" });
49 await page.getByText("Sign in here in the browser").click();
50 await page.waitForSelector("#thread-list .thread-row", { timeout: 20000 });
51 // Pick the Lit Room theme + light appearance, matching the web frame.
52 await page.evaluate(() => {
53 localStorage.setItem("lchat_theme", "litroom");
54 localStorage.setItem("lchat_appearance", "light");
55 });
56 await page.reload({ waitUntil: "networkidle" });
57
58 // Open the flagship thread from the list.
59 await page.waitForSelector("#thread-list .thread-row", { timeout: 20000 });
60 const row = page.locator(".thread-row", { hasText: threadName }).first();
61 await row.click();
62 await page.waitForTimeout(1500); // let the feed fold + render
63
64 await page.screenshot({ path: out });
65 console.error(`web-check: wrote ${out}`);
66 await browser.close();
67}
68
69main().catch((e) => {
70 console.error("web-check:", e.message);
71 process.exit(1);
72});
73