Sync notes and exports between your Obsidian vault and Unabyss.
Two-way OAuth sync between your Obsidian vault and your Unabyss memory.
GET /api/exports/changed-since/
is mirrored as <slugified-title>.md in your chosen folder.Deleted/
subfolder.Clone this repository.
From the repository root run:
pnpm install
pnpm build
Copy main.js, manifest.json, and styles.css into
<vault>/.obsidian/plugins/unabyss/
(create the folder if it doesn't exist). manifest.json and
styles.css live in the repository root; pnpm build produces
main.js.
Enable the plugin in Settings -> Community plugins.
A Unabyss icon appears in the left ribbon - click it to open the plugin settings.
Open Settings -> Community plugins -> Unabyss.
| Setting | Default | Notes |
|---|---|---|
| API base URL | https://api.unabyss.com |
Set to your self-hosted backend if applicable. The plugin opens https://app.<host> in your browser for the consent page; point at the API host you have if your deploy doesn't follow the api. / app. convention. |
| Account | (empty until you connect) | Click Connect to start the OAuth PKCE flow. |
| Sync outbound | on | Master switch for the Obsidian -> Unabyss direction. When off, neither file-change events, the daily safety-net timer, nor the manual button sends notes to Unabyss. |
| Include folders | (empty = whole vault) | Vault folders included by outbound sync. Click Add folder to pick from a list of every folder in the vault. Empty = sync everything. |
| Sync inbound | on | Master switch for the Unabyss -> Obsidian direction. When off, the daily safety-net timer skips inbound and the manual button refuses to run it. |
| Export target folder | (empty) | Vault folder where Unabyss exports are written. Inbound sync requires this to be set. Auto-completes vault folders as you type. |
| When an export is deleted in Unabyss | Leave the local file alone | Choose between Leave, Delete (system trash), and Move to a Deleted/ subfolder inside your target folder. |
| Force full resync | - | Wipes the local manifest cache + inbound watermark and immediately runs an outbound sync so the server's hash-diff guard re-establishes the truth. |
Open the Unabyss settings any time from the ribbon icon in the left toolbar, or via Settings -> Community plugins -> Unabyss.
<your email>".Unabyss: Sync outbound now).<slug>.md (e.g.
daily-summary-2026-01-15.md). On slug collision with a different
export, the plugin appends -<first-6-of-uuid> to the filename so
no unrelated note is overwritten.<!-- unabyss-export-id: <uuid> -->. Do not delete this line if
you want the plugin to recognise the file as the same export on the
next sync.Unabyss: Sync inbound now.Click Disconnect in the settings tab. The plugin calls
POST /api/oauth/revoke/ to blacklist its refresh tokens server-side
and clears the local data.json token entries. You can also revoke
from the Unabyss web app's connected-accounts page if your machine is
inaccessible.
This plugin stores OAuth tokens in
<vault>/.obsidian/plugins/unabyss/data.json, which is plaintext
JSON on disk.
.obsidian/ directory.OS-keychain integration is on the roadmap. If plaintext token storage is unacceptable for your threat model, do not install this plugin yet.
hash_mismatch - this is the server
rejecting a row whose content changed between the manifest scan
and the body upload. Re-running Sync resolves it.pnpm install
pnpm run dev # esbuild watch mode
pnpm run typecheck # tsc -noEmit
pnpm test # jest unit suite
pnpm run build # production bundle
Symlink the repository into your vault's plugins folder so pnpm run dev
rebuilds the plugin in place:
ln -s "$(pwd)" "<vault>/.obsidian/plugins/unabyss"
manifest.json and styles.css already sit in the repo root and
pnpm run dev keeps main.js current, so the symlinked folder always
has the three files Obsidian loads (the extra source / node_modules
files are ignored). Enable Unabyss in Settings -> Community plugins,
then reload Obsidian (or toggle the plugin off/on) after each build to
pick up changes.
The unit suite covers:
tests/oauth.test.ts).tests/manifestCache.test.ts).tests/slugify.test.ts).tests/syncInbound.test.ts).Anything that touches the Obsidian runtime (Vault, App, Plugin,
requestUrl) is dependency-injected at the call site, so the tests
do not require Electron.
MIT.