Initial commit: moreminimore-service content pipeline
- 9 mm* skills (orchestrator, article, social, publish, analytics) - 6 dependency skills (content-writer, geo-optimizer, etc.) - 3 analytics scripts (GSC, Google Ads, Meta Ads) - Config template + setup guide - SOUL-MM.md persona extension - OrbitOS integration reference
This commit is contained in:
367
skills/mm-content-orchestrator/SKILL.md
Normal file
367
skills/mm-content-orchestrator/SKILL.md
Normal file
@@ -0,0 +1,367 @@
|
||||
---
|
||||
name: mm-content-orchestrator
|
||||
argument-hint: "<command> [options]"
|
||||
description: >
|
||||
Top-level orchestrator for moreminimore content pipeline.
|
||||
Chains Data Stage (research/idea) → Content Stage (article) → Publish Article → Social Stage (posts) → Publish Social.
|
||||
Manages the full lifecycle of content creation and publishing.
|
||||
Use when: "moreminimore", "mm orchestrate", "content pipeline", "เริ่มงาน content",
|
||||
"สร้างบทความ", "เขียนและเผยแพร่", "mm".
|
||||
---
|
||||
|
||||
# mm-content-orchestrator
|
||||
|
||||
Top-level orchestrator that chains all moreminimore skills into a complete
|
||||
content pipeline: Data Stage → Content Stage → Publish Article → Social Stage → Publish Social.
|
||||
|
||||
## When This Must Trigger
|
||||
|
||||
- "moreminimore", "mm", "mm orchestrate"
|
||||
- "content pipeline", "เริ่มงาน content"
|
||||
- "สร้างบทความและเผยแพร่", "เขียนและเผยแพร่"
|
||||
- "run content workflow", "full content pipeline"
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────┐
|
||||
│ mm-content-orchestrator │
|
||||
│ │
|
||||
│ 1. Determine entry point (research or idea) │
|
||||
│ 2. Run Data Stage → produces brief.md │
|
||||
│ 3. Run Content Stage → produces article + images │
|
||||
│ 4. Run Publish Article → get published_url │
|
||||
│ 5. Run Social Stage → produces posts (with URL) │
|
||||
│ 6. Run Publish Social → publish posts + archive │
|
||||
└──────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────┐
|
||||
│ Data Stage │
|
||||
│ │
|
||||
│ Entry A: │
|
||||
│ mm-article-from │
|
||||
│ -research │
|
||||
│ (Research→Brief)│
|
||||
│ │
|
||||
│ Entry B: │
|
||||
│ mm-article-idea │
|
||||
│ -extract │
|
||||
│ (Idea→Brief) │
|
||||
└────────┬────────┘
|
||||
│ brief.md
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Content Stage │
|
||||
│ │
|
||||
│ mm-content- │
|
||||
│ writer │
|
||||
│ │
|
||||
│ 1. Write article│
|
||||
│ 2. GEO optimize │
|
||||
│ 3. Generate imgs│
|
||||
│ 4. Approve │
|
||||
└────────┬────────┘
|
||||
│ article (draft)
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Publish Stage │
|
||||
│ (Article) │
|
||||
│ │
|
||||
│ mm-publish- │
|
||||
│ content │
|
||||
│ │
|
||||
│ • Publish article│
|
||||
│ • Get published │
|
||||
│ URL │
|
||||
│ • Save to │
|
||||
│ frontmatter │
|
||||
└────────┬────────┘
|
||||
│ published_url
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Social Stage │
|
||||
│ │
|
||||
│ mm-social- │
|
||||
│ writer │
|
||||
│ │
|
||||
│ 1. Read article │
|
||||
│ + URL │
|
||||
│ 2. Create posts │
|
||||
│ (FB, X, IG) │
|
||||
│ 3. Approve │
|
||||
└────────┬────────┘
|
||||
│ posts (draft)
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Publish Stage │
|
||||
│ (Social) │
|
||||
│ │
|
||||
│ mm-publish- │
|
||||
│ content │
|
||||
│ │
|
||||
│ • Publish posts │
|
||||
│ • Archive check │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## Quick Commands
|
||||
|
||||
### Full pipeline (from research)
|
||||
```
|
||||
mm from research
|
||||
```
|
||||
→ Scans 30_Research/ → user picks one → creates brief → writes article → publishes → creates posts → publishes posts
|
||||
|
||||
### Full pipeline (from idea)
|
||||
```
|
||||
mm idea: [topic]
|
||||
```
|
||||
→ Researches topic → creates brief → writes article → publishes → creates posts → publishes posts
|
||||
|
||||
### Content only (no publish)
|
||||
```
|
||||
mm write [slug]
|
||||
```
|
||||
→ Finds brief → writes article + images (no publish)
|
||||
|
||||
### Publish article only
|
||||
```
|
||||
mm publish article [slug]
|
||||
```
|
||||
→ Finds approved article → publishes to website → gets URL
|
||||
|
||||
### Create social posts only
|
||||
```
|
||||
mm social [slug]
|
||||
```
|
||||
→ Finds published article with URL → creates social posts
|
||||
|
||||
### Publish social only
|
||||
```
|
||||
mm publish social [slug]
|
||||
```
|
||||
→ Finds approved social posts → publishes to platforms
|
||||
|
||||
### Status check
|
||||
```
|
||||
mm status
|
||||
```
|
||||
→ Shows all articles in pipeline with their current status
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 1: Determine command
|
||||
|
||||
Parse the user's message to determine which command:
|
||||
|
||||
| Pattern | Command |
|
||||
|---------|---------|
|
||||
| "from research", "จาก research" | full-pipeline-research |
|
||||
| "idea: [topic]", "ไอเดีย: [topic]" | full-pipeline-idea |
|
||||
| "write [slug]", "เขียน [slug]" | content-only |
|
||||
| "publish article [slug]" | publish-article |
|
||||
| "social [slug]", "เขียนโพส [slug]" | social-only |
|
||||
| "publish social [slug]" | publish-social |
|
||||
| "status", "สถานะ" | status-check |
|
||||
|
||||
If ambiguous, ask:
|
||||
|
||||
```
|
||||
ต้องการดำเนินการอะไร?
|
||||
|
||||
1. 📚 เริ่มจาก Research — เลือก research จาก vault → เขียน → publish → โพส
|
||||
2. 💡 เริ่มจากไอเดีย — ระบุหัวข้อ → research → เขียน → publish → โพส
|
||||
3. ✍️ เขียนเท่านั้น — มี brief แล้ว → เขียนบทความ + รูป
|
||||
4. 📤 Publish บทความ — บทความพร้อม → publish → ได้ URL
|
||||
5. 📱 เขียนโพส — บทความ publish แล้ว → สร้าง social posts
|
||||
6. 📤 Publish โพส — โพสพร้อม → publish ไป social
|
||||
7. 📊 ดูสถานะ — ดู pipeline ทั้งหมด
|
||||
```
|
||||
|
||||
### Step 2: Execute Data Stage (if full pipeline)
|
||||
|
||||
#### 2a. From Research (mm-article-from-research)
|
||||
|
||||
Load and follow the `mm-article-from-research` skill:
|
||||
1. Scan 30_Research/<client-id>/ + 30_Research/general/ for unused resources
|
||||
2. User selects one
|
||||
3. Summarize and ask for focus
|
||||
4. Create brief.md in 60_Articles/<client-id>/
|
||||
|
||||
#### 2b. From Idea (mm-article-idea-extract)
|
||||
|
||||
Load and follow the `mm-article-idea-extract` skill:
|
||||
1. Receive idea from user
|
||||
2. Research in vault + internet
|
||||
3. Iterate on angles
|
||||
4. Create brief.md in 60_Articles/<client-id>/
|
||||
|
||||
### Step 3: Execute Content Stage (mm-content-writer)
|
||||
|
||||
Load and follow the `mm-content-writer` skill:
|
||||
1. Read brief.md
|
||||
2. Write article with SEO + GEO
|
||||
3. Generate images (Nano Banana)
|
||||
4. Present for approval
|
||||
|
||||
**This stage produces the article only — no social posts.**
|
||||
|
||||
### Step 4: Execute Publish Article (mm-publish-content)
|
||||
|
||||
Load and follow the `mm-publish-content` skill:
|
||||
1. Find approved articles
|
||||
2. Look up client config for credentials
|
||||
3. Publish article to website (Astro/WordPress)
|
||||
4. **Capture published_url** — save to frontmatter
|
||||
|
||||
### Step 5: Execute Social Stage (mm-social-writer)
|
||||
|
||||
Load and follow the `mm-social-writer` skill:
|
||||
1. Read published article with published_url
|
||||
2. Create social posts (Facebook, X, IG) with article URL embedded
|
||||
3. Generate social images
|
||||
4. Present for approval
|
||||
|
||||
### Step 6: Execute Publish Social (mm-publish-content)
|
||||
|
||||
Load and follow the `mm-publish-content` skill again:
|
||||
1. Find approved social posts
|
||||
2. Publish to each platform
|
||||
3. Run archive check
|
||||
|
||||
### Step 7: Summary
|
||||
|
||||
```
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
Pipeline Complete
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
📚 Data Stage:
|
||||
Source: [research title / idea]
|
||||
Brief: 60_Articles/<client-id>/slug/brief.md
|
||||
|
||||
✍️ Content Stage:
|
||||
Article: [title] — [word count] words
|
||||
Images: [N] generated
|
||||
|
||||
📤 Publish — Article:
|
||||
Website: [Astro/WordPress] ✅
|
||||
URL: [published_url]
|
||||
|
||||
📱 Social Stage:
|
||||
Posts: Facebook ✅ | X ✅ | IG ✅
|
||||
|
||||
📤 Publish — Social:
|
||||
Facebook: ✅
|
||||
X/Twitter: ✅
|
||||
Instagram: ✅
|
||||
|
||||
📂 All files: ~/vault/60_Articles/<client-id>/<slug>/
|
||||
```
|
||||
|
||||
## Status Check (mm status)
|
||||
|
||||
When user asks for status, scan 60_Articles/ per-client:
|
||||
|
||||
```python
|
||||
import os, re
|
||||
|
||||
vault = os.path.expanduser("~/vault/60_Articles")
|
||||
articles = []
|
||||
|
||||
for client_dir in os.listdir(vault):
|
||||
client_path = os.path.join(vault, client_dir)
|
||||
if not os.path.isdir(client_path) or client_dir == 'Archive':
|
||||
continue
|
||||
|
||||
for entry in sorted(os.listdir(client_path), reverse=True):
|
||||
if entry == 'Archive':
|
||||
continue
|
||||
article_path = os.path.join(client_path, entry, 'article.md')
|
||||
if not os.path.exists(article_path):
|
||||
continue
|
||||
content = open(article_path).read()[:500]
|
||||
|
||||
status_match = re.search(r'^status:\s*(.+)$', content, re.MULTILINE)
|
||||
title_match = re.search(r'^title:\s*["\']?(.+?)["\']?\s*$', content, re.MULTILINE)
|
||||
published_match = re.search(r'^published_to:\s*\[(.+?)\]', content, re.MULTILINE)
|
||||
url_match = re.search(r'^published_url:\s*["\']?(.+?)["\']?\s*$', content, re.MULTILINE)
|
||||
|
||||
status = status_match.group(1).strip() if status_match else 'unknown'
|
||||
title = title_match.group(1) if title_match else entry
|
||||
published = published_match.group(1) if published_match else ''
|
||||
url = url_match.group(1) if url_match else ''
|
||||
|
||||
# Check for social posts
|
||||
has_posts = any(os.path.exists(os.path.join(client_path, entry, f'post-{p}.md'))
|
||||
for p in ['facebook', 'x', 'ig'])
|
||||
|
||||
articles.append({
|
||||
'client': client_dir,
|
||||
'slug': entry,
|
||||
'title': title,
|
||||
'status': status,
|
||||
'published_to': published,
|
||||
'url': url,
|
||||
'has_posts': has_posts
|
||||
})
|
||||
```
|
||||
|
||||
Present as a table:
|
||||
|
||||
```
|
||||
📊 Content Pipeline Status
|
||||
|
||||
| Client | Title | Status | URL | Posts |
|
||||
|--------|-------|--------|-----|-------|
|
||||
| moreminimore | AI Marketing Guide | published | ✅ | ✅ |
|
||||
| moreminimore | SEO Tips 2026 | approved | — | — |
|
||||
| client-b | CMS Comparison | draft | — | — |
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
Client credentials are stored in `~/vault/99_System/clients-config.json`.
|
||||
|
||||
See `mm-publish-content` skill for the full config schema.
|
||||
|
||||
If config is missing or empty:
|
||||
|
||||
```
|
||||
⚠️ ยังไม่ได้ตั้งค่า clients-config.json
|
||||
|
||||
ต้องการตั้งค่าตอนนี้ไหม?
|
||||
1. ตั้งค่าเลย — เพิ่ม client แรก
|
||||
2. ข้าม — publish ทีหลัง
|
||||
3. ดูตัวอย่าง — ดู format ของ config
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
If any stage fails:
|
||||
1. Report the error clearly
|
||||
2. Save progress (brief.md and partial outputs are preserved)
|
||||
3. Offer to resume from the failed step
|
||||
|
||||
```
|
||||
❌ [Stage] failed: [error]
|
||||
|
||||
Progress saved:
|
||||
✅ [completed steps]
|
||||
❌ [failed step]
|
||||
|
||||
ต้องการ:
|
||||
1. ลองใหม่จาก [failed step]
|
||||
2. ข้ามไป step ถัดไป
|
||||
3. หยุดและแก้ไขปัญหา
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **User approval is required** before publishing article and before publishing social posts
|
||||
- **Config is required** before publishing (Publish Stage)
|
||||
- Each stage produces files in `~/vault/60_Articles/<client-id>/<slug>/`
|
||||
- Research sources are in `~/vault/30_Research/<client-id>/` or `30_Research/general/`
|
||||
- Published content moves to `~/vault/60_Articles/<client-id>/Archive/` when ALL parts are published
|
||||
- The pipeline is resumable — each stage checks for existing outputs
|
||||
- Frontmatter is the source of truth for status tracking
|
||||
Reference in New Issue
Block a user