Personal dotfiles, designed around one premise: developer workflows now run on two co-equal runtimes — the human shell and the agent harness. This repo provisions both on a fresh macOS machine in a single ./install.sh.
Human shell
- zsh + Oh My Zsh,
eza,bat,ripgrep,fzf,git-delta,zoxide,atuin,gh,httpie,jq/yq. - Ghostty as the terminal, Zed as the editor. VS Code kept as a backup.
- Node.js via
fnm, package managerspnpm+npm. - Sensible Git config and a comprehensive global gitignore.
- macOS defaults (Finder / Dock / keyboard) applied via
osx/index.sh.
Agent harness
~/.claude/symlinked to this repo:settings.json(sanitized — see Sanitization)CLAUDE.md(global agent memory)agents/,commands/,hooks/,output-styles/for authored cognitive toolsplugins/installed_plugins.jsondeclaring enabled plugins (caveman,vercel,coderabbit)
- Zed agent configured under
zed/settings.json. - MCP server templates in
mcp/. bin/scaffold-aito drop a.claude/+AGENTS.md+.mcp.jsonstarter into any new repo.
git clone https://github.com/phoinixi/dotfiles.git ~/workspace/dotfiles
cd ~/workspace/dotfiles
./install.shRun a single module instead of everything:
./install.sh --list # see available modules
./install.sh --only claude # re-symlink the Claude harness only
./install.sh --only zed
./install.sh --only ghosttyAfter install, restart your terminal (or source ~/.zshrc).
~/.claude/settings.json mixes durable user preferences with per-project absolute paths in permissions.allow. Only the durable parts are tracked.
- Tracked here (
claude/settings.json):enabledPlugins,effortLevel,editorMode, generic permission patterns (Bash(git push:*),Bash(rg:*),Bash(gh api *), etc.). - Machine-local (
~/.claude/settings.local.json, gitignored): per-project allowlists likeBash(node /Users/.../some-project/scripts/x.js). The install script never overwrites this file.
Before committing changes pulled from the live settings, run:
./scripts/sync-claude-settings.shIt diffs live vs tracked and prints exactly which entries would be stripped.
Stored in macOS Keychain. The .zshrc exposes a tiny helper:
kc OPENAI_API_KEY # prints the secret to stdout
$(kc GITHUB_TOKEN) # use inline as a valueTo add a secret:
security add-generic-password -a "$USER" -s OPENAI_API_KEY -wSwap to a different vault later (Bitwarden, doppler, …) without touching the rest of the repo.
scaffold-ai drops the AI-aware starter into any directory:
mkdir my-app && cd my-app
scaffold-ai . # uses dirname as project name
scaffold-ai . --name my-app # explicit nameIt writes .claude/settings.json, .claude/commands/, .mcp.json, AGENTS.md, .editorconfig, .gitignore, replacing {{PROJECT}} with the chosen name.
.zshrc shell config
Brewfile brew bundle source
install.sh dispatcher (--only <module> for partial runs)
install/ numbered modules (00-brew … 60-macos)
scripts/ one-off helpers
utils/ install printers
git/ gitconfig + global gitignore
osx/ macOS defaults
claude/ Claude Code harness (settings, CLAUDE.md, agents, commands, hooks, output-styles, plugins)
zed/ Zed editor config
ghostty/ Ghostty terminal config
raycast/ extensions manifest (real Raycast sync = Cloud Sync in app)
mcp/ MCP server templates and notes
template/project/ starter dropped into new repos by scaffold-ai
bin/scaffold-ai project bootstrap CLI
AGENTS.md contract for agents modifying this repo
- Add a CLI? Edit
Brewfile, re-run./install.sh --only brew. - Add a Claude slash command? Drop a
.mdintoclaude/commands/. No install re-run needed (the parent dir is symlinked). - Add a new install step? See
AGENTS.md— createinstall/<NN>-<name>.shand append the suffix to theMODULESarray ininstall.sh.