37960186c6
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.
89 lines
3.3 KiB
Bash
Executable File
89 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# opencode-devbox-version — show which opencode-devbox image build is running.
|
|
#
|
|
# WHY THIS EXISTS
|
|
# The image bakes ground-truth build info into
|
|
# /etc/opencode-devbox/build-manifest.json at `docker build` time (see
|
|
# Dockerfile.variant): the release tag, build date, source commit, the live
|
|
# `opencode --version` at build time, the installed oh-my-opencode-slim
|
|
# version (omos variant only), and the actual checked-out commit of the
|
|
# /opt/mempalace-toolkit clone. That answers "what image am I running?" —
|
|
# but only if you know to go look for the file. This wraps it into one
|
|
# command, prints it human-first at container start (see entrypoint-user.sh),
|
|
# and stays available on demand for the rest of the session.
|
|
#
|
|
# USAGE
|
|
# opencode-devbox-version human-readable summary (default)
|
|
# opencode-devbox-version --json raw manifest JSON (for scripting)
|
|
# opencode-devbox-version --quiet one-line "release_tag (source_revision)"
|
|
#
|
|
# EXIT STATUS
|
|
# 0 on success. 1 if the manifest is missing (e.g. an image built before
|
|
# this file existed, or a non-opencode-devbox base) — prints a short notice
|
|
# to stderr rather than failing silently.
|
|
|
|
set -euo pipefail
|
|
|
|
MANIFEST=/etc/opencode-devbox/build-manifest.json
|
|
MODE="human"
|
|
|
|
case "${1:-}" in
|
|
--json) MODE="json" ;;
|
|
--quiet|-q) MODE="quiet" ;;
|
|
--help|-h)
|
|
sed -n '2,22p' "$0" | sed 's/^# \?//'
|
|
exit 0
|
|
;;
|
|
esac
|
|
|
|
if [ ! -f "$MANIFEST" ]; then
|
|
echo "opencode-devbox-version: no build manifest at $MANIFEST" >&2
|
|
echo " (image predates the manifest, or this isn't an opencode-devbox image)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v jq >/dev/null 2>&1; then
|
|
echo "opencode-devbox-version: jq not found; dumping raw manifest instead" >&2
|
|
cat "$MANIFEST"
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$MODE" = "json" ]; then
|
|
cat "$MANIFEST"
|
|
exit 0
|
|
fi
|
|
|
|
release_tag=$(jq -r '.release_tag' "$MANIFEST")
|
|
build_date=$(jq -r '.build_date' "$MANIFEST")
|
|
source_rev=$(jq -r '.source_revision' "$MANIFEST")
|
|
opencode_version_baked=$(jq -r '.opencode_version' "$MANIFEST")
|
|
|
|
if [ "$MODE" = "quiet" ]; then
|
|
printf '%s (%s)\n' "$release_tag" "${source_rev:0:7}"
|
|
exit 0
|
|
fi
|
|
|
|
# Live drift check: has `opencode` been upgraded since this container was built?
|
|
# The image is immutable, but `npm install -g` as the developer user lands on the
|
|
# persistent devbox-opencode-config volume (NPM_CONFIG_PREFIX is
|
|
# ~/.config/opencode/npm-global), which CAN shadow the baked /usr binary. So we
|
|
# report the live version and flag a mismatch rather than trusting the manifest
|
|
# blindly — same "ground truth over intent" spirit as how the manifest itself is
|
|
# generated in Dockerfile.variant.
|
|
opencode_version_live=""
|
|
if command -v opencode >/dev/null 2>&1; then
|
|
opencode_version_live=$(opencode --version 2>/dev/null | head -n1 | tr -d '\r\n')
|
|
fi
|
|
|
|
printf 'opencode-devbox %s\n' "$release_tag"
|
|
printf ' built: %s (source %s)\n' "$build_date" "${source_rev:0:12}"
|
|
if [ -n "$opencode_version_live" ] && [ "$opencode_version_live" != "$opencode_version_baked" ]; then
|
|
printf ' opencode: %s \033[33m(baked as %s — drift detected)\033[0m\n' \
|
|
"$opencode_version_live" "$opencode_version_baked"
|
|
else
|
|
printf ' opencode: %s\n' "${opencode_version_live:-$opencode_version_baked}"
|
|
fi
|
|
|
|
printf ' components:\n'
|
|
jq -r '.components | to_entries[] | select(.value != null) | " \(.key): \(.value[0:12])"' "$MANIFEST"
|