feat: Add OurDigital custom skills package (10 skills)
Complete implementation of OurDigital skills with dual-platform support (Claude Desktop + Claude Code) following standardized structure. Skills created: - 01-ourdigital-brand-guide: Brand reference & style guidelines - 02-ourdigital-blog: Korean blog drafts (blog.ourdigital.org) - 03-ourdigital-journal: English essays (journal.ourdigital.org) - 04-ourdigital-research: Research prompts & workflows - 05-ourdigital-document: Notion-to-presentation pipeline - 06-ourdigital-designer: Visual/image prompt generation - 07-ourdigital-ad-manager: Ad copywriting & keyword research - 08-ourdigital-trainer: Training materials & workshop planning - 09-ourdigital-backoffice: Quotes, proposals, cost analysis - 10-ourdigital-skill-creator: Meta skill for creating new skills Features: - YAML frontmatter with "ourdigital" or "our" prefix triggers - Standardized directory structure (code/, desktop/, shared/, docs/) - Shared environment setup (_ourdigital-shared/) - Comprehensive reference documentation - Cross-skill integration support Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
64
custom-skills/04-ourdigital-research/code/CLAUDE.md
Normal file
64
custom-skills/04-ourdigital-research/code/CLAUDE.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Overview
|
||||
|
||||
Research-to-publication workflow toolkit. Exports research to Ulysses for OurDigital blog publishing.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Export research to Ulysses
|
||||
python scripts/export_to_ulysses.py --input research.md --group "Blog Drafts"
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `export_to_ulysses.py` | Export markdown to Ulysses app for editing/publishing |
|
||||
|
||||
## Ulysses Export
|
||||
|
||||
```bash
|
||||
# Basic export
|
||||
python scripts/export_to_ulysses.py --input research.md
|
||||
|
||||
# With target group
|
||||
python scripts/export_to_ulysses.py \
|
||||
--input research.md \
|
||||
--group "Blog Drafts" \
|
||||
--tags "research,draft"
|
||||
|
||||
# From Notion export
|
||||
python scripts/export_to_ulysses.py \
|
||||
--notion-export notion_export.zip \
|
||||
--group "From Notion"
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Complete research in Claude/Notion
|
||||
2. Export to markdown format
|
||||
3. Run export script to Ulysses
|
||||
4. Edit and polish in Ulysses
|
||||
5. Publish to Ghost/OurDigital
|
||||
|
||||
## Output Targets
|
||||
|
||||
- **blog.ourdigital.org** - Main blog
|
||||
- **journal.ourdigital.org** - Long-form essays
|
||||
- **ourstory.day** - Personal narratives
|
||||
|
||||
## Ulysses Integration
|
||||
|
||||
Requires:
|
||||
- Ulysses app installed
|
||||
- x-callback-url scheme enabled
|
||||
- Target group created in Ulysses
|
||||
|
||||
## References
|
||||
|
||||
See `references/` for:
|
||||
- `blog-style-guide.md` - OurDigital writing style
|
||||
- `publishing-checklist.md` - Pre-publish checklist
|
||||
- `ghost-api-config.md` - Ghost CMS integration
|
||||
124
custom-skills/04-ourdigital-research/code/SKILL.md
Normal file
124
custom-skills/04-ourdigital-research/code/SKILL.md
Normal file
@@ -0,0 +1,124 @@
|
||||
---
|
||||
name: ourdigital-research
|
||||
description: |
|
||||
Deep research and prompt generation for OurDigital.
|
||||
Activated with "ourdigital" keyword.
|
||||
|
||||
Triggers:
|
||||
- "ourdigital research", "ourdigital 리서치"
|
||||
- "ourdigital deep research"
|
||||
|
||||
Features:
|
||||
- Research planning
|
||||
- Multi-source research
|
||||
- Notion archiving
|
||||
- Blog pipeline
|
||||
version: "1.0"
|
||||
author: OurDigital
|
||||
environment: Code
|
||||
---
|
||||
|
||||
# OurDigital Research (Code)
|
||||
|
||||
Research-to-publication workflow with script automation.
|
||||
|
||||
## Activation
|
||||
|
||||
Only with "ourdigital" keyword:
|
||||
- "ourdigital research [topic]"
|
||||
- "ourdigital 리서치"
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Export research to Ulysses
|
||||
python shared/scripts/export_to_ulysses.py --input research.md
|
||||
|
||||
# Full pipeline
|
||||
python shared/scripts/research_pipeline.py --topic "AI Marketing" --output blog
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
Discovery → Planning → Research → Paper → Notion → Blog → Export
|
||||
```
|
||||
|
||||
### 1. Discovery
|
||||
|
||||
Ask clarifying questions:
|
||||
- Target audience?
|
||||
- Depth level?
|
||||
- Specific angles?
|
||||
|
||||
### 2. Research Planning
|
||||
|
||||
Generate:
|
||||
- Primary questions (3-5)
|
||||
- Secondary questions
|
||||
- Source strategy
|
||||
|
||||
### 3. Deep Research
|
||||
|
||||
Execute with tools:
|
||||
- `web_search` / `web_fetch`
|
||||
- `Notion:notion-search`
|
||||
- Internal documents
|
||||
|
||||
### 4. Research Paper
|
||||
|
||||
Synthesize into:
|
||||
```
|
||||
├── Executive Summary
|
||||
├── Key Findings
|
||||
├── Analysis
|
||||
├── Recommendations
|
||||
└── References
|
||||
```
|
||||
|
||||
### 5. Notion Save
|
||||
|
||||
Archive to Working with AI:
|
||||
- Database: f8f19ede-32bd-43ac-9f60-0651f6f40afe
|
||||
- Properties: Name, Status, AI used, Summary
|
||||
|
||||
### 6. Blog Draft
|
||||
|
||||
Route to appropriate skill:
|
||||
- Korean → `02-ourdigital-blog`
|
||||
- English → `03-ourdigital-journal`
|
||||
|
||||
### 7. Export
|
||||
|
||||
```bash
|
||||
python shared/scripts/export_to_ulysses.py --input draft.md
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `export_to_ulysses.py` | Export to Ulysses app |
|
||||
| `research_pipeline.py` | Full automation |
|
||||
|
||||
## Quick Commands
|
||||
|
||||
| Command | Action |
|
||||
|---------|--------|
|
||||
| "ourdigital research [topic]" | Start discovery |
|
||||
| "ourdigital research → blog" | Full pipeline |
|
||||
| "ourdigital research → notion" | Research + save |
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
04-ourdigital-research/
|
||||
├── code/SKILL.md
|
||||
├── desktop/SKILL.md
|
||||
├── shared/
|
||||
│ ├── references/
|
||||
│ │ └── research-frameworks.md
|
||||
│ └── scripts/
|
||||
│ └── export_to_ulysses.py
|
||||
└── docs/CHANGELOG.md
|
||||
```
|
||||
@@ -0,0 +1,87 @@
|
||||
# {제목 / Title}
|
||||
|
||||
> **요약**: {1-2문장 핵심 요약}
|
||||
>
|
||||
> **Summary**: {1-2 sentence key takeaway}
|
||||
|
||||
---
|
||||
|
||||
## 들어가며 / Introduction
|
||||
|
||||
{독자의 관심을 끄는 도입부. 문제 제기, 질문, 또는 흥미로운 사실로 시작.}
|
||||
|
||||
{Opening hook that captures reader attention. Start with a problem, question, or interesting fact.}
|
||||
|
||||
---
|
||||
|
||||
## 배경 / Background
|
||||
|
||||
{주제에 대한 맥락 설명. 왜 이것이 중요한지, 현재 상황은 어떤지.}
|
||||
|
||||
{Context for the topic. Why this matters, current state of things.}
|
||||
|
||||
---
|
||||
|
||||
## 핵심 내용 / Key Points
|
||||
|
||||
### 첫 번째 포인트 / First Point
|
||||
|
||||
{상세 설명과 근거}
|
||||
|
||||
{Detailed explanation with evidence}
|
||||
|
||||
### 두 번째 포인트 / Second Point
|
||||
|
||||
{상세 설명과 근거}
|
||||
|
||||
{Detailed explanation with evidence}
|
||||
|
||||
### 세 번째 포인트 / Third Point
|
||||
|
||||
{상세 설명과 근거}
|
||||
|
||||
{Detailed explanation with evidence}
|
||||
|
||||
---
|
||||
|
||||
## 실무 적용 / Practical Application
|
||||
|
||||
{독자가 바로 적용할 수 있는 액션 아이템}
|
||||
|
||||
{Actionable items readers can implement immediately}
|
||||
|
||||
1. **첫 번째 단계**: {설명}
|
||||
2. **두 번째 단계**: {설명}
|
||||
3. **세 번째 단계**: {설명}
|
||||
|
||||
---
|
||||
|
||||
## 마치며 / Conclusion
|
||||
|
||||
{핵심 메시지 재강조, 독자에게 남기는 생각거리 또는 다음 단계}
|
||||
|
||||
{Reinforce key message, leave reader with thought or next step}
|
||||
|
||||
---
|
||||
|
||||
## 참고 자료 / References
|
||||
|
||||
- [출처 1](URL)
|
||||
- [출처 2](URL)
|
||||
- [출처 3](URL)
|
||||
|
||||
---
|
||||
|
||||
**태그 / Tags**: #{tag1} #{tag2} #{tag3}
|
||||
|
||||
**카테고리 / Category**: {category}
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
SEO Meta (Ghost/CMS용):
|
||||
- Meta Title: {60자 이내}
|
||||
- Meta Description: {150-160자}
|
||||
- URL Slug: {짧고-명확한-슬러그}
|
||||
- Featured Image Alt: {이미지 설명}
|
||||
-->
|
||||
@@ -0,0 +1,114 @@
|
||||
# OurDigital Blog Style Guide
|
||||
|
||||
## Channel-Specific Voice & Tone
|
||||
|
||||
### blog.ourdigital.org (Korean)
|
||||
**Voice**: 전문적이면서 친근한 선배 마케터
|
||||
**Tone**: 실용적, 데이터 기반, 인사이트 중심
|
||||
|
||||
Writing patterns:
|
||||
- 제목: 핵심 키워드 포함, 30자 이내
|
||||
- 도입부: 독자의 고민/질문으로 시작
|
||||
- 본문: 번호 매기기보다 소제목 활용
|
||||
- 전문용어: 한글(영문) 형식 - 예: 검색엔진최적화(SEO)
|
||||
- 문장: ~입니다/~습니다 경어체
|
||||
- 단락: 3-4문장, 모바일 가독성 고려
|
||||
|
||||
Example opening:
|
||||
```
|
||||
"구글 상위 노출, 왜 이렇게 어려울까요?
|
||||
많은 마케터들이 SEO에 시간을 투자하지만
|
||||
결과가 보이지 않아 좌절합니다.
|
||||
오늘은 실제로 효과를 본 전략 3가지를 공유합니다."
|
||||
```
|
||||
|
||||
### journal.ourdigital.org (English)
|
||||
**Voice**: Thoughtful industry analyst
|
||||
**Tone**: Insightful, evidence-based, forward-looking
|
||||
|
||||
Writing patterns:
|
||||
- Headlines: Clear value proposition, under 60 chars
|
||||
- Opening: Hook with industry trend or data point
|
||||
- Body: Structured arguments with supporting evidence
|
||||
- Terminology: Define jargon on first use
|
||||
- Style: Active voice, varied sentence length
|
||||
- Paragraphs: 2-4 sentences for scannability
|
||||
|
||||
Example opening:
|
||||
```
|
||||
"The digital marketing landscape shifted dramatically in 2024.
|
||||
With AI reshaping search behavior, traditional SEO metrics
|
||||
no longer tell the full story. Here's what the data reveals—
|
||||
and what it means for your strategy."
|
||||
```
|
||||
|
||||
### ourstory.day (Korean)
|
||||
**Voice**: 성찰하는 동료, 이야기꾼
|
||||
**Tone**: 개인적, 진솔한, 영감을 주는
|
||||
|
||||
Writing patterns:
|
||||
- 제목: 감성적, 질문형 또는 은유적
|
||||
- 도입부: 개인 경험이나 장면 묘사로 시작
|
||||
- 본문: 이야기 흐름, 대화체 허용
|
||||
- 문장: ~해요/~네요 부드러운 경어체 가능
|
||||
- 단락: 자유로운 길이, 호흡에 따라
|
||||
- 마무리: 열린 질문 또는 여운
|
||||
|
||||
Example opening:
|
||||
```
|
||||
"새벽 5시, 아이를 깨우지 않으려 살금살금 책상에 앉았다.
|
||||
화면에는 어제 작성한 리포트가 그대로 남아있었다.
|
||||
'이게 정말 내가 하고 싶은 일인가?'
|
||||
문득 그런 생각이 스쳤다."
|
||||
```
|
||||
|
||||
### Medium (English)
|
||||
**Voice**: Knowledgeable peer sharing discoveries
|
||||
**Tone**: Conversational, practical, slightly informal
|
||||
|
||||
Writing patterns:
|
||||
- Headlines: Curiosity-driven, specific numbers work well
|
||||
- Opening: Personal anecdote or surprising fact
|
||||
- Body: Mix of storytelling and practical advice
|
||||
- Style: First person allowed, contractions okay
|
||||
- Subheadings: Every 300-400 words
|
||||
- Closing: Clear takeaway or call-to-action
|
||||
|
||||
Example opening:
|
||||
```
|
||||
"I've spent 15 years in digital marketing, and nothing
|
||||
prepared me for what happened when AI entered the chat.
|
||||
Last month, I ran an experiment that changed how I think
|
||||
about content strategy entirely. Let me walk you through it."
|
||||
```
|
||||
|
||||
## Universal Guidelines
|
||||
|
||||
### SEO Considerations
|
||||
- Primary keyword in title and first 100 words
|
||||
- Secondary keywords naturally distributed
|
||||
- Meta description: 150-160 chars, action-oriented
|
||||
- URL slug: Short, keyword-rich, no dates
|
||||
- Alt text for all images
|
||||
|
||||
### Formatting Rules
|
||||
- Use `##` for main sections, `###` for subsections
|
||||
- Code blocks with language specification
|
||||
- Blockquotes for key insights or quotes
|
||||
- Bold for emphasis (sparingly)
|
||||
- Lists only when truly listing items
|
||||
|
||||
### Citation Style
|
||||
- Inline links preferred over footnotes
|
||||
- Source attribution: "According to [Source Name](URL)..."
|
||||
- Data citations: Include date of data
|
||||
- Internal links: Reference related OurDigital posts
|
||||
|
||||
## Word Count Guidelines
|
||||
|
||||
| Channel | Target | Min | Max |
|
||||
|---------|--------|-----|-----|
|
||||
| blog.ourdigital.org | 1,500 | 1,000 | 2,500 |
|
||||
| journal.ourdigital.org | 1,800 | 1,200 | 3,000 |
|
||||
| ourstory.day | 1,000 | 500 | 2,000 |
|
||||
| Medium | 1,500 | 800 | 2,500 |
|
||||
@@ -0,0 +1,74 @@
|
||||
# Ghost Admin API Configuration
|
||||
|
||||
## Configured Channels
|
||||
|
||||
| Channel | Domain | API Status |
|
||||
|---------|--------|------------|
|
||||
| blog.ourdigital.org | Korean main blog | ✅ Configured |
|
||||
| journal.ourdigital.org | English journal | ✅ Configured |
|
||||
| ourstory.day | Personal essays | ✅ Configured |
|
||||
|
||||
## API Endpoints
|
||||
|
||||
Base URL pattern: `https://{domain}/ghost/api/admin/`
|
||||
|
||||
### Authentication
|
||||
Ghost Admin API uses JWT tokens generated from Admin API keys.
|
||||
|
||||
```
|
||||
Admin API Key Format: {id}:{secret}
|
||||
- id: 24 hex characters
|
||||
- secret: 64 hex characters
|
||||
```
|
||||
|
||||
### Key Endpoints
|
||||
|
||||
| Endpoint | Method | Purpose |
|
||||
|----------|--------|---------|
|
||||
| `/posts/` | POST | Create new post |
|
||||
| `/posts/{id}/` | PUT | Update existing post |
|
||||
| `/images/upload/` | POST | Upload image |
|
||||
| `/tags/` | GET/POST | Manage tags |
|
||||
|
||||
### Post Creation Payload
|
||||
|
||||
```json
|
||||
{
|
||||
"posts": [{
|
||||
"title": "Post Title",
|
||||
"html": "<p>Content in HTML</p>",
|
||||
"status": "draft",
|
||||
"tags": [{"name": "tag1"}, {"name": "tag2"}],
|
||||
"feature_image": "https://...",
|
||||
"meta_title": "SEO Title",
|
||||
"meta_description": "SEO Description",
|
||||
"og_title": "Social Title",
|
||||
"og_description": "Social Description",
|
||||
"published_at": "2024-01-15T09:00:00.000Z"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### Status Options
|
||||
- `draft`: Save without publishing
|
||||
- `published`: Publish immediately
|
||||
- `scheduled`: Schedule for future (requires `published_at`)
|
||||
|
||||
## Future Automation Opportunities
|
||||
|
||||
### Zapier Integration Points
|
||||
1. **Trigger**: New Notion page in "Working with AI" → Create Ghost draft
|
||||
2. **Trigger**: Ghost post published → Share to social channels
|
||||
3. **Trigger**: New MD file in iCloud folder → Create Ghost draft
|
||||
|
||||
### n8n Workflow Ideas
|
||||
1. Research complete → Auto-create drafts across all relevant channels
|
||||
2. Scheduled publishing queue management
|
||||
3. Cross-posting between Ghost instances
|
||||
|
||||
## Security Notes
|
||||
|
||||
- API keys stored in environment variables
|
||||
- Never expose keys in code or logs
|
||||
- Rotate keys if compromised
|
||||
- Use separate keys for different integrations
|
||||
@@ -0,0 +1,118 @@
|
||||
# Pre-Publishing Checklist
|
||||
|
||||
## Content Quality
|
||||
|
||||
### Writing
|
||||
- [ ] Title is compelling and SEO-optimized
|
||||
- [ ] Opening hook captures attention within first 3 sentences
|
||||
- [ ] Clear thesis/value proposition stated early
|
||||
- [ ] Logical flow between sections
|
||||
- [ ] Strong conclusion with takeaway or CTA
|
||||
- [ ] Proofread for typos and grammar (Ulysses phase)
|
||||
|
||||
### Accuracy
|
||||
- [ ] All facts verified with sources
|
||||
- [ ] Statistics include source and date
|
||||
- [ ] Links tested and working
|
||||
- [ ] No outdated information presented as current
|
||||
- [ ] Technical accuracy reviewed
|
||||
|
||||
### Formatting
|
||||
- [ ] Consistent heading hierarchy (H2 → H3 → H4)
|
||||
- [ ] Paragraphs appropriately sized for readability
|
||||
- [ ] Code blocks properly formatted with language tags
|
||||
- [ ] Lists used only for actual list content
|
||||
- [ ] Emphasis (bold/italic) used sparingly
|
||||
|
||||
## SEO Elements
|
||||
|
||||
### On-Page
|
||||
- [ ] Primary keyword in title
|
||||
- [ ] Primary keyword in first 100 words
|
||||
- [ ] Secondary keywords naturally distributed
|
||||
- [ ] URL slug: short, descriptive, keyword-rich
|
||||
- [ ] Meta description: 150-160 chars, includes CTA
|
||||
|
||||
### Technical
|
||||
- [ ] Internal links to related posts (2-3 minimum)
|
||||
- [ ] External links to authoritative sources
|
||||
- [ ] Alt text for all images
|
||||
- [ ] Heading structure is semantic (one H1 only)
|
||||
|
||||
## Visual Elements (Web UI Phase)
|
||||
|
||||
### Featured Image
|
||||
- [ ] High quality, relevant to content
|
||||
- [ ] Proper dimensions for channel
|
||||
- Ghost: 1200 x 630px recommended
|
||||
- Medium: 1500 x 750px recommended
|
||||
- [ ] Alt text added
|
||||
- [ ] Copyright/license verified
|
||||
|
||||
### In-Post Images
|
||||
- [ ] Compressed for web (< 200KB ideal)
|
||||
- [ ] Descriptive filenames (not IMG_001.jpg)
|
||||
- [ ] Captions added where helpful
|
||||
- [ ] Alt text for accessibility
|
||||
|
||||
## Channel-Specific
|
||||
|
||||
### Ghost (blog.ourdigital.org, journal.ourdigital.org, ourstory.day)
|
||||
|
||||
**Before Publishing:**
|
||||
- [ ] Tags assigned (3-5 relevant tags)
|
||||
- [ ] Author profile selected
|
||||
- [ ] Excerpt/custom snippet written
|
||||
- [ ] Publication date/time set
|
||||
- [ ] Email newsletter toggle reviewed
|
||||
|
||||
**Ghost Admin Settings:**
|
||||
- [ ] Code injection (if needed): header/footer scripts
|
||||
- [ ] Facebook/Twitter card preview checked
|
||||
- [ ] Canonical URL set (if republishing)
|
||||
|
||||
### Medium
|
||||
|
||||
**Before Publishing:**
|
||||
- [ ] Tags selected (max 5)
|
||||
- [ ] Publication submitted to (if applicable)
|
||||
- [ ] Subtitle/kicker written
|
||||
- [ ] Reading time appears reasonable
|
||||
- [ ] Preview in both web and mobile
|
||||
|
||||
**Medium-Specific:**
|
||||
- [ ] No excessive self-promotion
|
||||
- [ ] Paywall setting decided (member-only?)
|
||||
- [ ] Cross-post canonical URL added (if from blog)
|
||||
|
||||
## Final Verification
|
||||
|
||||
### Preview Check
|
||||
- [ ] Desktop preview looks correct
|
||||
- [ ] Mobile preview is readable
|
||||
- [ ] Links work in preview mode
|
||||
- [ ] Images display properly
|
||||
- [ ] Social share preview correct
|
||||
|
||||
### Publication
|
||||
- [ ] Schedule vs. publish now decided
|
||||
- [ ] Social sharing plan ready
|
||||
- [ ] Newsletter inclusion decided
|
||||
- [ ] Analytics tracking confirmed
|
||||
|
||||
## Post-Publication
|
||||
|
||||
### Immediate (within 1 hour)
|
||||
- [ ] Verify live URL works
|
||||
- [ ] Share to social channels
|
||||
- [ ] Notify team/subscribers if relevant
|
||||
|
||||
### Follow-up (within 24-48 hours)
|
||||
- [ ] Check initial engagement metrics
|
||||
- [ ] Respond to comments
|
||||
- [ ] Fix any reported issues
|
||||
|
||||
### Long-term (monthly)
|
||||
- [ ] Review analytics performance
|
||||
- [ ] Update outdated information
|
||||
- [ ] Add internal links from newer posts
|
||||
@@ -0,0 +1,133 @@
|
||||
# Research Frameworks
|
||||
|
||||
## Framework Selection Guide
|
||||
|
||||
| Topic Type | Framework | Best For |
|
||||
|------------|-----------|----------|
|
||||
| Trend analysis | STEEP + Timeline | Industry shifts, emerging tech |
|
||||
| Problem-solution | Problem Tree | Pain points, how-to guides |
|
||||
| Comparison | Feature Matrix | Tool reviews, option analysis |
|
||||
| Strategy | SWOT + Action | Business recommendations |
|
||||
| Technical | Layered Deep-Dive | Implementation guides |
|
||||
|
||||
## STEEP + Timeline Framework
|
||||
|
||||
For analyzing trends and industry changes:
|
||||
|
||||
```
|
||||
S - Social: User behavior changes, demographics
|
||||
T - Technological: New tools, platforms, capabilities
|
||||
E - Economic: Market conditions, pricing trends
|
||||
E - Environmental: Sustainability, resource factors
|
||||
P - Political/Legal: Regulations, compliance
|
||||
|
||||
Timeline:
|
||||
- Past (2-3 years): What changed?
|
||||
- Present: Current state of play
|
||||
- Future (1-2 years): Projections
|
||||
```
|
||||
|
||||
## Problem Tree Framework
|
||||
|
||||
For diagnostic and solution-oriented research:
|
||||
|
||||
```
|
||||
ROOT PROBLEM
|
||||
├── Cause 1
|
||||
│ ├── Sub-cause 1.1
|
||||
│ └── Sub-cause 1.2
|
||||
├── Cause 2
|
||||
│ └── Sub-cause 2.1
|
||||
└── Cause 3
|
||||
|
||||
SOLUTIONS
|
||||
├── Solution A → addresses Cause 1
|
||||
├── Solution B → addresses Cause 2
|
||||
└── Solution C → addresses Cause 3
|
||||
```
|
||||
|
||||
## Feature Matrix Framework
|
||||
|
||||
For comparisons and evaluations:
|
||||
|
||||
```
|
||||
| Criteria | Option A | Option B | Option C | Weight |
|
||||
|----------|----------|----------|----------|--------|
|
||||
| Feature 1 | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ | High |
|
||||
| Feature 2 | ⭐⭐ | ⭐⭐⭐ | ⭐ | Medium |
|
||||
| Feature 3 | ⭐ | ⭐⭐ | ⭐⭐⭐ | Low |
|
||||
| Price | $$$ | $$ | $ | High |
|
||||
|
||||
Weighted Score: Calculate based on importance
|
||||
Recommendation: Based on user's priority
|
||||
```
|
||||
|
||||
## Layered Deep-Dive Framework
|
||||
|
||||
For technical and implementation topics:
|
||||
|
||||
```
|
||||
Layer 1: Concept (What is it?)
|
||||
- Definition
|
||||
- Key components
|
||||
- How it works (simplified)
|
||||
|
||||
Layer 2: Context (Why does it matter?)
|
||||
- Business value
|
||||
- Use cases
|
||||
- When to use vs. alternatives
|
||||
|
||||
Layer 3: Implementation (How to do it?)
|
||||
- Prerequisites
|
||||
- Step-by-step process
|
||||
- Code/configuration examples
|
||||
|
||||
Layer 4: Optimization (How to do it well?)
|
||||
- Best practices
|
||||
- Common pitfalls
|
||||
- Advanced techniques
|
||||
|
||||
Layer 5: Measurement (How to know it works?)
|
||||
- Success metrics
|
||||
- Monitoring approach
|
||||
- Iteration guidance
|
||||
```
|
||||
|
||||
## Research Question Templates
|
||||
|
||||
### Exploratory Questions
|
||||
- "What is the current state of [topic]?"
|
||||
- "How has [topic] evolved in the past [timeframe]?"
|
||||
- "Who are the key players/stakeholders in [topic]?"
|
||||
|
||||
### Analytical Questions
|
||||
- "What factors drive [outcome] in [context]?"
|
||||
- "How does [variable A] affect [variable B]?"
|
||||
- "What patterns emerge when comparing [X] and [Y]?"
|
||||
|
||||
### Evaluative Questions
|
||||
- "What are the strengths and limitations of [approach]?"
|
||||
- "How effective is [solution] for [problem]?"
|
||||
- "What criteria should guide [decision]?"
|
||||
|
||||
### Practical Questions
|
||||
- "How can [audience] implement [solution]?"
|
||||
- "What resources are needed for [action]?"
|
||||
- "What are the risks and mitigations for [approach]?"
|
||||
|
||||
## Source Priority
|
||||
|
||||
1. **Primary**: Official documentation, research papers, authoritative reports
|
||||
2. **Secondary**: Industry publications, expert analysis, case studies
|
||||
3. **Tertiary**: News articles, blog posts, community discussions
|
||||
|
||||
Always cross-reference claims across multiple source types.
|
||||
|
||||
## Data Quality Checklist
|
||||
|
||||
- [ ] Source credibility verified
|
||||
- [ ] Publication date recent (within context)
|
||||
- [ ] Statistics include sample size/methodology
|
||||
- [ ] Claims are falsifiable/verifiable
|
||||
- [ ] Potential biases identified
|
||||
- [ ] Conflicting viewpoints considered
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Ulysses Export Helper
|
||||
|
||||
Exports markdown files to iCloud folder for Ulysses sync.
|
||||
Designed for OurDigital research-to-publisher workflow.
|
||||
|
||||
Usage:
|
||||
python export_to_ulysses.py --content "# Title\n\nContent..." --filename "my-post.md"
|
||||
python export_to_ulysses.py --file /path/to/draft.md --channel blog
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# Default iCloud paths (user should customize)
|
||||
ICLOUD_BASE = Path.home() / "Library/Mobile Documents/com~apple~CloudDocs"
|
||||
|
||||
# Channel-specific folders (customize based on Ulysses library structure)
|
||||
CHANNEL_FOLDERS = {
|
||||
"blog": "Ulysses/OurDigital/Blog Drafts",
|
||||
"journal": "Ulysses/OurDigital/Journal Drafts",
|
||||
"ourstory": "Ulysses/OurDigital/OurStory Drafts",
|
||||
"medium": "Ulysses/OurDigital/Medium Drafts",
|
||||
"default": "Ulysses/Blog Drafts"
|
||||
}
|
||||
|
||||
def get_export_path(channel: str = "default") -> Path:
|
||||
"""Get the export path for a specific channel."""
|
||||
folder = CHANNEL_FOLDERS.get(channel, CHANNEL_FOLDERS["default"])
|
||||
export_path = ICLOUD_BASE / folder
|
||||
|
||||
# Create directory if it doesn't exist
|
||||
export_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
return export_path
|
||||
|
||||
def generate_filename(title: str = None) -> str:
|
||||
"""Generate a filename with timestamp."""
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M")
|
||||
if title:
|
||||
# Clean title for filename
|
||||
clean_title = "".join(c if c.isalnum() or c in "- " else "" for c in title)
|
||||
clean_title = clean_title.replace(" ", "-").lower()[:50]
|
||||
return f"{timestamp}_{clean_title}.md"
|
||||
return f"{timestamp}_draft.md"
|
||||
|
||||
def export_content(content: str, filename: str, channel: str = "default") -> Path:
|
||||
"""Export content to the appropriate iCloud folder."""
|
||||
export_path = get_export_path(channel)
|
||||
file_path = export_path / filename
|
||||
|
||||
# Add Ulysses-friendly frontmatter if not present
|
||||
if not content.startswith("---"):
|
||||
frontmatter = f"""---
|
||||
created: {datetime.now().isoformat()}
|
||||
channel: {channel}
|
||||
status: draft
|
||||
---
|
||||
|
||||
"""
|
||||
content = frontmatter + content
|
||||
|
||||
file_path.write_text(content, encoding="utf-8")
|
||||
return file_path
|
||||
|
||||
def export_file(source_path: str, channel: str = "default") -> Path:
|
||||
"""Copy an existing file to the iCloud folder."""
|
||||
source = Path(source_path)
|
||||
if not source.exists():
|
||||
raise FileNotFoundError(f"Source file not found: {source_path}")
|
||||
|
||||
content = source.read_text(encoding="utf-8")
|
||||
filename = source.name
|
||||
|
||||
return export_content(content, filename, channel)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Export markdown to Ulysses via iCloud")
|
||||
parser.add_argument("--content", help="Markdown content to export")
|
||||
parser.add_argument("--file", help="Path to existing markdown file")
|
||||
parser.add_argument("--filename", help="Output filename (auto-generated if not provided)")
|
||||
parser.add_argument("--channel", choices=list(CHANNEL_FOLDERS.keys()),
|
||||
default="default", help="Target channel/folder")
|
||||
parser.add_argument("--list-paths", action="store_true",
|
||||
help="List configured export paths")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.list_paths:
|
||||
print("Configured export paths:")
|
||||
for channel, folder in CHANNEL_FOLDERS.items():
|
||||
full_path = ICLOUD_BASE / folder
|
||||
exists = "✓" if full_path.exists() else "✗"
|
||||
print(f" [{exists}] {channel}: {full_path}")
|
||||
return
|
||||
|
||||
if args.file:
|
||||
result = export_file(args.file, args.channel)
|
||||
print(f"✓ Exported to: {result}")
|
||||
elif args.content:
|
||||
filename = args.filename or generate_filename()
|
||||
result = export_content(args.content, filename, args.channel)
|
||||
print(f"✓ Exported to: {result}")
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,3 @@
|
||||
# 31-ourdigital-research dependencies
|
||||
markdown>=3.5.0
|
||||
python-dotenv>=1.0.0
|
||||
Reference in New Issue
Block a user