google/dev-setup
Setting up a Capsem development environment from scratch. Use when onboarding a new developer, setting up a new machine, or troubleshooting environment issues. Covers prerequisites, first-time setup, tool installation, VM asset builds, container runtime configuration (Colima/Docker memory and CPU requirements), and verification steps.
npx skills add https://github.com/google/capsem --skill dev-setup
just _build-assets (kernel + rootfs builds)just testRun just doctor to check all of these:
| Tool | Purpose | Install |
|------|---------|---------|
| Rust (stable) | Host + guest binaries | rustup |
| just | Task runner | cargo install just |
| pnpm | Frontend package manager | npm i -g pnpm |
| Node.js 24+ | Frontend build | nvm or brew install node |
| uv | Python package manager | curl -LsSf https://astral.sh/uv/install.sh \| sh |
| Docker (via Colima on macOS) | VM image builds | brew install colima docker (macOS) or sudo apt install docker.io (Linux) |
| Docker BuildKit (buildx) | Cross-arch container builds | brew install docker-buildx (macOS) or sudo apt install docker-buildx-plugin (Linux) |
| Tart + sshpass (macOS) | Disposable clean-Mac package install gate | brew trust --formula cirruslabs/cli/softnet && brew install cirruslabs/cli/tart cirruslabs/cli/sshpass |
Rust targets (auto-installed by just doctor fix):
aarch64-unknown-linux-musl -- guest binaries (arm64)x86_64-unknown-linux-musl -- guest binaries (x86_64)Cargo tools (auto-installed by just doctor fix):
cargo-llvm-cov -- coveragecargo-audit -- vulnerability scannercargo-tauri -- Tauri CLIb3sum -- BLAKE3 checksumsOn macOS, Docker runs inside a Colima VM. The default memory allocation may be too small -- the rootfs build runs apt installs, npm installs, and curl-based CLI installers concurrently, which can OOM-kill the build (exit code 137).
Minimum: 12GB RAM. Recommended: 16GB RAM, 8 CPUs (Tauri's GTK/webkit2gtk dep chain pushes the install-test build past 8GB on cold caches; 12GB is the floor that doesn't OOM).
# First-time setup
brew install colima docker
colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8
# Restart with new resources
colima stop
colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8
# Verify
docker info | grep -E 'Total Memory|CPUs'
If Docker-dependent recipes fail on macOS, do not report Docker/Colima as
unavailable until you have checked for the common half-running Colima state.
The signature is:
colima list says the profile is Runningdocker version / docker info cannot connect to~/.colima/default/docker.sock
colima ssh -- docker ps fails with kex_exchange_identification,Connection reset by peer, or colima status reports
error retrieving current runtime: empty value
First recovery attempt:
colima stop
colima start
docker version
If the profile needs its expected resources restored, start with the explicit
Capsem defaults instead:
colima stop
colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8
docker version
Only after that restart fails should you treat Colima as a real environment
blocker. Record the exact failed command and the Docker/Colima output.
Docker runs natively on Linux -- no Colima or memory tuning needed.
sudo apt install docker.io
just doctor checks these resources automatically and fails if below minimum.
# 1. Clone and enter
git clone <repo> && cd capsem
# 2. Bootstrap (interactive: prompts [Y/n] before each install; --yes for CI)
./bootstrap.sh
# ./bootstrap.sh --yes # non-interactive
# 3. Boot the VM to verify everything works
just exec "echo hello from capsem"
bootstrap.sh lives at the repo root (not under scripts/). It runs just _build-assets as part of doctor's auto-fix, so step 3 just confirms the VM boots.
Three phases. Default at every prompt is Yes (Enter accepts; type n to decline). --yes and non-tty input both auto-accept.
| Phase | Tool | Channel |
|-------|------|---------|
| 1 (hard prereqs) | bash, git, curl | system package manager (you install) |
| 1 | rustup (stable, minimal profile) | sh.rustup.rs |
| 1 | just | just.systems -> ~/.local/bin |
| 2 | uv | astral.sh/uv -> ~/.local/bin |
| 2 | Python deps | uv sync |
| 2 (macOS) | flock, pnpm | brew |
| 2 (macOS) | tart, sshpass | brew |
| 2 (macOS) | colima, docker, docker-buildx | brew (+ symlink into ~/.docker/cli-plugins) |
| 2 (macOS) | Colima VM | colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8 |
| 2 | Frontend deps | pnpm install --frozen-lockfile |
| 3 | Doctor --fix | scripts/doctor-common.sh --fix -- Rust targets, cargo-llvm-cov, cargo-audit, b3sum, cargo-tauri (= tauri-cli crate), cargo-sbom, build VM assets, pack initrd |
Release-only local preflight also needs cdxgen. Install it with
npm install -g @cyclonedx/[email protected] before running
bash scripts/check-release-workflow.sh or local VM asset release dry runs.
Kernel selection is part of the profile-derived image build, not a standalone
developer setting. The build backend resolves the configured kernel branch
while materializing and building profile assets through capsem-admin/just.
Do not add a parallel kernel setting under runtime settings or backend-only
config.
Or step by step:
just doctor # Check tools (colored output, structured recap)
just doctor fix # Auto-fix missing targets, cargo tools, config files
just _build-assets # Build kernel + rootfs (~10 min)
just exec "echo hi" # Verify VM boots
If step 4 prints "hello from capsem" and exits cleanly, you're set.
just shell # Build + boot VM interactively (~10s)
just exec "CMD" # Build + boot + run command + exit
just test # Full release gate, including clean Tart .pkg install on macOS
just dev ui # Frontend dev server (mock mode, no VM)
just dev # Full Tauri app with hot-reload
See /dev-just for the complete recipe reference.
Do not create ~/.capsem/user.toml. Credentials are captured and replayed by
the credential broker plugin through profile/corp policy. Hermetic tests use
the local mock server and Ironbank fixtures; real OAuth/API-key manual runs are
debug evidence, not release proof.
Do not add setup-time admin or guest config roots. Runtime behavior is
profile/corp-owned; settings are UI/application preferences only. Generated
settings UI metadata may render controls, but it is not a product config
authority.
To avoid repeated permission prompts when using just and capsem commands, add these to your Claude Code settings. Run /update-config or edit .claude/settings.local.json:
{
"permissions": {
"allow": [
"Bash(just *)",
"Bash(uv run *)",
"Bash(cargo *)",
"Bash(pnpm *)",
"Bash(cd frontend && pnpm *)",
"Bash(npx *)",
"Bash(python3 scripts/*)",
"Bash(rustup *)"
]
}
}
This allows:
just * -- all recipes (run, test, build-assets, query-session, list-sessions, doctor, etc.)uv run * -- capsem-builder CLI and Python scriptscargo * -- Rust builds, tests, checkspnpm * -- frontend package management and buildsnpx * -- skills CLI and other npx toolspython3 scripts/* -- project scripts (check_session, list_sessions, etc.)rustup * -- target/component managementThe app binary must be codesigned with com.apple.security.virtualization entitlement or
Virtualization.framework calls crash. The justfile handles this automatically via _sign recipe.
Prerequisites (macOS only):
xcode-select --installentitlements.plist must exist in the repo root (checked into git)Verification: just doctor includes a signing test that compiles a tiny binary, signs it with
the entitlements, and verifies the operation succeeds. Run just doctor after initial setup to
confirm signing works.
Linux developers: codesign is not available and not needed on Linux. VM features use the
KVM backend when /dev/kvm and /dev/vhost-vsock are available. Use just test
for the same artifact-recording performance suite as macOS.
just exec fails with codesign errorjust doctor -- it will diagnose the specific signing issuexcode-select --installcat entitlements.plistcodesign --sign - --entitlements entitlements.plist --force target/debug/capsemcsrutil statusjust doctor failsRun just doctor fix to auto-fix all fixable issues. Fixes run in dependency order (rustup targets before cargo tools before build-assets before pack-initrd). Non-fixable issues show install hints.
just _build-assets or just _gate-install fails with exit code 137 (or 143 mid-cargo-build)The container runtime VM ran out of memory. Bump Colima to at least 12GB (16GB recommended):
colima stop && colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8just _build-assets fails with "Release file not valid yet"The container VM's clock has drifted. The builder uses Acquire::Check-Valid-Until=false to work around this, but if you see this error on an old builder version:
colima stop && colima start --vm-type vz --vz-rosetta --memory 16 --cpu 8 (resets clock)just _build-assets fails (other)docker infocapsem-admin profile check config/profiles/code/profile.toml --config-root configjust exec fails with "assets not found"Run just _build-assets first. Assets are gitignored and must be built locally.
cargo run or cargo test crashes with signing error.cargo/config.toml must exist and be tracked in git -- it configures the custom runner (scripts/run_signed.sh) that signs binaries with Virtualization.framework entitlements before executiongit checkout .cargo/config.toml_sign recipe signs separately, so just exec works even without the cargo runner -- but direct cargo run/cargo test and IDE integrations will crash.gitignore patterns (no / prefix) match at any depth. Always anchor with / when you mean root-only (e.g., /config.toml not config.toml), or you risk silently ignoring files in subdirectories like .cargo/.cargo/config.toml has linker config for musl targetsrustup target add aarch64-unknown-linux-musl x86_64-unknown-linux-muslas _ for libc calls (see /dev-rust-patterns)Docker builds accumulate images, build cache, and stopped containers inside the Colima VM. The VM uses a Virtualization.framework raw disk that only grows, never shrinks on its own -- even after docker system prune, macOS doesn't get the space back.
The _docker-gc recipe runs automatically after build-assets, cross-compile, and test-install to prevent this. It prunes containers, images >72h, build cache >72h, and runs fstrim to release freed blocks back to macOS. If disk is already full:
# One-time recovery
docker system prune -af --volumes # free space inside VM
colima ssh -- sudo fstrim /mnt/lima-colima # release it to macOS
To check current state: colima ssh -- docker system df (inside VM) and du -sh ~/.colima (host).
docker-credential-osxkeychain not found)When Colima is installed standalone (without Docker Desktop), ~/.docker/config.json may reference a credential helper that doesn't exist. The symptom is docker run failing to pull images with exec: "docker-credential-osxkeychain": executable file not found.
Fix: set credsStore to empty string in ~/.docker/config.json:
{ "credsStore": "" }
just doctor checks for this under "Container Runtime" and will flag the mismatch.
codesign -dvv target/debug/capsem 2>&1 | grep entitlementsls assets/arm64/vmlinuz assets/arm64/rootfs.erofsVmConfig::build() now rejects mismatched kernels at config time.RUST_LOG=capsem=debug just execThe doctor system is three bash scripts:
scripts/
doctor-common.sh # Entry point, cross-platform checks, fix registry, recap
doctor-macos.sh # macOS: Tart, Colima, Rosetta, codesigning, brew hints
doctor-linux.sh # Linux: KVM, apt/dnf hints
just doctor calls doctor-common.sh. just doctor fix calls doctor-common.sh --fix.
All fixable issues use an ordered fix registry defined at the top of doctor-common.sh. Each entry has an ID, command, and description. Checks call fixable <id> <label> to mark a fix as needed. Fixes run in registry order (dependency order), deduped by design.
Registry order (each depends on the ones above it):
rustup-targets -- cross-compile targetsllvm-tools -- rust-lld linkercargo-llvm-cov, cargo-audit, b3sum, cargo-tauri -- cargo toolsentitlements, cargo-config, run-signed -- git checkout config filespnpm-install -- frontend depsbuild-assets -- VM kernel + rootfs (needs docker)pack-initrd -- guest binaries (needs assets)fixable <id> <label>, not raw fail(). This registers the fix in the ordered registry.fail() with an install hint. System tools (node, docker, etc.) can't be auto-installed safely.doctor-macos.sh / doctor-linux.sh. Each defines check_platform() and tool_hint().docker buildx version tests functionality, not just file existence.can leave the Docker socket present but unusable. Use the Colima recovery
discipline above before filing or reporting a Docker/Colima blocker.
bootstrap.sh checks bare minimums (bash, git, curl, rustup, just), installs Python/frontend deps, then runs doctor-common.sh --fix.Take google/dev-setup from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm, npx, brew, cargo, go, docker.
Without those the skill loads but fails at the first command.