# Harness agent-seat image. One wrapper invocation runs inside one instance of this.
# Build ON a buildbox: modules/harness/seat/build-image.sh debian1 debian2
#
# Contains only what a WRAPPER-CONTRACT wrapper needs: bash, coreutils (timeout),
# python3 (codex.sh model/effort parsing), git, ripgrep, node/bun/pnpm, and the agent CLIs.
# No sudo, no systemd, no podman-in-podman. The runtime denies every capability
# (--cap-drop=ALL --security-opt no-new-privileges) and mounts / read-only.
FROM docker.io/library/node:24.19.0-bookworm-slim

ARG GO_VERSION=1.24.0
ARG GO_SHA256=dea9ca38a0b852a74e81c26134671af7c0fbe65d81b0dc1c5bfe22cf7d4c8858
ARG CODEX_VERSION=0.146.0
ARG BUN_VERSION=1.3.14
ARG PNPM_VERSION=11.5.2
ARG CLAUDE_VERSION=2.1.223

ENV DEBIAN_FRONTEND=noninteractive \
    BUN_INSTALL=/opt/bun \
    PNPM_HOME=/opt/pnpm \
    PATH=/usr/local/go/bin:/opt/bun/bin:/opt/pnpm:/usr/local/bin:/usr/bin:/bin

RUN apt-get update \
 && apt-get install -y --no-install-recommends \
      bash ca-certificates curl git jq less procps python3 ripgrep unzip xz-utils \
 && rm -rf /var/lib/apt/lists/*

RUN curl -fsSLo /tmp/go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
 && echo "${GO_SHA256}  /tmp/go.tar.gz" | sha256sum -c - \
 && tar -xzf /tmp/go.tar.gz -C /usr/local \
 && rm -f /tmp/go.tar.gz \
 && /usr/local/go/bin/go version

RUN npm install -g --no-fund --no-audit "@openai/codex@${CODEX_VERSION}" \
 && npm cache clean --force

RUN curl -fsSL https://bun.sh/install | bash -s "bun-v${BUN_VERSION}" \
 && /opt/bun/bin/bun --version

RUN corepack enable \
 && corepack prepare "pnpm@${PNPM_VERSION}" --activate \
 && mkdir -p /opt/pnpm \
 && ln -sf "$(command -v pnpm)" /opt/pnpm/pnpm

# cursor-agent installs into $HOME/.local; $HOME is a tmpfs at runtime, so install
# it to a fixed system path at build time and symlink the launcher onto PATH.
RUN HOME=/opt/cursor-home sh -c 'mkdir -p /opt/cursor-home && curl -fsS https://cursor.com/install | bash' || true \
 && ln -sf /opt/cursor-home/.local/bin/cursor-agent /usr/local/bin/cursor-agent \
 && /usr/local/bin/cursor-agent --version

# same fixed-path install as cursor-agent: claude's launcher lives under $HOME, which is a
# runtime tmpfs. The installer takes the pinned version as its only positional argument.
RUN HOME=/opt/claude-home CLAUDE_VERSION="${CLAUDE_VERSION}" \
      sh -c 'mkdir -p /opt/claude-home && curl -fsSL https://claude.ai/install.sh | bash -s -- "$CLAUDE_VERSION"' \
 && rm -rf /opt/claude-home/.claude/downloads \
 && ln -sf /opt/claude-home/.local/bin/claude /usr/local/bin/claude \
 && /usr/local/bin/claude --version

# / is read-only at runtime, so an in-place self-update can only fail noisily.
ENV DISABLE_AUTOUPDATER=1

# codex.sh looks for the laptop-only `cdx` launcher first; in this image the engine binary
# is the npm-installed codex. The wrapper's own documented override says so without patching it.
ENV _CODEX_ENGINE_BIN=/usr/local/bin/codex

COPY seat-entrypoint.sh /usr/local/bin/seat-entrypoint.sh
COPY sandbox-git-shim /usr/local/bin/git
RUN chmod 0755 /usr/local/bin/seat-entrypoint.sh /usr/local/bin/git

ENTRYPOINT ["/usr/local/bin/seat-entrypoint.sh"]
