Personal macOS configuration management system with automated dotfiles synchronization, security scanning, and one-command setup/rollback capabilities.
This repository manages configurations for the following applications:
| Category | Application | Config Location |
|---|---|---|
| Shell | Zsh + Oh-My-Zsh | ~/.zshrc, ~/.zsh/ |
| Terminal | Ghostty | ~/.config/ghostty/config |
| Editor | Neovim, Vim | via Homebrew |
| Version Control | Git, Tig | ~/.gitconfig, ~/.tigrc |
| Multiplexer | tmux | ~/.tmux.conf |
| Fuzzy Finder | fzf | ~/.fzf.zsh |
| Packages | Homebrew | Brewfile |
| Runtimes | mise | ~/.config/mise/config.toml |
| AI Assistant | Claude Code | ~/.claude/ (CLAUDE.md, hooks, agents) |
Brewfile includes:
- 100+ CLI tools (aws, gh, ripgrep, bat, jq, etc.)
- 40+ GUI applications (Cursor, Ghostty, Arc, Raycast, etc.)
- 80+ VSCode/Cursor extensions
Configuration files reside in this repository and symlink to their standard locations:
~/.zshrc → laptop/zsh/.zshrc
~/.gitconfig → laptop/git/.gitconfig
~/.config/ghostty → laptop/ghostty/config
Why symlinks?
- Git tracks actual content, not just symlink paths
- No specialized tooling required (stow, chezmoi, etc.)
- Easy to understand and debug
- Industry-standard approach
laptop/
├── install.sh # Main installer
├── rollback.sh # Restore from backup
├── Brewfile # Homebrew packages manifest
│
├── zsh/ # Shell configuration
│ ├── .zshrc # Main config (loads below in order)
│ ├── .aliases # Shell aliases
│ ├── functions/ # Custom zsh functions
│ └── configs/ # Modular configs
│ ├── pre/ # Loaded first
│ ├── *.zsh # Main configs (color, editor, history, etc.)
│ └── post/ # Loaded last (PATH, completion)
│
├── git/ # Git configuration
│ ├── .gitconfig # Main git config
│ ├── .gitignore # Global gitignore
│ ├── .gitmessage # Commit message template
│ └── .git_template/ # Git hooks template
│
├── ghostty/ # Ghostty terminal config
├── tmux/ # tmux configuration
├── tig/ # Tig (git TUI) config
├── fzf/ # Fuzzy finder config
├── mise/ # mise runtime manager config
├── claude/ # Claude Code configuration
│ ├── CLAUDE.md # User global instructions
│ ├── statusline.sh # Custom status line script
│ ├── hooks/ # PostToolUse hooks
│ └── agents/ # Subagents
│
├── scripts/
│ └── auto-sync.sh # Hourly auto-sync script
│
├── .pre-commit-config.yaml # Pre-commit hooks
├── .gitleaks.toml # Secret scanning rules
└── .gitignore # Security-focused ignore patterns
-
Pre-commit Hooks - Runs before every commit:
gitleaks- Scans for secrets and credentialsdetect-private-key- Catches SSH/PGP keystrailing-whitespace,end-of-file-fixer- Code hygiene
-
Comprehensive .gitignore - Blocks 30+ sensitive patterns:
- Environment files (
.env,.secrets.env) - Cloud credentials (AWS, GCP, Azure)
- SSH/GPG keys (
id_rsa*,*.pem) - Terraform state (
*.tfstate,*.tfvars)
- Environment files (
-
Secrets Template - API keys belong in
~/.secrets.env:# ~/.secrets.env (gitignored, created by install.sh) export OPENAI_API_KEY="" export ANTHROPIC_API_KEY="" export GITHUB_TOKEN=""
# Manual gitleaks scan
gitleaks detect --source=. --no-git
# Run all pre-commit hooks
pre-commit run --all-filesAn hourly launchd agent runs scripts/auto-sync.sh:
- Regenerates
Brewfilefrom current installations - Runs
gitleaksscan (aborts if secrets detected) - Executes pre-commit hooks
- Commits and pushes changes automatically
Log files:
~/.dotfiles_autosync.log- Standard output~/.dotfiles_autosync.error.log- Errors
Manual sync:
./scripts/auto-sync.sh# Clone repository
git clone https://github.com/snkrheadz/laptop.git ~/ghq/github.com/snkrheadz/laptop
# Run installer
cd ~/ghq/github.com/snkrheadz/laptop
./install.shWhat install.sh does:
- Checks macOS and installs Xcode CLI tools
- Installs Homebrew (if not present)
- Creates timestamped backup of existing configs
- Creates symlinks to repository configs
- Installs all Homebrew packages from Brewfile
- Sets up mise and installs runtimes (Go, Node.js, Python, Ruby)
- Sets up gitleaks + pre-commit hooks
- Configures launchd auto-sync agent
- Creates
~/.secrets.envtemplate
# List available backups
./rollback.sh
# Restore specific backup
./rollback.sh 20231223_120000What rollback.sh does:
- Disables auto-sync launchd agent
- Removes all symlinks
- Restores files from backup
# Dump current installations to Brewfile
brew bundle dump --force --file=Brewfile
# Install packages from Brewfile
brew bundle --file=Brewfilemise manages programming language runtimes (Go, Node.js, Python, Ruby).
| Runtime | Version |
|---|---|
| Go | 1.24.3 |
| Node.js | 25.2.1 |
| Python | 3.13.x |
| Ruby | 3.4.8 |
# List installed runtimes
mise list
# Install all runtimes from config
mise install
# Install specific runtime
mise use go@1.23.1
# Update to latest versions
mise upgradeEdit mise/config.toml to change versions:
[tools]
go = "1.24.3"
node = "25.2.1"
python = "3.13"
ruby = "3.4.8"Create ~/.zshrc_local for machine-specific settings (automatically sourced, not tracked):
# ~/.zshrc_local
export WORK_PROJECT_PATH="/path/to/work"
alias deploy="./scripts/deploy-work.sh"- Add config file to appropriate directory (e.g.,
tool/.toolrc) - Update
install.shto create symlink:safe_ln "$DOTFILES_DIR/tool/.toolrc" "$HOME/.toolrc"
- Update
rollback.shsymlinks array - Commit and push
1. zsh/functions/* # Custom functions
2. zsh/configs/pre/* # Pre-configs
3. zsh/configs/*.zsh # Main configs
4. zsh/configs/post/* # Post-configs (PATH, completion)
5. ~/.aliases # Shell aliases
6. oh-my-zsh # Plugins: git, zsh-autosuggestions
- Don't create functions with names that conflict with oh-my-zsh aliases
- Example:
gis already defined by the git plugin
- Example:
- Run
aliasafter installation to check for conflicts
install.sh uses safe_ln() which removes existing symlinks before creating new ones. This prevents circular references when running install.sh multiple times.
This repository manages Claude Code settings via symlinks:
claude/
├── CLAUDE.md # User global instructions → ~/.claude/CLAUDE.md
├── statusline.sh # Custom status line script → ~/.claude/statusline.sh
├── hooks/
│ └── validate-shell.sh # PostToolUse hook → ~/.claude/hooks/
└── agents/
└── verify-shell.md # Shell verification agent → ~/.claude/agents/
| Component | Description |
|---|---|
CLAUDE.md |
User global instructions (workflow, best practices, prohibitions) |
statusline.sh |
Custom status line showing model, cost, context |
validate-shell.sh |
PostToolUse hook for shellcheck validation on .sh files |
verify-shell.md |
Subagent for comprehensive shell script verification |
Displays in Claude Code CLI:
[Opus] 📁 laptop | 🌿 main | 💰 $5.20 (Today) | 📊 185k
Features:
- Model name (Opus/Sonnet)
- Current directory
- Git branch
- Daily cumulative cost
- Context window remaining
PostToolUse: validate-shell.sh
- Triggers after
WriteorEdittools - Runs
shellcheckon.shfiles - Blocks commit if issues found
/commit-commands:commit-push-pr- Commit, push, and create PR in one command
~/.claude/settings.json is NOT managed (Claude auto-modifies it). Required hook config:
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{"type": "command", "command": "~/.claude/hooks/validate-shell.sh"}]
}]
}
}MIT