kains30 downloadsRecords vault changes as a machine-readable feed with per-reader cursors, so AI assistants can incrementally catch up on what you changed.
Give your AI agents a changelog of your vault. Every edit you make is recorded as a machine-readable event feed with per-reader cursors — so any AI can catch up on what changed since its last visit, instead of blindly rescanning thousands of notes.
中文文档 · Obsidian Community Listing
If this plugin saves you time, you can buy me a coffee — it keeps the development going. 如果这个插件帮你省了时间,可以请我喝杯咖啡 ☕
+added / −removed)AGENTS.md / CLAUDE.md / GEMINI.md on first run, so coding agents discover the feed with zero setupYour AI assistant has no idea what you edited between sessions. Scanning the whole vault every time is expensive; not scanning means it works from stale knowledge. This plugin continuously records which file changed, how, and by how much — the AI pulls that incrementally, on demand.
Community market (recommended): Settings → Community plugins → Browse → search Vault Change Feed → Install → Enable. The AI protocol block installs itself on first run.
BRAT: add kains2866/vault-change-feed as a beta plugin.
Manual: copy main.js and manifest.json from the latest release into <vault>/.obsidian/plugins/vault-change-feed/, then enable the plugin.
<configDir>/plugins/vault-change-feed/:changelog.jsonl — the event stream, one JSON event per linecursors.json — per-reader read cursorsbaseline.gz — content baseline snapshot (for diffs and reconciliation)Note: the plugin has built-in standby protection — concurrent instances coordinate through a heartbeat writer lock (writer.lock); only the lock holder records, other instances stand by (read-only API still works) and automatically take over once the lock goes stale (90 s). Still, prefer running it in only one Obsidian instance per vault at a time.
{"seq": 1284, "ts": 1785000000000, "op": "modify", "path": "ML/overfitting.md", "stat": {"added": 12, "removed": 3}, "source": "live"}
op: create / modify / delete / rename (carries oldPath) / resync (baseline rebuilt — full rescan advised)stat: {added, removed} line counts; null means "changed, magnitude unknown — open the file" (binaries, oversized files)source: live / reconcile (startup backfill) / systemAI agents don't know the feed exists out of the box. On first enable, the plugin automatically installs a reading-protocol block (wrapped in <!-- vault-change-feed:start/end --> markers) into the vault-root AGENTS.md, CLAUDE.md, and GEMINI.md — the conventional discovery points for coding agents (AGENTS.md is the cross-tool standard; CLAUDE.md for Claude Code; GEMINI.md for Gemini CLI, which doesn't read AGENTS.md by default). Zero clicks needed.
Auto-install AI protocol on first run to fall back to a one-time notice; the Install AI protocol for agents / Remove AI protocol from agent files commands remain availableCopy unread changes for AI command insteadThe protocol block relies on the AI choosing to read it. extras/vault-feed-hook.mjs goes further: hooked into an agent's SessionStart event, it injects merged unread changes into the context automatically and advances the cursor. The script walks up from the session cwd to find a tracked vault, and stays completely silent outside a vault or when nothing is unread.
Kimi Code (~/.kimi-code/config.toml):
[[hooks]]
event = "SessionStart"
command = "node /path/to/extras/vault-feed-hook.mjs --reader=kimi-code --format=kimi"
timeout = 10
Claude Code (hooks.SessionStart in ~/.claude/settings.json):
{ "type": "command", "command": "node /path/to/extras/vault-feed-hook.mjs --reader=claude-code --format=claude", "timeout": 10 }
--reader is the agent's stable cursor name. Use an absolute node path.
This vault is tracked by the vault-change-feed Obsidian plugin. Before editing notes, catch up on what the user changed since your last visit:
.obsidian/plugins/vault-change-feed/cursors.json and find your reader name (use your agent id, e.g. "kimi-cli"; absent means cursor 0)..obsidian/plugins/vault-change-feed/changelog.jsonl (one JSON event per line) and take events with seq greater than your cursor.> 0 and the smallest seq in the file is greater than cursor + 1, the log was rotated and you missed events — stop and do a full vault rescan instead.op: "resync", the plugin rebuilt its baseline — a full rescan is advised.{"seq", "ts", "op": "create"|"modify"|"delete"|"rename"|"resync", "path", "oldPath"?, "stat": {"added", "removed"} | null, "source"}. stat: null means "changed, magnitude unknown — open the file if you care".seq you saw back to cursors.json under your reader name. Write atomically: write cursors.json.tmp, then rename it to cursors.json.Inside Obsidian, other plugins/scripts can use the JS API instead of files:
const api = app.plugins.plugins['vault-change-feed'].api;
const { events, stale, latestSeq } = await api.getChanges('my-plugin');
// ...handle events...
await api.markRead('my-plugin', latestSeq);
The JS API's getChanges merges unread events per file by default (api.getChanges(name, { merge: false }) returns the raw stream; groups that can't be merged losslessly are passed through, see below). External agents reading changelog.jsonl directly see the raw event stream and may implement the same merging:
seq first (the log may be out of order), then group by path (resync is never merged); merged events take the group's max seq/ts and the last event's sourcedelete and the group contains a rename → delete on the first rename's oldPath (no oldPath field, stat from the delete itself); last event is delete → delete (stat from the last delete)modify (stat null); starts with create → create; contains a rename → rename (keeps the first rename's oldPath); otherwise → modifystat is the per-line sum if all entries are non-null, else null; output sorted by merged seqCopy unread changes for AI — copies a compact summary of unread changes (reader manual) to the clipboard, ready to paste into any AI chatInstall AI protocol for agents / Remove AI protocol from agent files — manage the discovery blocks in AGENTS.md / CLAUDE.md / GEMINI.md| Setting | Default | Description |
|---|---|---|
| Tracked text extensions | md, markdown, txt, canvas, json, csv |
These extensions get diff stats |
| Exclude globs | empty | Extra exclusion rules; the vault config folder is always excluded |
| Large file threshold | 1024 KB | Larger files get stat: null |
| Baseline content budget | 102400 KB (100 MB) | Text kept in memory for diffing; beyond the budget, files store hash only (stat falls back to null) |
| Retention days / max entries | 90 / 50000 | Log rotation, whichever limit hits first |
| Baseline flush interval | 300 s | Baseline persistence period |
| Auto-install AI protocol on first run | on | Install the protocol block on first enable |
| Sync AGENTS.md / CLAUDE.md / GEMINI.md | on | Per-file install targets |
| Auto-sync protocol block | on | Refresh installed blocks after plugin updates |
Fully local: no network calls, no uploads, no data collection. Everything lives in your own vault.
npm install
npm run build # typecheck + bundle main.js
npm test # vitest
Works on desktop and mobile (all file operations go through the Obsidian vault API).
MIT © tiyukains