包名:
cross-agent-sync(CLI 命令ass)当前版本:0.2.2
同一台机器上同时开着 Claude Code、Codex、Cursor、OpenCode......同一个项目、同一件事,需求 1~3 用 Claude 做,4~5 想换 Codex。结果历史全留在上一个 Agent 里,换过去等于失忆,图片还得重新贴。
这篇文章讲四件事:我踩过什么坑、怎么用 Agent 把工具做出来、发布后怎么一轮轮修、以及现在怎么用、后面还想改什么。
一、场景、困难、阻碍
1.1 真实工作流长什么样
日常大概是这样:
- 一个需求拆成多段,不同段用不同模型(便宜的扫代码、强的做架构)
- 同一个 Agent 也经常「新开一个会话」,因为旧会话上下文脏了、或 token 快爆了
- 偶发场景:Codex 里刚贴完截图问完一题,想立刻丢给 Claude 再答一遍------问题本身要搬过去,不只是结论
表面看是「复制粘贴总结一下」,真做几次就会发现这不是粘贴问题,是上下文所有权 问题:每个 Agent 的会话是私有的,Claude 的 .jsonl Codex 读不懂,Cursor 的 state.vscdb 更是另一套。
1.2 手工交接的痛点
| 痛点 | 具体表现 |
|---|---|
| 复述成本高 | 每次换 Agent 都要口述「目标 / 已做 / 待办 / 别动哪些文件」 |
| 决策丢了 | 「为什么这么定」只活在对话里,下一个 Agent 会重新发明一遍 |
| 踩坑重复 | 上一个 Agent 验证过「方案 B 不行」,下一个又会再试一遍 |
| 图片难搬 | base64 / 附件路径各家不一样,复制对话文本等于丢图 |
| 会话对不上仓库 | 从子目录启动、软链、Cursor workspace 清理后,会话「还在」但按项目一筛就没了 |
更糟的是:你以为「让 Agent 自己读历史」就行------但没有统一入口时,它只会猜,或者让你再讲一遍。
1.3 技术侧真正难的点
动手之前我以为难在「写个 CLI」。做完才发现难在这些:
-
存储形态完全不统一
JSONL(Claude / Codex)、SQLite(Cursor / OpenCode)、附件目录各玩各的。没有「通用 Session API」。
-
「只读」必须是强制的,不能是口头承诺
一旦工具写坏了某个 Agent 的会话库,用户会直接卸载。SQLite 默认还可能以可写方式打开,顺手生成
-journal/-wal。 -
摘要不能无脑长
交接摘要最终要塞进下一个 Agent 的上下文窗口。硬编码截断要么砍错、要么占满 token;静默省略会让下一个 Agent 以为「摘要里没有 = 会话里没有」。
-
从对话里「猜」决策不可靠
启发式一放宽就抓进整段叙述,一收紧就啥也抓不到。猜错的「决策」比没有更危险。
-
发布与接入比功能本身更碎
npm 包名被占、Cursor 没有用户级全局 MCP 文件、IDE 注入标签把用户原话当成系统注入丢掉......这些都是上线后才暴露的。
一句话:缺的不是 Memory,是「跨 Agent 的 Session Handoff」------能按仓库对齐、能选会话、能带图、能把「决策/踩坑」置顶交给下一个 Agent。
二、我怎么解决的:模型、提示词、流程
2.1 用了什么模型 / Agent
这个工具本身就是用多 Agent 协作做出来的,也正好成了第一批「狗粮」:
| 阶段 | 主要用谁 | 干什么 |
|---|---|---|
| 需求澄清 / 方案拆解 | Codex、Claude Code | 把痛点拆成「会话 vs 任务」两层,定包形态 |
| 主开发 | Claude Code(对话里用过 deepseek-v4-flash 等) | adapters、CLI、MCP、只读守护 |
| 换模型续写同一件事 | Codex ↔ Claude | 用「任务」把多段会话绑在一起,避免失忆 |
| 文档 / 规则 / 体验打磨 | Cursor + Claude | README、规则块、首屏信息架构 |
包名最终是 cross-agent-sync (npm 上 agent-session-sync 已被占用);运行时配置目录、MCP server 名仍叫 agent-session-sync,避免改名冲掉已有安装。
- codex + deepseek

