This repository manages my macOS settings. It uses mise and custom Zsh scripts.
The configuration includes keyboard shortcuts for launching apps, managing windows, and editing text. These shortcuts work best with my custom keyboard layout.
Clone the repository and initialize a machine:
git clone --single-branch --branch main git@github.com:minusfive/dot.git ~/dev/personal/dot
cd ~/dev/personal/dot
./scripts/install-mise.zsh
source scripts/mise-env.zsh
mise run system:bootstrap
mise run bootstrap- The
./scripts/install-mise.zshinstallsmisewhen it is not available and checks the supported installation. On success it prints the commands for next steps. - Sourcing
scripts/mise-env.zshaddsmiseto$PATHso the command can be executed, and loads the persisted profile (if one exists) before the first bootstrap. - The
misesystem:bootstraptask asks for approval before it updatesmise, changesmacOSpreferences, places files, installs tools and applications, and clones repositories. - The
bootstrap:pre-packagestask asks for a second confirmation before it persists the selected profile. mise run system:bootstrap --dry-runforwards the selected profile to nativemise bootstrap --dry-runwithout invoking an explicit self-update or changing profile state. The control-planeself_update.autosetting remains authoritative for eligible interactive mise invocations.- The
misebootstraptask updates the cleanup inventory, removes stale links, and applies repository fixes after the system bootstrap. - The bootstrap is not transactional. If a phase fails, earlier phases remain applied. Fix the reported phase, then rerun
mise run system:bootstrap --profile <profile>with the same profile.
The work profile is the default and excludes personal-only tools and applications. To apply the personal profile, run:
mise run system:bootstrap --profile personalThe bootstrap:pre-packages task saves the selected profile at ${XDG_STATE_HOME:-$HOME/.local/state}/minusfive/profile after confirmation. The system bootstrap exports the selected value as the zsh environment variable DOT_PROFILE. A run without --profile reuses the persisted profile; when no profile has been saved, it uses work.
Each profile loads a different group of mise modules. These modules list the files and tools for that profile.
Hammerspoon reads the same state file through the ProfileState Spoon so it can customize keyboard shortcuts and other automations for the selected profile. The hs.settings interface stores the profile in macOS defaults under a custom key, so other applications can read it.
Each repository path selects a local identity and credential profile for Git. The personal domain list has a tracked source. Work domains, identity data, and authentication settings stay outside this repository. The read-only pre-commit check blocks credential helpers and unapproved host settings in tracked files. See Git credential profiles for setup and migration.
The home/ directory mirrors the target user's $HOME layout. mise places selected files where the corresponding tool or application expects to find them, including mise itself. A placed file can be a link, a copy, or an edit of an existing file.
The dotfiles, bootstrap.files, and bootstrap.directories entries describe how and when mise manages files and directories.
mise supports several ways to define how files are managed. This repository primarily uses the following types:
- A
symlinklinks one file directly to the repository. Edits at the installed path change the repository file and appear as repository changes. Edits made by external tools to linked files appear as repository changes. Those changes are then checked by hooks, and reviewed by agents and myself, before every commit. symlink-eachlinks every file that it finds in a source directory. It does not copy files that exist only at the target. Repository-only files need explicit exclusions.- A
copycreates a regular target file from a source file.blockandlineedits can then manage selected parts of that target without making it a link. - A
templatedynamically creates a target output file from a source file and arbitrary inputs. Edits to the output do not change the source. - A
blockmanages text between marker comments. Alinemanages one exact line. Both leave the rest of the target unchanged. - A
mergecan update specific entries or values in a target file without managing the whole file. Combined withtemplatethose values can be dynamically rendered from other inputs.
This granular file management approach means other generated files or values such as histories, caches, databases, credentials, etc., stay in their original location, outside this repository. This prevents accidental check-ins of sensitive data, and preserves application-managed permissions and cleanup.
The files are grouped by purpose. Each module manages related resources. A dotfiles entry can manage a whole file or selected configuration values. This keeps each setup area small and easier to understand. Repository-only guidance or maintenance files can stay co-located with managed files without polluting target locations.
.
├── .agents/ # repository-only guidance, skills, and evaluation files
├── AGENTS.md # repository instructions
├── .mise/ # repository-local tools and tasks
├── assets/ # images
├── home/ # files mirrored under ~/
│ ├── .agents/
│ │ └── skills/ # global agent skills
│ ├── .config/
│ │ ├── 1Password/
│ │ ├── BetterDisplay/
│ │ ├── ...
│ │ └── mise/
│ │ ├── conf.d/ # per-tool module files
│ │ │ ├── module.1password.toml
│ │ │ ├── module.agents.toml
│ │ │ ├── module.bat.toml
│ │ │ └── ...
│ │ ├── config.toml
│ │ ├── mise.lock
│ │ ├── miserc.toml
│ │ ├── tasks/
│ │ └── utils/
│ ├── .ssh/
│ │ └── config # ~/.ssh/config
│ └── AGENTS.md # global agent instructions
├── scripts/ # setup and development tasks
├── tests/ # script tests
└── ...
The repository keeps global agent instructions and skills in home/. home/AGENTS.md and home/.agents/skills/ are source files. The mise agents module manages these sources like any other module. Harness-specific modules symlink the same files to each harness's global instruction and skill locations. This keeps one source of truth while allowing each harness to use its own paths.
The root AGENTS.md and .agents/ directory are repository-only. They guide work in this repository and are not deployed as global files.
mise tasks keep the root and home/ skill indexes synchronized. They validate the global skill evaluation files and check for name conflicts between repository-only and global skills. The hk check and pre-commit hooks run these validations with the other repository checks.
The repository manages the tools used for development. When you enter the repository, mise activates its project tools.
Run the setup task to install project dependencies and add automatic hk checks to mise:
mise run setupRun all configured checks:
mise run checkThe hk configuration defines the checks and fixes in one place. Markdown checks preserve the existing line wrapping and reformat paragraphs that use hard line breaks. The repository also permits selected inline HTML.
I previously maintained a configuration based on Nix. I no longer maintain it because mise now provides many of the features I used from Nix.
