Personal dotfiles managed with chezmoi.
Fresh machine (one-liner):
sh -c "$(curl -fsLS get.chezmoi.io)" -- \
init --apply bkahlert --source ~/.local/share/chezmoiExisting machine:
brew install chezmoi
chezmoi init --apply bkahlert- chezmoi manages dotfiles — copies files to
$HOME(no symlinks). Source state lives inhome/(via.chezmoiroot). - ZDOTDIR — zsh config lives in
~/.config/zsh/, only~/.zshenvremains in$HOME. - Sheldon — zsh plugin manager (TOML config, Rust-based).
- Starship — cross-shell prompt (TOML config, Rust-based).
- Shell features — scripts, functions, aliases and keybindings are spread over several prefixed source paths. quick-access/ maps them with prefix-free symlinks and explains where a new one belongs.
- AI assistant configs —
~/.claude/,~/.copilot/,~/.codex/,~/.gemini/, and~/.config/agents/are tracked so settings, prompt rules and slash commands stay in sync across machines.
chezmoi edit ~/.gitconfig # edit a managed file
chezmoi diff # preview pending changes
chezmoi apply # apply changes to $HOME
chezmoi add ~/.config/foo/config # start managing a new fileSee quick-access/README.md — location map, which place a new command belongs in, resolution order, and zsh load order.
Edit the plugin list:
chezmoi edit ~/.config/sheldon/plugins.tomlAdd a plugin by adding a [plugins.<name>] section:
[plugins.my-plugin]
github = "author/repo"Update all plugins:
sheldon lock --updateEdit the prompt configuration:
chezmoi edit ~/.config/starship.tomlChanges take effect on the next prompt render (no restart needed).
On macOS, the Brewfile installs the Codex CLI. On Linux, install the CLI before applying if you want its setup to run. The Codex setup installs Superpowers through its upstream Codex marketplace and installs the same third-party skills as the other agents. Node.js comes from fnm.
User instructions explicitly read the shared
guidance at ~/.config/agents/AGENTS.md. Codex discovers repo-owned skills in
~/.agents/skills/ directly. The
config modifier manages
MCP definitions, plugin enablement, status line and desktop preferences.
Model selections, project trust, onboarding state and local integrations survive
applies. Authentication and session history stay local.
After applying, run codex login once, then start a new codex session.
codexd provides the same permission-bypass shortcut as the other agents;
it disables both approvals and the sandbox. Ordinary codex keeps its defaults.
Provisioning is covered by sandboxed tests; the paid capability targets below
currently cover Claude and Copilot only.
Claude's formatter and
Copilot's formatter use
a shared component.
See each script for its rendered parts and --help for options.
Copilot's dollar cost is a display estimate at 100 AIC per USD, not a verified
billed amount.
Use the preview helper when editing status lines. It runs both providers' source and installed formatters with Nerd Font icons and emoji fallbacks, so differences before and after applying are visible. Run it from the repository root:
./scripts/statusline-previewFor debugging, both formatters save their latest raw input as
claude-statusline-input.json and copilot-statusline-input.json in Python's
temporary directory (TMPDIR when set). These owner-only files contain session
metadata and are overwritten on every render.
Edit the terminal configuration:
chezmoi edit ~/.config/ghostty/configLive reload: press Cmd+Shift+, (macOS) or Ctrl+Shift+, (Linux).
See Ghostty configuration reference.
Personal SSH keys (github, etc.) live in iCloud Drive's Vault directory.
On chezmoi apply, .chezmoiscripts/run_onchange_after_dump-ssh-from-kdbx.tmpl
reads the vault (prompting for the master password via a macOS dialog) and
materializes ~/.ssh/conf.d/*.conf + *.pub files; the actual private keys are
pushed live into the launchd ssh-agent (SSH_AUTH_SOCK) by KeePassXC's own SSH
Agent integration when the database is unlocked.
KeePassXC is installed via the Brewfile, but its SSH Agent integration is an app preference chezmoi can't manage — set it up once per machine:
- Open KeePassXC and unlock your
kdbxfile(s). - Settings → SSH Agent → check "Enable SSH Agent integration", then fully quit and reopen KeePassXC (the per-entry tab below only appears after a restart).
- For each key entry, edit it → SSH Agent tab → check "Add key to agent when database is opened/unlocked" (usually already set from the kdbx template).
| Command | Coverage |
|---|---|
make lint |
shellcheck, zsh syntax, workflow lint |
make unit |
pytest unit tests and node driver test |
make integration |
Apply this checkout in a Fedora container; needs Podman |
make integration-native |
Apply into a temporary HOME on macOS; check Homebrew packages |
make ci |
Lint, unit and container integration; no agent login or model usage |
make integration-claude |
Paid, opt-in: effective Claude capabilities; needs Claude login |
make integration-copilot |
Paid, opt-in: effective Copilot capabilities; needs Copilot login |
make run / make vnc |
Start the inspection container / open its VNC viewer |
make stop / make clean |
Stop the inspection container / remove its images |
CI runs the same targets on every pull request; main requires the ci check. Details in AGENTS.md.
The authenticated targets test the currently applied configuration, not source
JSON or installer commands. They do not apply dotfiles or install missing tools.
Normal CLI sessions load user and project settings, plugins, skills and MCPs.
They are never part of make ci, make unit, or either apply integration target.
Running pytest directly skips them unless --live-agent claude or
--live-agent copilot is supplied.
| Capability | Required evidence |
|---|---|
| Context7 | Successful library resolution and a documentation query about Python's len |
| Chrome DevTools | Successful list_pages response from a real browser; no navigation or page changes |
IntelliJ idea |
Successful read of a tiny public fixture with a known marker |
| Superpowers | Successful verification-before-completion skill invocation, followed by a real printf check and evidence cited in the answer |
Assertions inspect structured tool calls and their results. An assistant's claim that a capability works is insufficient. These smoke tests prove explicit skill invocation, not automatic skill selection or consistent methodology adherence. The browser check proves connection and page listing, not every browser tool.
Prerequisites: the chosen CLI must be installed and logged in; Node.js/npm must be
on PATH for stdio MCPs; Chrome must be installed; IntelliJ must have this repository
open and serve MCP at http://127.0.0.1:64342/stream. Start from your normal shell
so exported secrets, including CONTEXT7_API_KEY, are available. Missing,
disabled, unauthenticated or broken capabilities fail rather than silently skip.
Copilot provisioning runs on chezmoi apply: its
agent setup registers
Context7 and Chrome DevTools alongside idea, installs Superpowers from its
upstream marketplace, and installs third-party skills. The
Claude setup registers
idea and installs skills; the
Gemini setup installs skills.
Each script runs only for its installed agent. Renaming these onchange scripts
makes their setup run again on the next apply. Copilot's
source settings also declare the
Superpowers marketplace and enabled plugin, so later applies keep it enabled
without rerunning setup. Chrome uses an isolated,
headless profile with usage statistics disabled; it does not attach to your
personal browser. Claude keeps its existing plugin configuration, so its live
check can expose the profile-picker failure recorded in the browser guidance.
Each target shares one session across all probes, has a 180-second timeout,
and performs no test-level retries. Claude uses Haiku, at most eight turns and a
$0.50 budget. Copilot uses Auto's efficiency tier and a 30-AI-credit soft cap,
the CLI's minimum. These are usage limits, not exact bill guarantees; an in-flight
response can exceed a soft cap. Normal startup hooks and CLI-level API retries can
also run. Only probe tools and printf receive explicit approval; file-write
tools are denied in Copilot. This is not an OS sandbox.
Copilot can read the shared agent guidance directory to follow its normal instructions.
For a cheaper focused check:
make integration-copilot AGENT_TEST_ARGS='--agent-capability idea'The selector is repeatable and works for either authenticated target. Private
transcripts and stderr are saved under pytest's temporary directory, printed at
startup, rather than committed or dumped into failures. Copilot's final usage
statistics are saved alongside them as usage.json.
Shared IntelliJ configurations live in .run/: ci (no AI usage), Claude capabilities (paid, opt-in) and Copilot capabilities (paid, opt-in). If IntelliJ does not discover externally added configurations, reopen the project. The CI target does not touch your real HOME or invoke paid agents, but still uses network downloads and container resources; “no AI usage” is not “no side effects.”