Files
blog/.agents/skills/obsidian-sync/SKILL.md
T
venus d8fb8a3699 feat: implement dynamic Eleventy tiling blog, modular CSS, and agent customizations
- Add project foundation README.md and root AGENTS.md for pair programming
- Configure .agents/ rules and skills for Eleventy tiling and Obsidian publishing
- Decompose monolithic styles into modular tokens, reset, layout, and component CSS
- Implement Nunjucks layout inheritance (base.njk, post.njk, page.njk) and reusable partials
- Configure Eleventy 3 with markdown-it-anchor, syntax highlighting, and dynamic collections
- Migrate sample prototypes into dynamic dispatches lander, gateway, and Markdown posts
- Add multi-stage Dockerfile and clean-URL nginx.conf for production serving
2026-09-13 00:49:27 -05:00

3.9 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.


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": "reverse-engineering-iot-firmware",
      "content": "---\ntitle: \"Reverse Engineering IoT Firmware\"\ndate: 2026-09-12\ntags: [\"#firmware\"]\n---\n\n## Content...",
      "assets": [
        {
          "filename": "diagram.png",
          "data": "<base64-encoded-image>"
        }
      ]
    }
    
  • Response:
    • 200 OK: {"status": "published", "path": "/posts/reverse-engineering-iot-firmware/"}
    • 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.
  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 River Rooks 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 River Rooks 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/.