A macOS desktop client for coding agents. Puck gives Claude Code and Codex Slack-style, long-lived conversations — each agent is a contact in the sidebar — while every turn executes inside a Docker container you configure.
- Agents are named provider configurations: provider, model, system instructions, thinking level, a schema-driven options form (permission / sandbox modes, per-tool toggles, limits — declared per provider, rendered generically), and an advanced JSON passthrough. Each agent has one permanent conversation, persisted as a structured event log and replayed on launch — clickable turn cards, tool calls, and sub-agent chats survive restarts.
- Environments are persistent Docker containers with a host directory
mounted at
/workspace. Puck installs the provider CLIs + SDKs into the container, deploys a small runner agent, and speaks NDJSON to it overdocker execstdio. The container is the safety boundary: agents run with full tool access inside it, and nothing from the host is writable. - Providers implement one interface (
src/main/providers/): descriptor metadata, OAuth (sign-in in the system browser with a loopback callback, RFC 8252 style; tokens encrypted via the OS keychain), and container integration (packages, credential mirroring, environment). Adding a provider is one descriptor module, one registry entry, and one entry in the container runner'sPROVIDERStable.
Turns stream live: text renders as markdown, tool calls collapse into a per-turn card that opens full-screen, sub-agents get their own nested chats, and Claude's mid-turn questions render as answerable cards.
- macOS with Docker running (Docker Desktop or colima — bind-mount quirks are handled either way)
- Node 22+
npm install
npm startThen, in the app:
- Settings → Providers - connect Claude and/or ChatGPT. The sign-in opens in your default browser, where your existing sessions live, and completes on its own when the browser is redirected back to Puck.
- Settings → Environments — create an environment (base image or Dockerfile) and start it. First start installs the CLIs/SDKs.
- Pick an agent in the sidebar and say hello.
npm run typecheck # strict tsc
npm run lint
npm test # vitest unit suites
npm run test:e2e # boots the real app and smoke-checks the UIThe container runner lives in src/main/runner/runner.js (plain CommonJS,
bundled as a raw string and docker-cp'd into environments on start). Runner
changes take effect on the next environment restart.
MIT — see LICENSE.