WorkBuddy 会话 + 产物跨盘迁移
把 WorkBuddy 会话连同其工作目录产物从一个盘符整体搬到指定目录,并同步修正所有路径指针,让会话在客户端里照常打开。
为什么需要它
WorkBuddy 把「会话 ↔ 工作目录」的绑定存在 4 个数据库字段 + 1 个目录名里。手动把工作目录挪走,这 5 处全部失配,会话就会在侧边栏丢失或打不开。本 skill 把这 5 处一次性改齐。
存储机制(已实测确认)
| 位置 | 内容 | 迁移时的处理 |
|---|---|---|
sessions.cwd |
每条会话的工作目录 | 改写 |
workspaces.path |
最近打开的工作区 | 改写 |
automations.cwds |
定时任务的工作目录(JSON 数组) | 解析数组逐项改写 |
automation_runs.source_cwd |
定时任务运行记录 | 改写 |
projects/<slug>/ |
会话正文 jsonl 所在目录,目录名是 cwd 编码 | 重命名 |
slug 编码规则:盘符冒号与所有路径分隔符折叠成单个 -,去掉首尾 -。
F:\workbuddy\proj → f-workbuddy-proj
历史版本大小写不统一(既有 c-Users 也有 C-Users),比对必须忽略大小写。
不受影响:artifact-index/、changes-index/、changes-detail/、file-history/、file-tree-manifests/、media-index/ 全部按会话 UUID 组织,与路径无关,无需处理。projects/*.meta.json 也不含路径。
大小写重复的 cwd 记录(务必注意)
Windows 文件系统不区分大小写,但数据库会把 C:\x\Claw 和 c:\x\Claw 存成两条独立记录(实测存在)。它们指向同一个物理目录,共用同一个 projects/ 目录。因此:
- 统计产物体积时必须按小写路径去重,否则体积会翻倍虚高;
- 搬运产物时只能搬一次,脚本用
artifact_owner标记责任记录,其余记录只改数据库指针; - 数据库改写要覆盖全部记录,一条不能漏。
scan / plan 会同时报出「cwd 记录数」和「物理目录数」,两者不等就说明存在这类重复。
执行流程(严格按序,不得跳步)
第 0 步 · 列出盘符分布,让用户选择源盘(必须)
python scripts/scan_sessions.py list-drives
拿到各盘符的会话数、工作目录数、产物体积后,必须用 AskUserQuestion 把盘符做成选项让用户选,不要替用户假定。选项标签用「F: — 99 条会话 / 12.4GB 产物」这种带实据的写法。同时问清目标目录(如 D:\wb-archive)。
第 1 步 · 扫描源盘明细(只读)
python scripts/scan_sessions.py scan --drive F
python scripts/scan_sessions.py doctor # 顺带体检:失效 cwd / 孤立正文
把工作目录列表、会话条数、产物体积念给用户核对。
第 2 步 · 生成迁移计划(只读,绝不跳过)
python scripts/relocate_sessions.py plan --drive F --target "D:\wb-archive"
plan 会打印每个 旧路径 -> 新路径、projects 目录改名、数据库将改动的行数,并跑一遍阻断检查(目标盘空间、路径冲突、目标是否在源目录内部、客户端是否在运行)。把计划结果展示给用户确认后才能继续。
布局二选一:
- --layout mirror(默认)保留去掉盘符后的层级:F:\a\b → D:\wb-archive\a\b
- --layout flat 只保留末级目录名:F:\a\b → D:\wb-archive\b
只迁个别会话:加 --only-cwd(可重复传多次)限定范围,整盘迁移则省略。迁移的最小单位是工作目录而不是单条会话 —— 同一目录下的会话会一起搬,因为它们共用 projects/ 正文目录和产物目录。想只搬一条会话,就挑一个只有一条会话的工作目录。
python scripts/relocate_sessions.py plan --drive C --target "D:\下载" \
--only-cwd "C:\Users\me\WorkBuddy\20260427175240" --layout flat
--only-cwd 在 plan / apply / verify / backup_sessions.py 四处保持一致;备份务必也加上,否则会为了迁一个目录而打包整盘正文。
第 3 步 · 让用户确认注意事项(必须逐项列出并等待确认)
- 完全退出 WorkBuddy 桌面端(含托盘进程)。运行中热改数据库可能损坏数据。
- 确认源盘、目标目录、布局模式、产物处理模式四个具体值准确无误(逐一念出)。
- 知悉产物默认是 move(搬走,源盘释放空间);若想保留原件请改
--artifact-mode copy。 - 知悉这是非官方操作,产品升级 / schema 变更时存在兼容风险。
- 迁移期间不要打开正在被搬运的目录(资源管理器 / 编辑器占用会导致失败)。
第 4 步 · 备份(用户确认后立即执行)
python scripts/backup_sessions.py --drive F # 局部迁移时同样加 --only-cwd
打包数据库快照 + 受影响会话正文到桌面 zip,记录输出的 BACKUP_ZIP=<路径>,确认文件已生成且大小正常。
> 默认不打包产物(可能几十 GB)。产物安全由 move/copy 语义 + 回滚清单保证;若产物不可再生且格外重要,加 --include-artifacts,或先用 --artifact-mode copy 跑一轮。
第 5 步 · 执行迁移
python scripts/relocate_sessions.py apply --drive F --target "D:\wb-archive" --backup-verified
产物模式:
| 模式 | 行为 | 适用 |
|---|---|---|
move(默认) |
搬走,源盘释放空间 | 常规迁移、腾空间 |
copy |
复制,原件保留 | 想先验证再删原件 |
skip |
只改指针,不动文件 | 文件已手动搬好,只需修数据库 |
执行顺序:搬产物 → 改数据库(事务)→ 改 projects 目录名,每步都实时写入回滚清单 ~/.workbuddy/relocate-manifests/relocate-manifest-<时间戳>.json。任何一步失败都会停下并提示用清单回滚。
第 6 步 · 复核
python scripts/relocate_sessions.py verify --drive F --target "D:\wb-archive"
四项均为 OK 才算完成:源盘残留会话 0、已指向目标的会话数正确、工作目录都存在、projects 正文都能对上。然后让用户重启 WorkBuddy 客户端,在侧边栏确认会话可打开、正文可加载。
回滚
python scripts/relocate_sessions.py rollback --manifest <清单路径> # 预演
python scripts/relocate_sessions.py rollback --manifest <清单路径> --apply # 执行
按 projects 改名 → 数据库 → 产物 的逆序还原。copy 模式下原件本就在,不会重复搬回。
彻底还原数据库:退出客户端 → 用桌面 zip 内 db/workbuddy.db 覆盖 ~/.workbuddy/workbuddy.db → 重开。
自测
首次使用或换机器后建议先跑一次,在沙箱里完整演练 plan→backup→apply→verify→rollback,不碰真实数据:
python scripts/selftest.py --target-drive F # 目标盘须与系统临时目录所在盘不同
33 项断言覆盖产物落位、4 处数据库字段改写、projects 改名、大小写重复去重、--only-cwd 范围限定、安全拦截、完整回滚。
安全红线
- 未经用户对第 3 步注意事项显式确认,不得备份或迁移。
- 未跑
plan并向用户展示结果,不得apply。 - 未生成备份 zip,不得
apply(脚本用--backup-verified硬拦截)。 - 客户端未退出时不得写库(脚本自动检测
WorkBuddy.exe;--force仅限明确知道后果时使用)。 - 目标目录不得位于源工作目录内部,不得与源盘相同(脚本会拦截)。
- 不改写 jsonl 正文内容。正文里内嵌的
Workspace Folder:是历史对话记录,属于既成事实,改它等于篡改聊天记录;它不参与会话定位,留着无害。
关键路径
- 数据库:
~/.workbuddy/workbuddy.db(读取时连-wal/-shm一起快照,否则读不到最新数据) - 会话正文:
~/.workbuddy/projects/<cwd slug>/<session_id>.jsonl - 回滚清单:
~/.workbuddy/relocate-manifests/relocate-manifest-<时间戳>.json - 备份 zip:
<桌面>/workbuddy-relocate-backup-<盘符>-<时间戳>.zip
环境说明
脚本只依赖 Python 标准库。若 Git Bash 报 dirname: command not found 之类的 PATH 错误,命令前加 export PATH="/usr/bin:/bin:$PATH"。