Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

History Plugin (@lapis-notes/history)

Source target: packages/plugins/plugin-history/src/

Manifest target: id plugin-history, version 0.0.1, min app version 1.7.7.

The History plugin is a first-party core plugin for persisting text-file revision history so users can inspect previous versions of a file and restore a selected revision.

Ownership

The plugin owns the user-facing history workflow:

  • Capture debounced text-file snapshots from vault create, modify, rename, delete, and restore flows.
  • Provide a workspace history sidebar for the active file plus a main-area compare tab for selected revisions.
  • Render a revision list, a syntax-highlighted unified comparison editor, and restore actions.
  • Expose settings for revision retention, debounce timing, maximum tracked file size, and tracked extensions.

Generated revision storage belongs to AppDatabase; the plugin must not write history snapshots into user note folders or .obsidian/. The shared persistence contract is documented in File System, Metadata, and Search.

Revision Model

The first rollout stores bounded full-text snapshots rather than patch deltas. Each stored revision records:

  • stable file identity and current path
  • path at the time the revision was captured
  • event type: baseline, create, modify, rename, delete, or restore
  • creation time, source file mtime, source file size, and content hash
  • UTF-8 text content

The storage layer deduplicates consecutive revisions with the same content hash and prunes old revisions according to the configured per-file retention limit. The default policy is 100 revisions per file, a 2 MiB maximum tracked file size, and a 2 s per-path debounce window.

File Scope

The planned v1 scope is text files only. Markdown, canvas JSON, bases, notebook documents, and other UTF-8 text formats may be tracked when they are below the configured size limit. Binary files and files under .obsidian/ are skipped.

The plugin should treat read failures, oversized files, and invalid text content as skipped captures rather than plugin failures.

View, Commands, And Settings

Workspace surface:

  • View type: HistoryViewType = "history".
  • Compare view type: HistoryCompareViewType = "history-compare".
  • Command: plugin-history:open-file-history, opening the history view for the active file, preferably in the right sidebar.
  • Ribbon action: icon-only history action using the plugin command.
  • Settings tab: retention count, debounce window, maximum tracked file size, and tracked extension list.

The history sidebar shows the active file path and revision count above a compact VS Code-style timeline. Timeline rows are newest-first, use rail markers, relative timestamps, event labels such as File Saved or Restored, and active-row highlighting. Clicking a timeline row opens or reuses a normal main-area history-compare workspace tab and compares that revision against the current file by default.

The compare surface uses CodeMirror’s unified merge extension with history-specific per-chunk Take revision and Keep current controls on changed regions when comparing against the live file. Changed current-file lines are highlighted in green, and revision-only text appears in red deleted-chunk blocks above the editor. Unchanged regions are not collapsed, so the full compare document stays visible. Select an older revision to see differences against the current file; the newest revision usually matches the live file and shows no diff. Take revision applies the selected revision into the editable compare document; Keep current dismisses the chunk while keeping the current side. Those chunk actions update the in-memory compare buffer only until Save current file writes back through the vault API. The diff editor resolves the tracked file through determineViewTypeForPath() and injects the same source-mode editor extensions and workspace editor configuration that a normal file editor receives, so syntax, line numbers, wrap, indent settings, and source-mode plugin extensions stay consistent. The current-file editor becomes editable when comparing a revision against the live file and can be saved back through the normal vault API. Compare with previous is read-only and hides chunk action controls.

The compare tab keeps the diff body simple: it does not render a revision aside or component-local toolbar. Compare current, compare previous, save current file, restore, and close are exposed as icon-only workspace view-header actions when the tab title bar is enabled.

Restoring a revision writes through app.vault.modify(), records a restore revision, and avoids creating a duplicate follow-up modify revision for the same content hash.

The bundled workspace and web hosts register the plugin as a core plugin and include its CSS through the workspace app bundle.

Rename, Delete, And Restore Behavior

History follows file renames by moving the stable file identity to the new path and recording a rename revision. Deleting a file records delete state for the history identity without deleting prior revisions, so a user can still inspect or copy the latest known content from the history view.

Restore is intentionally file-first: it writes selected text back to the current vault file through the normal vault API, so metadata, search, and file watchers observe the same modify flow as ordinary edits.

Validation Expectations

Current validation covers:

  • App-database storage contracts across memory, IndexedDB, SQLite worker, and coordinated proxy paths.
  • Direct history-plugin runtime coverage for command and view registration, baseline capture, rename or delete behavior, and restore duplicate suppression.
  • Workspace Playwright UI-smoke coverage for opening history, selecting a revision, launching the compare tab, verifying the syntax-highlighted unified diff surface, visible green/red diff decorations, Take revision / Keep current chunk controls, saving current-file edits, and restoring a selected revision through the compare view.