🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

路标记忆 oranchenjie/cairn

DeepSeek Harness
oranchenjie19 天前有提交已提供中文文档扫描:含敏感能力

一条命令还原上次进度,跨智能体续接工作

30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add oranchenjie/cairn
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]!
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
数据截至 2026/10/31·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 19 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

⚠︎ 实装验证未通过(unknown · 2026/10/31) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 10 处,展示前 10 条)
  • 读取本地文件
    adapters/vscode/extension.js:39
    try { if (fs.existsSync(p)) { return p; } } catch (e) { }
  • 读取本地文件
    adapters/vscode/extension.js:57
    if (!fs.existsSync(cli)) {
  • 执行外部命令来自配置/变量
    adapters/vscode/extension.js:72
    child = cp.spawn(python, [cli, ...args], {
  • 读取本地文件
    adapters/vscode/extension.js:282
    fs.readFileSync(path.join(os.homedir(), '.cairn', 'index.json'), 'utf8')
  • 读取本地文件
    adapters/vscode/extension.js:296
    if (fs.existsSync(m)) {
  • 读取本地文件
    adapters/vscode/extension.js:297
    const slug = fs.readFileSync(m, 'utf8').trim();
  • 读取本地文件
    selftest-vscode.js:80
    if (!fs.existsSync(INDEX)) {
  • 读取本地文件
    selftest-vscode.js:85
    const idx = JSON.parse(fs.readFileSync(INDEX, 'utf8'))
  • 读取本地文件
    selftest-vscode.js:96
    if (!root || !fs.existsSync(root)) {
  • 读取本地文件
    selftest-vscode.js:106
    subs = fs.readdirSync(root, { withFileTypes: true })
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
展开完整介绍(133 字)↓

跨 agent / 跨文件夹的工作记忆 CLI。一条命令还原"上次做到哪", 一条命令留下路标。存储是人可读的 Markdown,零依赖, 支持 Claude Code / VS Code Copilot / DSH / 任何认 AGENTS.md 的 agent。

README

由 DeepSeek 最新模型翻译生成
Cairn cairn /kern/ · n. 登山者在岔路上垒起的一堆石头,给后来的人指路。 它不修路,只在关键处留一个记号:这边走过,那边是死路。 跨智能体、跨文件夹的工作记忆。 一条命令还原现场,一条命令留下路标。 纯 Python 标准库 · 零依赖 · 存储是人可读的 Markdown · 不在你的项目里留任何文件 你遇到的问题不是「没有记忆」 是记忆锁在某个智能体的某个会话里: | 症状 | 代价 | | 换个智能体(Claude Code ↔ Copilot ↔ Codex ↔ DSH) | 背景重讲一遍 | | 换个文件夹 | 上下文归零 | | 隔三天回来 | 忘了做到哪,也忘了上次为什么否掉某个方案 | | 同一个坑 | 踩第二次、第三次 | | 上下文越聊越糊 | 智能体开始编数字,而你没法核对 | cairn 把「上次做到哪」从会话里捞出来,变成一份谁都能读的全局文件。 30 秒看懂 cairn init # 在项目里跑一次,登记 cairn boot # 以后每次开工:还原现场 cairn wrap # 每次收工:留下路标 cairn boot 打出来的是这样(真实格式,内容为示例): cairn · 开工上下文 项目 支付网关(pay-gw)你是被交接的 agent。读完下面内容,先复述再动手。
展开完整文档(README 剩余 1 节)
Cairn

cairn /kern/ · n. 登山者在岔路上垒起的一堆石头,给后来的人指路。
它不修路,只在关键处留一个记号:这边走过,那边是死路。

跨智能体、跨文件夹的工作记忆。
一条命令还原现场,一条命令留下路标。

纯 Python 标准库 · 零依赖 · 存储是人可读的 Markdown · 不在你的项目里留任何文件

你遇到的问题不是「没有记忆」

是记忆锁在某个智能体的某个会话里:

| 症状 | 代价 |
| 换个智能体(Claude Code ↔ Copilot ↔ Codex ↔ DSH) | 背景重讲一遍 |
| 换个文件夹 | 上下文归零 |
| 隔三天回来 | 忘了做到哪,也忘了上次为什么否掉某个方案 |
| 同一个坑 | 踩第二次、第三次 |
| 上下文越聊越糊 | 智能体开始编数字,而你没法核对 |

cairn 把「上次做到哪」从会话里捞出来,变成一份谁都能读的全局文件。

30 秒看懂

cairn init # 在项目里跑一次,登记 cairn boot # 以后每次开工:还原现场 cairn wrap # 每次收工:留下路标

cairn boot 打出来的是这样(真实格式,内容为示例):

cairn · 开工上下文 项目 支付网关(pay-gw)你是被交接的 agent。读完下面内容,先复述再动手。
不要改文件,不要开始干活 —— 复述完停下等用户确认。
项目路径:D:\work\pay-gw

--- NOW.md(当前状态,最重要)------------------------------ 最后更新:2026-03-14

在干嘛把 refund 的幂等键从 order_id 换成 order_id + attempt。
线上有个重复退款的 case,复现脚本已经写出来了。

下一步打开 src/refund/handler.py:88,那里 _idem_key() 还是旧的拼法。

不要碰 db/migrations/ —— 下周要合并另一个分支的迁移,现在动会冲突。

--- LOG.md(最近 5 条)-------------------------------------
- 16:20 | 复现了重复退款 | pytest tests/test_refund.py -k idem 稳定红 | 确认不是偶发
- 15:02 | 排除了并发窗口 | 加了 asyncio.sleep(0.5) 仍然重复 | 不是竞态

--- DECISIONS.md -------------------------------------------
| 2026-03-11 | 幂等键不用 Redis 去重 | 少一个外部依赖,且要能离线重放 | Redis SETNX 方案 |

--- GOTCHAS.md ---------------------------------------------
- 本地跑迁移会把 dev 库清空 → 原因:make migrate 里写死了 DROP SCHEMA → 对策:用 make migrate-safe 复述这 4 句,然后停下: ① 这个项目在做什么? ② 上次做到哪?
③ 下一步是什么? ④ 哪些坑不能踩?

这就是「上次做到哪」。 不用谁再讲一遍。

安装

需要 Python 3.8+(只用标准库,不需要 pip install 任何东西)。

git clone https://github.com/oranchenjie/cairn.git $env:USERPROFILE\.cairn\src
cd $env:USERPROFILE\.cairn\src
.\install.ps1

装完新开一个终端(PATH 生效),然后:

cd <你的项目>
cairn init # 登记(项目里已有 _ai/ 的话会自动迁移) cairn boot # 看看它能不能说出「上次做到哪」

可选参数:

.\install.ps1 -SkipPath # 不动 PATH .\install.ps1 -Python "C:\...\python.exe" # 指定 Python .\install.ps1 -DshHome "\\wsl$\...\.dsh" # DSH 跑在 WSL 里时看这里 .\install.ps1 -SkipVSCode -SkipClaude -SkipDsh # 只装 CLI

不碰系统 PATH、不碰注册表、不装任何包。
出问题了就把 ~/.cairn 和 ~/.vscode/extensions/oranchenjie.cairn- 删掉。

存储长什么样

~/.cairn/
index.json 项目索引:路径 → slug projects/<slug>/ NOW.md ← 当前状态。每次收工整体重写,≤60 行 LOG.md ← 工作日志。只追加,最新在上 DECISIONS.md ← 决策 + 否决了什么 GOTCHAS.md ← 踩过的坑:症状 → 原因 → 对策 STATE.md ← 环境 / 路径 / 命令 / 实测数字

为什么拆成 5 个? 因为 NOW 要短(每次重写)、LOG 要长(只追加),混在一个文件里两边都做不好。

为什么是 Markdown? 你能用眼睛看、能 git diff、能 grep、坏了能手动改一行。
它不是黑盒 —— 这一条直接排除掉了数据库和向量库。
项目根里一个文件都不留。 项目识别靠 index.json 里登记的路径,从当前目录往上比对。所以你在任何子目录里跑 cairn 都能认出来,而不会在你的仓库里凭空多出一个未跟踪文件。

早期版本会在项目根写一个标记文件。它能工作,但代价很实在 ——那是个裸的未跟踪文件,会一直挂在 git status 里。现在标记只读不写:老项目不用重新登记,init 会顺手清掉遗留的,doctor 会把残留的报出来。

代价说清楚:新登记的项目不再有标记,所以把项目文件夹改名或搬走之后认不出来了 ——到新位置重新 cairn init 一次即可。

命令

| 命令 | 干什么 |
| cairn boot | ★ 会话开头:打印开工上下文(有硬上限,不会撑爆 context) |
| cairn wrap | ★ 会话结尾:打印收工清单 + 当前规模 |
| cairn init [dir] | 登记项目,自动迁移已有的 _ai/ |
| cairn now / --set - | 读 / 整体重写 NOW.md |
| cairn log "..." | 追加日志(没证据会警告,纯空话直接拒写) |
| cairn decide "..." --why "..." --rejected "..." | 记决策 |
| cairn gotcha "症状" --cause "..." --fix "..." | 记坑 |
| cairn state / --set - | 环境 / 路径 / 命令 / 实测数字 |
| cairn find <kw> [--all] | 全文搜索(--all 跨所有项目) |
| cairn doctor | 体检:超长的 NOW、没证据的日志、没写否决项的决策 |
| cairn status | 所有项目一览 |
| cairn forget <slug> [--purge] | 注销(默认留记忆,--purge 连记忆一起删) |
| cairn prompt --agent <X> | 生成喂给某个 agent 的接入提示词 |

now 和 state 都支持 --set - 从 stdin 读,长内容一律走它。

它怎么保证「记了有用」

大多数「记忆」工具死于同一个原因:记了一堆三个月后没人看得懂的东西。 cairn 在三个地方设了闸。

① 没证据的不让写。 cairn log 会检查内容里有没有数字 / 文件名 / 路径 ——纯空话(「优化了一下」)直接拒写并以退出码 2 结束:

$ cairn log "优化了一下"
[x] 这条又没证据又是空话(如「优化了一下」),不写。
改成:干了什么 | 命令/文件名/数字 | 影响确认要写就加 --force。

② 「否决了什么」才是决策的重点。 DECISIONS.md 的意义不是记你选了什么,而是记你没选什么、为什么 —— 否则三天后(包括你自己)会把已经否掉的方案再提一遍。
没写 --rejected 会收到提醒。

③ 记忆不能自己变成负担。 boot 的输出有硬上限(NOW 70 行、LOG 5 条、 GOTCHAS 12 行、STATE 45 行)。上下文本身是稀缺资源,一个把所有日志塞进 prompt 的「记忆工具」是在帮倒忙。

各 agent 怎么接

一份实现(core/cairn.py),N 个壳。所有适配器都只做转发 ——所以不会出现「插件说的和 CLI 说的不一致」。

| Agent | 机制 | 自动吗 |
| Claude Code | 插件:SessionStart hook 自动注入 cairn boot + 3 个斜杠命令 + 1 个技能 | ✅ 装了就行 |
| VS Code Copilot | 扩展注册 7 个 languageModelTools + 8 个命令 | ✅ 装了就行 |
| DSH(DeepSeek Harness) | skill(按需加载)+ $DSH_HOME/AGENTS.md(自动注入) | ✅ 装 skill 就行;全自动要贴一次片段 |
| Codex / Zed / Windsurf / Amp / Jules / Junie / Devin / Kilo | 都认 AGENTS.md | ✅ 把 adapters/generic/AGENTS.snippet.md 贴进去 |
| Cursor | .cursor/rules/.mdc | ⚠️ 要建文件 |
| Cline | .clinerules/ | ⚠️ 要建文件 |
| Aider / Gemini CLI | 默认不读 | ❌ 要改配置 |

细节见 adapters/<名字>/README.md。

为什么不做成 MCP,也不做成数据库

这两条路都认真考虑过,都否掉了。

MCP server —— 每个 agent 要单独装、单独配。你换工具就得重配一遍,反而更浪费时间。而「有终端」是所有 agent 的公共能力,CLI 一个命令谁都能调。

数据库 / 向量库 —— 你不能用眼睛看、不能 git diff、不能手动改一行、不能 grep。
出问题时是黑盒,调试成本远大于收益。而且「记忆」这件事, 可核对性比检索能力重要得多。

所以:存储是 Markdown,接口是命令行。

设计取舍(以及否决了什么)

| 决策 | 为什么 | 否决了什么 |
| 存储用全局目录,不用 repo 内的 _ai/ | 你要的就是「跨文件夹」 | 每个 repo 一份 _ai/ |
| 项目识别用 index.json 路径匹配 | 往用户仓库里塞文件不可接受 —— 它会在 git status 里裸奔 | 项目根的标记文件(降为只读兼容) |
| 拆成 5 个文件 | NOW 要短、LOG 要长,混一起两边都做不好 | 一个 NOTES.md |
| 认不出项目就报错,绝不回退 | 在 C:\ 里跑能面无表情地吐出另一个项目的内容 —— 比报错可怕得多 | 「只有唯一项目就用它」的回退 |
| 日志拒写空话 | 没证据的日志三个月后等于没写 | 什么都让写 |
| boot 输出有硬上限 | 记忆不能自己变成负担 | 把整个 LOG 塞进去 |
| VS Code 扩展用纯 JS | 装机成本 = 拷文件夹,没有 npm/tsc/vsce 三层失败点 | TypeScript + 打包 |
| 适配器不自己实现逻辑 | 一份实现,不会出现说法不一致 | 在 TypeScript 里重写一遍 |
| slug 必须校验 | forget "../../x" --purge 曾能删掉 projects/ 之外的任意目录。这工具是给智能体用的,提示词注入足以触发 | 信任传入的项目名 |

目录

~/.cairn/
src/ ← 源码(本仓库的全部内容) core/cairn.py 唯一的核心实现(纯标准库) install.ps1 部署:CLI→bin、扩展→VS Code、插件→Claude Code、skill→DSH make-vsix.ps1 打包 .vsix selftest-vscode.js 无头验证扩展的项目识别(不用启动 VS Code) adapters/ vscode/ 纯 JS 扩展,无构建 claude-code/ Claude Code 插件 dsh/ DSH 适配 generic/AGENTS.snippet.md 给所有认 AGENTS.md 的智能体 README.md 本文件 bin/ ← 部署出来的 CLI(别手改,会被 src 覆盖) claude-plugin/ ← 部署出来的 Claude Code 插件 projects/<slug>/ ← ★ 你的记忆数据(这里才是活数据)

⚠️ 不要在这个仓的上级目录(~/.cairn/)里 git init。
那会把 projects/ 里你的私人工作记忆一起提交上去。
仓库根是 src/。 .gitignore 里也列了这些名字作为兜底,但别依赖它。

为什么源码不住在项目目录里。 源码曾经放在某个项目的 agent-memory/ 下,那是个坑:你把那个项目删了/移了,工具本身就跟着没了。
工具是跳项目的,它的家也应该是跳项目的。

开发

改了 core/cairn.py 之后:

cd $env:USERPROFILE\.cairn\src
.\make-vsix.ps1 # 先打包(它会自动把 core 同步到 adapters/vscode/vendor/) .\install.ps1 # 再部署

改了扩展代码必须先 make-vsix.ps1。 install.ps1 只安装现成的 .vsix,不会重新打包 —— 忘了这一步的后果是 CLI 更新了、扩展还是旧的。

.ps1 文件必须带 UTF-8 BOM。 PowerShell 5.1 在无 BOM 时按 ANSI(GBK) 读,中文会乱,严重时连解析都过不去。检查前三个字节是不是 EF BB BF。

License

MIT
预览分享卡片长什么样 ↓oranchenjie/cairn
分享 · DeepSeek Harness Hub
oranchenjie/cairn

一条命令还原上次进度,跨智能体续接工作

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部