diff --git a/CHANGELOG.md b/CHANGELOG.md index 45d9e0d..d1f33df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,24 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`). ### Added +- **`agent-browser` — headless browser automation, baked into every variant.** + The base now ships the [`agent-browser`](https://www.npmjs.com/package/agent-browser) + CLI plus a Playwright-fetched Chromium, so the agent can drive a real browser + (open/click/fill/`eval`/screenshot/snapshot) and *verify* front-end work + involving live DOM or WebGL instead of guessing. The `agent-browser` skill + (from the skillset repo) was previously a no-op because the binary was + absent; it now works out of the box. Two pieces: the standalone Rust CLI + (npm, `NPM_CONFIG_PREFIX=/usr` so it survives the `~/.pi/npm-global` volume), + and a Chromium fetched via `playwright install --with-deps chromium` into + `PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/ms-playwright` (a system path, + never shadowed by the `/home/developer` volume — unlike agent-browser's own + `~/.agent-browser/browsers` default). A stable `/usr/local/bin/agent-chrome` + symlink, exported as `AGENT_BROWSER_EXECUTABLE_PATH`, insulates the config + from Playwright's per-version `chromium-` directory name. Debian trixie + `--with-deps` dependency resolution verified (the t64 renames are handled). + Adds ~960 MB (Chromium + headless shell). Base-affecting, rebuilds + `base-`. + - **`pi-devbox-version` command.** Wraps `/etc/pi-devbox/build-manifest.json` into a human-readable summary (release tag, build date, source revision, baked `pi_version`, and short SHAs for every `/opt` component) instead of diff --git a/Dockerfile.base b/Dockerfile.base index 2384e10..36821c2 100644 --- a/Dockerfile.base +++ b/Dockerfile.base @@ -14,7 +14,7 @@ # content-addressed over this file, so any byte change invalidates the # cache. Recommended cadence: once per release for security updates. # -# BASE_REBUILD_DATE: 2026-07-11 (Unreleased — typst PDF engine + xz-utils + pandoc typst-template default-font patch) +# BASE_REBUILD_DATE: 2026-07-13 (Unreleased — agent-browser CLI + Playwright Chromium for headless browser automation; prior: typst PDF engine + xz-utils + pandoc typst-template default-font patch) # # ── Lineage note ───────────────────────────────────────────────────── # Adapted from opencode-devbox/Dockerfile.base (commit before v1.16.2). @@ -457,6 +457,52 @@ RUN curl -fsSL --retry 5 --retry-delay 5 --retry-all-errors https://deb.nodesour apt-get install -y --no-install-recommends nodejs && \ rm -rf /var/lib/apt/lists/* +# ── agent-browser — headless browser automation for the agent ──────── +# Gives the agent a real browser it can drive (open/click/fill/eval/ +# screenshot) so front-end work involving live DOM or WebGL can be VERIFIED +# rather than guessed at. The `agent-browser` skill (shipped from the +# skillset repo, not this image) documents the CLI; without this block that +# skill is a no-op because the binary isn't present. Verified end-to-end +# 2026-07-13: drives the baked Chromium headless (open + screenshot + eval +# into a WebGL SPA) — doctor's launch test passes in ~0.5s. +# +# TWO pieces, because agent-browser is a standalone Rust CLI that ships NO +# browser of its own — it only drives one you provide: +# 1. the CLI itself (npm; ~70 MB of prebuilt native binaries), and +# 2. a Chromium, which we fetch via Playwright. +# +# Why Playwright fetches the browser (and NOT `agent-browser install`): +# agent-browser's own installer drops Chrome under ~/.agent-browser/browsers +# — inside /home/${USER_NAME}, which is a NAMED VOLUME at runtime, so a +# build-time download would be SHADOWED (invisible) once the volume mounts. +# Playwright honours PLAYWRIGHT_BROWSERS_PATH, so we place the browser under +# /usr/local/share (never shadowed) and hand agent-browser a STABLE symlink +# via AGENT_BROWSER_EXECUTABLE_PATH — the symlink insulates the ENV from +# Playwright's per-version `chromium-` directory name (glob picks the +# real headful build; the `chromium_headless_shell-*` dir has an underscore +# so `chromium-*` never matches it). +# +# `playwright install --with-deps chromium` also apt-installs Chromium's +# runtime libs; verified to resolve correctly on Debian trixie (exit 0 — the +# t64 library renames are handled by Playwright's dep list). Build runs as +# root, so the apt step works. NPM_CONFIG_PREFIX=/usr keeps both CLIs on /usr +# so they survive the ~/.pi/npm-global volume mount (same trick the variant +# uses for pi). Cost: ~960 MB (Chromium + headless shell) — the bulk of the +# base's browser footprint; the one real tradeoff of shipping this everywhere. +ARG AGENT_BROWSER_VERSION=latest +ARG PLAYWRIGHT_VERSION=latest +ENV PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/ms-playwright +RUN NPM_CONFIG_PREFIX=/usr npm install -g \ + "agent-browser@${AGENT_BROWSER_VERSION}" \ + "playwright@${PLAYWRIGHT_VERSION}" && \ + playwright install --with-deps chromium && \ + for chrome in "${PLAYWRIGHT_BROWSERS_PATH}"/chromium-*/chrome-linux/chrome; do \ + ln -sf "$chrome" /usr/local/bin/agent-chrome; break; \ + done && \ + agent-browser --version && \ + test -x "$(readlink -f /usr/local/bin/agent-chrome)" +ENV AGENT_BROWSER_EXECUTABLE_PATH=/usr/local/bin/agent-chrome + # ── tldr (tealdeer) — community-maintained command examples ────────── # Tealdeer is a Rust port of the tldr-pages client; ~5 MB static binary, # ~135 MB smaller than the Node tldr global. Same `tldr` command, same UX.