工作空间路径搬迁(WorkBuddy workspace-relocate)
何时用
用户把某个工作空间对应的文件夹(在资源管理器里)移动或重命名后,要求「更新工作空间对应关系」「同步工作空间路径」时使用。典型表现:侧边栏里该工作空间指向死路径、点开找不到文件、历史会话丢失。
核心原理(必读)
WorkBuddy 在 C:\Users\pengjun\.workbuddy\workbuddy.db(SQLite)里记录工作空间 ↔ 文件夹的对应关系,共三处,缺一处都会出问题:
workspaces表:path TEXT PRIMARY KEY—— 侧边栏工作空间列表的来源(最重要)。sessions表:cwd字段 —— 每个会话的工作目录;某会话 id 的cwd要同步改。~/.workbuddy/projects/<路径转义名>/—— 按文件夹路径命名,存该空间全局历史会话(如 14.8MB 的 jsonl)。搬迁时需同步重命名,否则历史会话关联不上。
> 转义名规则:路径 \ → -,冒号 : 去掉。例如 C:\my-projects\907-4\招标要求 → c-my-projects-907-4-招标要求。
标准流程(全量搬迁:文件已搬好,三处一起改)
- 核查现状(只读):
ls确认旧路径已不存在、新路径已就位且含.workbuddy;用 Python 读workspaces/sessions表,定位旧 path 与需改的会话 id(cwd含旧路径)。 - 备份:复制
workbuddy.db及其-wal/-shm为带时间戳的.bak-YYYYMMDD-HHMMSS(三件套),确保可回滚。 - 改库(事务 + 短锁):
-UPDATE workspaces SET path=? WHERE path LIKE ?(用LIKE '%关键词%'匹配,别用字面量精确匹配,见下方「关键坑」)。
-UPDATE sessions SET cwd=? WHERE id=?(确定性 id 匹配,最稳)。 - 重命名 projects 历史目录:
os.rename(old_escaped, new_escaped),保留历史。 - WAL 固化:
PRAGMA wal_checkpoint(TRUNCATE),避免依赖-wal。 - 校验:SELECT 确认 workspaces 新 path 存在且为反斜杠、旧 path 消失、sessions
cwd已更新、projects 新目录存在。 - 提示用户:修改时 WorkBuddy 在运行,改完请完全退出(含系统托盘图标)再重开,侧边栏才刷新。
⚠️ 关键坑:Git Bash heredoc 吞反斜杠
在 Bash 工具里用 python - <<'PY' heredoc 写 Windows 路径时,反斜杠 \ 会被吞掉,导致:
- 写入的 path 变成正斜杠 C:/my-projects/...,与 WorkBuddy 原生(反斜杠)格式不一致,应用做精确字符串比较时可能匹配不上;
- WHERE path='C:\...' 字面量精确匹配0 行(首次 UPDATE 失败即此因)。
解决:用 chr(92) 在 Python 里构造反斜杠字符再拼接路径,彻底绕过转义歧义。示例:
sep = chr(92)
NEW = "C:" + sep + "my-projects" + sep + "907-4" + sep + "招标要求"
校验时 repr(v) 应显示 C:\my-projects\907-4\招标要求(反斜杠),sep in v 为 True。
变体:只改库(用户自行搬文件)
当用户明确「只改库、别动文件」时:
- 只 UPDATE workspaces.path 与 sessions.cwd 两表,不碰磁盘(含 projects/ 历史目录)。
- 必须提示:因 projects/ 内部历史目录名未随新 path 改,目录名与新 path 不一致,历史会话可能关联不上/不显示。若用户在意历史,搬完文件后需其授权,再单独重命名该内部目录(os.rename)。
- 同时提示:库已指向新路径,但磁盘上用户的移动可能还没真正生效(核查时旧文件夹仍在原处),需用户把文件真的搬好后侧边栏才能打开。
操作红线
- 改库前必备份(db / -wal / -shm 三件套)。
- 用事务 + 短锁,降低与运行中的 WorkBuddy 并发冲突风险。
- 绝不用
rm/ 通配符删workspaces表或projects/目录;重命名用os.rename,保留历史。