Files
Mike Schwarz a2d4d261fd fix(cli): include the SDK in clean installations (#2374)
A clean install of the CLI couldn't start: bare `rig` and `rig --help` exited 1 with `ERR_MODULE_NOT_FOUND` for `@modelcontextprotocol/sdk`. `packages/cli/src/commands/environment.ts` imports the SDK client at module load and `index.ts` loads the environment command statically, but the SDK was declared only in the CLI's `devDependencies`, so an install without development dependencies didn't have it. The SDK (`^1.32.2`) is now a production dependency of `packages/cli`; the lockfile update is metadata only (its dev flags), with no package added, removed or re-versioned. `scripts/cli-runtime-dependencies.test.mjs` walks the import closure from the CLI's entry points and fails if any external package it reaches isn't a production dependency, and the testbed image now runs `rig --help` after `rig --version`.

4 files, +77/-87.
2026-11-01 17:49:09 -08:00

70 lines
3.7 KiB
Docker

# 51-04 testbed image (openrig-testbed) — see IMPL-PLAN §1. Built HOST-side by
# scripts/build-testbed-image.sh, which resolves + records the base digest, pins node, stages the
# stub assets, and COPYs the local openrig pack tarball. Byte-reproducible BY CONTRACT: the base is
# digest-pinned (the verb refuses a tag-floating reference), node is pinned, and openrig comes from
# the tree — never the npm registry (0.5.1 is unreleased). Layers are ordered stable -> volatile.
# --- base: a digest-pinned LTS-slim Linux, supplied by the build verb (docker/testbed/base-image,
# which REFUSES a non-@sha256 reference). No floating tag is baked into this file. ---
ARG BASE_IMAGE
FROM ${BASE_IMAGE}
# --- layer 1: userland + tmux + git + PTY/process essentials + the native-build toolchain (most stable) ---
# python3/make/g++ are REQUIRED, not optional: the sealed Q2 packaging ruling builds better-sqlite3
# FRESH ON TARGET (never a prebuilt/nested binary — that would risk a wrong-arch native module). Its
# install is `prebuild-install || node-gyp rebuild`; with a self-contained tarball npm reaches that
# step, prebuild-install is absent, and node-gyp needs python3+make+g++ to compile from source. Without
# them layer 3 dies ('prebuild-install: not found' → 'Could not find any Python installation'). This is
# testbed-image scope only (no multi-stage gold-plating — the image is a throwaway test target).
RUN set -eux; \
apt-get update; \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates curl xz-utils git tmux tini procps \
python3 make g++; \
rm -rf /var/lib/apt/lists/*
# --- layer 2: pinned node (an in-range engines version — see scripts/check-engines) ---
ARG NODE_VERSION=22.23.4
ARG TARGETARCH
RUN set -eux; \
case "${TARGETARCH}" in \
amd64) NODE_ARCH=x64 ;; \
arm64) NODE_ARCH=arm64 ;; \
"") echo "TARGETARCH is empty — the legacy (non-BuildKit) builder does not populate it. Pass --build-arg TARGETARCH explicitly (build-testbed-image.sh does) or enable BuildKit. REFUSING to default to amd64, which would install wrong-arch Node." >&2; exit 1 ;; \
*) echo "unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
esac; \
NODE_TARBALL="node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz"; \
curl -fsSLo "/tmp/${NODE_TARBALL}" \
"https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}"; \
curl -fsSLo /tmp/SHASUMS256.txt \
"https://nodejs.org/dist/v${NODE_VERSION}/SHASUMS256.txt"; \
(cd /tmp && awk -v tarball="${NODE_TARBALL}" '$2 == tarball' SHASUMS256.txt | sha256sum -c -); \
tar -xJf "/tmp/${NODE_TARBALL}" -C /usr/local --strip-components=1 --no-same-owner; \
rm -f "/tmp/${NODE_TARBALL}" /tmp/SHASUMS256.txt; \
node --version; npm --version
# --- layer 3: the OpenRig package from the LOCAL pack tarball, never the npm registry ---
ARG OPENRIG_TARBALL
COPY ${OPENRIG_TARBALL} /tmp/openrig.tgz
RUN set -eux; \
npm install -g /tmp/openrig.tgz; \
rm -f /tmp/openrig.tgz; \
rig --version; \
rig --help
# --- layer 4: stub runtime assets (zero-token by construction; staged by the build verb into the
# build context as ./stub-assets/, hashed into the manifest via deriveStubAssetsHash) ---
COPY stub-assets/ /opt/openrig-testbed/stub-assets/
# --- layer 5: a non-root openrig user + a tini entrypoint into tmux-server-friendly init ---
RUN set -eux; \
useradd --create-home --shell /bin/bash openrig; \
mkdir -p /opt/openrig-testbed; \
chown -R openrig:openrig /opt/openrig-testbed
COPY entrypoint.sh /opt/openrig-testbed/entrypoint.sh
RUN chmod 0755 /opt/openrig-testbed/entrypoint.sh
USER openrig
WORKDIR /home/openrig
ENTRYPOINT ["/usr/bin/tini", "--", "/opt/openrig-testbed/entrypoint.sh"]
CMD ["sleep", "infinity"]