Skip to content
DivkixPublic

About

My personal macOS setup using Starship πŸš€, Fish Shell 🐠 (with fisher βœ…), Brew and RayCast

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Latest commit

Β 

History

178 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dotfiles

CI

This is my setup for my Macbook Pro (M4 Pro) for development purposes.

Previously used on:

  • MacBook Air (2020, M1)

Managed config

bootstrap.sh applies the repo-managed version of these configs:

  • fish/
  • fisher/
  • git/
  • ssh/
  • omp/ β€” Oh My Pi agent (~/.omp/agent)
  • claude/ β€” Claude Code (~/.claude)
  • codex/ β€” Codex CLI (~/.codex)
  • skills/ β€” agent skills, reinstalled from a manifest
  • herdr/ β€” herdr (~/.config/herdr) and its plugins
  • worktrunk/ β€” Worktrunk (~/.config/worktrunk)
  • btop/ β€” btop (~/.config/btop)
  • gh/ β€” GitHub CLI (~/.config/gh)
  • macos/ β€” macOS system preferences (defaults)
  • ghostty/ β€” Ghostty terminal (~/.config/ghostty)
  • zed/ β€” Zed editor (~/.config/zed)
  • gnupg/
  • starship/

RayCast/ is only an encrypted backup artifact. It is not restored by bootstrap.sh.

