diff --git a/README.md b/README.md
index 0f1b1d7..99290eb 100644
--- a/README.md
+++ b/README.md
@@ -1,28 +1,188 @@
# Zhuochun's dotfiles
-A set of files across Mac and Windows.
+A set of macOS and Windows dotfiles, keyboard customizations, editor settings, and backup/restore helpers.
+
+> **Current setup status:** the maintained setup flow is the manifest-driven `dot/` CLI. The older `scripts/*.sh` files are legacy helpers; do not use them as the primary setup path unless you are intentionally debugging old behavior.
Table of Contents (click to expand)
+- [AI Agent Quick Start](#ai-agent-quick-start)
+ - [Repository Rules for Agents](#repository-rules-for-agents)
+ - [Fresh macOS Setup Checklist](#fresh-macos-setup-checklist)
+ - [Validation Checklist](#validation-checklist)
+- [Command Reference](#command-reference)
+ - [`dot/dot`](#dotdot)
+ - [`dot/local`](#dotlocal)
- [Mac Setup](#mac-setup)
- [System Preferences](#system-preferences)
- - [Applications](#applications)
+ - [Applications and CLI Tools](#applications-and-cli-tools)
+ - [Shell](#shell)
+ - [Tmux](#tmux)
- [Keyboard Enhancements](#keyboard-enhancements)
-- [Vim](#vim)
+- [Vim / Neovim](#vim--neovim)
- [Windows Setup](#windows-setup)
- [AutoHotkey](#autohotkey)
- [Others](#others)
- [Custom Scripts](#custom-scripts)
- [Fonts](#fonts)
+ - [Themes](#themes)
+ - [Text Expander](#text-expander)
- [Rime](#rime)
- [Atom](#atom)
+## AI Agent Quick Start
+
+Use this section as the source of truth when completing setup on behalf of a user.
+
+### Repository Rules for Agents
+
+- **Do not assume `~/dotfiles` exists.** Clone this repository there before running setup commands, or replace `~/dotfiles` in commands with the actual checkout path.
+- **Do not run destructive restores without an explicit `--apply`.** `dot/dot restore` and `dot/local restore` intentionally default to dry-run mode unless `--apply` is supplied.
+- **Do not put private secrets in this repository.** Machine/company/private files belong in `~/.localrc`, `~/.localenv`, `~/.gitconfig`, and `~/.ssh`, and can be backed up with `dot/local backup`.
+- **Prefer the manifest-driven CLI.** The maintained entrypoints are `dot/dot` and `dot/local`; the old scripts in `scripts/` are not the primary setup flow.
+- **macOS support is first-class.** `dot/dot setup`, `dot/dot backup`, and `dot/dot restore` currently enforce macOS via `uname -s == Darwin`.
+
+### Fresh macOS Setup Checklist
+
+1. Install Apple's command line tools if Git is not already available:
+
+ ```bash
+ xcode-select --install
+ ```
+
+2. Clone this repository:
+
+ ```bash
+ git clone git@github.com:zhuochun/dotfiles.git ~/dotfiles
+ cd ~/dotfiles
+ ```
+
+3. Install Homebrew if `brew` is not available:
+
+ ```bash
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ ```
+
+4. Install the Homebrew bundle. `dot/dot setup` requires Homebrew, but it does **not** install the bundle for you:
+
+ ```bash
+ brew bundle check --file=~/dotfiles/scripts/Brewfile || brew bundle install --file=~/dotfiles/scripts/Brewfile
+ ```
+
+5. Preview dotfile setup actions:
+
+ ```bash
+ ~/dotfiles/dot/dot setup --dry-run --verbose
+ ```
+
+6. Apply tracked dotfile setup. The default conflict policy is `--overwrite`; use `--skip-existing` for a safer first pass on an existing machine:
+
+ ```bash
+ ~/dotfiles/dot/dot setup --skip-existing --verbose
+ ```
+
+7. Ensure Zsh is allowed and make it the default shell if needed:
+
+ ```bash
+ which zsh
+ grep -Fx "$(which zsh)" /etc/shells || echo "$(which zsh)" | sudo tee -a /etc/shells
+ chsh -s "$(which zsh)"
+ ```
+
+8. Install oh-my-zsh and custom plugins if they are missing:
+
+ ```bash
+ test -d ~/.oh-my-zsh || sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
+ test -d ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions || git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
+ test -d ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions || git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions
+ ```
+
+9. Install Tmux Plugin Manager if it is missing:
+
+ ```bash
+ test -d ~/.tmux/plugins/tpm || git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
+ ```
+
+10. Install Vim/Neovim plugins:
+
+ ```bash
+ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Shougo/dein-installer.vim/master/installer.sh)"
+ nvim +'call dein#install()' +qall
+ ```
+
+11. Open GUI apps that need permissions and complete their prompts:
+
+ - Karabiner-Elements: grant keyboard/input monitoring permissions, then restart Karabiner.
+ - Espanso: grant accessibility permissions.
+ - Rectangle: import or verify its config if needed.
+ - Rime/Squirrel: deploy the input method configuration if installed.
+
+12. Create or restore private local config outside this repository:
+
+ ```bash
+ touch ~/.localrc ~/.localenv
+ ~/dotfiles/dot/local backup --dry-run --verbose
+ # To restore an existing private backup:
+ # ~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --dry-run --verbose
+ # ~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --apply --verbose
+ ```
+
+### Validation Checklist
+
+Run these checks after setup:
+
+```bash
+brew bundle check --file=~/dotfiles/scripts/Brewfile
+~/dotfiles/dot/dot setup --dry-run --verbose
+zsh -n ~/dotfiles/zshrc ~/dotfiles/zshenv
+bash -n ~/dotfiles/dot/dot ~/dotfiles/dot/local ~/dotfiles/dot/lib/common.sh ~/dotfiles/dot/lib/symlink.sh
+nvim --headless +q
+```
+
+Expected results:
+
+- `brew bundle check` exits successfully, or prints the packages still needing installation.
+- `dot/dot setup --dry-run --verbose` lists planned actions without writing files.
+- Shell syntax checks exit successfully.
+- `nvim --headless +q` exits successfully after Neovim is installed.
+
+## Command Reference
+
+### `dot/dot`
+
+`dot/dot` manages tracked dotfiles and app configuration on macOS.
+
+```bash
+~/dotfiles/dot/dot setup [--dry-run] [--overwrite|--skip-existing|--interactive] [--verbose]
+~/dotfiles/dot/dot backup [--dry-run] [--verbose]
+~/dotfiles/dot/dot restore [--dry-run] [--apply] [--verbose]
+```
+
+- `setup` reads `dot/manifests/setup.macos.tsv` and creates symlinks/copies into `$HOME`.
+- `backup` updates `scripts/Brewfile` with `brew bundle dump` when Homebrew is available, then copies/syncs configured app files from `$HOME` into the repo using `dot/manifests/backup.macos.tsv`.
+- `restore` copies/syncs tracked app files from the repo back into `$HOME` using `dot/manifests/restore.macos.tsv`; it is dry-run by default and requires `--apply` to write.
+- Restore creates rollback snapshots under `~/.dotfiles-restore-backups//` before overwriting existing paths.
+
+### `dot/local`
+
+`dot/local` manages private machine/company config that should not be committed.
+
+```bash
+~/dotfiles/dot/local backup [--dry-run] [--verbose]
+~/dotfiles/dot/local restore --from [--dry-run] [--apply] [--overwrite|--skip-existing] [--verbose]
+```
+
+- `backup` writes timestamped backups under `~/localrc/backup-YYYY-MM-DD/` or `~/localrc/backup-YYYY-MM-DD-HHMMSS/` if the daily directory already exists.
+- Backup content includes `.localrc`, `.localenv`, `.gitconfig`, and `~/.ssh/` excluding `authorized*` files when present.
+- `restore` is dry-run by default and requires `--apply` to write.
+- Local restores also create rollback snapshots under `~/.dotfiles-restore-backups//`.
+
## Mac Setup
### System Preferences
@@ -40,131 +200,113 @@ A set of files across Mac and Windows.
Other preferences:
-``` bash
+```bash
# Disable "press and hold" option
defaults write -g ApplePressAndHoldEnabled -bool false
# Display all file extensions in Finder
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
```
-### Applications
-
-Install [GitHub Desktop](https://desktop.github.com/) and clone this repo ([SSH Setup](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)).
+### Applications and CLI Tools
-``` bash
-git clone git@github.com:zhuochun/dotfiles.git ~/dotfiles
-```
-
-Install [Homebrew](https://brew.sh/):
+Install [GitHub Desktop](https://desktop.github.com/) if you prefer a GUI Git client. Otherwise, use the CLI clone flow from [Fresh macOS Setup Checklist](#fresh-macos-setup-checklist).
-``` bash
-/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
-```
-Run the setup script to install formulas and create all config symlinks:
+Install Homebrew formulas and casks from the tracked bundle:
-``` bash
-~/dotfiles/dot/dot setup
+```bash
+brew bundle check --file=~/dotfiles/scripts/Brewfile || brew bundle install --file=~/dotfiles/scripts/Brewfile
```
+Apply tracked dotfile setup:
-Run backup/restore commands with dry-run safety:
+```bash
+~/dotfiles/dot/dot setup --skip-existing --verbose
+```
-``` bash
-# tracked dotfiles
-~/dotfiles/dot/dot backup
-~/dotfiles/dot/dot restore --dry-run
-~/dotfiles/dot/dot restore --apply
+Back up and restore tracked app config with dry-run safety:
-# private machine/company configs
-~/dotfiles/dot/local backup
-~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --dry-run
-~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --apply
+```bash
+~/dotfiles/dot/dot backup --verbose
+~/dotfiles/dot/dot restore --dry-run --verbose
+~/dotfiles/dot/dot restore --apply --verbose
```
-If you prefer the manual steps, review and install brew formulas:
+Back up and restore private machine/company config:
-``` bash
-brew bundle check --file=~/dotfiles/scripts/Brewfile || brew bundle install --file=~/dotfiles/scripts/Brewfile
+```bash
+~/dotfiles/dot/local backup --verbose
+~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --dry-run --verbose
+~/dotfiles/dot/local restore --from ~/localrc/backup-YYYY-MM-DD --apply --verbose
```
-Setup Zsh ([guide](https://github.com/robbyrussell/oh-my-zsh/wiki/Installing-ZSH)):
+### Shell
-``` bash
-# Check zsh PATH and whether it is in authorized shells list (/etc/shells)
+Set up Zsh ([guide](https://github.com/ohmyzsh/ohmyzsh/wiki/Installing-ZSH)):
+
+```bash
which zsh
-# Make zsh the default
-chsh -s $(which zsh)
+grep -Fx "$(which zsh)" /etc/shells || echo "$(which zsh)" | sudo tee -a /etc/shells
+chsh -s "$(which zsh)"
```
-Setup [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh):
-
-``` bash
-sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
+Set up [oh-my-zsh](https://github.com/ohmyzsh/ohmyzsh):
-git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
-git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
-git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions
+```bash
+test -d ~/.oh-my-zsh || sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
-ln -s ~/dotfiles/zshrc ~/.zshrc
-ln -s ~/dotfiles/zshenv ~/.zshenv
+test -d ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions || git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
+test -d ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions || git clone https://github.com/zsh-users/zsh-completions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-completions
-touch ~/.localrc
-touch ~/.localenv
+touch ~/.localrc ~/.localenv
```
-Setup Tmux and [Tmux-Plugins](https://github.com/tmux-plugins/tpm):
+`zshrc` currently enables `autojump`, `git`, `gitignore`, `golang`, `tmux`, `zsh-completions`, and `zsh-autosuggestions`.
-``` bash
-git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
+### Tmux
-ln -s ~/dotfiles/tmux.conf ~/.tmux.conf
-ln -s ~/dotfiles/tmux-theme.conf ~/.tmux-theme.conf
+Set up Tmux and [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm):
+
+```bash
+test -d ~/.tmux/plugins/tpm || git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
# Start a session
tmux new -s dev
-# Reload Tmux environment to source TPM (Optional)
+# Reload Tmux environment to source TPM (optional)
tmux source ~/.tmux.conf
-# Press prefix (C-b) + I to install the plugins
+# Press prefix (C-b) + I to install plugins
```
### Keyboard Enhancements
-Open [Karabiner](https://pqrs.org/osx/karabiner/index.html) and grant permissions.
+Open [Karabiner-Elements](https://karabiner-elements.pqrs.org/) and grant permissions.
-Setup the rules and restart Karabiner.
+`dot/dot setup` copies the main Karabiner config and symlinks custom rules. To re-run only the documented manual steps:
-``` bash
+```bash
cp ~/dotfiles/mac/karabiner.json ~/.config/karabiner/karabiner.json
-```
-
-To customise [rules](https://pqrs.org/osx/karabiner/complex_modifications/):
-
-``` bash
ln -s ~/dotfiles/mac/karabiner-rules ~/.config/karabiner/assets/complex_modifications
```
-Refer to [zhuochun/mac-keyboard](https://github.com/zhuochun/mac-keyboard) and Ergodox-EZ layout ([Mac](https://github.com/zhuochun/qmk_firmware/blob/zhuochun-keymaps-3/keyboards/ergodox_ez/keymaps/zhuochun/keymap.c)/[Win](https://configure.ergodox-ez.com/ergodox-ez/layouts/Qz39g/latest/0))
+Refer to [zhuochun/mac-keyboard](https://github.com/zhuochun/mac-keyboard) and Ergodox-EZ layout ([Mac](https://github.com/zhuochun/qmk_firmware/blob/zhuochun-keymaps-3/keyboards/ergodox_ez/keymaps/zhuochun/keymap.c)/[Win](https://configure.ergodox-ez.com/ergodox-ez/layouts/Qz39g/latest/0)).
-## Vim
+## Vim / Neovim
-Both my Mac/Windows use similar key mappings. For muscle memories, `` mappings on Mac are `` mappings on Windows.
+Both Mac and Windows use similar key mappings. For muscle memory, `` mappings on Mac are `` mappings on Windows.
-- **Mac OS:** Use `vimrc` with `brew install neovim`.
-- **Windows:** Use `windows/_vimrc` (Not actively updated).
+- **macOS:** Use `vim/vimrc` with `brew install neovim` or the tracked Homebrew bundle.
+- **Windows:** Use `windows/_vimrc` (not actively updated).
-Follow [Shougo/dein.vim](https://github.com/Shougo/dein.vim) or [Shougo/dein-installer.vim](https://github.com/Shougo/dein-installer.vim) to setup the plugin system.
+Set up [Shougo/dein.vim](https://github.com/Shougo/dein.vim):
-``` bash
-sh -c "$(wget -O- https://raw.githubusercontent.com/Shougo/dein-installer.vim/master/installer.sh)"
-
-# it creates ~/.cache/dein directory
+```bash
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/Shougo/dein-installer.vim/master/installer.sh)"
```
-Setup `vimrc` files:
+`dot/dot setup` creates the Vim/Neovim symlinks. Manual equivalents are:
-``` bash
+```bash
# neovim
ln -s ~/dotfiles/vim/vimrc ~/.config/nvim/init.vim
ln -s ~/dotfiles/vim/rc ~/.config/nvim/rc
@@ -175,29 +317,32 @@ ln -s ~/dotfiles/vim/rc ~/.vim/rc
ln -s ~/dotfiles/vim/gvimrc ~/.gvimrc
```
-Open vim and install plugins: `:call dein#install()`.
+Open Vim/Neovim and install plugins: `:call dein#install()`.
## Windows Setup
### AutoHotkey
-I use [AutoHotkey](http://ahkscript.org/) in Windows to enhance productivity.
+I use [AutoHotkey](https://www.autohotkey.com/) in Windows to enhance productivity.
+
+Refer to:
-Refer to `windows/AutoHotkey.ahk`.
+- `windows/AutoHotkey.ahk`
+- `windows/AutoHotkey-v2.ahk`
+- `windows/AutoHotkey-LLM.ahk`
+- `windows/README.md`
## Others
### Custom Scripts
-Some useful/interesting scripts are under [/bin](https://github.com/zhuochun/dotfiles/tree/master/bin), e.g. rename PDFs.
+Some useful/interesting scripts are under [`bin/`](https://github.com/zhuochun/dotfiles/tree/master/bin), e.g. PDF renaming helpers.
-``` bash
-echo 'export PATH="$HOME/dotfiles/bin:$PATH"' >> ~/.zshrc
-```
+`zshenv` adds `~/dotfiles/bin` to `PATH`, so `dot/dot setup` plus a new shell should make these available.
### Fonts
-Install [Powerline Fonts](https://github.com/powerline/fonts).
+Install [Powerline Fonts](https://github.com/powerline/fonts) if your terminal theme needs them.
### Themes
@@ -205,11 +350,11 @@ Install [gruvbox](https://github.com/morhetz/gruvbox-contrib) colorscheme for te
### Text Expander
-Install [Espanso](https://espanso.org/).
+Install [Espanso](https://espanso.org/). `dot/dot setup` symlinks the tracked match files. Manual equivalents are:
-``` bash
-ln -s ~/dotfiles/espanso/match.yml $HOME/Library/Application\ Support/espanso/match/base.yml
-ln -s ~/dotfiles/espanso/form.yml $HOME/Library/Application\ Support/espanso/match/form.yml
+```bash
+ln -s ~/dotfiles/espanso/match.yml "$HOME/Library/Application Support/espanso/match/base.yml"
+ln -s ~/dotfiles/espanso/form.yml "$HOME/Library/Application Support/espanso/match/form.yml"
```
### Rime
@@ -218,10 +363,12 @@ ln -s ~/dotfiles/espanso/form.yml $HOME/Library/Application\ Support/espanso/mat
- Use `Ctrl + ~` to adjust Traditional/Simplified Chinese.
-``` bash
+`dot/dot setup` symlinks the macOS Squirrel custom config. Manual equivalent:
+
+```bash
ln -s ~/dotfiles/rime/squirrel.custom.yaml ~/Library/Rime/squirrel.custom.yaml
```
### Atom
-- Install Atom Plugins: `apm install markdown-writer`
+Atom is no longer part of the main setup flow. Historical plugin note: `apm install markdown-writer`.