Patch bump so Obsidian runs a fresh automated review on the lint-fixed code. The prior version's automated scan is cached as failed (it ran on the release tag's old pre-fix commit); a new version forces a clean re-scan. No code change beyond version metadata; main.js is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| docs | ||
| scripts | ||
| src | ||
| test | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| CHANGELOG.md | ||
| community-plugins.json | ||
| esbuild.config.mjs | ||
| eslint.config.mjs | ||
| LICENSE | ||
| manifest.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| styles.css | ||
| tsconfig.json | ||
| versions.json | ||
Prior Art
You already wrote this note. Prior Art tells you before you write it again.
As you title a new note and type the first few lines, a sidebar panel fills with the existing notes that look like it — the Stack Overflow "questions that may already have your answer" pattern, for your vault. When one of them is the note you were about to write, Prior Art merges the two without breaking a single inbound link.
Prior Art never edits a note on its own. Every merge is confirmed, and the one irreversible step — moving the emptied duplicate to trash — is confirmed twice.
What it does
While you type. The panel watches the note you are capturing (created in the last 30 minutes, still under 400 characters, or sitting in your inbox folder — all configurable) and lists up to five existing notes that look like it. Each card says the note's title, why it matched, and whether it is a probable duplicate or merely similar.
It queries 400 ms after you stop typing, never per keystroke, and a query that is overtaken by a newer one is cancelled and its answer thrown away — so the panel always answers the question you are asking now, not the one you were asking two words ago.
When you find the duplicate. Three actions, on the card:
| Action | What it does | Reversible? |
|---|---|---|
| Open side by side | Opens the existing note in a split next to the one you are writing. | Changes nothing. |
| Append into this note | Copies your new note's body into the existing one, under ## From <your note>. Your note is left alone. |
Delete the section. |
| Redirect | Adds your note's name to the existing note's aliases, replaces your note's body with Moved to [[Existing note]]., and then offers to trash it. Your note's frontmatter is kept exactly as it was. |
Undo the two edits. |
The redirect is the point. Deleting a duplicate breaks every [[link]] that pointed at it. Adding the duplicate's name as an alias of the survivor means every one of those links keeps resolving — to the note that actually has the content. Prior Art never adds an alias by overwriting the ones a note already has.
Your frontmatter is never touched. Redirect replaces the body and nothing else: your tags, dates, aliases and custom fields stay on the note. Nothing in Prior Art rewrites YAML it did not put there.
What you get
Free — and it is not a demo
- The similar-notes panel, matching on titles, aliases, and headings: exact titles, near-identical titles (a cheap character-trigram distance — it catches "Postgres Indexing Notes" vs "Notes on Postgres Indexes"), and significant shared words. Common words are ignored, so two notes do not match because they both say "the".
- The whole merge-assist path — side by side, append, and the alias redirect.
- Runs entirely off Obsidian's own metadata cache. No files are read, nothing is sent anywhere, and it works on mobile.
Pro — $29 one-time, unlocks all five Second Read add-ons
- Similar notes by meaning, as you type. The free tier finds the note you titled the same way. Pro finds the note you said the same thing in — different words, different title, same idea. It uses a local semantic engine (below); nothing leaves your computer.
One key unlocks Pro in Note Decay, Standing Questions, Effort Index, Prior Art, and Unwritten. Paste it into any one of them. It is verified offline with an Ed25519 signature compiled into the add-on — no account, no server, no network request, ever.
The semantic engine — please read this
Pro's "by meaning" matching needs an embedding model, and Obsidian add-ons cannot ship one. So Prior Art offers to download a local engine: a self-contained program that runs on your computer, embeds your notes, and answers similarity queries over a pipe.
Everything about it is opt-in and inspectable.
- Nothing is downloaded until you click "Download engine" in settings, and then only after a modal that names the exact URL, the version, the SHA-256, and the folder it installs to.
- The download is verified against a SHA-256 that is compiled into this add-on before a single byte of it is made executable. If the hash does not match, the file is deleted and nothing runs.
- The engine is never updated silently. A new version shows an "Update engine" button. You click it or you do not.
- It opens no network connections. It has no network stack: the TLS libraries are excluded from the build, which you can verify by listing the archive.
- It runs only while Obsidian does. It dies with the parent process, it exits on its own if it is idle for ten minutes, and it is killed when the last Second Read add-on unloads.
- It is shared. One engine process and one index serve every Second Read add-on you have installed — not one each.
- You can bring your own. Set "Path to an existing engine" in settings and nothing is ever downloaded; Prior Art spawns the binary you point it at. This is the fallback for any system that refuses to run a downloaded program.
Files it touches outside your vault
The engine and its index are stored outside the vault, in your operating system's application-data folder — deliberately, so a 100 MB index never syncs to your phone through Obsidian Sync, Dropbox, or iCloud:
| Platform | Location |
|---|---|
| Windows | %LOCALAPPDATA%\second-read-engine\ |
| macOS | ~/Library/Application Support/second-read-engine/ |
| Linux | ${XDG_DATA_HOME:-~/.local/share}/second-read-engine/ |
That folder holds the engine binary, the embedding index for each vault you use it with, and a log. "Remove engine" in settings deletes the binary; the index is kept until you delete it too.
The engine's source is public: github.com/israerusan/second-read-engine.
The free tier never downloads anything, never runs a program, and never touches a file outside your vault.
Commands
| Command | What it does |
|---|---|
| Open the similar-notes panel | Opens the panel in the right sidebar. |
| Find similar notes for this note | Checks the current note, even if it is old and long. |
| Merge this note into another… | Pick a target, then choose an action. |
| Rebuild the semantic index | Pro + engine. Re-reads every note into the index. |
Settings worth knowing
- Only check new notes — on by default. The panel is for notes you are writing; it should not follow you around a note you are reading. Turn it off to check everything you open.
- Typing pause — 400 ms by default. Shorter feels more live; longer asks less often.
- Title similarity and shared words — the two free-tier thresholds. Lower them to find more, and to find more noise.
Privacy
- No telemetry, no analytics, no phoning home. Not in the free tier, not in Pro.
- License verification is a signature check against a public key compiled into the add-on. It happens in microseconds, offline.
- The semantic engine, if you install it, runs locally and opens no sockets. Your notes are never sent anywhere.
Development
npm install
npm run lint # tsc --noEmit + the Obsidian review bot's own eslint ruleset, zero warnings
npm test # lint + vendored-shared drift check + every test
npm run build # production bundle -> main.js
VAULT=/path/to/vault npm run install:vault
src/shared/ is vendored from obsidian-plugin-core by npm run sync:shared and must never be edited here — npm test fails if it drifts. Everything under src/core/ is pure, dependency-free, and tested: the lexical matcher, the merge transforms, the debounce/supersede scheduler, and the ranking.
License
MIT. Copyright (c) 2026 Israel Avila.