Skip to content
LarsNorlanderPublic

About

A project for managing macOS configurations across machines. πŸ§™πŸ»β€β™‚οΈ

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

117 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Grimoire

Personal macOS configuration: system packages, GUI apps, shell setup, and tool configs for work and personal Macs.

Grimoire is intentionally macOS-only. It is built around nix-darwin, Homebrew, darwin-rebuild switch, and macOS desktop conventions; Linux support belongs in a separate tool, not behind conditionals here.

Install

On a new machine, clone to ~/.grimoire and run the wrapper directly:

git clone git@github.com:LarsNorlander/grimoire.git ~/.grimoire
~/.grimoire/grimoire bootstrap

The wrapper offers to install Nix and Homebrew if they are missing. bootstrap prompts for a profile, applies runes, then applies rites. It is safe to re-run.

After bootstrap, use the narrower verbs for day-to-day work. Run grimoire --help and grimoire <verb> --help for the current flag reference.

Concepts

  • Runes (runes/) are nix-darwin system configuration: packages, Homebrew apps, fonts, and macOS defaults.
  • Rites (rites/<tool>/) build and link per-tool config into place.
  • Tome (tome/) is gitignored build output. Managed symlinks point here, not directly at tracked source files.
  • Familiars (familiars/) are ephemeral Nix shells for tools that should not persist on the machine.
  • Profiles (work or personal) select the nix-darwin output and any profile-specific rite behavior. The current profile lives in ~/.grimoire-profile.

Commands

  • grimoire bootstrap β€” provision a fresh machine by applying runes, then rites.
  • grimoire inscribe β€” apply runes.
  • grimoire cast [tool ...] β€” apply rites, rebuilding tome files and refreshing symlinks.
  • grimoire diff [tool] β€” inspect drift between rite sources, tome files, and the manifest.
  • grimoire accept <tool ...> β€” copy externally edited tome files back to rite sources where possible.
  • grimoire update β€” fast-forward the checkout to its upstream; with local commits or uncommitted changes in the way, it reports them and leaves the reconciliation to git.
  • grimoire profile β€” show or change the current profile.
  • grimoire summon <name> β€” enter an ephemeral familiar shell, or run one command in it with --.
  • grimoire scribe [tool ...] β€” generate cheatsheet JSON from rites that document themselves.

Rites and drift

A rite is a Python module, rites/<tool>/rite.py, whose rite(ctx) function registers operations with RiteContext:

  • copy() copies source files from the rite into tome/.
  • write() generates files into tome/ from Python builders.
  • link() creates user-facing symlinks to tome/.
  • patch() owns selected keys inside a JSON file the machine otherwise owns. The rite holds a fragment; its leaf keys are merged into the live file in place, so this is the one operation that writes a real file instead of symlinking. Arrays are replaced whole, not merged.
  • hook() performs necessary imperative setup.
  • doc() registers cheatsheet data for grimoire scribe.

tome/.manifest records each built file's hash, the operation that produced it, and the symlinks pointing at it, so a full cast can prune files a rite stopped managing along with their links. If a tool edits a managed file in tome/, cast skips it rather than overwriting it silently. Use diff to inspect the state, cast --force to rebuild from source, or accept to pull external edits back into copy()-managed rite sources. Generated write() files require manual reconciliation. For patch() files, drift and accept look only at the owned keys; the rest of the file is free to change.

Profile-specific rites use a header directive:

#!/usr/bin/env python3
# profile: work

Rites without a directive apply to every profile.

Claude Code instructions and ccstatusline are work-only. Zed settings are generated from the shared rites/zed/settings.json base plus an optional profile overlay; rites/zed/work.json enables Claude ACP only on work. Reconcile edits to Zed's generated settings in those source files manually.

Containers

The work profile runs Docker through Lima rather than Docker Desktop. The lima rite manages the VM template at ~/.lima-templates/docker.yaml and creates the rootless docker instance on first cast, which downloads an Ubuntu image and takes a few minutes. The docker rite creates a lima-docker context pointed at the VM's socket and owns the keys in ~/.docker/config.json that select it and Homebrew's CLI plugins. The VM does not start at login; limactl start docker brings it up.

Cheatsheets

grimoire scribe writes schema-validated JSON for documented rites. Grimoire only produces data; rendering belongs to homepage. By default, sheets are written to homepage's content directory; override with --output or GRIMOIRE_SCRIBE_OUTPUT.

Generated sheets carry a generator marker, and grimoire only overwrites or prunes sheets it owns so hand-written sheets can share the same directory.

Secrets

Secrets are managed through 1Password and its CLI (op). Nothing sensitive belongs in this repository.

Contributing

This is a personal configuration repo. Contributions are not accepted, but you are welcome to fork it.

Built with Pi

This repo is maintained with the help of Pi.

About

A project for managing macOS configurations across machines. πŸ§™πŸ»β€β™‚οΈ

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages