Skip to content

Add plugin: Sync Vault with GEML - #893

Open
xiongjy2104 wants to merge 2 commits into
logseq:masterfrom
xiongjy2104:add-sync-vault-with-geml
Open

Add plugin: Sync Vault with GEML#893
xiongjy2104 wants to merge 2 commits into
logseq:masterfrom
xiongjy2104:add-sync-vault-with-geml

Conversation

@xiongjy2104

@xiongjy2104 xiongjy2104 commented Aug 26, 2026

Copy link
Copy Markdown

New plugin: Sync Vault with GEML

Sync Vault with GEML keeps a Logseq DB graph continuously synced to a local folder of readable plain-text files — GEML: as readable as the Markdown export, as lossless as the EDN one — so a DB graph can be diffed, versioned and backed up as text, and imported back again.

Why the in-app half is deliberately small. A 2.0 plugin runs in a sandboxed iframe: no arbitrary-path filesystem, no git, no shell. So this plugin does only the two things only it can do — hear the graph change (debounced DB.onChanged) and write a marker file through the plugin storage API, then show the last sync result in the toolbar. Everything with side effects lives in a companion command-line watcher (npx @geml/logseq-sync), which exports through the CLI that ships inside the Logseq desktop app, writes only the files that changed, and commits scoped strictly to the vault. The two halves meet in the plugin's own storage directory — a file as the bridge, so there is no port, no server and no CORS.

Users who install the plugin alone get the status light and the settings; the README says plainly that the watcher is the other half and how to start it.

Community discussion: https://discuss.logseq.com/t/35193

@xiongjy2104

xiongjy2104 commented Aug 26, 2026

Copy link
Copy Markdown
Author

Ready for review — the submission checklist, with links:

  • Release with the plugin zip attached: v2.2.0logseq-plugin-sync-vault-with-geml-v2.0.4.zip (57 KB). The zip's root holds package.json (the plugin manifest), the built dist/, and icon.png.
  • publish.yml: added — pushing a v* tag builds the plugin, assembles the zip, checks it carries the manifest, dist/index.js and the icon, and uploads it.
  • Images of it in action: the README now shows the toolbar reporting a sync, and the settings panel. (Both were taken on the 2.0.0 build, so they show the previous label for the vault setting; they will be refreshed.)
  • DB graphs only: supportsDB: true, supportsDBOnly: true, effect: false.

One thing worth flagging rather than leaving to be discovered: the plugin alone does not write files. A 2.0 plugin runs in a sandboxed iframe with no arbitrary-path filesystem, no git and no shell, so this one does only what it can — hears DB.onChanged (debounced), writes a marker through the plugin storage API, and shows the last result in the toolbar. The writing and the git commits happen in a companion CLI (npx @geml/logseq-sync), which exports through the CLI that ships inside the Logseq desktop app. The two halves meet in the plugin's own storage directory, so there is no port, no local server and no CORS. The marketplace description and the README both say this up front, so nobody installs it expecting the other half to be there.

Happy to change anything that does not fit the marketplace's conventions.

@xiongjy2104

xiongjy2104 commented Aug 28, 2026

Copy link
Copy Markdown
Author

Update — now at v2.2.0 (the links further up point at v2.2.0; the release process is unchanged — a v* tag builds the zip and attaches it. This one carries the -1 suffix because an earlier tag at that version pointed at a bad mirror commit, and releases here are never deleted or re-pointed.)

Three things changed that are worth stating for review:

  • Sync is two-way now, opt-in with --two-way on the companion watcher: vault edits import back into the graph on every cycle. Three rules keep it conservative — a file changed on both sides since the last sync is a conflict, held exactly as the user left it and named in the toolbar status until they merge it; deletions are never imported; and a graph backup is taken before the first import and every tenth after.
  • Block references are checked. Logseq stores a block ref as [[<uuid>]], which nothing validates; the vault now carries GEML's checked form, so a reference that goes nowhere is reported instead of shrugged at. Page links ([[Some Page]]) are untouched and the translation reverses exactly.
  • The screenshots are refreshed — the earlier note said they were from the 2.0.0 build; they now show the current labels.

The plugin half is unchanged throughout: still the debounced DB.onChanged signal and the status light, with everything that writes files or touches git in the external CLI. Nothing about the manifest, the zip shape or the DB-only flags has changed.

@xiongjy2104

Copy link
Copy Markdown
Author

The marketplace PR (#893) is still in review, so until it
lands:

  1. Logseq → Settings → Advanced → Developer mode
  2. Download logseq-plugin-sync-vault-with-geml-v2.0.8.zip from
    https://github.com/geml-spec/logseq-plugin-sync-vault-with-geml/releases/latest
    and unzip it
  3. Plugins → "..." → Load unpacked plugin → pick the unzipped folder
    (the one with package.json in it)
  4. Pin to show sync icon in tool bar
  5. Settings → Plugins → Sync Vault with GEML → set the Vault folder.
    Do this BEFORE step 6: the watcher has no default and refuses to guess one.
    (Or skip it and pass the folder instead: logseq-sync ~/logseq-vault)
  6. npm i -g @geml/logseq-sync then run: logseq-sync

Stuck? logseq-sync doctor prints what it can see — graph, CLI, vault folder,
git — and names the missing piece.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant