WorkBuddy 工作空间迁移
Overview
把 WorkBuddy 的工作空间根目录从一个位置整体迁移到另一个位置,并保证迁移后历史会话依然可用。
关键认知:工作空间迁移不是普通的文件夹复制。WorkBuddy 的状态分散在三处,只复制目录会留下大量悬空引用:
| 数据 | 位置 | 只复制目录的后果 |
|---|---|---|
| 项目文件 | 工作空间根目录下各会话子目录 | —(这部分能复制成功) |
| 会话 → 工作目录的绑定 | 应用数据目录下的 workbuddy.db(sessions.cwd、workspaces.path) |
旧会话点开指向已删除路径,应用可能新建空目录 |
| 缓存与索引中的路径 | 侧边栏快照、产物索引、任务列表等 | 产物卡片点不开、侧边栏显示错误路径 |
因此必须按「复制 → 校验 → 重新绑定 → 清理缓存引用」四步执行,缺一不可。
触发场景
- 用户要把工作空间从系统盘(C 盘)迁到数据盘,通常因为系统盘空间告急。
- 用户已改了 WorkBuddy 的默认工作空间路径,要求历史项目跟着走。
- 迁移做了一半:目录复制完了,但旧会话打开时报错、指向不存在的目录。
Workflow
Phase 0:侦察(只读,必须先做)
- 列出源根目录与目标根目录,统计各子目录体积(
scripts/migrate_workspace.py --inspect)。 - 识别可排除项:临时目录(浏览器调试 profile、
.tmp*、__pycache__)、其他程序的缓存目录。
把这些列给用户确认,不要自作主张。 - 检查源目录内是否有被进程占用的文件(见
references/pitfalls.md的"文件被占用"一节)。 - 确认目标磁盘剩余空间 ≥ 源目录体积 × 1.1。
停下确认:向用户报告体积、可排除项、以及"是复制还是移动"。默认先复制、保留源,校验通过后再谈删除。
Phase 1:复制
优先用平台原生工具(Windows 用 robocopy),不要用慢速的逐文件拷贝。
排除项的典型写法:临时/profile 目录、__pycache__、node_modules(可重建)。
注意:不要用镜像模式(/MIR),它会把目标端已有目录删掉。
Phase 2:校验
分两层,缺一不可:
- 计数与体积:比对文件数与字节总数。
注意:du显示的是磁盘占用,开了 NTFS 压缩或稀疏文件时会小于文件逻辑大小。
必须比对文件逻辑字节数,不要只看du。 - 可用性抽检:对迁移过来的数据库、配置、可执行入口做一次真实打开或解析,确认不是坏文件。
Phase 3:重新绑定会话(最容易漏的一步)
会话绑定存在应用数据目录的 SQLite 库里:
- 库文件:应用数据目录下的
workbuddy.db - 表与字段:
sessions.cwd(会话绑定的工作目录)、workspaces.path(最近打开的工作空间列表)
用 scripts/rebind_sessions.py 一次性改写,它会同时处理多种路径书写形式。
重要约束:不要用命令行 sqlite3 工具直连仍在运行的应用数据库。用独立脚本、写入前备份、写完立即复检。
改完必须让用户重启 WorkBuddy 才能生效。
Phase 4:清理缓存与索引引用
在应用数据目录内,把旧根路径替换为新根路径。用 scripts/scan_stale_refs.py 先扫描定位,再改写。
必须覆盖的四种书写形式(漏一种就会残留):
- 正斜杠
X:/a/b - 反斜杠
X:\a\b - JSON 转义后的双反斜杠
X:\\a\\b - 小写盘符
file:///x:/a/b
应当保留原样的位置(重要判断,不要"顺手全改"):
- 审计日志(
audit-log/一类):改写会破坏审计真实性。 - 变更历史与其配对的文件撤销备份:两边是配对关系,只改一边会让"撤销"功能路径错乱,要么一起改、要么都不改;默认都不改。
- 调试追踪日志:无功能影响。
这几类都不影响会话打开与继续对话,向用户说明即可。
Phase 5:处理源目录
校验全部通过后再删源目录。
- 删除前列出将被删除的内容,取得用户明确确认。
- 优先移入回收站;若用户诉求是"腾出磁盘空间",则需说明回收站不释放空间。
- 按批处理,单批不超过 10 个条目,每批后复检,任一步失败立即停止。
Critical Rules
- 先复制后删除,绝不在校验通过前动源目录。
- 不擅自终止用户的进程。文件被占用时优先用备份模式读取;确需停服务时先向用户说明并取得同意。
- 不做静默的全量替换。替换前先扫描并展示命中范围,让用户知道哪些文件会被改。
- 写含反斜杠的脚本必须用文件写入工具直接落盘,不要用 shell heredoc 拼接——heredoc 在传递过程中会把反斜杠转成正斜杠,导致路径替换静默失效。
- 改写配置前先备份,并把备份路径告诉用户。
Resources
scripts/
migrate_workspace.py— 侦察、复制、校验三合一。支持--inspect/--copy/--verify。rebind_sessions.py— 改写应用数据库中的会话与工作空间绑定,自动处理四种路径形式并校验 JSON 有效性。scan_stale_refs.py— 扫描应用数据目录中仍残留的旧根路径引用,按文件归类输出。
三个脚本均为纯标准库实现,接收 --old-root / --new-root 参数,无任何硬编码路径。
references/
pitfalls.md— 各类失败模式与处置办法:文件被占用、换行符被破坏、体积统计误判、路径形式遗漏、应用覆盖修改等。执行前建议先读。