ARG TASK_IMAGE=ubuntu:24.04 FROM ${TASK_IMAGE} ARG NODE_VERSION=22.20.0 ARG OPENCODE_VERSION=1.18.16 ARG RUNTIME_BUILD_REVISION=2 ARG RUNTIME_SOURCE_FINGERPRINT=unknown # OpenCode's Skill, glob, and grep tools use ripgrep. Install it in the # reusable image so an evaluation never has to download rg from GitHub at # agent runtime. RUN set -eux; \ if command -v rg >/dev/null 2>&1; then \ :; \ elif command -v apt-get >/dev/null 2>&1; then \ apt-get update; \ apt-get install -y --no-install-recommends ripgrep; \ rm -rf /var/lib/apt/lists/*; \ elif command -v dnf >/dev/null 2>&1; then \ dnf -y install ripgrep; \ dnf clean all; \ elif command -v apk >/dev/null 2>&1; then \ apk add --no-cache ripgrep; \ else \ echo 'OpenCode runtime requires a package manager to install ripgrep' >&2; \ exit 127; \ fi; \ rg --version RUN set -eux; \ if [ -x /opt/benchflow/node/bin/node ]; then \ /opt/benchflow/node/bin/node --version; \ else \ if ! command -v curl >/dev/null 2>&1 || ! command -v tar >/dev/null 2>&1; then \ if command -v apt-get >/dev/null 2>&1; then \ apt-get update; \ apt-get install -y --no-install-recommends curl ca-certificates tar; \ rm -rf /var/lib/apt/lists/*; \ elif command -v dnf >/dev/null 2>&1; then \ dnf -y install curl ca-certificates tar; \ dnf clean all; \ elif command -v apk >/dev/null 2>&1; then \ apk add --no-cache curl ca-certificates tar; \ else \ echo 'Node/OpenCode bootstrap requires curl and tar' >&2; \ exit 127; \ fi; \ fi; \ arch="$(uname -m)"; \ case "$arch" in \ x86_64|amd64) node_arch=x64 ;; \ aarch64|arm64) node_arch=arm64 ;; \ *) echo "Unsupported architecture for Node.js: $arch" >&2; exit 1 ;; \ esac; \ temporary_dir="$(mktemp -d)"; \ curl -fL \ --retry 8 --retry-delay 2 \ --connect-timeout 20 --max-time 900 \ -o "$temporary_dir/node.tar.gz" \ "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.gz"; \ mkdir -p /opt/benchflow/node /opt/benchflow/js-agents /opt/benchflow/bin; \ tar -xzf "$temporary_dir/node.tar.gz" \ -C /opt/benchflow/node --strip-components=1 --no-same-owner; \ rm -rf "$temporary_dir"; \ fi ENV PATH="/opt/benchflow/bin:/opt/benchflow/js-agents/bin:/opt/benchflow/node/bin:${PATH}" RUN set -eux; \ if [ ! -x /opt/benchflow/js-agents/bin/opencode ]; then \ npm install -g \ --fetch-retries=8 \ --fetch-retry-factor=2 \ --fetch-retry-mintimeout=2000 \ --fetch-retry-maxtimeout=60000 \ --prefix /opt/benchflow/js-agents \ "opencode-ai@${OPENCODE_VERSION}"; \ fi; \ npm cache clean --force; \ rm -rf /root/.npm; \ printf '%s\n' \ '#!/bin/sh' \ 'exec /opt/benchflow/js-agents/bin/opencode "$@"' \ > /opt/benchflow/bin/opencode; \ chmod +x /opt/benchflow/bin/opencode; \ chmod -R a+rX /opt/benchflow LABEL org.skillc.opencode-runtime="1.18.16" \ org.skillc.node-runtime="22.20.0" \ org.skillc.opencode-runtime-build="${RUNTIME_BUILD_REVISION}" \ org.skillc.opencode-runtime-source="${RUNTIME_SOURCE_FINGERPRINT}"