From 735fabbb6775f3492d9b262a818b0f31c3c06734 Mon Sep 17 00:00:00 2001
From: Helder Burato Berto
Date: Fri, 9 Oct 2026 18:03:07 +0100
Subject: [PATCH 1/5] fix(git): rewrite only pushes to SSH so installs clone
before key setup
---
README.md | 8 ++------
dot_gitconfig | 2 +-
test-chezmoi.sh | 7 +++++++
3 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index b251be2a..a4db6895 100644
--- a/README.md
+++ b/README.md
@@ -64,16 +64,12 @@ Then open Terminal and run each command **one at a time**. Wait for each to fini
Close Terminal and open Ghostty. Your shell config loads from here on.
-1. Add your SSH key to GitHub. Git uses SSH for every GitHub URL, so clones fail until this is done.
+1. Add your SSH key to GitHub. Git pushes to GitHub over SSH.
```bash
pbcopy < ~/.ssh/id_ed25519.pub # paste at https://github.com/settings/ssh/new
ssh -T git@github.com # answer "yes" to trust GitHub
```
-2. Install runtimes. This step failed during install because the key didn't exist yet.
- ```bash
- cut -d' ' -f1 ~/.tool-versions | xargs -n1 asdf plugin add; asdf install
- ```
-3. Start `tmux` and press `prefix + I` to install its plugins.
+2. Start `tmux` and press `prefix + I` to install its plugins.
### 5. Set up apps
diff --git a/dot_gitconfig b/dot_gitconfig
index 8d3776af..9e56b1d0 100644
--- a/dot_gitconfig
+++ b/dot_gitconfig
@@ -110,4 +110,4 @@
al = config --get-regexp alias
alf = config --get-regexp alias | grep
[url "git@github.com:"]
- insteadOf = https://github.com/
+ pushInsteadOf = https://github.com/
diff --git a/test-chezmoi.sh b/test-chezmoi.sh
index 06796aa3..47910946 100755
--- a/test-chezmoi.sh
+++ b/test-chezmoi.sh
@@ -279,6 +279,13 @@ else
fail "dot_gitconfig has stray template syntax"
fi
+if grep -q "pushInsteadOf = https://github.com/" "$GITCONFIG" && \
+ ! grep -qE "^[[:space:]]*insteadOf" "$GITCONFIG"; then
+ pass "dot_gitconfig rewrites only pushes to SSH"
+else
+ fail "dot_gitconfig rewrites clones to SSH, breaking installs before key setup"
+fi
+
if ! grep -q "^\[data\]" "$CHEZMOI_SOURCE/.chezmoi.toml.tmpl"; then
pass ".chezmoi.toml.tmpl has no dead [data] section"
else
From 1b685a8307672a812edc3cb5c26b126336a2de30 Mon Sep 17 00:00:00 2001
From: Helder Burato Berto
Date: Fri, 9 Oct 2026 18:03:48 +0100
Subject: [PATCH 2/5] feat(tmux): install plugins on apply and on dot_tmux.conf
change
---
.chezmoiscripts/run_onchange_after_tmux.sh.tmpl | 14 ++++++++++++++
.../run_onchange_before_packages.sh.tmpl | 4 ----
README.md | 12 ++++++------
test-chezmoi.sh | 14 +++++++++++++-
4 files changed, 33 insertions(+), 11 deletions(-)
create mode 100755 .chezmoiscripts/run_onchange_after_tmux.sh.tmpl
diff --git a/.chezmoiscripts/run_onchange_after_tmux.sh.tmpl b/.chezmoiscripts/run_onchange_after_tmux.sh.tmpl
new file mode 100755
index 00000000..d2c066ee
--- /dev/null
+++ b/.chezmoiscripts/run_onchange_after_tmux.sh.tmpl
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# dot_tmux.conf hash: {{ include "dot_tmux.conf" | sha256sum }}
+set -e
+{{- if eq .chezmoi.arch "arm64" }}
+eval "$(/opt/homebrew/bin/brew shellenv)"
+{{- else }}
+eval "$(/usr/local/bin/brew shellenv)"
+{{- end }}
+
+if [ ! -d "$HOME/.tmux/plugins/tpm" ]; then
+ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
+fi
+
+"$HOME/.tmux/plugins/tpm/bin/install_plugins"
diff --git a/.chezmoiscripts/run_onchange_before_packages.sh.tmpl b/.chezmoiscripts/run_onchange_before_packages.sh.tmpl
index b91f7f29..9f652c35 100755
--- a/.chezmoiscripts/run_onchange_before_packages.sh.tmpl
+++ b/.chezmoiscripts/run_onchange_before_packages.sh.tmpl
@@ -19,10 +19,6 @@ fi
$(brew --prefix)/opt/fzf/install --key-bindings --completion --no-update-rc || true
-if [ ! -d "$HOME/.tmux/plugins/tpm" ]; then
- git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
-fi
-
brew cleanup || true
echo "Homebrew packages installed"
diff --git a/README.md b/README.md
index a4db6895..78c7b3e1 100644
--- a/README.md
+++ b/README.md
@@ -64,12 +64,12 @@ Then open Terminal and run each command **one at a time**. Wait for each to fini
Close Terminal and open Ghostty. Your shell config loads from here on.
-1. Add your SSH key to GitHub. Git pushes to GitHub over SSH.
- ```bash
- pbcopy < ~/.ssh/id_ed25519.pub # paste at https://github.com/settings/ssh/new
- ssh -T git@github.com # answer "yes" to trust GitHub
- ```
-2. Start `tmux` and press `prefix + I` to install its plugins.
+Add your SSH key to GitHub. Git pushes to GitHub over SSH.
+
+```bash
+pbcopy < ~/.ssh/id_ed25519.pub # paste at https://github.com/settings/ssh/new
+ssh -T git@github.com # answer "yes" to trust GitHub
+```
### 5. Set up apps
diff --git a/test-chezmoi.sh b/test-chezmoi.sh
index 47910946..6719ecce 100755
--- a/test-chezmoi.sh
+++ b/test-chezmoi.sh
@@ -246,6 +246,10 @@ if $POST_APPLY; then
fail "TPM missing (~/.tmux/plugins/tpm)"
fi
+ while read -r plugin; do
+ [ -d "$HOME/.tmux/plugins/${plugin##*/}" ] && pass "tmux plugin ${plugin##*/}" || fail "tmux plugin ${plugin##*/} missing"
+ done < <(sed -n "s/^set -g @plugin '\(.*\)'/\1/p" "$HOME/.tmux.conf")
+
# Workspace
if [ -d "$HOME/workspace" ]; then
pass "~/workspace exists"
@@ -383,6 +387,14 @@ else
fail "asdf script not driven by .tool-versions"
fi
+TMUX_TMPL="$CHEZMOI_SOURCE/.chezmoiscripts/run_onchange_after_tmux.sh.tmpl"
+if grep -qF '{{ include "dot_tmux.conf" | sha256sum }}' "$TMUX_TMPL" 2>/dev/null && \
+ grep -qF 'tpm/bin/install_plugins' "$TMUX_TMPL"; then
+ pass "tmux plugins install on dot_tmux.conf change"
+else
+ fail "tmux plugins not installed on apply"
+fi
+
grep -qx 'cask "claude"' "$BREWFILE" && pass "claude desktop via brew" || fail "claude desktop cask missing"
! grep -q '^cask "claude-code' "$BREWFILE" && pass "claude code installed natively, not via brew" || fail "claude-code cask in Brewfile"
@@ -396,7 +408,7 @@ else
fail "claude code installer script missing"
fi
-for script in run_onchange_before_packages.sh.tmpl run_onchange_after_asdf.sh.tmpl; do
+for script in run_onchange_before_packages.sh.tmpl run_onchange_after_asdf.sh.tmpl run_onchange_after_tmux.sh.tmpl; do
rendered=$(chezmoi execute-template --source "$CHEZMOI_SOURCE" < "$CHEZMOI_SOURCE/.chezmoiscripts/$script")
if env -i HOME="$HOME" PATH=/usr/bin:/bin bash -c "$(echo "$rendered" | sed -n '/brew shellenv/p'); command -v brew" >/dev/null 2>&1; then
pass "$script finds brew on a fresh PATH"
From 70cff83d541ccf1d72ea83a3b7e3415848fc4eed Mon Sep 17 00:00:00 2001
From: Helder Burato Berto
Date: Fri, 9 Oct 2026 18:42:58 +0100
Subject: [PATCH 3/5] feat(dock): pin Claude desktop
---
.chezmoiscripts/run_once_after_dock.sh | 3 ++-
test-chezmoi.sh | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/.chezmoiscripts/run_once_after_dock.sh b/.chezmoiscripts/run_once_after_dock.sh
index 0ec4b452..061387cf 100755
--- a/.chezmoiscripts/run_once_after_dock.sh
+++ b/.chezmoiscripts/run_once_after_dock.sh
@@ -29,9 +29,10 @@ defaults write com.apple.dock show-recents -bool false
add_app_to_dock "Chrome"
add_app_to_dock "Ghostty"
-add_app_to_dock "Visual Studio Code"
add_app_to_dock "Obsidian"
+add_app_to_dock "Visual Studio Code"
add_app_to_dock "Slack"
+add_app_to_dock "Claude"
add_app_to_dock "Spotify"
add_folder_to_dock "$HOME/Downloads"
diff --git a/test-chezmoi.sh b/test-chezmoi.sh
index 6719ecce..e8cb13f4 100755
--- a/test-chezmoi.sh
+++ b/test-chezmoi.sh
@@ -398,6 +398,8 @@ fi
grep -qx 'cask "claude"' "$BREWFILE" && pass "claude desktop via brew" || fail "claude desktop cask missing"
! grep -q '^cask "claude-code' "$BREWFILE" && pass "claude code installed natively, not via brew" || fail "claude-code cask in Brewfile"
+grep -q 'add_app_to_dock "Claude"' "$CHEZMOI_SOURCE/.chezmoiscripts/run_once_after_dock.sh" && pass "Claude in Dock" || fail "Claude missing from Dock"
+
grep -q '^defaults write' "$CHEZMOI_SOURCE/.chezmoiscripts/run_onchange_after_macos.sh" 2>/dev/null && pass "macos defaults script present" || fail "macos defaults script missing"
[ ! -e "$CHEZMOI_SOURCE/.chezmoiscripts/run_once_after_mas.sh" ] && pass "mas script merged into Brewfile" || fail "mas script still present"
From 7bcd1263117ab65da69eee464d8be9cfc2b0c3a1 Mon Sep 17 00:00:00 2001
From: Helder Burato Berto
Date: Fri, 9 Oct 2026 18:04:35 +0100
Subject: [PATCH 4/5] docs(readme): add existing Mac setup, drop redundant
apply after update
---
README.md | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 78c7b3e1..7d5872ab 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
-**Already using these?** `chezmoi update && chezmoi apply`
+**Already using these?** `chezmoi update`
---
@@ -86,6 +86,25 @@ These need a login or a manual step:
Work tools stay out of this repo. Set them up on the work Mac.
+## Existing Mac
+
+Adds what's missing. Preview first: `~` may hold edits you want to keep.
+
+1. Clone without applying.
+ ```bash
+ brew install chezmoi
+ chezmoi init --source ~/.dotfiles helderberto
+ ```
+2. Preview changes to `~`. Move machine-only bits to `~/.private` first.
+ ```bash
+ chezmoi diff
+ ```
+3. Sign in to the App Store, then apply. `brew bundle` installs only what's missing.
+ ```bash
+ chezmoi apply
+ ```
+4. Do [steps 4 and 5](#4-finish-in-ghostty) for anything not set up yet.
+
---
From b6f3e10b22149809740a9bb92ccaf738dfcd7218 Mon Sep 17 00:00:00 2001
From: Helder Burato Berto
Date: Fri, 9 Oct 2026 18:05:23 +0100
Subject: [PATCH 5/5] feat: detect Brewfile drift before migrating and after
apply
---
README.md | 9 +++++++++
test-chezmoi.sh | 6 ++++++
2 files changed, 15 insertions(+)
diff --git a/README.md b/README.md
index 7d5872ab..b42e5a0e 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,15 @@
### 1. Before leaving the old Mac
+Check the repo has everything:
+
+```bash
+chezmoi status # managed files edited outside the repo → chezmoi re-add
+brew bundle cleanup --file ~/.dotfiles/Brewfile # installed but not in Brewfile → add or ignore
+```
+
+Never pass `--force` to `cleanup`. It uninstalls everything unlisted, including Apple's apps.
+
Save these to 1Password:
- Raycast settings: Settings → Advanced → Export (`.rayconfig` file)
diff --git a/test-chezmoi.sh b/test-chezmoi.sh
index e8cb13f4..19480e8d 100755
--- a/test-chezmoi.sh
+++ b/test-chezmoi.sh
@@ -215,6 +215,12 @@ if $POST_APPLY; then
fi
done
+ if brew bundle check --file "$CHEZMOI_SOURCE/Brewfile" >/dev/null 2>&1; then
+ pass "Brewfile satisfied"
+ else
+ fail "Brewfile has missing packages (brew bundle check --verbose)"
+ fi
+
# Zsh plugin paths (referenced in dot_zshrc)
ZSH_PLUGINS=(
"/opt/homebrew/share/powerlevel10k/powerlevel10k.zsh-theme"