An operating system for your Obsidian vault, driven by your coding agent.
Your agent starts every session already knowing every project you have, its status, and the exact next action. When the session ends it writes back what it learned and pushes. You do nothing.
git clone https://github.com/openwarehq/cairn
cd cairn && ./install.shOne command. No plugins, no subscription, no server, no account. Plain markdown and two shell hooks.
session starts
│
├─ pulls the vault
└─ injects 00-index/projects.md + 00-index/active-tasks.md
into the agent's context, before your first word
│
you work — normally, saying nothing about any of this
│
session ends
│
├─ agent writes a distilled note to Sessions/
├─ agent updates both index files
├─ hook redacts any credential that made it into a note
└─ commits and pushes
The second time you open a terminal, the agent already knows what you were doing. The tenth time, it knows why you rejected the approach you are about to suggest again.
Read this part first.
- It does not make the agent smarter, it makes it briefed. The whole value is
that
projects.mdandactive-tasks.mdare true. If you let them rot, this is an elaborate way to inject stale context into every session, which is worse than none. - It does not summarise your transcripts. Nothing here reads your chat history. The agent writes the note deliberately, during the session, because it knows which decision mattered and a summariser does not. If you want raw transcript export, that is a different tool.
- It is Claude Code specific. The hooks use Claude Code's
SessionStartandStopevents and itsadditionalContextoutput shape. The vault is plain markdown and works with anything; the automation is not portable as-is. - The context it injects is not free. Both index files go into every session, so
they cost tokens on every single one. That is the trade — and it is why the
templates push you toward one line per project instead of a page. If
projects.mdgrows past a screen, split detail intoprojects/<name>/. - The secret scrub is a backstop, not permission. It redacts common credential shapes from staged markdown before committing. It will not catch every format, and redacting a note does not un-paste a key you already sent somewhere. Rotate it.
- Sync is git, with all that implies. Two machines editing the same index file in the same hour will conflict, and the hook resolves nothing clever — it rebases, and if that fails it leaves your work committed locally and unpushed.
- No mobile. Obsidian mobile can read the vault fine, but hooks only run where Claude Code runs.
Two files run everything.
00-index/projects.md is one row per project: what it is, its status, and the
current focus. 00-index/active-tasks.md is the next action for each. Both are
injected verbatim at session start. There is no database and no index to rebuild —
if you edit them by hand in Obsidian, the next session sees your edit.
Distilled, not logged. The shipped CLAUDE.md is specific about what a session
note is for: the decisions and why, what broke, the number you measured, the thing
you would have got wrong. Explicitly not what happened step by step, and not
anything recoverable from git log. The test it gives the agent is would this have
saved me an hour if I had read it before starting?
The graph is configured to be readable. Obsidian's default graph is one grey mush
of dots at any real size. cairn ships colour groups keyed to the folders, so the
vault reads as a map: index in gold at the centre, projects in teal around it, the
mass of sessions in indigo underneath, and #decision / #gotcha picked out in warm
tones. This is the difference between a graph you screenshot once and a graph you
actually navigate.
Nothing to install inside Obsidian. Core plugins only — no community plugins, no Dataview, no Templater, nothing to break on an Obsidian update. The CSS snippet is one file you can delete.
~/ObsidianVault/ ← or wherever you point it
├── CLAUDE.md the operating rules the agent follows
├── 00-index/
│ ├── projects.md ★ injected every session
│ └── active-tasks.md ★ injected every session
├── projects/
│ └── _template.md architecture · decisions · gotchas · next action
├── Sessions/ one distilled note per session
└── .obsidian/ dark theme, graph colour groups, one CSS snippet
~/.claude/hooks/
├── cairn-session-start.sh pull, then inject the two indexes
└── cairn-sync.sh scrub secrets, commit, push
Both hooks are appended to ~/.claude/settings.json. Existing hooks are kept —
the installer merges rather than overwrites, backs the file up first, and running it
twice does not install twice. ./uninstall.sh removes both and leaves your notes
alone.
./install.sh /path/to/vault |
install somewhere other than ~/ObsidianVault |
CAIRN_VAULT |
the vault path, written into settings.json by the installer |
CAIRN_PULL_TIMEOUT |
seconds before the session-start pull gives up (default 8) |
To sync across machines, give the vault a private remote:
git -C ~/ObsidianVault remote add origin git@github.com:you/second-brain.git
git -C ~/ObsidianVault push -u origin mainPrivate. Your second brain is a map of everything you are building and every credential you nearly pasted into it.
Safe. The installer writes a file only when nothing is there, so every existing note,
setting and snippet survives — it will tell you how many files it skipped. The one
thing to check afterwards is CLAUDE.md: if you already had one, yours is kept and
cairn's is not written, so merge the rules in by hand.
MIT. Obsidian is not affiliated with this and is a separate program you install yourself — cairn only writes markdown into a folder it happens to open.