Noah Zender58 downloadsCreate manual Markdown version snapshots and compare them with inline diffs.
Draftline is an Obsidian plugin for manual Markdown version snapshots and inline comparisons between them. It's built for two things: keeping version control over your notes, and giving you (or an AI assistant) a shared, readable format for discussing what changed between drafts. Versions live inside the note itself — not in a sidecar file or plugin database — so history travels with the note (sync, git, backups), and agents or other tools can read and reason about it straight from the source file.
Draftline is not yet listed in the Obsidian Community Plugins directory. Until it is, install it with BRAT (Beta Reviewer's Auto-update Tool):
Once Draftline is accepted into the Community Plugins directory, it will be installable directly from Obsidian without BRAT.
%% draftline-* %% markers, so both humans and tools can read version history without a special parserEverything lives in one Markdown file; there is no external database, index, or network call.
%% draftline-document {...} %% marker holding schema/version metadata. Every inactive snapshot is wrapped in a [!draftline-version] callout with its own %% draftline-version {...} %% marker (id, number, timestamp, parent). The active (currently editable) version is plain Markdown after its own marker, running to end of file. See File format below.src/version-format/ parses a file's text into a VersionedDocument, validates it, and implements the operations — creating a version, switching the active version — by producing new file text. None of this touches the Obsidian API, so it's covered by unit tests in tests/version-format/.src/services/versioned-note-service.ts reads/writes the active file (preferring the open editor buffer so unsaved edits aren't lost) and calls into version-format to transform it. src/commands/ and src/ui/view-actions.ts expose that service as commands and a header button. src/ui/version-popover.ts is the version list / "Show changes" panel.src/editor/ adds three CodeMirror 6 extensions (src/editor/extensions.ts): a state field that holds the parsed document and diff for the current file, a decoration set that hides inactive/archived text in Live Preview and Reading View (so only the active version is shown and edited), and a decoration set that overlays word-level diff highlighting when comparison is enabled. Diffs themselves are computed on demand by src/diff/diff-model.ts (built on the diff package) and are never written to disk.src/main.ts listens for file-open, active-leaf-change, and vault modify events, re-parses the active note (debounced), and dispatches the result into the CodeMirror state field so the editor view stays in sync.YAML frontmatter is not versioned. Schema 2 stores archived snapshots as inactive callouts, then the selected version as ordinary Markdown:
---
title: Example
---
%% draftline-document {"schema":2,"latestVersionId":"v2"} %%
> [!draftline-version]
> %% draftline-version {"id":"v1","number":1,"createdAt":"2026-07-18T20:00:00.000Z","parentId":null} %%
> # Earlier draft
> Earlier body...
%% draftline-version {"id":"v2","number":2,"createdAt":"2026-07-18T21:00:00.000Z","parentId":"v1"} %%
# Current draft
Current body...
| Command | Action |
|---|---|
| Create version | Archive current body as Version 1 / open Version 2, or duplicate the active version |
| Open version history | Open the version popover |
| Select next / previous version | Move through versions |
| Toggle comparison | Show or hide inline changes |
A history icon is also added to each Markdown note header, opening the same popover.
| Setting | Description |
|---|---|
| Enable Draftline | Master switch for Draftline commands, version history, and editor decorations. On by default when the plugin is enabled. Turning it off leaves notes unchanged. |
| Auto-compare on version select | When enabled, selecting a version that has a parent turns comparison on against that parent automatically. Off by default. Only applies while Draftline is enabled. |
Use a dedicated disposable vault only. Never enable development builds in a primary vault.
npm ci
npm run dev
Symlink or copy this folder into .obsidian/plugins/draftline/ (folder name must match manifest.json#id).
Production gate:
npm run build
npm run lint
npm run test
Source layout, module boundaries, and the format contract are documented in docs/development.md; the release checklist is in docs/releasing.md.
Draftline is local and offline. It does not network, self-update, or send vault content anywhere.