release: v2.9.0 — agent-browser, manifest reader, opencode 1.18.13
Not tagged yet; this is the v2.9.0 changeset landing on main. Added - agent-browser + a Playwright-managed headless Chromium in the base (~625 MB after deleting the redundant chromium_headless_shell build), so an agent can drive a real browser and VERIFY front-end work instead of assuming it renders. Ported from pi-devbox. AGENT_BROWSER_EXECUTABLE_PATH points at the stable symlink /usr/local/bin/agent-chrome, which the Dockerfile resolves with `find` rather than hardcoding: Playwright's browser dir is per-version AND per-arch (chrome-linux on arm64, chrome-linux64 on amd64), and the headless shell binary is named chrome-headless-shell so `-name chrome` skips it. - opencode-devbox-version: a reader for the build manifest. The image has baked ground truth to /etc/opencode-devbox/build-manifest.json for several releases, but nothing read it and nothing printed it — so "which image am I running?" meant knowing the path by heart. Three modes (--json/--quiet/human), plus a live-vs-baked drift check, because NPM_CONFIG_PREFIX points at the persistent config volume and a user `npm install -g opencode` can shadow the baked binary. entrypoint-user.sh prints it as its first output. - ENV COLORTERM=truecolor, completing a true-colour story the image already half-shipped (terminfo entries + Neovim termguicolors, but no capability advertisement, so bat/delta fell back to 256 colours). - Smoke assertions for agent-browser, that agent-chrome resolves to an executable (catches a Playwright layout change, not just a dangling symlink), COLORTERM, the manifest's release_tag, and all three version-command modes. Changed - opencode 1.17.20 -> 1.18.13. Verified by diffing upstream source, not release notes: core config.ts, config/provider.ts and schema.json are byte-identical, so generate-config.py needs no change. 1.18.13 (published mid-audit) was re-verified separately — 249 files in the compare payload, under GitHub's 300-file cap, so the list is complete rather than truncated; content is the Electron app plus localisation; the five contract-surface files hash identical at both tags. The bg-subagents removal trigger has NOT fired: runtime-flags.ts still gates the flag behind OPENCODE_EXPERIMENTAL at all three tags. - yq: dropped Debian's apt package (the unrelated Python kislyuk/yq — jq syntax, 3.x line) for mikefarah's Go yq v4 from GitHub. The cloud-init repo's provision.sh/deploy.sh need v4 syntax, and THIRD_PARTY.md already credited "yq (mikefarah)" while the image shipped the Python one, so this also closes a documented-vs-shipped mismatch. Smoke pins the contract to mikefarah v4. BEHAVIOUR CHANGE for any in-image script calling yq with jq-style syntax. - mempalace pin 3.5.0 -> 3.6.0, in lockstep with pi-devbox (5724302). Reviewed for MCP tool-schema changes before bumping — none, and nothing touches diary_write. - Default models -> claude-opus-5 (anthropic, and bedrock's global.anthropic.claude-opus-5) and openai/gpt-5.6. gpt-5.4 had gone stale: gpt-5.6 shipped four days before the v2.8.0 cut. Affects only new containers with no OPENCODE_MODEL and no existing config. - Smoke size thresholds +650 MB (base 2950->3600, omos 3650->4300), sized to keep the same ~250 MB headroom so the guardrail still catches runaway growth rather than routine apt drift. Do NOT copy pi-devbox's number: it sums `docker history`, this repo uses `docker image inspect .Size`. Documentation - New README section "Choosing a provider and model", making explicit that the baked defaults are only defaults and nobody is locked to Anthropic/Bedrock, including the three real gotchas: defaults seed only a NEW config, an existing opencode.jsonc on the persistent volume is never rewritten, and switching model needs no rebuild. - New README section "Browser automation (agent-browser)"; opencode-devbox-version documented under Build provenance; COLORTERM under Terminal compatibility. - README Build Args table drift fixed — FOUR missing args added (AGENT_BROWSER_VERSION, PLAYWRIGHT_VERSION, YQ_VERSION and GITLEAKS_VERSION, the last of which had existed as an ARG but was never listed), plus rows for the two pinned args absent entirely (MEMPALACE_VERSION, DEBIAN_VERSION), plus a refreshed stale OPENCODE_VERSION example. Third consecutive release to find drift in this table. - AGENTS.md: the stale MemPalace anyOf convention rewritten. It described a perl RUN block already DELETED at the 3.5.0 bump and asserted "PyPI latest is 3.4.0 (== our pin), no release contains the fix yet, the workaround must stay" — all three false. Replaced with a pin-review rule. Two new conventions added: the agent-browser/Chromium size coupling, and the yq identity trap. - THIRD_PARTY.md: agent-browser, Playwright, Chromium. Verified locally with the CI-pinned hadolint 2.14.0 and actionlint 1.7.7, the shell guard, DOCKER_HUB.md sync, bash -n, py_compile, and by generating the config for all three providers.
This commit is contained in:
+43
-3
@@ -139,7 +139,13 @@ run "fzf" "fzf --version"
|
||||
run "fd" "fd --version"
|
||||
run "rg" "rg --version | head -1"
|
||||
run "jq" "jq --version"
|
||||
run "yq" "yq --version"
|
||||
# yq MUST be mikefarah's Go yq v4, NOT Debian's `yq` apt package (the unrelated
|
||||
# Python kislyuk/yq — a jq wrapper on a 3.x line with incompatible syntax). v2.9.0
|
||||
# swapped the apt package for the mikefarah binary. Pinning the contract to major
|
||||
# v4 makes BOTH a regression to the Python package AND a surprise future yq v5
|
||||
# fail CI loudly, instead of silently breaking the cloud-init repo's
|
||||
# provision.sh/deploy.sh which require v4 syntax.
|
||||
run "yq is mikefarah v4" "yq --version | grep -qE 'mikefarah.*version v4' && yq --version"
|
||||
run "git-crypt" "git-crypt --version | head -1"
|
||||
run "gitleaks" "gitleaks version"
|
||||
run "aws" "aws --version"
|
||||
@@ -148,6 +154,17 @@ run "gosu" "gosu --version"
|
||||
run "tmux" "tmux -V"
|
||||
run "pandoc" "pandoc --version | head -1"
|
||||
run "typst" "typst --version"
|
||||
# agent-browser + its Chromium. The ENV must point at a resolvable executable:
|
||||
# AGENT_BROWSER_EXECUTABLE_PATH -> /usr/local/bin/agent-chrome -> Playwright's
|
||||
# per-version, per-ARCH chrome binary. Asserting the resolved target is
|
||||
# executable catches a Playwright layout change (the reason the Dockerfile
|
||||
# `find`s the binary instead of hardcoding the path) rather than just checking
|
||||
# that a dangling symlink exists.
|
||||
run "agent-browser" "agent-browser --version"
|
||||
run "agent-chrome resolves to an executable" \
|
||||
"test -x \"\$(readlink -f /usr/local/bin/agent-chrome)\" && readlink -f /usr/local/bin/agent-chrome"
|
||||
run_expect "AGENT_BROWSER_EXECUTABLE_PATH baked" \
|
||||
"printenv AGENT_BROWSER_EXECUTABLE_PATH" "/usr/local/bin/agent-chrome"
|
||||
run "pandoc+typst PDF engine" "printf '# hi\n' | pandoc --pdf-engine=typst -o /tmp/_smoke.pdf - && test -s /tmp/_smoke.pdf; rm -f /tmp/_smoke.pdf"
|
||||
run "graphviz (dot)" "dot -V"
|
||||
run "tldr (tealdeer)" "tldr --version"
|
||||
@@ -157,6 +174,9 @@ run "dot-watch" "test -x /usr/local/bin/dot-watch && bash -n /usr/local/
|
||||
# and OMOS V2+ default orchestration depends on it. Baked ON as an ENV in
|
||||
# Dockerfile.base — assert it's present in the image environment (both variants).
|
||||
run_expect "bg-subagents env baked" "printenv OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS" "true"
|
||||
# True-colour advertisement for colour-aware tools (bat, delta, Neovim's
|
||||
# auto-detect). Pairs with the terminfo entries + sysinit.vim termguicolors.
|
||||
run_expect "COLORTERM env baked" "printenv COLORTERM" "truecolor"
|
||||
|
||||
# SSH ControlMaster baked defaults: the config file must exist (image-level)
|
||||
# and ssh -G must report ControlPath rooted at /tmp/sshcm/ for an arbitrary
|
||||
@@ -242,6 +262,17 @@ run_expect "manifest records opencode_version" \
|
||||
"cat /etc/opencode-devbox/build-manifest.json" '"opencode_version"'
|
||||
run_expect "manifest records mempalace-toolkit component" \
|
||||
"cat /etc/opencode-devbox/build-manifest.json" '"mempalace-toolkit"'
|
||||
run_expect "manifest records release_tag" \
|
||||
"cat /etc/opencode-devbox/build-manifest.json" '"release_tag"'
|
||||
# The manifest is only useful if something can READ it. v2.9.0 added
|
||||
# opencode-devbox-version as that reader (and entrypoint-user.sh prints it at
|
||||
# container start), so assert the command itself works in all three modes —
|
||||
# otherwise the manifest stays an invisible artifact, which is what it was for
|
||||
# every release before this one.
|
||||
run_expect "opencode-devbox-version --json emits the manifest" \
|
||||
"opencode-devbox-version --json" '"release_tag"'
|
||||
run "opencode-devbox-version --quiet" "opencode-devbox-version --quiet"
|
||||
run "opencode-devbox-version (human)" "opencode-devbox-version | head -1"
|
||||
# Every resolved component must be a real value, never the 'unknown'
|
||||
# sentinel that rev()/version lookups emit on failure. (oh-my-opencode-slim
|
||||
# is JSON null in the base variant — that is expected, not 'unknown'.)
|
||||
@@ -403,8 +434,17 @@ echo " Uncompressed size: ${SIZE_MB} MB"
|
||||
# headroom keeps the guardrail catching *runaway* growth (accidental texlive/
|
||||
# chrome bake-in) rather than tripping on routine apt drift or a minor opencode
|
||||
# bump. smoke still prints the actual landed size each run; tighten if low.
|
||||
THRESHOLD=2950
|
||||
[ "$VARIANT" = "omos" ] && THRESHOLD=3650
|
||||
# v2.9.0: bumped +650 MB (2950->3600 base, 3650->4300 omos) for agent-browser +
|
||||
# Playwright Chromium on the BASE layer (~625 MB after dropping the redundant
|
||||
# chromium_headless_shell build). Sized to keep roughly the same ~250 MB of
|
||||
# headroom the previous thresholds had, so the guardrail still catches *runaway*
|
||||
# growth (an accidental texlive or a second browser) rather than tripping on
|
||||
# routine apt drift. NOTE: do NOT copy pi-devbox's threshold number across — it
|
||||
# sums `docker history` while this script uses `docker image inspect .Size`, so
|
||||
# the two are not directly comparable. smoke prints the actual landed size every
|
||||
# run; tighten these if they come in low.
|
||||
THRESHOLD=3600
|
||||
[ "$VARIANT" = "omos" ] && THRESHOLD=4300
|
||||
if [ "$SIZE_MB" -gt "$THRESHOLD" ]; then
|
||||
fail "image size ${SIZE_MB} MB exceeds threshold ${THRESHOLD} MB for variant=$VARIANT"
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user