Each tool is backed up as a curated, secret-free subset of its live config:

  • OMP (~/.omp/agent): AGENTS.md (the global agent rules, also linked as Claude Code's ~/.claude/CLAUDE.md) and config.yml (with secret-bearing values such as searxng.token, searxng.basicPassword, and auth.broker.token blanked to ""; booleans and numbers are left as-is). Provider credentials live in the agent.db auth store, sessions and history are machine state, and models.yml can pin literal API keys β€” none of those are synced.
  • Claude Code (~/.claude): settings.json and the herdr hook script it references. settings.json is stored with __HOME__ in place of the home directory (hook commands embed absolute paths in quotes) and claude/setup.sh swaps it back. CLAUDE.md is not copied; it is re-linked to ~/.omp/agent/AGENTS.md, and a real file already there is kept as CLAUDE.md.bak. ~/.claude.json (OAuth account, user id), history, sessions, caches, and plugin installs are machine state and are not synced; plugins re-install from enabledPlugins on launch.
  • Codex (~/.codex): config.toml, hooks.json and the herdr hook script. update.sh drops the per-machine sections of config.toml ([projects.*] trusted paths, [hooks.state.*] trust hash, [tui.model_availability_nux]) and stores hooks.json with __HOME__ for the home directory. auth.json (login), sessions, history, and the sqlite databases are never synced. Run codex and sign in on a new machine; it asks you to trust the session hook on first launch.
  • Skills (~/.agents/skills, linked into ~/.claude/skills and other agents): skills/skills.list records each GitHub source and its skills, generated by update.sh from ~/.agents/.skill-lock.json (hashes and timestamps left out). skills/setup.sh reinstalls them with pnpm dlx skills add -g; it needs the network and reports failures without stopping bootstrap. Skills are not copied into this repo.
  • Packages (packages/): Brewfile is generated by update.sh from brew bundle dump. App Store apps go to Brewfile.appstore (via mas) so that a Mac not yet signed in to the App Store only gets a warning instead of failing the whole brew bundle. List app ids in packages/appstore.skip to keep an installed app out of that file (currently Office and HP). If mas is not installed, update.sh leaves Brewfile.appstore untouched. Prefer brew over go install: bu upgrades brew packages but never the go entries.
  • herdr (~/.config/herdr): config.toml (keybindings) plus plugins.list, one GitHub owner/repo per installed plugin, generated by update.sh from herdr plugin list --json. herdr/setup.sh reinstalls them with herdr plugin install -y and reports failures without stopping bootstrap. Plugin folders, plugins.json, sockets, logs, and session snapshots are machine state. Locally linked plugins have no GitHub source and are not captured.
  • Worktrunk (~/.config/worktrunk): config.toml.
  • btop (~/.config/btop): btop.conf. Keep color_theme set to a theme name ("tomorrow-night"), not a path: a Cellar path like /opt/homebrew/Cellar/btop/<version>/... breaks on the next btop upgrade.
  • GitHub CLI (~/.config/gh): config.yml only. hosts.yml is login state; run gh auth login on a new machine.
  • macOS settings (macos/): keys.list is the curated list of <domain> <key> preferences (Dock, Finder, trackpad, appearance, clock, screenshots, window manager). update.sh reads each live value into defaults.list (tab-separated, with its defaults type) and macos/setup.sh writes them back with defaults write, then restarts Dock, Finder and the menu bar. To track another setting, add a line to keys.list and run ./update.sh. Only scalar values are supported; arrays/dicts (e.g. AppleLanguages, keyboard shortcuts) and unset keys are skipped. Some keys (trackpad, global) need a log out and back in, and com.apple.universalaccess may need a privacy grant; failures warn without stopping bootstrap. The computer name is not captured.
  • Ghostty (~/.config/ghostty): config. ghostty/setup.sh also sets Ghostty as the default terminal via duti.
  • Zed (~/.config/zed): settings.json and keymap.json. The prompt-library database, settings_backup.json, and themes/ are excluded as machine state. No redaction is needed because Zed stores provider API keys in the macOS keychain, not in settings.json. Extensions are synced declaratively through the auto_install_extensions block in settings.json (Zed's recommended approach β€” it auto-installs them on launch). update.sh regenerates that block on every run from the live installed-extensions directory (~/Library/Application Support/Zed/extensions/installed/), so just install or remove extensions in Zed and run ./update.sh β€” no manual ID editing. The regeneration is a full rebuild, so manual "id": false ("never install") pins are not preserved. The compiled extension binaries under ~/Library/Application Support/Zed/ are machine state and are not synced.

Because the repo is public, update.sh sanitizes on capture: it blanks secret-bearing set -gx exports in fish/config.fish and secret values in omp/config.yml, so keys and tokens never get committed.

Local install artifacts such as node_modules/, package manager files, and other machine-specific state are intentionally excluded.

Installation

These steps must be followed to ensure smooth installation:

Run the bootstrap.sh file

bootstrap.sh prompts for sudo, installs Homebrew if it is missing, installs packages from packages/Brewfile, applies the managed config listed above, and sets fish as the login shell if needed.

Use this command to install the dotfiles setup:

./bootstrap.sh

Post-install manual steps

Do not run ./bootstrap.sh on a machine whose live config you want to keep. It overwrites ~/.config/fish/config.fish and ~/.omp/agent/config.yml with the repo copies, whose secret values (*_API_KEY, tokens) are blanked. Run ./update.sh first if you want the repo to match.

A few things bootstrap intentionally cannot restore:

  • API keys: the set -gx *_API_KEY "" lines in fish/config.fish are blanked. Re-enter them in ~/.config/fish/config.fish (e.g. MORPH_API_KEY, FIRECRAWL_API_KEY, TINYFISH_API_KEY).

  • GPG signing key: commits and tags are signed (commit.gpgsign, tag.gpgSign) with the key in git/.gitconfig / gnupg/gpg.conf. The private key is not in this repo. Import it (gpg --import) or generate a new one and update signingkey and default-key; otherwise git commit fails.

  • SSH keys: keys live in Secretive (Secure Enclave) and cannot be exported. Create new ones in Secretive and register them on GitHub, then rebuild ~/.ssh/allowed_signers (referenced by gpg.ssh.allowedSignersFile; not stored here).

  • gh login: run gh auth login (git uses gh as its credential helper).

  • OMP provider credentials: omp/config.yml ships without them β€” stored credentials live in ~/.omp/agent/agent.db (not in this repo). Run omp and /login <provider> on a fresh machine.

  • Raycast: import the encrypted backup from RayCast/ via the Raycast app (Settings β†’ Advanced β†’ Import). See RayCast/README.md.

Updating the repo from the current machine

Run this to sync the live machine back into the repo:

./update.sh

This builds a temp mirror of the managed live config, updates the Fisher manifest, and regenerates packages/Brewfile before applying the changes to the repo. If a managed live file or directory is missing, ./update.sh removes the corresponding repo snapshot on purpose. If snapshot or generation fails, the repo stays unchanged and the hidden repo-local .update.sh.* temp directory is cleaned up. If apply fails after changes start, ./update.sh tries to roll touched targets back; if rollback also fails, it reports that the repo may be partially updated and keeps that repo-local .update.sh.* artifacts path for inspection.

Tests

Run the regression tests with:

python3 -m unittest discover -s tests -p 'test_*.py' -v

About

My personal macOS setup using Starship πŸš€, Fish Shell 🐠 (with fisher βœ…), Brew and RayCast

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Sponsor this project

Used by

Contributors

Languages