4.6 KiB
name, description
| name | description |
|---|---|
| obsidian-sync | Use this skill when designing, building, or troubleshooting the Obsidian vault publishing integration, the server upload API, note normalization (wikilinks, callouts, frontmatter), or the custom Obsidian plugin. |
Obsidian Vault Publishing & Sync Skill
This skill guides the agent in implementing the custom Obsidian plugin and server-side ingestion workflow for publishing blog posts directly from an Obsidian vault.
Important
User Content Sovereignty: User-authored content, post titles, tags, and formatting are the highest level of truth. The sync and normalization pipelines must preserve user-authored text verbatim and never overwrite or mutate user writing without explicit instruction.
1. System Architecture
+-------------------+ +-----------------------+
| Obsidian Vault | | Blog Server |
| | | |
| [Active Markdown] | POST /api/posts | /api/posts Endpoint |
| + | -------------------> | + |
| Custom Plugin | (Payload: JSON/MD) | Frontmatter Validator |
+-------------------+ | + |
| Wikilink Normalizer |
| + |
+-------------------+ | Write to `src/posts/` |
| Self-Hosted | CouchDB Sync | + |
| LiveSync Server | ===================> | 11ty Build Trigger |
+-------------------+ +-----------------------+
2. Ingestion API Specification
Endpoint: POST /api/posts
- Headers:
Content-Type: application/jsonAuthorization: Bearer <API_SECRET>
- Request Body:
{ "slug": "sample-post", "content": "---\ntitle: \"Sample Post Title\"\ndate: 2026-09-12\ntags: [\"#tag1\"]\n---\n\n## Content...", "assets": [ { "filename": "diagram.png", "data": "<base64-encoded-image>" } ] } - Response:
200 OK:{"status": "published", "path": "/posts/sample-post/"}400 Bad Request:{"error": "Missing required frontmatter: title, date"}
3. Obsidian Markdown Normalization Rules
-
Frontmatter Invariants:
- Must contain
title,date,tags(array), and optionalexcerpt,readingTime,draft,hidden.
- Must contain
-
Wikilinks Translation:
[[article-slug]]\rightarrow[article-slug](/posts/article-slug/)[[article-slug|Custom Label]]\rightarrow[Custom Label](/posts/article-slug/)
-
Callout Translation:
- Obsidian callouts:
Must be rendered with corresponding terminal alert styling.
> [!NOTE] > Informational notice
- Obsidian callouts:
-
Internal Attachments:
![[screenshot.png]]\rightarrowtranslated toand written tosrc/assets/images/posts/.
4. Custom Obsidian Plugin Development
The Obsidian plugin runs inside Obsidian desktop/mobile and interacts with the Obsidian API:
- Registers a ribbon icon (e.g.
sendorterminal) and a command:Publish Current Note to Blog. - Reads the active file:
const activeFile = this.app.workspace.getActiveFile(); const content = await this.app.vault.read(activeFile); - Parses frontmatter using Obsidian's metadata cache:
const cache = this.app.metadataCache.getFileCache(activeFile); - Sends the HTTP payload to the configured blog server URL with the Bearer token.
- Displays an Obsidian
Notice('Published successfully to Blog!').
5. Self-Hosted LiveSync Compatibility
If using CouchDB-based self-hosted LiveSync:
- A local watcher or CouchDB change listener daemon can be configured to detect updates to notes marked with
published: trueor in a dedicatedBlog/folder. - When an update event fires, the daemon pulls the latest revision from the CouchDB database, runs the normalization pipeline, and saves it to
src/posts/.
6. Validation & Verification
Always write automated test cases in test/ingestion-api.test.js before modifying or adding any functional synchronization or endpoint code:
- Mandatory Adversarial Testing: Include adversarial tests covering unauthorized tokens, invalid/missing frontmatter schemas, path traversals in slugs, and malformed base64 asset payloads.
- Pre-Presentation Verification: Run
npm testand ensure all test cases pass before presenting the final output.