- 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
9.6 KiB
name, description
| name | description |
|---|---|
| mm-article-from-research | 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:
# 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// for available resources
VAULT_PATH="$HOME/vault"
Search for research notes in both client-specific and general folders that have NOT been marked as used for articles:
# 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:
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:
- Search internet for current information on the topic
- Look for statistics, examples, case studies
- Find expert quotes or references
- 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).
---
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:
---
...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:
# 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-extractskill - The brief is the contract between Data Stage and Content Stage — be thorough
- Always preserve the wikilink to the source research