- When changing this repo's architecture or how Pi is built, launched, containerized, configured, or persisted, update the repo-memory notes in this
AGENTS.md. - Do not edit anything under
pi/agent/git/. - Do not commit files matched by
.gitignore. - You are Pi, running inside the Pi coding-agent harness. Do not start another Pi session or run
piunless explicitly asked for testing. - Pi documentation:
- Main:
/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/README.md - Docs:
/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/docs - Examples:
/usr/local/lib/node_modules/@earendil-works/pi-coding-agent/examples
- Main:
This repository is a Docker wrapper around @earendil-works/pi-coding-agent plus a persisted, preconfigured Pi home under pi/.
- Build flow:
./build.sh [version]builds imagepi-coding-agentfromDockerfile.release, passing hostUID,GID, and Pi npm packageVERSION(defaultlatest)../build.sh --installed-versionruns./pi.sh --versionand extracts the installed semver.Dockerfile.gitis an alternate development Dockerfile that clonesearendil-works/pi-mono, builds packages, packspackages/coding-agent, and installs that tarball instead of npm release. GitHub Actions workflow.github/workflows/publish-dockerhub.ymlpublishes multi-archDockerfile.releaseimages to DockerHub onmain,v*tags, or manual dispatch usingDOCKERHUB_USERNAME/DOCKERHUB_TOKENsecrets. - Release image: based on
node:current-trixie-slim; creates userpimatching host UID/GID; installs zsh, git, gh, glab, sentry-cli, curl/wget/jq/rg/tree/file, sudo/gosu, tmux/qemu plus QEMU firmware/ROM packages needed by Gondolin (ovmf/ipxe-qemuon amd64,qemu-efi-aarch64/ipxe-qemuon arm64), Java 21, uv-managed Python, autopep8, pytest, mitmproxy, and debugging CLIs (xh,grpcurl,websocat). It updates npm globally to latest, installs Pi globally withnpm install -g @earendil-works/pi-coding-agent@$VERSION @earendil-works/gondolin, setsWORKDIR /workspaceandHOME=/home/pi, and usesentrypoint.shas the container entrypoint. - Runtime entrypoint:
entrypoint.shstarts as root, sets thepiuser's sudo password fromPI_SUDO_PASSWORDor generates/prints a random one, configures global git identity fromBOT_GIT_NAME/BOT_GIT_EMAIL, logsghin withBOT_GH_TOKEN, writes Sentry auth fromBOT_SENTRY_TOKEN, then executesgosu pi pi "$@". In other words: the image entrypoint always ends by calling the actualpibinary as the non-rootpiuser. - Host launcher:
./pi.sh [launcher-options] [pi args...]is how Pi is normally called. It creates/sources.env, parses wrapper flags, discovers the project root by walking upward from$PWDuntil.git,.project, or.projectile, computes the relative working directory, and starts Docker. Normal Pi CLI args are passed through to the container after wrapper-added args.--entrypoint PATH|NAMEselects the host entrypoint script mounted over/usr/local/bin/entrypoint.sh; bare names resolve to bundled shortcuts such aszsh->entrypoint-zsh.sh. - Docker invocation in
pi.sh:docker run --rmplus-itonly for interactive terminals; optional wrapper flags can add Docker-pport publishing,--network/--docker-networkto attach the started container to an existing Docker network,--volume/--docker-volumeto pass additional Docker-vmounts,--env/--docker-envfor extra environment variables, and--env-file/--docker-env-filefor extra env-files (relative env-file paths resolve from the invocation cwd and are passed after this repo's.env); mounts detected project root to/workspaceas rw or ro; mounts this repo'spidirectory to/home/pi/.pi:rw; mounts.cache/checkoutsand.cache/gondolin; sets-w /workspace/$REL_PATH; passesPI_PROJECT_ROOT,PI_MOUNT_MODE,PI_HOST_HOSTNAME, selected provider/API env vars, and--env-file .env; image ispi-coding-agent; final command ispi-coding-agent $TOOLS --session-dir ... [extra args] [user pi args], which the entrypoint converts togosu pi pi .... - Session/config persistence: Pi config and state live outside target projects in this repo's
pi/agent/because it is mounted as/home/pi/.pi. Sessions are forced to/home/pi/.pi/agent/sessions/--<canonical-host-project-root>--so each host project gets stable saved sessions. Runtime/secrets paths such aspi/agent/auth.json,pi/agent/sessions/*,pi/agent/git/, and.cache/are gitignored. - Important
pi.shmodes:--ro/--readonlymounts/workspaceread-only and limits tools to read/search/list; a.pi_rofile in the current directory also forces ro.--port/--publishaccepts Docker-style port mappings such as8080:8080and forwards them intodocker run -p; short-pis left for Pi CLI args.--network/--docker-networkaccepts an existing Docker network name or mode and forwards it intodocker run --network.--volume/--docker-volumeaccepts Docker-style volume mappings such as/host/path:/workspace/sharepoint:roand forwards them intodocker run -v.--env/--docker-envand--env-file/--docker-env-filepass per-run Docker environment values/files.--installwrites shell aliasespi,pic, andpicommit.--updatechecks npm latest, rebuilds if a newer Pi release exists, and always runs./pi.sh updatefor Pi packages even when the image is already current.--sessionslists persisted session files.--commitrewrites args to run/commit --force --user ... --email ..., optionally withPI_FAST_PROVIDER/PI_FAST_MODEL. - Package-management passthrough: if the first Pi arg is
install,remove,update,list, orconfig,pi.shsuppresses wrapper tool/session args so Pi package commands operate normally. - Optional project notes: if
.volumes.ymlexists in this repo and maps the original host cwd to another directory,pi.shmounts that directory read-only at/workspace-notesand appends a system prompt telling Pi about it. - Bundled Pi customization lives under
pi/agent:settings.jsonchooses theme/defaults/enabled models/packages and disables older quota extensions;models.jsondefines local Ollama/LM Studio OpenAI-compatible providers athost.docker.internal;modes.jsonstores named modes;extensions/includes/files-changed+get_files_changed,/quota+ quota tools, Kilo Code provider commands,switch_model,/codex-account+/codex-switchfor Pi-only OpenAI Codex account snapshots, and a footer showing host project/root/mount mode;prompts/commit.mddefines/commit;skills/git-autopep8formats only changed Python lines.