Files
blog/.agents/skills/obsidian-sync/SKILL.md
T

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/json
    • Authorization: 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

  1. Frontmatter Invariants:

    • Must contain title, date, tags (array), and optional excerpt, readingTime, draft, hidden.
  2. Wikilinks Translation:

    • [[article-slug]] \rightarrow [article-slug](/posts/article-slug/)
    • [[article-slug|Custom Label]] \rightarrow [Custom Label](/posts/article-slug/)
  3. Callout Translation:

    • Obsidian callouts:
      > [!NOTE]
      > Informational notice
      
      Must be rendered with corresponding terminal alert styling.
  4. Internal Attachments:

    • ![[screenshot.png]] \rightarrow translated to ![screenshot](/assets/images/posts/screenshot.png) and written to src/assets/images/posts/.

4. Custom Obsidian Plugin Development

The Obsidian plugin runs inside Obsidian desktop/mobile and interacts with the Obsidian API:

  1. Registers a ribbon icon (e.g. send or terminal) and a command: Publish Current Note to Blog.
  2. Reads the active file:
    const activeFile = this.app.workspace.getActiveFile();
    const content = await this.app.vault.read(activeFile);
    
  3. Parses frontmatter using Obsidian's metadata cache:
    const cache = this.app.metadataCache.getFileCache(activeFile);
    
  4. Sends the HTTP payload to the configured blog server URL with the Bearer token.
  5. 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: true or in a dedicated Blog/ 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 test and ensure all test cases pass before presenting the final output.