#!/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"