Skip to content
bkahlertPublic

About

Personal dotfiles — chezmoi-managed zsh setup with Sheldon, Starship, Ghostty, lazy-loaded plugins, and 1Password secrets. macOS + Linux.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

dotfiles CI License Buy Me A Coffee

Personal dotfiles managed with chezmoi.

Quick start

Fresh machine (one-liner):

sh -c "$(curl -fsLS get.chezmoi.io)" -- \
  init --apply bkahlert --source ~/.local/share/chezmoi

Existing machine:

brew install chezmoi
chezmoi init --apply bkahlert

How it works

  • chezmoi manages dotfiles — copies files to $HOME (no symlinks). Source state lives in home/ (via .chezmoiroot).
  • ZDOTDIR — zsh config lives in ~/.config/zsh/, only ~/.zshenv remains 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.

Making changes

Dotfiles (chezmoi)

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 file

See chezmoi daily operations.

Shell features (scripts, functions, aliases)

See quick-access/README.md — location map, which place a new command belongs in, resolution order, and zsh load order.

Plugins (Sheldon)

Edit the plugin list:

chezmoi edit ~/.config/sheldon/plugins.toml

Add a plugin by adding a [plugins.<name>] section:

[plugins.my-plugin]
github = "author/repo"

Update all plugins:

sheldon lock --update

See Sheldon documentation.

Prompt (Starship)

Edit the prompt configuration:

chezmoi edit ~/.config/starship.toml

Changes take effect on the next prompt render (no restart needed).

See Starship configuration.

Codex

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.

Agent status lines

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-preview

For 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.

Ghostty

Edit the terminal configuration:

chezmoi edit ~/.config/ghostty/config

Live reload: press Cmd+Shift+, (macOS) or Ctrl+Shift+, (Linux).

See Ghostty configuration reference.

SSH keys (KeePassXC)

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:

  1. Open KeePassXC and unlock your kdbx file(s).
  2. Settings → SSH Agent → check "Enable SSH Agent integration", then fully quit and reopen KeePassXC (the per-entry tab below only appears after a restart).
  3. 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).

Testing

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.

Live agent capabilities

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.”

About

Personal dotfiles — chezmoi-managed zsh setup with Sheldon, Starship, Ghostty, lazy-loaded plugins, and 1Password secrets. macOS + Linux.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages