内容
# uni-code
[](https://github.com/Lum1104/uni-code/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@yuxianglin/uni-code) [](https://lum.is-a.dev/uni-code/)
**在 Claude Code、Codex 等多个编码代理之间切换自如 — 不会遗漏任何信息。**
> 想要快速了解?请直接访问 **[lum.is-a.dev/uni-code](https://lum.is-a.dev/uni-code/)**
你在一个代理中修复了一个 bug,切换到另一个代理后,它却不知道这个修复。你使用的每个编码代理都将自己的会话存储在你的机器上,以其独特的格式存储,其他代理无法访问。uni-code 将所有这些信息索引到一个本地存储库中,并通过 MCP 服务器为你的代理提供服务 — 让当前代理能够回忆起其他代理所做的任何事情。
```
你(在 Codex 中):如何解决 playwright 超时问题?肯定是在上周的 Claude Code 会话中解决的
⚙ codex → uni-code · search_history("playwright timeout")
⚙ codex → uni-code · read_session("f3a9c2d1-8")
Codex: 找到了 — oss/atlas-ui,2026-05-28,在 Claude Code 中:你固定了 playwright.config.ts 中的 webServer 超时,并为 chromium 添加了一个重试。让我在这里应用相同的修复吗?
```
> **状态:实验中。** 核心功能已经在实际存储库中得到验证(下面的数字);界面仍在变化。v1 版本涵盖 Claude Code + Codex;更多代理将陆续支持。
## 安装
所有功能都打包在一个 npm 包中 — `@yuxianglin/uni-code`,Node ≥ 22.5,**零运行时依赖**(它运行在 Node 内置的 SQLite 上)。
**作为 Claude Code 插件** — MCP 工具加上一个召回技能,用于教 Claude 何时使用它们:
```bash
/plugin marketplace add Lum1104/uni-code
/plugin install uni-code@uni-code
```
**作为 Claude Code 普通的 MCP 服务器:**
```bash
claude mcp add uni-code -- npx -y @yuxianglin/uni-code mcp
```
**Codex:**
```bash
codex mcp add uni-code -- npx -y @yuxianglin/uni-code mcp
```
**Cursor 或其他 MCP 客户端:** stdio 服务器,命令 `npx`,参数 `-y @yuxianglin/uni-code mcp`。
然后,预热索引一次(第一次需要 ~30 秒;之后的每次刷新都是增量且自动的):
```bash
npx @yuxianglin/uni-code ingest
```
注册过程通过每个代理的 CLI 进行 — uni-code 从不编辑你的代理配置,也不会写入它们的 数据目录。
## 代理可以做什么
MCP 服务器暴露了五个工具;代理在引用过去的工作时会主动使用它们:
| 工具 | 它回答的问题 |
|---|---|
| `search_history` | "我们如何修复 X?" — 每个消息、思考、shell 命令和工具输出的排名全文搜索,来自所有代理 |
| `list_sessions` | "昨天我在做什么?" — 跨代理的统一最近会话列表 |
| `read_session` | "显示那个会话" — 一个会话的时间线,结果优先 |
| `get_handoff` | "让我了解情况" — 一页简报:目标、结束位置、触摸的文件、运行的命令(带有失败)、看到的错误 |
| `resume_session` | "继续我离开的地方" — 真正的跨代理恢复:源代理自己的压缩摘要,直接重用,加上其后的一切 |
`resume_session` 是旗舰功能:原生 `--resume` 重载的不是完整的历史记录 — 而是最后的压缩摘要加上其后的实时窗口。uni-code 在原生文件中找到这种结构,并以代理中立的方式重建它,因此 Codex 可以像 Claude Code 本身一样恢复 Claude Code 会话。(一个不对称的情况,诚实地说:Claude Code 以纯文本写入其压缩摘要,并直接重用;Codex 对其摘要进行加密,因此从压缩的 Codex 会话恢复需要回退到其保留的用户提示。)
每个查询在回答之前都会重新索引更改的原生文件(预热时即时),因此结果包括您五分钟前在**其他**代理中关闭的会话。无需守护进程,无需保持运行。
## CLI
相同的存储库,供人类使用。使用 `npx @yuxianglin/uni-code <cmd>`,或全局安装 `npm i -g @yuxianglin/uni-code` 以获得全局 `uni:`
| 命令 | 它执行的操作 |
|---|---|
| `uni search <q>` | 排名全文搜索 — 代理使用的相同引擎 |
| `uni handoff [id]` | 会话的一页简报(默认为最新)— 将其传输到下一个代理 |
| `uni resume [id]` | 完整的有效上下文(压缩摘要 + 实时窗口)— 跨代理恢复 |
| `uni sessions` | 跨代理的统一会话列表,最新的优先 |
| `uni log <id>` | 通过 id 前缀查看一个会话的时间线 |
| `uni status` | 找到的代理、发现的文件、索引与待处理的文件、存储大小 |
| `uni ingest` | 增量、幂等原生存储的拉取 |
| `uni mcp` | MCP 服务器(stdio)— 上述注册运行的内容 |
标志:`-n/--limit`,`-p/--project`(`.` = 当前 git 根目录),`-a/--agent`,`--all` 包括子代理的记录。
```
$ uni search "playwright"
codex projects/webshop 2026-03-29 0195aa1c-7 tool_calls:web_search
… site:«playwright».dev passWithNoTests «playwright» config official docs …
claude-code oss/atlas-ui 2026-05-28 f3a9c2d1-8 tool_calls:Bash
… npx «playwright» test --project=chromium 在推送 CI 修复之前 …
```
## 现实世界的数字
下面的所有测量都是在真实的开发机器(MacBook,Apple M4,Node 24)上进行的,与作者实际的代理历史记录对抗 — 而不是合成的固定装置。
| 指标 | 值 |
|---|---|
| 索引代理 | 2(Claude Code,Codex 包括存档会话) |
| 原始会话文件 | 760 个文件,**392 MB** 磁盘占用 |
| 会话/事件索引后 | 759 会话,**81,414 事件** |
| 可搜索文本 | **72.4M 字符 ≈ 18M tokens** |
| 原始存档(逐字源行) | **350.2M 字符 ≈ 87.5M tokens** |
| 首次完整索引 | **~35 秒**(~11 MB/s 端到端) |
| 增量重新索引 | **< 1 秒** |
| 预热全文搜索 | **5–50 毫秒** 每查询 — ≈ 50 毫秒整个 `uni search` 过程,英文和 CJK 相同 |
| 存储大小(SQLite + FTS 索引) | 582 MB |
| 隔离的无法解析行 | **0** |
令牌计数使用粗略的 4 个字符/令牌启发式,用于代码繁重的英文(中文运行更密集,因此实际数字更高)。换句话说:这台笔记本电脑已经有 **~87M tokens** 的代理工作历史记录,没有任何工具可以跨工具看到。
## 工作原理
中心辐射式结构。原生存储库从不写入;每个代理适配器将每个未文档化的格式映射到一个规范模型;MCP 服务器和 CLI 都读取相同的存储库。
```
~/.claude ~/.codex (~/.gemini, ~/.cursor, … 后续) 原始存储库 — 只读
│ │
└────┬─────┘ 单向索引适配器(容错解析器,固定装置测试)
▼
~/.uni-code/store.db SQLite + FTS5 — 规范会话和事件
│
├──► MCP 服务器 search_history · list_sessions · read_session (uni mcp)
├──► CLI status · ingest · sessions · log · search
└──► 投影 交接包、内存蒸馏 (计划中)
```
### 设计原则
- **原生存储库是只读的。** uni-code 从不写入代理目录。
- **没有双向同步。** 将一个代理的会话转换为另一个代理的原生格式是 N×N、有损且在每次发布时都会中断。写入始终是代理在其自身条件下消费的**生成工件**。
- **有损但有用的核心 + 原始边车。** 规范模型保留公共核心;每个源行在 `raw` 列中原样保存,以便没有映射决策是不可逆的。
- **构造容错。** 原始格式未记录且会静默更改。格式错误的行被隔离和计数,未知的记录类型被保留为不透明的事件 — 解析永远不会在内容上硬失败。
- **存储库是一个派生缓存 — 比代理自己的内存长寿。** 删除它并重新索引会重建所有原生存储库仍然保留的内容;并且由于代理会随着时间的推移修剪自己的历史记录,因此存储库通常会记住代理已经忘记的会话。
- **仅限本地,无遥测。** 记录包含机密信息。存储库为 `0600` 且没有任何内容会离开机器 — MCP 服务器是到本地进程的 stdio。
- **无需守护进程。** 像 `git status` 一样,在调用时进行增量索引。
### 中文 / CJK 搜索内置
大多数嵌入式全文引擎在中文上默默失败:默认分词器无法分割 CJK 文本,因此句子中的单词无法找到,而三元组索引无法提供两个字符的单词(部署,优化,隔离 — 大多数中文开发词汇)。uni-code 将每个 CJK 运行作为重叠的字符双字母组合,并对称转换查询,为任何 ≥2 个字符的 CJK 术语提供精确的子字符串匹配,也适用于混合中文/英文查询。英文/代码文本不受影响,索引会在方案更改时自行迁移。
```
$ uni search "隔离机制"
claude-code work/sandbox-runner 2026-07-06 9d41e0b7-3 meta
讨论«隔离机制»的目的和优化方案
```
## 路线图
1. ~~规范存储库,Claude Code + Codex 适配器,统一跨代理搜索~~ ✅
2. ~~MCP 服务器 + Claude Code 插件 — 代理之间主动回忆会话~~ ✅
3. ~~**交接和恢复** — `uni handoff`/`get_handoff` 简报,以及 `uni resume`/`resume_session`:从源代理自己的压缩摘要和实时窗口构建的跨代理恢复~~ ✅ — 一个可选的 `--distill` 精炼传递,将调用已安装的代理(因此 uni-code 本身不需要 API 密钥)仍在计划中。
4. **更多适配器** — Gemini CLI,Cursor,opencode,Copilot CLI。`src/adapters/` 是接口;每个适配器都附带一个合成的固定装置作为契约测试。
5. **说明/配置投影** — 一个真实来源 → `AGENTS.md`,`CLAUDE.md`,`.cursor/rules`,MCP 服务器列表。
## 开发
```bash
npm run dev -- status # 从源代码运行(tsx)
npm test # vitest — 适配器、存储库和 MCP 协议测试超过固定装置
npm run build # tsc → dist/
npx @modelcontextprotocol/inspector node dist/cli.js mcp # 交互式探测 MCP 服务器
```
`tests/fixtures/` 中的固定装置是**合成的** — 永远不要提交真实的记录。