Skip to content

About

VS Code dev container for the pi coding agent: hardened, non-root, mise-based tooling. First target: Go.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

57 Commits

Folders and files

Repository files navigation

pi-devcontainer

A VS Code dev container that runs the pi coding agent in a lightly hardened, non-root Linux environment, without restricting anything pi can do. Go, Java and a language-agnostic base are supported as equal, independently maintained targets.

The agent gets a real toolchain and a workspace it can write to. It does not get your host filesystem, your SSH keys, your other repositories, or your pi credentials. Adding a new CLI tool is one line and no image rebuild, which matters more than it sounds: pi has no MCP, so CLI tools are the extension mechanism.

Prerequisites

  • Docker (Docker Desktop on Windows or macOS)
  • VS Code with the Dev Containers extension
  • Git, with Git Bash on Windows (needed for git clone anyway, and the shell the scripts below run in)
  • Optional, for the acceptance checks: the devcontainer CLI

Quick start

git clone https://github.com/zorak1103/pi-devcontainer
cd pi-devcontainer
./scripts/init-project.sh go /path/to/your/go-project     # or: java /path/to/your/java-project
                                                          # or: base /path/to/your/project

(Windows: run these in Git Bash, not PowerShell or cmd, since the scripts are .sh files.)

base is for projects without a build toolchain of their own — documentation, notes, pure pi projects. It ships git and nothing language-specific; anything the project does need goes into the project's mise.toml (Python, Rust, ...), see docs/extending.md.

Already using this template? init-project.sh <dir> is now init-project.sh <go|java|base> <dir> — the language argument became mandatory when Java support was added. --update is unaffected: it reads the language back out of your project's existing devcontainer.json.

Add the two lines the script prints to your project's .gitignore, set your API key once (see docs/setup-windows.md; on Windows this needs a VS Code restart; for OpenRouter or another provider, see docs/providers.md), then open the project in VS Code and choose Reopen in Container. In the container's terminal:

pi

Optionally, create ~/.pi/devcontainer/ for settings, tools and context that follow you across projects. personal/ is a working template. Without it the container still comes up, with pi's defaults.

What you get

Layer Lives in Holds
Base devcontainer.json in your project language image (Go, Java, or base), Node, mise, pi, OpenSpec, the hardening flags — see architecture.md
Personal ~/.pi/devcontainer/ on your host your pi settings, model/provider config, MCP servers, Claude plugins, your tools, your global AGENTS.md
Project committed in the repo project toolchain, AGENTS.md, project pi settings

The personal layer is copied into the container, never mounted, so it stays writable inside and untouched outside. Details in docs/architecture.md.

Verifying an installation

./scripts/verify.sh /path/to/your/project    # Go, Java or base, detected from its devcontainer.json

~30 checks against the live container: pi's version, the packages, tools reachable from a non-interactive shell, a real build (go build or mvn compile), the capability ceiling, that sudo is refused, that the API key is absent from docker inspect, and that every volume is writable.

verify.sh deliberately makes no model call. One test is therefore manual:

pi -p "say hello"

It must answer without a trust prompt and leave a session file in .pi/sessions/.

Security posture

Lightly hardened, and the emphasis is on lightly: this bounds the blast radius of a misbehaving agent, it does not contain a determined attacker. Non-root, capabilities dropped to one, no-new-privileges, the API key kept out of docker inspect, the host home never mounted. Just as deliberately out of scope: the key still lives in the container, and network egress is unrestricted. See docs/threat-model.md.

Documentation

Document Contents
architecture.md the three layers, the mount and volume map, what each script does
decisions.md every design decision, its alternatives, and what it costs
findings.md measurements against the real base image, with reproduction commands
setup-windows.md Docker Desktop, the API key, the CRLF trap
how-to.md recipes: add/remove a pi package, persist an extension's config, set up or update a project
providers.md configuring OpenRouter, other API-key providers, and self-hosted/proxied endpoints
threat-model.md what the hardening bounds, and what it explicitly does not
extending.md adding tools, system packages, pi resources, new language targets
comparison.md how this relates to marcfargas/pi-devcontainers

If you read one, read findings.md. Half of this project's design exists because a measurement contradicted a reasonable assumption.

Credits

  • pi by earendil-works.
  • marcfargas/pi-devcontainers (MIT): the origin of several ideas here, including the isolated pi runtime and the layered-mount approach. It solves a different problem: running pi on a Windows ARM host without an IDE. comparison.md explains what was adopted and what was not.
  • mise for the tool plane.

License

MIT

About

VS Code dev container for the pi coding agent: hardened, non-root, mise-based tooling. First target: Go.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages