$npx -y skills add ttfake92-lab/skills --skill macos-migrationmacOS 系统迁移助手 — 两阶段:先在旧系统采集清单(JSON),再在新系统还原。 Use when user mentions: 系统迁移、换电脑、新装系统、Time Machine 恢复、 数据迁移、重装系统、migration、setup new mac、restore from backup、备份系统。 自动检测当前是旧系统(采集模式)还是新系统(还原模式)。 前置:先做一次 Time Machine 全量备份;唯一软件依赖是 Homebrew。
| 1 | # macOS 系统迁移助手 |
| 2 | |
| 3 | 两阶段设计:**旧系统采集 → 新系统还原**。中间通过一个 JSON 清单文件衔接。 |
| 4 | |
| 5 | ## 前置要求(务必先做) |
| 6 | |
| 7 | **在旧系统上先做一次 Time Machine 全量备份。** 这是整个迁移的安全网——新系统上 |
| 8 | 任何一步出问题,都能从这份全量备份里捞回来。还原阶段也直接从 Time Machine 挂载点 |
| 9 | 读取数据。 |
| 10 | |
| 11 | > 没有 Time Machine 全量备份,就不要开始迁移。 |
| 12 | |
| 13 | ## 运行模式检测 |
| 14 | |
| 15 | 判断「采集还是还原」只看一个信号:**清单文件在不在**。 |
| 16 | |
| 17 | ```bash |
| 18 | ls ~/migration-manifest.json 2>/dev/null |
| 19 | ``` |
| 20 | |
| 21 | | 条件 | 模式 | |
| 22 | |------|------| |
| 23 | | 无清单文件 | 采集模式(在旧系统上,生成清单) | |
| 24 | | 有清单文件 | 还原模式(在新系统上,读清单还原) | |
| 25 | |
| 26 | Time Machine 只是还原阶段的**数据来源**,不参与模式判断。 |
| 27 | 用户也可以直接指定:「采集」「备份」「还原」「迁移」。 |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ## 第零步:Homebrew 检查(两种模式都必须) |
| 32 | |
| 33 | ```bash |
| 34 | which brew && brew --version || echo "NOT_INSTALLED" |
| 35 | ``` |
| 36 | |
| 37 | - 已安装 → 继续 |
| 38 | - 未安装 → **引导用户在终端手动执行**安装命令。这一步需要输入管理员密码(sudo), |
| 39 | 无法静默完成: |
| 40 | |
| 41 | ```bash |
| 42 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" |
| 43 | ``` |
| 44 | |
| 45 | 装完后按提示把 brew 加入 PATH(Apple Silicon:`eval "$(/opt/homebrew/bin/brew shellenv)"`), |
| 46 | 再继续。 |
| 47 | |
| 48 | --- |
| 49 | |
| 50 | ## 模式 A:旧系统采集 |
| 51 | |
| 52 | 在旧系统上运行,扫描所有软件、配置、开发环境,生成 `~/migration-manifest.json`。 |
| 53 | |
| 54 | ### A1. Homebrew 软件包 |
| 55 | |
| 56 | ```bash |
| 57 | brew list --formula |
| 58 | brew list --cask |
| 59 | brew tap |
| 60 | ``` |
| 61 | |
| 62 | ### A2. 系统 Applications |
| 63 | |
| 64 | ```bash |
| 65 | ls /Applications/ |
| 66 | ls ~/Applications/ 2>/dev/null |
| 67 | ``` |
| 68 | |
| 69 | 与 Homebrew cask 列表对比,标记哪些是 Homebrew 装的、哪些是手动/App Store 装的。 |
| 70 | |
| 71 | ### A3. Mac App Store 应用 |
| 72 | |
| 73 | ```bash |
| 74 | mas list 2>/dev/null || echo "mas not installed" |
| 75 | ``` |
| 76 | |
| 77 | 如果 `mas` 未安装,提示用户是否要安装(`brew install mas`)。 |
| 78 | |
| 79 | ### A4. npm 全局包 |
| 80 | |
| 81 | ```bash |
| 82 | npm ls -g --depth=0 2>/dev/null |
| 83 | ``` |
| 84 | |
| 85 | ### A5. uv 工具 |
| 86 | |
| 87 | ```bash |
| 88 | uv tool list 2>/dev/null |
| 89 | ``` |
| 90 | |
| 91 | ### A6. pip/pipx 包 |
| 92 | |
| 93 | ```bash |
| 94 | pip list 2>/dev/null |
| 95 | pipx list 2>/dev/null |
| 96 | ``` |
| 97 | |
| 98 | ### A7. Go 全局工具 |
| 99 | |
| 100 | ```bash |
| 101 | ls ~/go/bin/ 2>/dev/null |
| 102 | ``` |
| 103 | |
| 104 | ### A8. 配置文件扫描 |
| 105 | |
| 106 | 扫描 home 目录下的 dotfiles 和配置目录: |
| 107 | |
| 108 | ```bash |
| 109 | ls -la ~/ |
| 110 | ``` |
| 111 | |
| 112 | 重点采集: |
| 113 | - Shell:`.zshrc`, `.zshenv`, `.zprofile`, `.bashrc`, `.bash_profile` |
| 114 | - Git:`.gitconfig`, `.gitignore_global` |
| 115 | - SSH:`.ssh/` |
| 116 | - 编辑器:`.claude/`, `.codex/`, `.config/`, `.cursor/`, `.zed/` |
| 117 | - 容器:`.docker/`, `.kube/` |
| 118 | - 包管理器:`.npm/`, `.nvm/`, `.bun/`, `.cargo/`, `.rustup/` |
| 119 | - 其他应用配置:`.SwitchHosts/`, `.ollama/`, `.syncthing/` 等 |
| 120 | |
| 121 | **敏感数据先问后采**:`.ssh/`(私钥)、dotfiles 里可能含 token、`.aws/`、`.kube/`、 |
| 122 | 钥匙串等都是密钥级信息。采集这些之前**先问用户是否纳入**: |
| 123 | |
| 124 | - 用户同意 → 正常采集,并**明确提醒**:「清单和备份里含私钥/凭据,传输、存放、 |
| 125 | 通过网盘或聊天工具发送时注意不要外泄。」 |
| 126 | - 用户拒绝 → 跳过这些项,在清单里记入 `"skipped_sensitive": [...]`,让用户日后 |
| 127 | 自行手动迁移(差异报告里也会再列一次)。 |
| 128 | |
| 129 | ### A9. LaunchAgents(自启动服务) |
| 130 | |
| 131 | ```bash |
| 132 | ls ~/Library/LaunchAgents/ |
| 133 | ``` |
| 134 | |
| 135 | ### A10. 用户项目目录 |
| 136 | |
| 137 | 列出 home 目录下非 dotfile 的顶层目录: |
| 138 | |
| 139 | ```bash |
| 140 | ls -d ~/*/ 2>/dev/null |
| 141 | ``` |
| 142 | |
| 143 | 排除系统目录(Library, Applications, Public 等),记录用户自建的项目/数据目录。 |
| 144 | |
| 145 | ### A11. Shell 环境 |
| 146 | |
| 147 | ```bash |
| 148 | # 当前 shell 版本 |
| 149 | zsh --version |
| 150 | # Homebrew 路径 / 版本管理器(nvm、fnm 等)配置 |
| 151 | grep -iE 'brew|nvm|fnm' ~/.zshrc |
| 152 | ``` |
| 153 | |
| 154 | ### A12. 其他易漏项 |
| 155 | |
| 156 | 迁移时最容易漏、丢了又很烦的几类: |
| 157 | |
| 158 | ```bash |
| 159 | # 编辑器扩展 |
| 160 | code --list-extensions 2>/dev/null |
| 161 | cursor --list-extensions 2>/dev/null |
| 162 | |
| 163 | # 自购/自装字体 |
| 164 | ls ~/Library/Fonts/ 2>/dev/null |
| 165 | |
| 166 | # 定时任务 |
| 167 | crontab -l 2>/dev/null |
| 168 | |
| 169 | # 手动装到非 Homebrew 路径的命令行工具 |
| 170 | ls /usr/local/bin/ 2>/dev/null |
| 171 | ls /opt/ 2>/dev/null |
| 172 | ``` |
| 173 | |
| 174 | > 系统偏好(`defaults`)量大且与机型强相关,不自动采集;如用户在意,在还原差异 |
| 175 | > 报告里提醒手动核对(键盘、触控板、Dock、快捷键等)。 |
| 176 | |
| 177 | ### A13. 生成清单文件 |
| 178 | |
| 179 | 将以上所有信息写入 `~/migration-manifest.json`: |
| 180 | |
| 181 | ```json |
| 182 | { |
| 183 | "version": 1, |
| 184 | "captured_at": "2026-06-28T16:00:00+08:00", |
| 185 | "source_macos": "15.5", |
| 186 | "source_hostname": "old-macbook", |
| 187 | |
| 188 | "homebrew": { |
| 189 | "taps": ["user/repo", "..."], |
| 190 | "formulas": ["git", "node@22", "..."], |
| 191 | "casks": ["1password", "docker-desktop", "..."] |
| 192 | }, |
| 193 | |
| 194 | "applications": { |
| 195 | "homebrew_casks": ["claude", "firefox", "..."], |
| 196 | "app_store": [{"id": 123456, "name": "App Name"}], |
| 197 | "manual": ["Final Cut Pro.app", "..."] |
| 198 | }, |
| 199 | |
| 200 | "package_managers": { |
| 201 | "npm_global": ["@anthropic-ai/claude-code", "..."], |
| 202 | "uv_tools": ["nano-pdf", "..."], |
| 203 | "pip_packages": ["package1", "..."], |
| 204 | "go_binaries": ["tool1", "..."] |
| 205 | }, |
| 206 | |
| 207 | "configs": { |
| 208 | "dotfiles": [".zshrc", ".gitconfig", ".ssh", "..."], |
| 209 | "config_dirs": [".claude", ".codex", ".config", ".docker", "..."], |
| 210 | "app_support_keys": ["Syncthing", "obs-studio", "..."] |
| 211 | }, |
| 212 | |
| 213 | "editor_extensions": { |
| 214 | "vscode": ["ms-python.python", "..."], |
| 215 | "cursor": ["..."] |
| 216 | }, |
| 217 | |
| 218 | "fonts": ["MyFont.otf", "..."], |
| 219 | "crontab": "<crontab -l 原文,无则空>", |
| 220 | "manual_bins": ["/usr/local/bin/foo", "/opt/bar", "..."], |
| 221 | |
| 222 | "launch_agents": ["com.github.syncthing.plist", "..."], |
| 223 | |
| 224 | "user_dirs": ["Projects", "Sites", "..."], |
| 225 | |
| 226 | "shell": { |
| 227 | "shell": "zsh", |
| 228 | "brew_in_path": true, |
| 229 | "nvm_installed": true, |
| 230 | "custom_env_vars": {} |
| 231 | }, |
| 232 | |
| 233 | "skipped_sensitive": [] |
| 234 | } |
| 235 | ``` |
| 236 | |
| 237 | ### A14. 采集完成 |
| 238 | |
| 239 | 输出清单摘要,提示用户: |
| 240 | |
| 241 | ``` |
| 242 | ✅ 采集完成!清单已保存到 ~/migration-manifest.json |
| 243 | |
| 244 | 采集内容: |
| 245 | - Homebrew: X taps, Y formulas, Z casks |
| 246 | - 应用: X 个 Homebrew, Y 个 App Store, Z 个手动安装 |
| 247 | - npm 全局包: X 个 |
| 248 | - 配置文件: X 个 dotfiles, Y 个配置目录 |
| 249 | - 编辑器扩展: X 个 / 字体: Y 个 / 定时任务: 有/无 |
| 250 | - 自启动服务: X 个 |
| 251 | - 用户目录: X 个 |
| 252 | - 跳过的敏感项: X 个(用户选择不采集) |
| 253 | |
| 254 | ⚠️ 若采集了 .ssh / dotfiles 中的凭据,清单与备份含私钥,传输存放注意不要外泄。 |
| 255 | |
| 256 | 下一步:确认已有 Time Machine 全量备份,将 migration-manifest.json 复制到新系统, |
| 257 | 再次运行此 skill。 |
| 258 | ``` |
| 259 | |
| 260 | --- |
| 261 | |
| 262 | ## 模式 B:新系统还原 |