@jh-cairn/cairn
v0.1.12
Published
Project-level state machine, gates, context directory, and auditable workflow orchestrator for Claude Code / Codex
Maintainers
Readme
cairn
在 Claude Code / Codex 之上补齐「项目级状态机、门禁、上下文目录、可审计流程」的编排器 CLI。
cairn(玛尼堆 / 路标石堆)是一个本地优先的编排层,把变更从「想法」到「合并」的过程变成显式、可强制、可审计的流程。
核心概念
- 状态机 — 跨会话的流程真相,决定下一步、约束路径、支持恢复
- 门禁 — 状态流转前置条件,质量阀门 + 失败回灌的自纠正环
- 审计 — append-only 事件流(
events.jsonl,每条事件带链式 hash),既是审计、也是状态真相;执行器对.cairn/的写入被 hook 拦截 - GitLab 投影 — 状态转移自动同步到 GitLab(scoped label、MR ready 状态、issue note)
安装
npm install
npm run build
npm link # 全局注册 cairn 命令开发阶段可直接用 npx tsx src/index.ts 运行。
快速开始
# 1. 初始化项目
cairn init
# 2. 从 GitLab issue 创建任务(自动开分支、创建 Draft MR、拉取 issue 内容)
cairn task new https://gitlab.com/group/project/-/issues/42
# 或者用 iid(从 git remote 推断项目)
cairn task new 42
# 或者纯本地任务
cairn task new my-feature
# 3. 启动 Claude Code 交互会话(带上下文 + hooks)
cairn code --task wi-42-some-title
# 或直接传 GitLab URL(自动创建 task)
cairn code https://gitlab.com/group/project/-/work_items/6
# 4. 查看状态
cairn status
# 5. 推进状态机(门禁全过后自动转移 + 自动提交 cairn 产物)
cairn advance --task wi-42-some-title
# 6. headless 编排模式(CI / 无人值守)
cairn run --task wi-42-some-title命令
| 命令 | 说明 |
|------|------|
| cairn init | 初始化 cairn(创建 .cairn/、CLAUDE.md import、hooks、.gitignore/.gitattributes) |
| cairn task new <ref> | 创建任务——接受 GitLab issue URL、iid 或本地名称;URL/iid 模式自动开分支、创建 Draft MR |
| cairn status [--task <id>] | 查看任务状态、门禁结果、转移历史 |
| cairn gate --task <id> | 运行门禁(--gate <name> 单个,--approve <name> 手动通过人工门禁,--format json) |
| cairn advance --task <id> | 推进状态机(先跑门禁),成功后自动提交 cairn 产物并同步 GitLab |
| cairn code [url] [--task <id>] | 启动 Claude Code 交互会话,可直接传 GitLab issue/work_item URL;退出后自动提交 cairn 产物 |
| cairn run --task <id> | headless 编排循环:execute → gate → 失败回灌 → 重试,直到终态或卡在外部门禁 |
| cairn hook stop | Stop hook:跑确定性门禁,失败回灌给执行器(有限轮次) |
| cairn hook pre-tool-use | PreToolUse hook:拦截执行器对 .cairn/ 的写入 |
两种运行模式
交互模式(cairn code)
开发者驱动。cairn 组装上下文、装 hooks、启动 Claude Code TUI。门禁和审计通过 hooks 自动强制。
开发者 → cairn code → 组装上下文 → 装 hooks → exec claude
↓
Stop hook → cairn gate → 回灌编排模式(cairn run)
cairn 驱动。循环调用 claude -p 执行任务,跑门禁,失败回灌,直到终态或卡在外部门禁(人工审批/MR/pipeline)。
cairn run → claude -p → gate → pass? → advance → 继续
↓ fail
回灌 reasons → 重试(最多 max_retries 次)
↓ external gate
exit 2(等待人工/CI)状态机流程
默认 flow.yaml 定义的状态流转:
spec → plan → implement → review → archive → done每个状态绑定门禁,门禁全过才能转移。implement 状态支持失败回灌和重试(最多 3 次)。
门禁类型
| 类型 | 判定方 | 例子 |
|------|--------|------|
| deterministic | shell 命令退出码 | build, test, lint |
| human | 本地审批文件 | plan_reviewed |
| gitlab_mr | GitLab MR approval | mr_approved |
| gitlab_pipeline | GitLab pipeline 状态 | pipeline_green |
GitLab 集成
cairn task new <iid/url>— 拉取 issue 内容,自动创建分支和 Draft MR- 状态转移 — 自动设置 scoped label(
flow::implement等) - 进入 review — 自动将 MR 标记为 Ready
- 审计锚点 — 转移事件的 chain hash 写入 issue note
目录结构
.cairn/
config.yaml # 全局配置
flow.yaml # 状态机定义(含 defaults 段)
context.md # per-state 注入上下文(生成物,gitignore)
rubrics/ # LLM 门禁评分标准(P3)
transcripts/ # 会话 transcript 留档(gitignore)
tasks/<id>/
meta.json # 任务元数据(issue iid、branch、MR iid)
state.json # 当前状态(事件折叠的派生缓存,gitignore)
events.jsonl # append-only 审计日志(链式 hash;merge=union)
approvals/<gate> # 人工门禁审批标记文件
steps/<n>-<state>/ # 会话 transcript 归档Git 产物管理
cairn 产物(.cairn/、.claude/settings.json、openspec/)在 advance 转移成功和 code 退出后自动提交,不需要手动提交两次。
gitignore(派生/临时文件):
.cairn/context.md— 每次会话重新生成.cairn/tasks/*/state.json— events.jsonl 的折叠缓存.cairn/tasks/*/.stop-hook.json— hook 临时状态.cairn/transcripts/— 会话原始 transcript
gitattributes:
events.jsonl merge=union— 并行分支合并时自动 union
退出码
| 码 | 含义 | |----|------| | 0 | 成功 | | 1 | 通用错误 | | 2 | 门禁阻塞(含外部门禁等待) | | 3 | 执行器错误 | | 4 | 预算超限 |
自定义门禁
编辑 .cairn/flow.yaml 中的 gates 部分:
gates:
test: { type: deterministic, cmd: "npm test" }
lint: { type: deterministic, cmd: "npm run lint" }
build: { type: deterministic, cmd: "npm run build" }
plan_reviewed: { type: human }
mr_approved: { type: gitlab_mr, min_approvals: 1 }
pipeline_green: { type: gitlab_pipeline }支持变量替换:$CHANGE(任务 ID)、$TASK_DIR(任务目录路径)。
技术栈
TypeScript + Node.js, commander, execa, yaml
License
MIT
