--- name: web-shot description: Screenshot any running web UI by spawning a one-shot Playwright Job on the koala k3s cluster. Auto-detects the calling host's Tailscale name so a dev server on flamingo:8099, iguana:3000 or koala:8181 just works. Use when the user asks for a screenshot, visual verification, "what does the UI look like", or any time chromium / firefox / a browser is requested but none is installed on the host. --- # web-shot Screenshot a locally-running web UI without installing a browser on the agent's host. ## Mechanism 1. `shot.sh` builds a k8s Job that runs `mcr.microsoft.com/playwright:v1.49.0-jammy` on koala's k3s cluster. 2. `hostNetwork: true` is **not** used — the pod uses cluster DNS so Tailscale Magic DNS resolves `flamingo`, `iguana`, `koala` directly when the koala node has Tailscale up (it does). 3. The pod renders the URL with chromium, drops PNGs into an `emptyDir`, then `sleep`s briefly so `kubectl cp` can pull the files out. 4. PNGs land in `./screenshots/` (or `--out DIR`) on the agent's host. ## Prerequisites - `kubectl` on the calling host with a kubeconfig pointing at koala's k3s. - The dev server **binds 0.0.0.0** (not 127.0.0.1) so pods on koala can reach it across Tailscale. For Go: `http.ListenAndServe(":8099", ...)`. For Node: `--host 0.0.0.0`. For Vite: `--host`. - The dev server's host (flamingo, iguana, koala, …) is reachable on Tailscale and Magic DNS resolves the short hostname. ## Usage ```bash # auto-detect Tailscale hostname, screenshot port 8099 root ~/dev/.skills/web-shot/shot.sh --port 8099 # explicit URL ~/dev/.skills/web-shot/shot.sh --url http://flamingo:5173 # capture a search state too (types into input[name=q]) ~/dev/.skills/web-shot/shot.sh --port 8181 --search agentsquad # different output dir ~/dev/.skills/web-shot/shot.sh --port 3000 --out /tmp/shots ``` ## Flags | Flag | Default | Notes | |-------------|-------------------------------|-----------------------------------------------------------| | `--port N` | — | Host port. Combined with `--host` and `--path`. | | `--path P` | `/` | URL path after the host:port. | | `--host H` | auto via `tailscale status` | Override the hostname pods will dial. | | `--url U` | — | Full URL. Overrides `--host`, `--port`, `--path`. | | `--search Q`| — | Also capture a search state — types `Q` into `input[name=q]`. | | `--out D` | `./screenshots` | Output dir (created if missing). | | `--name N` | `web-shot` | Job name prefix. | | `-h` | — | Show usage. | ## Output - `/home.png` — initial page. - `/search.png` — only when `--search` was passed. ## Failure modes - `kubectl: command not found` → install kubectl + tailscale-mode kubeconfig. - `connection refused` from the pod → dev server bound to 127.0.0.1, fix the bind. - `No matches for selector` when `--search` was given → page lacks `input[name=q]`. Use a project-specific script or rerun without `--search`. - Image pull slow on first run → ~1GB playwright image cached on koala after first use. ## When NOT to use - The site needs auth / cookies / login state — extend the script or use a project-local Playwright suite. - You need PDF, video, or interaction more elaborate than "type a query and screenshot". Promote to a real Playwright test under the project repo.