# Quince — a scheduled, headless Claude Code agent for Glitch University. # The image carries only tools. Everything that *is* Quince lives on the # mounted volume at /home/quince, so the container stays disposable. FROM node:22-bookworm-slim # System tools: python (for gutasktool), git + openssh (for ramanujan), # ca-certificates (HTTPS to the API), tzdata (for local-time scheduling), # procps (ps/sleep niceties), curl. RUN apt-get update && apt-get install -y --no-install-recommends \ python3 python3-pip python3-venv \ git openssh-client ca-certificates tzdata procps curl \ && rm -rf /var/lib/apt/lists/* # Claude Code CLI. RUN npm install -g @anthropic-ai/claude-code # Non-root user. Claude Code refuses --dangerously-skip-permissions as root, # and we want the volume owned by a stable uid the agent can write to. ARG QUINCE_UID=1000 # The node base image already has a user at uid 1000; drop it, then create quince. RUN existing="$(getent passwd ${QUINCE_UID} | cut -d: -f1)"; \ if [ -n "$existing" ] && [ "$existing" != "quince" ]; then userdel -r "$existing" 2>/dev/null || true; fi; \ useradd --create-home --uid ${QUINCE_UID} --shell /bin/bash quince # Entrypoint (scheduler loop) + wake script (one awakening). COPY entrypoint.sh /usr/local/bin/entrypoint.sh COPY wake.sh /usr/local/bin/wake.sh RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/wake.sh # Baked identity. This is the canonical Quince — CLAUDE.md, GOALS.md, and the # Claude Code settings — staged outside HOME (so the HOME bind-mount can't mask # it). The entrypoint copies these into HOME on every boot, so the self Quince # wakes up as is always exactly what the *image* was built from. Change the self # by editing deploy/identity/ in the repo and rebuilding. COPY identity/ /opt/quince/identity/ USER quince ENV HOME=/home/quince # ~/.local/bin holds the `gutask` console script after pip install --user -e. ENV PATH=/home/quince/.local/bin:$PATH WORKDIR /home/quince ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]