Skip to main content
Glama
README.md
# Cairn

> 跨 AI 编程工具、跨会话的项目进度中枢 —— 每个 agent、每个会话,干活前先读"走到哪了",干完自动堆上新的进度标记。

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
[![Node](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js&logoColor=white)](#开发)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-3178c6?logo=typescript&logoColor=white)](#)
[![MCP](https://img.shields.io/badge/MCP-server-7c5cff)](https://modelcontextprotocol.io)
[![Status](https://img.shields.io/badge/stage-MVP-orange)](#路线图)

Cairn 在 `~/.cairn/` 维护一份每项目的 `PROGRESS.md`,作为 Claude Code / Codex / Cursor 等 AI 编程工具共用的"事实来源"。

- **Web Console** 把当前任务(NOW)、下一步(NEXT)、里程碑时间线、Todos、各工具的 token / session 用量集中到一个深色仪表盘。
- **MCP server** 暴露 `cairn_read_progress` / `cairn_write_progress` / `cairn_add_activity` / `cairn_mark_milestone` 等工具,让 agent 一上来就读、干完就写。
- **SessionEnd hook**(目前覆盖 Claude Code)会话结束时自动追加进度。
- 文件级单一事实源:所有写入落到 `PROGRESS.md`,没有任何隐藏状态,能 `git diff` 看清楚。

当前为 MVP:单工具闭环(Claude Code)已通;Codex / Cursor 走日志扫描 + MCP 读写,未接 SessionEnd hook。详见 [路线图](#路线图)。

---

## 目录

- [核心理念](#核心理念)
- [快速上手](#快速上手)
- [CLI 命令](#cli-命令)
- [MCP 集成](#mcp-集成)
- [数据布局](#数据布局)
- [架构](#架构)
- [开发](#开发)
- [路线图](#路线图)
- [贡献](#贡献)
- [License](#license)

---

## 核心理念

1. **进度是文档,不是数据库。** `PROGRESS.md` 用 YAML frontmatter + 几节 Markdown 描述「正在做 / 接下来 / 里程碑 / Todos / 活动流」。AI 工具可以直接读,人也可以直接编辑。
2. **跨工具共享同一份记忆。** Claude Code 干一半,明天用 Codex 继续 —— 只要它接了 Cairn MCP,第一件事就是 `cairn_read_progress`,自然衔接。
3. **会话结束自动落账。** SessionEnd hook 抽 transcript 要点写进活动流,不靠用户记得。
4. **派生数据隔离。** Token / session 统计放在 `db.sqlite` 里,是缓存,可以随便删 —— `PROGRESS.md` 才是源。

## 快速上手

> 需要 Node ≥ 18,推荐 pnpm。

```bash
# 克隆并构建
git clone https://github.com/Zrzzzz/Cairn.git
cd Cairn
pnpm install
pnpm build

# 把当前项目接入 Cairn
node dist/cli/index.js init ~/dev/my-project

# 把 Cairn 注册到 Claude Code / Codex / Cursor 的 MCP 配置里
node dist/cli/index.js mcp-install --all

# 启动 Console(默认 http://127.0.0.1:3737)
node dist/cli/index.js serve
```

打开浏览器访问 `http://127.0.0.1:3737`,就能看到这个项目和其它已接入项目的进度仪表盘。

需要后台常驻:

```bash
node dist/cli/index.js serve -d        # daemon 模式
node dist/cli/index.js status          # 查看 pid / url
node dist/cli/index.js stop            # 停掉后台
```

## CLI 命令

| 命令 | 作用 |
|---|---|
| `cairn init [path]` | 接入项目:写 `~/.cairn/projects/<id>/PROGRESS.md`、注入 `CLAUDE.md` / `AGENTS.md` / `.cursorrules`、注册 Claude Code SessionEnd hook |
| `cairn serve [-p PORT] [--tools ...] [-d]` | 启动 Console Web + SSE;`--tools` 选要扫的工具日志,省略走交互式 |
| `cairn stop` / `cairn status` | 管理后台 daemon |
| `cairn hook session-end` | Claude Code SessionEnd 调用:把会话总结追加到当前项目的活动流 |
| `cairn mcp` | 在 stdio 上启动 MCP server,供 agent 接入 |
| `cairn mcp-install [-t ...\|-a] [-s user\|project]` | 把 Cairn MCP 注册到 Claude Code / Codex / Cursor 的配置里,省略 `-t` 走交互式 |
| `cairn mcp-uninstall [-t ...\|-a]` | 反操作 |

`cairn init` 关键 flag:

- `--id <slug>` 覆盖项目 id(默认从目录名 slugify)
- `--name <name>` 友好名称
- `--tool claude-code,codex,cursor` 一次性接入多个工具
- `--no-hook` 不写 Claude Code 的 SessionEnd hook
- `--force` 覆盖已有 `PROGRESS.md`

## MCP 集成

跑过 `cairn mcp-install` 之后,agent 在每个新会话开始时应当:

1. 调 `cairn_list_projects` 找到当前 cwd 对应的项目(或显式 `project` 参数)。
2. 调 `cairn_read_progress` 读取 Now / Next / Milestones / Todos。
3. 干活过程中用 `cairn_add_activity` / `cairn_mark_milestone` 回写。

可用工具:

| Tool | 说明 |
|---|---|
| `cairn_list_projects` | 列出已接入项目(带 cwd 命中标记) |
| `cairn_read_progress` | 读 PROGRESS.md(结构化输出 frontmatter + sections) |
| `cairn_write_progress` | 部分更新 Now / Next / Milestones / Todos |
| `cairn_add_activity` | 追加一条活动流 |
| `cairn_mark_milestone` | 把里程碑标成 done / current / blocked / next |
| `cairn_list_todos` | 列出未完成 Todos |

在 `CLAUDE.md` / `AGENTS.md` 里建议加这段提醒(`cairn init` 已自动写入):

```md
## Cairn 进度

本项目接入了 Cairn 跨工具进度中枢。会话开始前,请先通过 MCP 工具
`cairn_read_progress({ project: "<project-id>" })` 读取当前进度。
推进工作后,用 `cairn_add_activity` / `cairn_mark_milestone` / `cairn_write_progress` 回写。
```

## 数据布局

```
~/.cairn/
├── projects/
│   └── <project-id>/
│       └── PROGRESS.md      # 单一事实源
├── db.sqlite                # 派生缓存:token / session 统计
└── config.json
```

`PROGRESS.md` 示例:

```md
---
schema: cairn/v1
id: my-project
name: My Project
repo: ~/dev/my-project
tools: [claude-code, codex]
last_activity: 2026-06-19T20:11:00.000Z
created: 2026-06-18T09:30:00.000Z
---

## Now
把仪表盘的数据抓取从 fetch 换成 SWR + suspense

## Next
迁移登录页 · 灰度 10% 用户

## Milestones
- [x] 设计系统 — 6/02
- [x] 认证流 — 6/10
- [~] 仪表盘 — 进行中
- [ ] 上线

## Todos
- [ ] 设计 token 颜色梳理  <!-- src:web 2026-06-19 -->
- [x] 接通 SSE 实时刷新

## Activity
- 2026-06-19T20:11:00.000Z · claude-code · 把 ProjectCard 重写为时间线版
```

`db.sqlite` 只是用来撑仪表盘的派生数据,删了 `cairn serve` 下一次扫描会重建。

## 架构

```
┌───────────────────────────────────────────────────────────┐
│                  ~/.cairn/projects/<id>/                  │
│                       PROGRESS.md                         │  <- 单一事实源
└────^──────────────────────────────────────^───────────────┘
     │ 文件监听 (chokidar)                  │ 读 / 写
     │                                      │
┌────┴──────────────┐    ┌──────────────────┴──────────────┐
│  cairn serve      │    │  cairn mcp  (stdio)             │
│  · Hono + SSE     │    │  · Claude Code / Codex / Cursor │
│  · React Console  │    │  · cairn_read_progress 等       │
└────────^──────────┘    └─────────────────────────────────┘
         │ HTTP / SSE
         │
   浏览器 Dashboard
```

- **后端**:`src/web` 用 Hono 起 HTTP 服务,文件变更走 chokidar → SSE 推到前端。
- **MCP server**:`src/mcp` 走 `@modelcontextprotocol/sdk` 的 stdio transport。
- **派生统计**:`src/core/jsonl.ts` / `codex.ts` / `cursor.ts` 定时扫各工具的本地 transcript,把 token / session 聚合写入 `db.sqlite`。
- **前端**:`ui/` 是独立的 Vite + React 工程,构建产物被 `cairn serve` 直接 mount。

## 开发

```bash
pnpm install

# 前端热更(默认 http://localhost:5173)
pnpm dev:ui

# 后端 + MCP 热更
pnpm dev:server

# 一键类型检查
pnpm typecheck

# 全量构建
pnpm build
```

代码组织:

```
src/
├── cli/         # cairn 子命令:init / serve / hook / mcp / mcp-install ...
├── core/        # 进度文件解析、文件监听、各 AI 工具日志扫描
├── hook/        # SessionEnd hook 实现
├── mcp/         # MCP server + tools
├── shared/      # 前后端共享类型 (api.ts)
└── web/         # Hono routes + SSE
ui/              # React + Vite 控制台
templates/       # PROGRESS.md / CLAUDE.md / AGENTS.md / .cursorrules 模板
scripts/         # 构建辅助
```

详细贡献流程见 [CONTRIBUTING.md](./CONTRIBUTING.md)。

## 路线图

- [x] PROGRESS.md schema + 解析器
- [x] CLI `init` / `serve` / `mcp` / `mcp-install`
- [x] React Console(时间线 / 当前任务高亮 / 工具筛选 / 搜索)
- [x] Claude Code SessionEnd hook
- [x] Claude Code / Codex / Cursor 日志扫描
- [ ] Codex / Cursor 的"会话结束"等价 hook
- [ ] 多项目里程碑联动视图
- [ ] 远程 Console(认证 + 多用户)
- [ ] `PROGRESS.md` schema 版本号兼容机制

## 贡献

欢迎 issue / PR。开始之前请读一下 [CONTRIBUTING.md](./CONTRIBUTING.md) 和 [行为准则](./CODE_OF_CONDUCT.md)。

## License

[MIT](./LICENSE) © 2026 Zrzzzz