WorkBuddy 会话云端归档
> [!important] 核心结论(2026-08-10 实测)
> WorkBuddy 桌面端 UI 的会话列表 = 主进程读本地 DB + 按 status=='archived' 过滤 + 推送给渲染进程。直接改数据库不会通知 UI 刷新,且用户在 UI 里对未隐藏的会话发起对话时,主进程会把本地状态重新激活回 completed。云端归档 API 是幂等的,不会受影响。
存储位置速查
| 数据 | 位置 |
|---|---|
| 会话索引(状态/标题/时间) | ~/.workbuddy/workbuddy.db → sessions 表 |
| 会话内容(消息流) | ~/.workbuddy/projects/<工作目录>/<会话ID>.jsonl |
| 云端映射 | ~/.workbuddy/edge-sync-mapping.db(session_id = 云端 conversation_id) |
| 登录凭证(明文) | ~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/workbuddy-desktop.info |
云端归档 API
POST https://copilot.tencent.com/console/as/conversations/{conversationId}/archive
请求头:
Authorization: Bearer <accessToken>
X-User-Id: <uid>
X-Domain: <domain> # 如 www.codebuddy.cn
Content-Type: application/json
Body: {}
返回码:
200 {"code":0,"msg":"OK"}→ 归档成功HTTP 500 {"code":10000,"msg":"conversation status is archived, cannot be archived"}→ 云端已经是归档状态(幂等,说明之前归档成功过)HTTP 404→ 该会话从未迁移到云端,本地归档即可
> [!note] 凭证读取
> workbuddy-desktop.info 是明文 JSON,字段:auth.accessToken(JWT)、account.uid、auth.domain。读取示例:
> python
> auth = json.load(open(AUTH_FILE))
> token = auth['auth']['accessToken']; uid = auth['account']['uid']
> domain = auth['auth'].get('domain') or ''
>
如何获取凭证(使用者在自己的机器上操作)
> [!warning] 重要安全提示
> 凭证只属于你本人,只能在本机读取、不得外传。发布/分享任何脚本时,确保不含真实 token 值(脚本里只能有"读取逻辑",不能有 token 本体)。
第 1 步:找到凭证文件
WorkBuddy 桌面端登录后,认证 session 明文存储在工作目录的 Data/Public/auth/ 下,文件名类似 workbuddy-desktop.info(或 <产品名>.info)。常见位置:
| 平台 | 路径 |
|---|---|
| macOS | ~/Library/Application Support/CodeBuddyExtension/Data/Public/auth/ |
| 其他平台 | 在用户数据目录下找 Data/Public/auth/*.info(可全盘搜文件名) |
如果找不到,用命令直接搜:
# macOS
find ~/Library/Application\ Support ~/.workbuddy -maxdepth 5 -name "*.info" -path "*auth*" 2>/dev/null
# 或全盘
find ~ -maxdepth 6 -name "*desktop.info" 2>/dev/null | grep -v Library/Caches
第 2 步:确认文件是你要的凭证
文件是明文 JSON,结构如下(auth 字段里有 accessToken/domain,account 里有 uid/nickname):
python3 -c "
import json
d = json.load(open('凭证文件路径'))
print('uid:', d['account']['uid'])
print('nickname:', d['account']['nickname'])
print('accessToken 长度:', len(d['auth']['accessToken']))
print('domain:', repr(d['auth'].get('domain')))
"
- 能看到
accessToken(JWT,以eyJ开头)和uid→ 这就是登录凭证 - 如果报错或字段缺失 → 不是认证文件,换一个
Data/Public/auth/下的.info文件试
第 3 步:验证凭证可用(可选)
用 token 调一次只读接口确认有效:
curl -s -m 10 "https://copilot.tencent.com/console/as/conversations?limit=1" \
-H "Authorization: Bearer <accessToken>" \
-H "X-User-Id: <uid>" \
-H "X-Domain: <domain>"
返回 JSON 而非 401 → 凭证有效。
平台差异
- Windows/Linux:路径前缀不同,但结构一样——找到
Data/Public/auth/下的.info明文 JSON 即可 - 企业版/多账号:
auth/下可能有多个.info文件,选与当前登录产品名匹配的那个 - Web 版登录:Web 端凭证不走这个文件,本 skill 只适用桌面端
完整归档流程(可靠姿势)
> [!warning] 必须三步都做,否则 UI 不生效
> 1. 本地 DB:UPDATE sessions SET status='archived' WHERE id='<会话ID>'
> 2. 云端 API:调上面的 archive 接口(404 可跳过)
> 3. 重启 WorkBuddy:完全退出再打开,让主进程重新从 DB 加载 → UI 才隐藏
>
> 重启前不要在 UI 里点开该会话,否则本地状态会被重新激活。
踩坑记录(重要)
- 直接改 DB ≠ 归档成功:主进程/Renderer 有会话列表缓存,外部改库不推送
emitSessionRecordUpsert事件,UI 照旧显示。 - UI 发起对话会覆盖本地归档:用户还能看到会话 → 点进去发消息 → 主进程把本地
status改回completed、updated_at更新为对话时刻。云端不受影响(保持 archived)。 - 沙盒会话(
is_playground=1)与普通会话归档机制相同,无特殊处理。 - 最稳妥方式仍是 UI 手动归档(右键 → 归档):走
archiveSessionRPC → 本地 DB + 云端 + UI 刷新事件一步到位。批量场景才用脚本 + 重启。 - 归档前先备份 DB:
cp ~/.workbuddy/workbuddy.db ~/.workbuddy/automation-backups/workbuddy.db.bak.$(date +%Y%m%d-%H%M%S)。
常用查询
-- 找会话 ID
SELECT id, status, datetime(last_activity_at/1000,'unixepoch','localtime') as 最后活动
FROM sessions WHERE title LIKE '%关键字%';
-- 按状态统计
SELECT status, COUNT(*) FROM sessions GROUP BY status;
-- 1 个月以上未归档的
SELECT * FROM sessions
WHERE last_activity_at < strftime('%s','now','-30 days')*1000
AND status NOT IN ('archived');
配套脚本
本目录下 archive_conversation.py:传入会话 ID,自动完成「本地改状态 + 云端归档 + 结果验证」。用法:
python3 archive_conversation.py <会话ID> [更多ID...]
执行步骤(agent 操作指引)
- 用 SQL 查会话 ID:
sqlite3 ~/.workbuddy/workbuddy.db "SELECT id, title, status FROM sessions WHERE title LIKE '%关键字%';" - 确认会话信息后,运行脚本:
python3 ~/.workbuddy/skills/wb-session-archive/archive_conversation.py <会话ID> - 向用户说明:云端+本地已归档,重启 WorkBuddy 后 UI 才会隐藏,重启前不要点开该会话。