# claude-mem SWE-bench agent image
# Plan: .claude/plans/swebench-claude-mem-docker.md (Phase 1)
#
# Produces `claude-mem/swebench-agent:latest`: Claude Code CLI 2.1.114 +
# locally-built claude-mem plugin, ready to run headlessly per SWE-bench
# instance. Auth (ANTHROPIC_API_KEY) is passed at runtime, never baked in.

FROM node:20-bookworm-slim

ENV DEBIAN_FRONTEND=noninteractive

# System dependencies:
#   git, curl, ca-certificates, unzip — base tooling (Bun installer needs unzip)
#   jq                                — JSONL assembly in run-instance.sh
#   uuid-runtime                      — uuidgen for per-instance session IDs (Phase 2)
#   sqlite3                           — verifies the claude-mem observations DB
RUN apt-get update \
 && apt-get install -y --no-install-recommends \
      git \
      curl \
      ca-certificates \
      unzip \
      jq \
      uuid-runtime \
      sqlite3 \
 && rm -rf /var/lib/apt/lists/*

# Bun (claude-mem worker service runs under Bun). Installed to a system
# location so the non-root runtime user can execute it.
ENV BUN_INSTALL="/usr/local/bun"
RUN curl -fsSL https://bun.sh/install | bash \
 && chmod -R a+rX /usr/local/bun
ENV PATH="/usr/local/bun/bin:${PATH}"

# uv (provides Python for Chroma per CLAUDE.md). Installed to a system
# location, same reason.
ENV UV_INSTALL_DIR="/usr/local/bin"
# Group the chmod so the trailing `|| true` only absorbs chmod failures; without
# this grouping, bash precedence (`&&` binds tighter than `||`) would silently
# mask a failed `curl|sh` install step.
RUN set -eux \
 && curl -LsSf https://astral.sh/uv/install.sh | sh \
 && { chmod a+rX /usr/local/bin/uv /usr/local/bin/uvx 2>/dev/null || true; }

# Claude Code CLI — PINNED to the version whose flag surface was verified in
# the plan (Phase 0). Do NOT bump without re-verifying flags.
RUN npm install -g @anthropic-ai/claude-code@2.1.114

# Locally-built claude-mem plugin. The build-agent-image.sh wrapper runs
# `npm run build` before `docker build`, so plugin/ is populated in the build
# context. We do NOT install claude-mem from npm — we want the current
# worktree under test.
COPY plugin/ /opt/claude-mem/

# Runner script — entrypoint for per-instance invocation (Phase 2 deliverable).
COPY evals/swebench/run-instance.sh /evals/swebench/run-instance.sh
RUN chmod +x /evals/swebench/run-instance.sh

# Pre-create per-instance config dirs. run-instance.sh overrides HOME to a
# scratch dir for isolation, but having these present keeps tools from
# bailing if they probe the default locations before HOME is set.
RUN mkdir -p /root/.claude /root/.claude-mem

# Non-root user. Claude Code refuses `--dangerously-skip-permissions` /
# `--permission-mode bypassPermissions` when euid==0 as a safety rail, so we
# need an unprivileged user for headless batch runs. node:20 already ships a
# `node` user at uid 1000 — reuse it.
RUN mkdir -p /home/node/.claude /home/node/.claude-mem \
 && chown -R node:node /home/node /opt/claude-mem

USER node
WORKDIR /home/node

ENTRYPOINT ["/evals/swebench/run-instance.sh"]
