soul.demarkus.io:6309/plans/obsidian-plugin.md/v2 draft reader meta

Obsidian Plugin Plan

Goal

Build an Obsidian community plugin that lets users fetch, edit, and publish markdown documents to demarkus servers directly from their vault.

Architecture

Bridge: Shell out to demarkus CLI via Node.js child_process.execFile. Obsidian runs in Electron with full Node.js access, so no HTTP proxy or new infra needed. Users must have demarkus installed (detected on plugin load).

Plugin type: Standard Obsidian community plugin (TypeScript, esbuild, manifest.json).

Location: plugins/obsidian/ in the demarkus monorepo. Published separately to the Obsidian community plugin registry.

MVP Scope

Commands

  1. Demarkus: Fetch Document — Prompt for mark:// URL, fetch via CLI, create/update note in vault
  2. Demarkus: Publish Note — Publish current note to a configured demarkus server
  3. Demarkus: List Documents — Show documents on a server, pick one to fetch

Settings

  • Server URL — default mark:// host (e.g., mark://soul.demarkus.io)
  • Token — capability token for publish operations (stored in Obsidian settings, never in vault files)
  • CLI Path — path to demarkus binary (auto-detected, override in settings)
  • Insecure — allow self-signed certs (for local dev servers)

Frontmatter Handling

Demarkus responses include YAML frontmatter (status, version, modified, etag, content-hash). On fetch:

  • Store mark-url, mark-version, and mark-etag in note frontmatter
  • Strip protocol metadata (status, content-hash) — not useful in vault

On publish:

  • Read mark-url from frontmatter to know where to publish
  • Use mark-version for optimistic concurrency (expected-version)
  • Update frontmatter with new version after successful publish

CLI Integration

// Fetch
execFile('demarkus', ['fetch', url], callback)

// Publish  
execFile('demarkus', ['publish', url, '--expected-version', version, '--token', token], {
  input: noteContent  // pipe body via stdin
}, callback)

// List
execFile('demarkus', ['list', url], callback)

Parse CLI output (YAML frontmatter + markdown body) to extract metadata and content.

File Structure

plugins/obsidian/
├── src/
│   ├── main.ts          — Plugin class, command registration
│   ├── settings.ts      — Settings tab
│   ├── cli.ts           — demarkus CLI wrapper (execFile + output parsing)
│   └── frontmatter.ts   — Frontmatter read/write helpers
├── manifest.json
├── package.json
├── tsconfig.json
├── esbuild.config.mjs
└── README.md

Implementation Steps

  1. Scaffold from obsidian-sample-plugin template
  2. Implement CLI wrapper (cli.ts) — execFile, parse YAML frontmatter + body from stdout
  3. Implement settings tab — server URL, token, CLI path, insecure flag
  4. Implement "Fetch Document" command — prompt for URL, fetch, create/update vault note
  5. Implement "Publish Note" command — read frontmatter, publish via CLI, update frontmatter
  6. Implement "List Documents" command — list, show in modal, fetch selected
  7. Test with local demarkus server
  8. Test with remote server (soul.demarkus.io)

Future (Post-MVP)

  • Sidebar panel with server browser
  • Auto-sync on save (opt-in)
  • Version history viewer (VERSIONS verb)
  • Diff between local and remote
  • Multiple server profiles
  • Link resolution (mark:// links clickable in Obsidian)

Open Questions

  • Should the plugin live in this monorepo or a separate repo? (Monorepo for now, extract later if needed for Obsidian plugin registry submission)
  • Obsidian community plugin review requires a separate GitHub repo — will need to extract before submission
trail
  1. soul.demarkus.io:6309 v2