WorkBuddy 数据目录迁移
迁移的是整个 ~/.workbuddy,Windows 为 %USERPROFILE%\.workbuddy,其中包含程序、插件和文件数据。原路径改为目录链接,应用继续使用原地址。
只操作该目录,不扩展到 Library/Caches、Library/Application Support 等 Electron 目录。恢复的数据源始终是链接指向的当前实际数据,不能用旧快照覆盖迁移后的变更。
平台与能力边界
| 环境 | 支持方式 |
|---|---|
| Windows | Python ≥3.8;.bat 保留结果窗口;本地卷 junction,UNC 需要 symlink 权限 |
| macOS | Python ≥3.8;可双击 .command;POSIX symlink |
| Linux(含 UOS、银河麒麟) | Python ≥3.8;终端执行 .sh;POSIX symlink;重开使用检测到的原可执行文件 |
| 鸿蒙电脑版 | 明确识别并提示暂不能迁移;尚无已验证的本地数据路径、Python 运行环境、进程与链接接口 |
官网列出了鸿蒙电脑版,但不能据此推断它使用 Linux 的 ~/.workbuddy 和命令。遇到原生鸿蒙,先说明上述限制,不运行迁移命令、不修改数据。若不能运行 Python,依据用户确认的系统类型给出限制说明;不能把无法执行的 detect 描述为已完成。
需要独立系统 Python,解释器、Python 环境和执行脚本均须位于待迁移数据目录之外。执行框架使用 Python 标准库,默认 Python 复制;已有 Robocopy、rsync 和系统回收工具可作为可选适配器,不要求额外安装。源码入口是本 Skill 的 scripts/cache_mover.py,下文 $SCRIPT 表示其绝对路径。
执行约束
- 目标基准目录必须由用户指定;执行前完整展示最终目标
<基准目录>/.workbuddy、数据体积、自动关闭/重开应用的行为。已有授权覆盖相同目标,不重复询问。 - migrate、restore、rollback、recover 会管理 WorkBuddy 进程,不能在 WorkBuddy 会话内直接执行。生成独立 runner,由用户在系统终端或双击执行。detect、状态查询和生成 runner 不关闭应用。
- 关闭窗口不等于退出应用。检测主程序、托盘和子进程;按进程路径、父子关系及启动身份确认归属,持续追踪主程序退出后的助手。先请求退出,超时结束已核对的进程树,再确认全部退出;禁止按 CodeBuddy/electron 通用进程名全局结束。不完整的进程检测必须停止。
- 无法检测进程时停止,不把
unknown当作已退出。重复执行由内核独占锁拒绝,进程崩溃后锁会自动释放;不要手工删除锁文件来绕过正在运行的任务。 - 普通非空目标目录拒绝合并、覆盖。只有本工具记录的已校验副本或临时副本可在核对状态后复用。复用临时副本会按当前源数据重新复制与校验,不承诺百分比断点续传。
- 迁移、二次搬迁和恢复均先在专用临时目录复制,完整校验 SHA-256、目录、链接目标和权限,再复查源状态及进程、切换原路径。Python 方式合并复制与源摘要读取,独立读取副本校验;原生工具在复制后独立读取源与副本,不能只按工具退出码宣布成功。复用已发布副本或重新启动进程时重新读取源数据,不信任跨运行摘要。读取、落盘或校验失败即停止。
- 目标盘与恢复盘需有最新数据体积加 2% 余量;同卷也采用复制、校验、切换,以保留切换前的可用数据路径。不要再承诺同卷瞬时完成。
- 旧数据默认进系统废纸篓,Windows 使用原生 Shell 回收接口并拒绝永久删除降级;系统不支持回收时保留旧副本、报告完成但有提醒。
--keep-backup可保留。进废纸篓仍占空间,用户确认正常后清空才释放。永久删除仅在用户明确要求时使用--hard-delete。 - Windows 回收报拒绝访问时,先诊断权限,不把 Administrator 账号或管理员窗口等同于拥有删除权限。脚本可现场请求解除已定位的旧副本删除拒绝规则;生成脚本、
--yes、先前的迁移授权均不能代替本次权限修改确认。禁止自动接管所有权、重置整目录权限或修改当前数据的权限。 - 不宣称“任何时点都安全”“零丢失”。外部程序重新写入、断电、磁盘失联等可能需要恢复确认;存在异常时保留数据和阶段记录,不盲目覆盖。
Agent 的环境适配职责
Skill 约束数据流程;Agent 根据本机证据选择执行方式,不照搬其他机器的路径或命令:
- 先运行
capabilities查看本机工具、清理选项与默认并发,再结合 detect、用户提供的磁盘介质和问题日志决定方案。C/D 在同一物理 SSD 不等于同一卷;不能据此用直接改名替代复制。 - 选择复制方式、工具绝对路径、并发、清理与显示选项,使用 make-runner 生成。参数 JSON 保存能力报告、所选方式及临时样本验证结果;运行记录保存执行策略,便于解释和重试。
- 原生复制必须先验证本机临时样本,包括中文路径、空目录、只读文件、链接及内容。生成器会执行此验证;验证失败时可改用 Python。不要把工具存在等同于可靠或更快。
- 若本地工具参数或启动器需要进一步适配,可以修改启动器目录内的受控实现;在独立临时目录验证后交付,记录修改原因、工具路径和参数。保留单一入口及整个阶段记录、锁、复制到临时目录、落盘、完整校验、原路径保护与恢复流程,不绕开框架直接操作真实源数据。
可调整:复制工具及其受控参数、1–8 路并发、平台回收方式、保留副本、终端显示。不能自动决定永久删除、合并未知非空目标、跳过内容校验或把原目录提前删除。回收能力不足时选择保留即可,不必强行清理。
python3 "$SCRIPT" capabilities
python3 "$SCRIPT" make-runner --dest-base "<目标>" --copy-engine python --workers 2 --cleanup keep
| 选项 | 用途 |
|---|---|
--copy-engine auto/python |
默认兼容方式,复制时计算源摘要;auto 当前选择 Python |
--copy-engine robocopy |
Windows 可选原生方式;复制链接本身,有限重试,工具码 0–7 后仍做校验 |
--copy-engine rsync |
macOS/Linux 可选原生方式;本地 archive 复制,保留链接,不使用删除或跟随链接参数 |
--copy-tool "<绝对路径>" |
绑定本次验证的原生工具;不依赖执行时的 PATH |
--workers 1–8 |
调整复制/校验并发;默认值是起点,依据本地测量选择 |
--cleanup auto/keep |
系统回收或原位保留;保留不伪报已清理 |
--cleanup shell |
Windows 原生回收;拒绝永久删除降级 |
--cleanup trash/finder |
macOS 本机废纸篓重命名或 Finder 按卷回收 |
--cleanup gio/trash-put |
Linux 已存在的回收工具;不存在或失败时保留 |
--permission-repair ask/off |
Windows 旧副本权限受阻时现场确认修复(默认 ask);off 仅报告并保留,无自动授权选项 |
--display auto/compact/plain |
动态三行面板、兼容单行刷新或纯文本 |
原生复制只允许写入工具拥有的临时目录,不使用 Robocopy /MIR、/PURGE、/MOVE 或 rsync --delete、--copy-links。已有临时副本包含链接、多余文件或类型冲突时,原生方式停止,可选择 Python 核对重建。外部工具返回后仍确认文件落盘、核对源状态、完整校验。它们未必比合并源摘要的 Python 方式更快,尤其是小文件和高速本机 SSD。
推荐流程
1. 检测
python3 "$SCRIPT" detect
整理系统、架构、数据位置、体积、进程状态及未完成记录。已经迁移时告知实际位置;只有用户要求二次搬迁才继续。原路径不可访问时先检查磁盘与阶段记录,不新建空目录冒充已恢复。
2. 确定目标并生成 runner
python3 "$SCRIPT" make-runner --dest-base "<用户指定基准目录>"
一次操作只交付一个已验证解释器的启动入口。不要额外生成“对照组”或已知会失败的 PATH 版本。Agent 可以按本地环境调整唯一启动器及受控适配器,调整后需验证解释器、引用、退出码和窗口保留。参数 JSON 与 cache_mover.py 是配套文件,不是额外启动入口。
生成器实际探测 Python 版本、可执行路径与环境位置;优先绑定生成时的可用独立解释器。已有便携 Python 时用 --python "<解释器绝对路径>" 指定,例如:
python3 "$SCRIPT" make-runner --command restore --plan "<记录路径>" --python "<数据目录外的 python.exe>"
解释器不可用时停止生成,并说明原因;不要下载解释器或修改系统设置来绕过。
默认生成:
- Windows:
~/.wb-cache-move/run_migrate.bat - macOS:
~/.wb-cache-move/run_migrate.command - Linux:
~/.wb-cache-move/run_migrate.sh,使用sh "完整脚本路径"执行
Windows/macOS 可双击;Linux 是否双击打开终端由桌面文件管理器决定,优先给出终端执行方式。无需按键开始,迁移过程中不要使用或重新打开 WorkBuddy。
Windows 结果窗口保持打开,读完后关闭或输入 EXIT;macOS/Linux 在交互终端读完后按 Enter 结束,非交互运行直接返回真实退出码。
目标中文路径通过 JSON 传递,已验证的解释器路径按平台正确引用,脚本与参数按 runner 自身所在目录定位。更新 Skill 后必须重新生成 runner,旧文件不会自动更新。--out 会把所需脚本与参数一起放到指定启动器目录。
Windows 复制与校验默认 4 路并发;macOS/Linux 默认串行,避免高速本地文件系统上的线程调度开销。并发任务队列有上限,保留逐文件落盘和原路径保护。可用 --workers 1 改为串行,或在 1–8 范围调整;机械盘和低速网络不能承诺提高并发会更快。生成 runner 时的设置写入参数文件,无需用户手改代码。
3. 观察与验证
长阶段每两秒更新。支持 ANSI 的交互终端展示三行动态面板:阶段与耗时、进度条与数据量、条目与速度;总量已知且有稳定进展时标注预计剩余时间。自动启用 Windows 10 虚拟终端能力;不支持时回退单行,重定向或 plain 仅显示阶段起止。按终端宽度调整,NO_COLOR 可关闭颜色,日志始终保留完整纯文本采样。普通消息与错误另起行,不被面板覆盖。
原生复制过程中仅显示等待状态与耗时,不反复全目录扫描,也不伪造字节进度;后续落盘和完整校验展示可计数的进度。阶段失败显示已停止,不伪报完成。
Windows 的扫描、复制和内容校验使用 Unicode 长路径接口(支持本地盘及 UNC),临时文件使用独立短文件名,避免在长原文件名后追加后缀;不要求修改注册表。
结束后执行 detect,并让用户确认会话、文件、插件和技能可用。SUCCESS 表示脚本操作完成,不代表已完成用户侧应用检查。
结果、日志与记录
所有平台的 runner 和直接终端命令共用日志与结果语义:
| 退出码 | 结果 | 后续处理 |
|---|---|---|
| 0 | SUCCESS | 操作完成,检查应用正常 |
| 2 | COMPLETED_WITH_WARNINGS | 数据操作完成;按提醒处理清理或重开失败 |
| 1 | FAILED / FAILED_SAFE | 阅读原因和当前路径;有明确原路径保护时显示 FAILED_SAFE |
| 3 | RECOVERY_REQUIRED | 操作可能已部分完成,先 detect,再 recover |
| 4 | BUSY | 已有任务运行,等待原任务结束 |
| 5 | UNSUPPORTED_ENVIRONMENT | 环境不具备迁移能力,不执行搬迁 |
| 130 | INTERRUPTED | 用户中断,先核对阶段记录和实际路径 |
日志位置:
- Windows:
%LOCALAPPDATA%\WorkBuddyCacheMover\logs - macOS:
~/Library/Logs/WorkBuddyCacheMover - Linux:
$XDG_STATE_HOME/WorkBuddyCacheMover/logs,默认~/.local/state/WorkBuddyCacheMover/logs
日志记录阶段、完整异常与退出码。退出码 2 要明确说明数据操作已完成及具体待处理项,不描述为整次迁移失败。解释器启动前失败会留在终端显示,此时没有 Python 运行日志。
阶段记录为 ~/.wb-cache-move/plan-*.json,在每个关键操作前持久化,并以临时文件原子替换。operation.lock 保留在该目录;不要在任务运行时删除该目录。恢复完成后保留阶段记录与启动器便于诊断,不在正在执行的 Windows .bat 中删除自身;确认无需恢复且没有任务运行后,可手动删除迁移工具目录。日志独立保留。
中断恢复与重试
先 detect 核对实际路径。复制阶段失败且记录明确为 aborted、原路径仍可用时,可以修复原因后重新生成 runner 重试,保留并核对临时副本;不要仅凭退出码 1 要求 recover。其他未完成记录会阻止新迁移并展示对应记录。先检查磁盘仍已连接,再生成恢复确认 runner:
python3 "$SCRIPT" make-runner --command recover --plan "<明确的记录路径>"
用户独立执行。recover 根据记录和实际路径:确认已完成的切换,或恢复旧链接/原目录;不能确定身份时拒绝覆盖并保留全部数据。它不直接删除旧副本,也不自动重新开始复制。
确认原路径恢复可用后,重新生成并执行 migrate/restore runner。已有临时副本仍保留,只有能与工具记录匹配的副本才可复用。磁盘剩余空间不足时需要先处理保留副本;不自动永久删除未知目录。
旧版 v1 记录可以用于常规迁回;没有阶段记录的中断不能自动推断,需检查实际路径。旧快照缺少内容身份或发生变化时保留,不能将其当作可靠恢复数据源。
二次搬迁、恢复和清理
二次搬迁 A → B:重新指定 B 并 make-runner。数据源为 A 的当前内容,同样执行复制、内容校验、切换和旧副本清理。
彻底迁回默认路径并处理历史快照:
python3 "$SCRIPT" make-runner --command restore --plan "<记录路径>"
仅迁回最新数据、保留历史快照:
python3 "$SCRIPT" make-runner --command rollback --plan "<记录路径>"
recover、restore、rollback 均必须独立执行。复制失败时原链接保持可用;切换失败会尝试恢复原链接,仍不可用时明确报告 RECOVERY_REQUIRED。
清理残留旧副本(不会主动退出应用,但应在没有迁移任务时进行):
python3 "$SCRIPT" cleanup-backup --plan "<记录路径>" --yes
恢复已经完成、仅旧位置回收失败时,不重跑 restore,也不需要 recover。使用本次完成的 restore/rollback 记录执行上述 cleanup-backup,仅清理旧位置;核对当前真实目录及旧副本内容摘要,内容变更则保留。
清理前核对当前路径及旧副本内容身份。清理失败不把已成功迁移/恢复的数据操作误报为整体失败;输出完成但有提醒,保留副本。
Windows 删除权限受阻
0x80270021 表示源旧副本访问被拒绝;与需要提权、文件占用、只读属性和回收站容量等错误区分。父目录的当前账号 DENY (D,DC) 可继承到 log 文件,即使管理员组另有完全控制,删除仍可能被拒绝。不要根据截图断定规则由 WorkBuddy 创建;目录改名不会清除既有权限。
原生回收受阻后,脚本有界检查旧副本目录与文件样本,优先定位显式拒绝来源。仅支持当前账号的标准 DELETE/DELETE_CHILD 拒绝位;未找到可处理规则不等于权限正常。未知规则、占用、只读属性、系统回收限制、检查不完整且拟修复范围超限时保留副本,不猜测或扩大修复范围。
找到可处理规则后,在终端展示旧副本根路径、账号、提权状态、受阻位置、拟修改对象数量及原权限记录路径。交互进度暂停,用户输入 REPAIR 才授权;Enter、其他输入、输入阶段 Ctrl+C、无交互终端或 off 均保留副本,退出码 2。Agent 不代替用户输入 REPAIR,也不通过管道预填答案。
确认后先持久化本次授权和原 DACL,再逐对象检查身份、属性、权限及路径仍与预览一致。仅去除当前账号拒绝规则中的删除位,其他拒绝位、允许规则、所有者与继承设置保留;不改当前数据、不穿过 symlink/junction/reparse point、不处理多硬链接文件。使用不自动传播权限的句柄逐个修改已预览对象,避免影响链接目标。~/.wb-cache-move/cleanup-permissions-*.json 保存路径、原权限、授权时间和结果;每次应用前后在配套 -events.jsonl 追加并落盘,不逐文件重写整份报告。权限修改若部分失败,明确保留并报告,不声称全部撤销。原权限记录用于人工诊断,不作为绕过身份检查的自动回滚入口。
修复后仅重试一次移入回收站。仍失败时保留剩余内容,报告原错误及处理结果,不再次询问、不降级永久删除。macOS/Linux 保持各自回收流程,不照搬 Windows DACL 修改。
已迁移成功的机器只生成清理启动器,避免重新复制:
python3 "$SCRIPT" make-runner --command cleanup-backup --plan "<本次完整记录路径>"
仍只交付一个入口。清理启动器不退出应用;--yes 仅确认清理已核验旧副本,权限修改仍现场确认。若用户已经手动删过一部分旧副本,内容摘要可能不再匹配,需人工核对残留,不能绕过原有内容身份检查。生成 PowerShell 诊断/修复命令时使用已核对完整路径的直接赋值;不要求非技术用户通过 Read-Host 再输入路径,不猜测日志日期的目录层级。
验证维护
精简 Skill 安装包只含本文与执行主体;以下测试需使用 GitHub 完整仓库。
python3 -m unittest discover -s scripts -p "test_*.py" -v
测试使用临时目录,不操作真实 WorkBuddy。GitHub Actions 在 Windows、macOS Intel/Apple Silicon、Linux 上验证迁移、恢复、故障注入、进程树/孤儿助手/PID 复用、检测失败、独占锁、日志、长路径、进度面板和中文便携解释器原生启动器,并覆盖 Python 3.8 与现代版本。权限测试覆盖授权/取消/非交互、权限变化、原记录落盘失败、单次重试,以及 Windows 真实继承拒绝、其他拒绝位保留、junction 目标和硬链接保护。仅测试能力与工具行为,不将其等同于真实用户应用或鸿蒙实机验证。