- 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
100 lines
3.9 KiB
Markdown
100 lines
3.9 KiB
Markdown
---
|
|
name: obsidian-sync
|
|
description: >-
|
|
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
|
|
|
|
```text
|
|
+-------------------+ +-----------------------+
|
|
| 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:**
|
|
```json
|
|
{
|
|
"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:
|
|
```markdown
|
|
> [!NOTE]
|
|
> Informational notice
|
|
```
|
|
Must be rendered with corresponding terminal alert styling.
|
|
4. **Internal Attachments:**
|
|
- `![[screenshot.png]]` $\rightarrow$ translated to `` 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:
|
|
```typescript
|
|
const activeFile = this.app.workspace.getActiveFile();
|
|
const content = await this.app.vault.read(activeFile);
|
|
```
|
|
3. Parses frontmatter using Obsidian's metadata cache:
|
|
```typescript
|
|
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/`.
|