diff --git a/Dockerfile b/Dockerfile index f91d298..811fa6e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,7 +28,7 @@ ENV AGENT=${AGENT} \ LC_ALL=C.UTF-8 \ TZ=America/Los_Angeles \ HOME=/home/${AGENT} \ - PATH=/home/${AGENT}/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + PATH=/home/${AGENT}/.local/bin:/home/${AGENT}/.agent-config/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # System deps + gh + tmux + Node + bubblewrap + standard CLI utilities. # ttyd is fetched separately below — Debian Bookworm doesn't carry it. @@ -37,7 +37,8 @@ RUN set -eux; \ apt-get install -y --no-install-recommends \ ca-certificates curl git gnupg jq less vim sudo tini \ bash-completion locales tmux unzip zip openssh-client \ - build-essential python3 python3-pip \ + build-essential python3 python3-pip python3-venv \ + ripgrep fd-find dnsutils iputils-ping \ bubblewrap \ passwd; \ # Node.js from NodeSource (pinned major version). NodeSource ships @@ -72,6 +73,55 @@ RUN set -eux; \ chmod +x /usr/local/bin/ttyd; \ ttyd --version +# uv — fast Python package manager and tool runner. `uvx` is what +# agent-config's mcp-servers/plane.json launches (`uvx plane-mcp-server`), +# and codex/claude generally benefit from having it on PATH. +RUN curl -fsSL https://astral.sh/uv/install.sh \ + | env UV_INSTALL_DIR=/usr/local/bin sh + +# Debian renames fd → fdfind; expose canonical name codex/claude expect. +RUN ln -sf /usr/bin/fdfind /usr/local/bin/fd + +# Infra CLIs the agent will reach for when working on apk8s / Cloudflare. +# All single-binary installs from upstream — no apt repos to babysit. +ARG KUBECTL_VERSION=v1.34.1 +ARG HELM_VERSION=v3.16.3 +ARG FLUX_VERSION=2.4.0 +ARG CLOUDFLARED_VERSION=2026.2.0 +ARG OP_VERSION=2.31.1 +RUN set -eux; \ + arch="$(dpkg --print-architecture)"; \ + # kubectl + curl -fsSL "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${arch}/kubectl" \ + -o /usr/local/bin/kubectl; \ + chmod +x /usr/local/bin/kubectl; \ + kubectl version --client=true --output=yaml | head -2; \ + # helm + curl -fsSL "https://get.helm.sh/helm-${HELM_VERSION}-linux-${arch}.tar.gz" \ + | tar -xz -C /tmp; \ + mv "/tmp/linux-${arch}/helm" /usr/local/bin/helm; \ + rm -rf "/tmp/linux-${arch}"; \ + helm version --short; \ + # flux CLI + curl -fsSL "https://github.com/fluxcd/flux2/releases/download/v${FLUX_VERSION}/flux_${FLUX_VERSION}_linux_${arch}.tar.gz" \ + | tar -xz -C /tmp; \ + mv /tmp/flux /usr/local/bin/flux; \ + flux --version; \ + # cloudflared + curl -fsSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-${arch}" \ + -o /usr/local/bin/cloudflared; \ + chmod +x /usr/local/bin/cloudflared; \ + cloudflared --version | head -1; \ + # 1Password CLI (op). Uses .deb because the static binary needs the + # .deb's apparmor / udev hooks for the desktop integration; on Linux + # the deb just drops a binary in /usr/bin. + curl -fsSL "https://cache.agilebits.com/dist/1P/op2/pkg/v${OP_VERSION}/op_linux_${arch}_v${OP_VERSION}.zip" \ + -o /tmp/op.zip; \ + unzip -d /tmp/op /tmp/op.zip; \ + mv /tmp/op/op /usr/local/bin/op; \ + rm -rf /tmp/op /tmp/op.zip; \ + op --version + # Per-agent CLI install. Both are npm packages; the global install puts # `codex` or `claude` on PATH for the non-root user. RUN case "$AGENT" in \