2.2 提示词怎么设计
第一版需求提示词大致长这样(已压缩,完整版在仓库 提示词.md):
我同时用 Claude / Codex / Cursor / OpenCode 等。同一个项目里,需求 1~3 用 Claude,4~5 想换 Codex。历史、提示词、处理记录过不去,还得在新 Agent 里复述。
希望:换 Agent 或新开会话时,能读取别的 Agent 相关历史;最好有 MCP / 规则,新对话能「选一个会话同步过来」。
另一个场景:Codex 问完问题 A,切到 Claude 还想问同一题------不要复制粘贴,图片也不要重贴。
做成独立 npm 包,可自检索 Agent,也可让用户配置;别默认污染业务仓库。
后续反馈里又钉死了几条产品约束:
- 包名、技术栈、说明文档要明确
- IDE 不局限于 Cursor(Kiro / Trae 等同类也要能接)
- 项目级注入可以,但必须显式、可回滚
- 参考之前做过的独立工具包形态(类似 swagger-ts-gen)
提示词设计上刻意做了几件事:
-
先写「用户故事」再写「技术方案」
避免 Agent 一上来就堆 Memory / RAG 概念,偏离「选会话 → 搬上下文」。
-
把约束写成否定句
「不要直接在业务项目里开发」「不要默认写仓库」「不要假装支持读不到的 Agent」。否定句比愿望句更不容易被忽略。
-
用「任务」绑定多段会话
开发过程中真实发生了「Claude 做一段 → Codex 接着做」------于是产品里把「会话」和「任务」拆开:会话是一次对话,任务是一件事。
-
规则块写成纪律,而不是功能介绍
装 MCP 后,Agent 要遵守:「干活过程中随手
session_remember,别攒到最后」「默认给摘要,全文要显式要」「收尾落session_note」。
2.3 落地流程(可复用)
text
痛点口述(提示词.md)
→ 方案对齐(会话 vs 任务 / 只读 / 零依赖)
→ MVP:list + show + last + brief + MCP
→ 自用狗粮(用任务跨 Agent 续写本仓库)
→ 发布 npm
→ 真实机器上修适配器边缘 case
→ 把「只读 / 预算 / 决策通道」升级成硬能力
核心设计取舍(到现在也没改):
- 只读聚合 :源会话数据受保护区,写路径直接拒绝;读走
O_RDONLY;sqlite3带-readonly - 零运行时依赖 :只用 Node 内置;SQLite 走
node:sqlite或系统sqlite3 - 默认不碰仓库 :项目注入必须
ass init/ass mcp --write,带 dry-run / undo - 不假装支持:读不到就明说原因,不静默空列表
三、发布之后:怎么一次次调优
0.1.0 能用,但真机一跑就露出「文档写了、现场不对」的缝。下面这些是我觉得值得写进文章的迭代,而不是 changelog 流水账。
3.1 包名与版本漂移
- npm 包名被占 → 发布名改成
cross-agent-sync,运行时名字不动 ass --version曾硬编码成旧版本:CLI 和 MCP 各写一份字符串,改package.json忘了改它们
→ 改成运行时读package.json,两处常量消失
3.2 「静默」是体验杀手
连续修了几类静默行为:
- 列表默认 15 条,超了不说 → 用户以为「就这么多」
→ 触顶时明确提示,并告诉你ass --limit/--all --limit后面跟了另一个开关,被当成true,Number(true) === 1→ 只显示 1 条
→ 非法用法直接报错退出ass --all提示写了但 status 不认 → 提示在教不存在的功能
→ 行为与文案对齐
原则:宁可报错,也不要猜;宁可多一行提示,也不要静默截断。
3.3 适配器边缘 case(真实数据教出来的)
- Cursor 部分会话没有
workspace.json→ 按仓库过滤永远匹配不上 → 回退workspaceMetadata.displayPath - OpenCode 列表
preview硬编码空串 → 62 个会话预览全空 → 与read()共用提取逻辑 - IDE 前缀
<ide_selection>/<ide_opened_file>和用户原话拼在同一块 → 整段被当注入丢掉 →ass last搬到过期提问、轮次少算
这些几乎都不是设计阶段能穷举的,只能靠「本机真实会话」当测试集。
3.4 从「口头只读」到「可自证只读」
0.2.0 把只读做成运行时强制:
- 写路径命中受保护区即拒绝(逃生门环境变量显式打开)
- 读过的父目录自动进保护区(覆盖 adapter 声明之外的附件路径)
ass doctor报告「本次运行未改动任何源数据」- 活跃会话还在被追加写入时,标成「无法判定」,避免信号恒红等于没信号
3.5 交接预算:摘要要「可声明地缺席」
ass brief --budget tiny|small|standard|large|full:
- 每节有优先级,超预算按节降档(完整 → 精简 → 仅要点),再不行整节省略
- 主动记录的决策/踩坑置顶且最后才砍(宁可少两条,不整类丢掉)
- 被裁掉的部分写出来 ,并给出看全文的命令
刻意加一句:省略 ≠ 不重要,免得下一个 Agent 脑补成「没有」
3.6 决策通道:别再靠猜
extractDecisions 默认关掉,改成 ass brief --guess。
正式路径是 ass context / session_remember:决策、死胡同、约束、待办由 Agent(或人)主动写入,换 Agent 时置顶出现。
这也反向要求规则块写清楚:记决策是纪律,不是可选项。
3.7 首屏信息架构
ass 首屏重排,只回答四个问题:有几个会话 / 有哪些任务 / 怎么合并 / 怎么恢复。
以前把整段交接摘要顶在上面,真正要看的东西全被埋掉。稳定引用改成 claude:<完整id>,同时服务 claude --resume 和 ass brief。
四、怎么用这个工具,以及后续优化
4.1 安装
bash
npm install -g cross-agent-sync # 得到 ass 命令
# 或
npx cross-agent-sync list
ass install # 尽量自动接入本机各 Agent 的 MCP + 规则
ass doctor # 自检:能不能读、有没有动过源数据
ass agents # 探测到了哪些 Agent、数据在哪
要求 Node >= 18.17。读 Cursor / OpenCode 的 SQLite 时:Node >= 22.5(或系统有 sqlite3)。
4.2 三条最常用路径
① 看看这个仓库大家都聊过什么
bash
cd /path/to/your-project
ass
ass show #2
② 把上一个 Agent 的最后一问(含图)搬过来
bash
ass list --agent codex --limit 5
ass last #1 --rounds 2
图片会解码落盘,路径打在输出里,新 Agent 直接读文件即可。
③ 换 Agent 继续同一件事(推荐)
bash
# 开发过程中随手记
ass context --decision "接口错误统一走 msg 字段"
ass context --dead-end "在 axios 拦截器里重试会导致 refresh 死循环"
ass context --constraint "不要改旧版 SSO 签名"
ass context --todo "需求 5:表格换虚拟滚动"
# 绑成任务
ass task add 登录重构 claude:4134ec80-....
# 换到 Codex / Cursor 后
ass resume 登录重构
# 或对已接 MCP 的 Agent 说:继续 登录重构
接了 MCP 的 Agent(Claude Code / Codex / OpenCode 等)可以说自然语言,让它自己调 session_handoff / session_task_resume。
没接 MCP 的,跑 ass brief <引用> 把输出贴过去即可。
4.3 MCP 工具速查
| 你想做的事 | 工具 |
|---|---|
| 当前仓库状态 / 进行中任务 | session_status |
| 列会话让你挑 | session_list |
| 交接摘要 | session_handoff |
| 搬最后一问(含图) | session_last |
| 记决策 / 踩坑 | session_remember |
| 收尾存档 | session_note |
| 绑任务 / 恢复任务 | session_task / session_task_resume |
4.4 后续还想优化什么
按优先级大致是这些(不保证排期,但方向明确):
-
更多 Agent 适配
Trae / Windsurf / VS Code Copilot Chat 等:
detect能找到库,但解析还不完整;Gemini CLI 缺仓库路径,只能--all看。 -
Cursor 全局 MCP 一键写入
现在部分场景要靠
ass mcp --write写工程级配置;用户级路径各家不一致,还要继续磨。 -
交接质量
预算裁剪可以更「按目标 Agent 剩余上下文」自适应;任务视图可以挂上关键 diff / commit 引用。
-
更少的手工选择
在「明显只有一个进行中任务」时,新会话自动提示 resume;但仍坚持:别替用户静默选错会话。
-
可观测性
doctor / detect 报告再可读一点,方便别人在 issue 里贴自检结果。
4.5 使用测试
-
使用 ass 命令,输出会话列表,默认展示15条,同时有使用提示。

-
直接在另一个 agent 使用会话id ,让其读取另一个会话的概要,继续工作,实测在 claude、codex、cursro 中 都能正常工作。


写在最后
做这个工具之前,我以为痛点是「模型不够聪明」。做完之后更确定:很多时候不是模型不行,是上下文被各家私有格式锁住了。
如果你也在多 Agent 之间来回切,欢迎试一下:
bash
npm i -g cross-agent-sync
cd your-repo && ass
Issue / PR 都欢迎:github.com/lhbDesign/c...