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:
Kunthawat Greethong
2026-07-02 10:01:53 +07:00
commit 7b5af16f6d
36 changed files with 7803 additions and 0 deletions

View File

@@ -0,0 +1,310 @@
---
name: mm-article-from-research
description: >
Data Stage A: Convert a vault research note into an article brief.
Scans 30_Research/ for resources not yet used for articles, lets user pick one,
reads the content, summarizes key points, asks user which angles to focus on,
then creates a brief.md for the content-writer-mm skill.
Use when: "เขียนบทความจาก research", "article from research", "ใช้ research เขียนบทความ".
---
# Article From Research
Converts existing vault research notes into structured article briefs.
## When This Must Trigger
- "เขียนบทความจาก research", "article from research"
- "ใช้ research เขียนบทความ", "make article from research"
- "เลือก research มาเขียน"
- "ทั้งหมด", "ทุก research", "batch" (batch mode — see Step 1b)
## Process
### Step 1: Determine mode — Single or Batch
Ask the user if they want to work on ONE research or ALL at once:
```python
# Detect batch intent
batch_keywords = ['ทั้งหมด', 'ทุก', 'all', 'batch', 'ทุกไฟล์', '14', '13', '12',
'ทุก research', '14 บทความ', 'ทั้งหมดเลย']
user_msg = user_message.lower()
is_batch = any(kw in user_msg for kw in batch_keywords)
```
- **Single mode** (default): user picks one research → interactive focus questions
- **Batch mode**: process ALL unused research at once → skip interactivity
Trigger batch immediately if user says "ทั้งหมด" or "ทุก research" or "ทุกไฟล์"
### Step 0: Determine client
Ask which client this article is for:
```
บทความนี้สำหรับลูกค้าไหน?
1. [client-1] — [display_name]
2. [client-2] — [display_name]
```
If no clients configured, suggest running `mm-article-idea-extract` to add one first.
### Step 1: Scan 30_Research/<client-id>/ for available resources
```bash
VAULT_PATH="$HOME/vault"
```
Search for research notes in both client-specific and general folders that have
NOT been marked as used for articles:
```python
# Search 30_Research/<client-id>/ AND 30_Research/general/
# Exclude Archive/ subfolders and notes with article_created: true
import os, re
vault = os.path.expanduser("~/vault/30_Research")
results = []
search_dirs = [
os.path.join(vault, client_id), # client-specific
os.path.join(vault, "general"), # general research
]
for search_dir in search_dirs:
if not os.path.exists(search_dir):
continue
for root, dirs, files in os.walk(search_dir):
# Skip Archive folders
if 'Archive' in root.split(os.sep):
continue
for f in files:
if not f.endswith('.md'):
continue
path = os.path.join(root, f)
try:
content = open(path).read()
if 'article_created: true' in content[:500]:
continue
title_match = re.search(r'^#\s+(.+)$', content, re.MULTILINE)
title = title_match.group(1) if title_match else f.replace('.md', '')
type_match = re.search(r'^type:\s*(.+)$', content, re.MULTILINE)
note_type = type_match.group(1).strip() if type_match else 'unknown'
results.append({
'path': path,
'title': title,
'type': note_type,
'relative': os.path.relpath(path, os.path.expanduser("~/vault"))
})
except:
continue
```
Present results to user as a numbered list:
```
พบ research notes ที่ยังไม่ได้ใช้เขียนบทความ:
1. [Title] — type: reference — 30_Research/Area/Topic/Topic.md
2. [Title] — type: reference — 30_Research/Area/Topic2/Topic2.md
...
เลือกหมายเลขที่ต้องการเขียนบทความ (หรือพิมพ์ชื่อหัวข้อเพื่อค้นหา):
```
If no research notes found, suggest running `article-idea-extract` instead.
### Step 1b: Batch mode — Process ALL research at once
Skip interactive selection. Read ALL research notes from 30_Research/ that don't have `article_created: true`.
Classify into two buckets:
| Status | Action |
|--------|--------|
| `reference`, `candidate`, `draft` | Ready — create brief from existing content |
| `seed` | **Research first** — search the web for current info, stats, examples, and sources. Compile into a supplementary data block for the brief |
For seed-status notes, search internet for:
- Latest articles/tutorials on the topic
- Official documentation or product pages
- Statistics, benchmarks, or case studies
- Competitor or comparison info
### Step 1c: Apply date convention (ALL modes)
**Article date = source research date.** Extract `date:` from research frontmatter:
```python
date_m = re.search(r'^date:\s*(.+)$', content, re.MULTILINE)
article_date = date_m.group(1).strip() if date_m else today
```
Use this date for:
- Article folder name: `~/vault/60_Articles/<article_date>-<slug>/`
- Article frontmatter `date:` field
- DO NOT use today's date unless the research has no date field at all
### Step 2: Read the selected research note (Single mode)
Read the full content of the selected research note using `read_file`.
Extract:
- **Title** — from H1
- **Key concepts** — from H2/H3 headings
- **Main points** — from body content
- **Related notes** — from wikilinks `[[...]]`
- **Area** — from frontmatter `area:` field
- **Tags** — from frontmatter `tags:` field
### Step 3: Summarize and ask for focus
Present a summary of the research:
```
📄 Research: [Title]
📂 Area: [Area]
🏷️ Tags: [tags]
สรุปประเด็นหลัก:
1. [Key point 1]
2. [Key point 2]
3. [Key point 3]
...
บทความนี้ควรเน้นประเด็นไหนบ้าง?
(เลือกหมายเลข หรือพิมพ์ประเด็นเพิ่มเติม)
```
### Step 4: Iterate on details
After user selects focus areas, ask follow-up questions:
- มีมุมมองเฉพาะที่อยากเพิ่มไหม?
- กลุ่มเป้าหมายของบทความคือใคร?
- โทนบทความ: ทางการ / casual / technical?
- ความยาวที่ต้องการ: สั้น (800 words) / กลาง (1500) / ยาว (2000+)?
- ต้องการ SEO keyword ไหม? ถ้ามี คืออะไร?
### Step 5: Additional research (optional)
If the research note is thin or user wants more depth:
1. Search internet for current information on the topic
2. Look for statistics, examples, case studies
3. Find expert quotes or references
4. Check what competitors have written (SERP analysis)
### Step 6: Create brief.md
Create the article brief at:
```
~/vault/60_Articles/<client-id>/YYYY-MM-DD-<slug>/brief.md
```
Where `<slug>` is derived from the topic (kebab-case, English).
```markdown
---
type: brief
status: ready
created: YYYY-MM-DD
source_research: "[[Original Research Title]]"
source_path: "30_Research/Area/Topic/Topic.md"
---
# Article Brief: [Topic]
## Source
- Research: [[Original Research Title]]
- Path: 30_Research/Area/Topic/Topic.md
## Target
- Audience: [who]
- Tone: [formal/casual/technical]
- Length: [target word count]
- SEO Keyword: [if provided]
## Key Angles
1. [Angle 1]
2. [Angle 2]
3. [Angle 3]
## Outline
### H1: [Proposed title]
### H2: [Section 1]
- [Key point]
### H2: [Section 2]
- [Key point]
### H2: [Section 3]
- [Key point]
## Research Data
[Key statistics, quotes, facts from the research note + internet research]
## Related Content
- [[Related Note 1]]
- [[Related Note 2]]
## Content Requirements
- Featured image: [description]
- Inline images: [list with descriptions]
- FAQ section: [yes/no, topics if yes]
- Schema markup: [Article/BlogPosting]
```
### Step 7: Mark research note as used AND move to Archive
Update the original research note's frontmatter:
```yaml
---
...existing frontmatter...
article_created: true
article_link: "[[YYYY-MM-DD-slug]]"
---
```
Use `patch` to add the two fields to the frontmatter.
Then move the research note to the client's Archive folder:
```bash
# Determine source location
SOURCE_DIR=$(dirname "$RESEARCH_PATH")
ARCHIVE_DIR="$SOURCE_DIR/Archive"
# Create Archive if it doesn't exist
mkdir -p "$ARCHIVE_DIR"
# Move the file
mv "$RESEARCH_PATH" "$ARCHIVE_DIR/$(basename $RESEARCH_PATH)"
```
**Important**: Only move if the research is in a client-specific folder.
If the research is in `30_Research/general/`, mark as used but DON'T move
(general research can be reused for other clients).
### Step 8: Confirm
```
✅ Brief created: ~/vault/60_Articles/<client-id>/YYYY-MM-DD-slug/brief.md
✅ Research marked: article_created: true
✅ Research archived: moved to 30_Research/<client-id>/Archive/
ถัดไป: โหลด mm-content-writer skill เพื่อเริ่มเขียนบทความ
```
## Output
- `~/vault/60_Articles/<client-id>/<date>-<slug>/brief.md` — Article brief ready for mm-content-writer
- Updated frontmatter in `30_Research/<client-id>/` source note
- Source note moved to `30_Research/<client-id>/Archive/` (if client-specific)
## Notes
- If user can't find what they want in 30_Research/, suggest `article-idea-extract` skill
- The brief is the contract between Data Stage and Content Stage — be thorough
- Always preserve the wikilink to the source research