Skip to content

Customizing

Templates live in templates/ and are built into the limabean binary, which writes them to ~/.cache/limabean/templates/ for Lima to read. They're layered with Lima's base: composition:

templates/
  layer-os.yaml       Ubuntu 26.04 LTS, VM size, agent forwarding, zsh login shell
  layer-base.yaml     everything every VM gets (built on layer-os)
  scratch.yaml        an environment (built on layer-base)
  features/           idempotent provisioning scripts, one per capability
  files/              files written into the VM (zshrc, env.sh, editorconfig)
  packs/              tool packs: pinned mise TOMLs, and apt lists
To… Edit
Add or upgrade a CLI tool A pack in packs/, or a pack of your own in ~/.config/limabean/templates/packs/ (details). Pin a version; limabean bump upgrades every pin within its major (--major for more), and a monthly workflow (bump.yml) opens a PR with the same.
Add a system package A pack's .apt list, or for every VM packages=(…) in features/apt-common.sh
Change the prompt, aliases or shell options files/zshrc
Add an environment variable for every shell files/env.sh
Add a tool's zsh completion a gen line in features/completions.sh
Change the global editorconfig files/editorconfig
Change CPU, memory or disk CPUS/MEMORY/DISK in ~/.config/limabean/config (or up --cpus/--memory/--disk), or the defaults (2 CPUs, 4 GiB, a 10 GiB disk) in layer-os.yaml
Describe a repository's VM A .limabean.yaml in the repository, for limabean up
Add your own environment ~/.config/limabean/templates/<env>.yaml with base: [./layer-base.yaml], then limabean up <name> <env>. No rebuild of limabean needed.

VMs are disposable, and rebuilding is how changes get applied:

limabean rebuild dev

Lima doesn't allow .. in relative paths or base template file names starting with _. That's why everything sits under templates/ and the layers are named layer-*.yaml.

Working on the templates

Changes to templates/ reach a VM after you rebuild limabean, or straight away if you point limabean at your checkout:

limabean --templates ./templates rebuild dev

Checks

CI (lint.yml) runs gofmt, go vet, go test (failing if total coverage drops below 90%), shellcheck on the provisioning scripts, limactl tmpl validate on each environment template, and goreleaser check. Locally:

go test ./... && go vet ./...
go test -coverprofile=coverage.out ./... && go tool cover -func=coverage.out | tail -1
LIMABEAN_TEST_KEYCHAIN=1 go test ./internal/keychain/   # also tests against your login Keychain

Command tests run every command against a fake Lima, Keychain and GitHub API. Forms are driven with keystrokes: ui.NewTerminalForms gives each form its own ui.Keys(…) input.

Building and releasing

limabean is built with GoReleaser (.goreleaser.yaml) as one universal macOS binary:

goreleaser release --snapshot --clean   # → dist/limabean_darwin_all/limabean
  • Every pull request gets a snapshot build (snapshot.yml), downloadable from the run's Artifacts.
  • Pushing a tag such as v0.1.0 runs release.yml, which tests, builds and publishes a GitHub release with the archive, checksums and a changelog.

README and site graphics

The images in docs/assets are rendered from the HTML sources in docs/assets/src with Google Chrome:

docs/assets/render.sh            # all images, or name one: render.sh banner

social-preview.png is the image GitHub shows when the repository is linked. Upload it under the repository's Settings → General → Social preview.