base: bake agent-browser + Playwright Chromium (headless browsing, all variants)
Lint / actionlint (push) Successful in 28s
Lint / hadolint (push) Successful in 11s

Gives the agent a real browser it can drive so front-end work involving live
DOM/WebGL can be VERIFIED, not guessed. The agent-browser skill (from the
skillset repo) was a no-op without the binary; it now works out of the box.

- agent-browser CLI (standalone Rust, ships no browser) via npm, prefixed
  NPM_CONFIG_PREFIX=/usr so it survives the ~/.pi/npm-global volume.
- Chromium fetched with 'playwright install --with-deps chromium' into
  PLAYWRIGHT_BROWSERS_PATH=/usr/local/share/ms-playwright — a system path that
  the /home/developer volume can't shadow (unlike agent-browser's own
  ~/.agent-browser/browsers default, which WOULD vanish on recreate).
- Stable /usr/local/bin/agent-chrome symlink, exported as
  AGENT_BROWSER_EXECUTABLE_PATH, insulates the ENV from Playwright's
  per-version chromium-<rev> dir name.

Verified end-to-end (this session): agent-browser drives the baked Chromium
headless (open + title + screenshot + eval into a WebGL SPA); doctor launch
test passes in ~0.5s. Debian trixie --with-deps resolution verified (exit 0;
t64 lib renames handled). hadolint clean; check-base-hash OK (only *_VERSION
args added). Cost ~960 MB (Chromium + headless shell). Base-affecting →
rebuilds base-<hash> on next release.
This commit is contained in:
2026-07-17 16:12:47 +02:00
parent 71b12a9ed4
commit 8caafc3f49
2 changed files with 65 additions and 1 deletions
+18
View File
@@ -15,6 +15,24 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
### Added ### 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-<rev>` directory name. Debian trixie
`--with-deps` dependency resolution verified (the t64 renames are handled).
Adds ~960 MB (Chromium + headless shell). Base-affecting, rebuilds
`base-<hash>`.
- **`pi-devbox-version` command.** Wraps `/etc/pi-devbox/build-manifest.json` - **`pi-devbox-version` command.** Wraps `/etc/pi-devbox/build-manifest.json`
into a human-readable summary (release tag, build date, source revision, into a human-readable summary (release tag, build date, source revision,
baked `pi_version`, and short SHAs for every `/opt` component) instead of baked `pi_version`, and short SHAs for every `/opt` component) instead of
+47 -1
View File
@@ -14,7 +14,7 @@
# content-addressed over this file, so any byte change invalidates the # content-addressed over this file, so any byte change invalidates the
# cache. Recommended cadence: once per release for security updates. # 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 ───────────────────────────────────────────────────── # ── Lineage note ─────────────────────────────────────────────────────
# Adapted from opencode-devbox/Dockerfile.base (commit before v1.16.2). # 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 && \ apt-get install -y --no-install-recommends nodejs && \
rm -rf /var/lib/apt/lists/* 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-<rev>` 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 ────────── # ── tldr (tealdeer) — community-maintained command examples ──────────
# Tealdeer is a Rust port of the tldr-pages client; ~5 MB static binary, # 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. # ~135 MB smaller than the Node tldr global. Same `tldr` command, same UX.