Personal development environment configuration for macOS and Windows — terminal, JetBrains settings, provisioning, and shell plugins.
macOS
bash install.shWindows (PowerShell, run as Administrator)
pwsh install.ps1Both scripts:
- Install Homebrew (macOS) or Chocolatey (Windows) if missing.
- Install Bun and Git if missing.
- Clone this repository to
$DF_ROOT_DIRECTORYif not already present. - Hand off to
bun provision/main.ts <platform>which runs the full provisioner.
The shell loader (shell/shell.plugin.zsh) sources every shell/*.plugin.zsh file in numeric order.
Zsh is the primary shell on macOS; bash is supported on Windows via framework/bash_loader.sh.
All tool installation and configuration is driven by the TypeScript provisioner in provision/, run by
Bun with zero third-party dependencies. The entry point is provision/main.ts, which
reads provision/manifest.ts and executes each entry:
- Tools — installed via Homebrew on Apple Silicon Macs or Chocolatey on Windows. Homebrew is skipped on Intel Macs.
- Configurators — one-time setup scripts in
provision/configurators/. - Migrations — idempotent data-migration scripts in
provision/migrations/.
Controls where install scripts clone and where the provisioner looks for the repo.
export DF_ROOT_DIRECTORY=/path/to/your/dotfiles
bash install.shIf unset, the default fallback is $HOME/Documents/GitHub/dotfiles (macOS/Linux) or
%USERPROFILE%\Documents\GitHub\dotfiles (Windows).
This variable is a no-op in the current architecture. The legacy timing harness was removed when the bash orchestration layer was consolidated into the provisioner. There is no custom timing instrumentation in the provisioner.
Configurators record their completion in ~/.df_data/state.json. To force one to run again, remove
its key from that file:
# Example: re-run the ghostty configurator
# Open ~/.df_data/state.json and delete the "ghostty" key, then re-run:
bun provision/main.ts macOr you can delete the key with jq:
jq 'del(.configurators_run.ghostty)' ~/.df_data/state.json > /tmp/state.json && mv /tmp/state.json ~/.df_data/state.json
bun provision/main.ts mac| Dependency | Required for | Notes |
|---|---|---|
| Bun | Provisioning | Not needed for shell startup |
| Homebrew | Apple Silicon macOS tools | Installed automatically by install.sh |
| Chocolatey | Windows tool installation | Installed automatically by install.ps1 |
| zsh | Shell plugins (macOS) | Pre-installed on macOS |
Bun is a hard runtime dependency for provisioning. It is not required for shell startup — you can source the shell plugins without Bun installed.
User-specific and workflow-specific exports (API tokens, cert paths, etc.) live in the sibling private
repository at ~/Documents/GitHub/dotfiles-private/. The shell loader sources that repo's entrypoint.sh,
which loads config/env.sh, config/alias.sh, and config/func.sh when present.
The provisioner modernization consolidated the bash orchestration layer into a single typed entry point. It was first ported from bash to Lua, then from Lua to TypeScript (run by Bun with zero third-party runtime dependencies), which is the current implementation. Key metrics:
| Area | Before (shell/bash) | After (TypeScript) |
|---|---|---|
framework/ (7 files) |
974 lines | removed |
autoloader/ (2 files) |
60 lines | removed |
startup/ (1 file) |
18 lines | removed |
install.sh |
207 lines | 65 lines |
install.ps1 |
137 lines | 143 lines |
provision/ (TS) |
— | 1,580 lines |
| Total | 1,396 lines | 1,788 lines |
The provisioner total is higher because it is a proper library with state management, platform abstraction, and per-platform backend routing — capabilities that were previously handled ad-hoc or not at all.
| Before | After | |
|---|---|---|
| Add a tool | Edit install.sh (~1 line) + install.ps1 (~1 line) = 2 edits across 2 files with drift risk |
1 entry in provision/manifest.ts |
| Cross-platform consistency | Manual — easy to add Mac but forget Windows | Enforced by manifest structure |
The following OMZ plugins are loaded on macOS:
- colorize
- git
- terraform
- zsh-autosuggestions
- zsh-syntax-highlighting
zsh-autosuggestions uses the Tab key to accept suggestions (bindkey '^I' autosuggest-accept),
avoiding accidental command execution.
tools/battery.ts is a friendly macOS battery wrapper around pmset,
ioreg -rn AppleSmartBattery, and system_profiler SPPowerDataType. It is
exposed in the shell as the battery function (see shell/40_func.plugin.zsh).
| Subcommand | Description |
|---|---|
battery / status |
ASCII dashboard: charge, health, power, charging controls, and USB power owners |
battery percent |
Charge percent as a bare integer (scriptable) |
battery charging |
Prints yes/no; exits 0 if charging, 1 if not |
battery health |
MaxCapacity / DesignCapacity %, cycle count, condition |
battery adapter |
Adapter wattage, model, serial, connected/delivering state |
battery time |
Time-to-full or time-to-empty (calculating when unknown) |
battery temp |
Battery temperature in °C (1 decimal) |
battery power |
Adapter input, system draw, battery flow, and CPU load |
battery diagnose |
Charging limits, AC power settings, thermals, and USB power owners |
battery why |
Decoded NotChargingReason + Optimized Battery Charging state |
battery raw |
Full ioreg -rn AppleSmartBattery dump |
battery json |
All values as a single JSON object |
battery watch [N] |
Repaint every N seconds (default 5) |
battery help |
Usage |
Color is auto-disabled when stdout is not a TTY, when NO_COLOR is set, or when
--no-color is passed. Pass --basic to use the prior one-line status display.
macOS only — exits with an error elsewhere.
Keymaps and code inspection profiles are stored in JetBrains/. The copy_jetbrains_keymaps.ts tool
copies them to the correct JetBrains IDE config directories.
The local Raycast extension adds Next Background and Previous Background commands for macOS.
bash install.sh registers and refreshes it from source during the scripts phase. Assign hotkeys in Raycast to rotate through backgrounds/, using the same
stretch-to-fill settings as provisioning. To register or update only the extension, run bun provision/scripts/raycast_backgrounds.ts from the repository root.