15 KiB
15 KiB
Blog Setup
Interactive setup wizard to create blog constitution (.spec/blog.spec.json).
Usage
/blog-setup
This command creates a bash script in /tmp/ and executes it interactively to gather your blog configuration.
What It Does
- Generates interactive setup script in
/tmp/blog-kit-setup-[timestamp].sh - Prompts for blog configuration (name, context, tone, voice rules)
- Creates
.spec/blog.spec.jsonwith your configuration - Validates JSON structure
- Creates
CLAUDE.mdin content directory (documents constitution as source of truth) - Cleans up temporary script
Instructions
Generate and execute the following bash script:
# Generate unique script name
SCRIPT="/tmp/blog-kit-setup-$(date +%s).sh"
# Create interactive setup script
cat > "$SCRIPT" <<'SCRIPT_EOF'
#!/bin/bash
# Blog Kit Setup Wizard
# ======================
clear
echo "╔════════════════════════════════════════╗"
echo "║ Blog Kit - Setup Wizard ║"
echo "╚════════════════════════════════════════╝"
echo ""
echo "This wizard will create .spec/blog.spec.json"
echo "with your blog configuration."
echo ""
# Prompt: Blog Name
echo "📝 Blog Configuration"
echo "─────────────────────"
read -p "Blog name: " blog_name
# Validate non-empty
while [ -z "$blog_name" ]; do
echo "❌ Blog name cannot be empty"
read -p "Blog name: " blog_name
done
# Prompt: Context
echo ""
read -p "Context (e.g., 'Tech blog for developers'): " context
while [ -z "$context" ]; do
echo "❌ Context cannot be empty"
read -p "Context: " context
done
# Prompt: Objective
echo ""
read -p "Objective (e.g., 'Generate qualified leads'): " objective
while [ -z "$objective" ]; do
echo "❌ Objective cannot be empty"
read -p "Objective: " objective
done
# Prompt: Tone
echo ""
echo "🎨 Select tone:"
echo " 1) Expert (technical, authoritative)"
echo " 2) Pédagogique (educational, patient)"
echo " 3) Convivial (friendly, casual)"
echo " 4) Corporate (professional, formal)"
read -p "Choice (1-4): " tone_choice
case $tone_choice in
1) tone="expert" ;;
2) tone="pédagogique" ;;
3) tone="convivial" ;;
4) tone="corporate" ;;
*)
echo "⚠️ Invalid choice, defaulting to 'pédagogique'"
tone="pédagogique"
;;
esac
# Prompt: Languages
echo ""
read -p "Languages (comma-separated, e.g., 'fr,en'): " languages
languages=${languages:-"fr"} # Default to fr if empty
# Prompt: Content Directory
echo ""
read -p "Content directory (default: articles): " content_dir
content_dir=${content_dir:-"articles"} # Default to articles if empty
# Prompt: Voice DO
echo ""
echo "✅ Voice guidelines - DO"
echo "What should your content be?"
echo "Examples: Clear, Actionable, Engaging, Technical, Data-driven"
read -p "DO (comma-separated): " voice_do
while [ -z "$voice_do" ]; do
echo "❌ Please provide at least one DO guideline"
read -p "DO (comma-separated): " voice_do
done
# Prompt: Voice DON'T
echo ""
echo "❌ Voice guidelines - DON'T"
echo "What should your content avoid?"
echo "Examples: Jargon, Vague claims, Salesy language, Passive voice"
read -p "DON'T (comma-separated): " voice_dont
while [ -z "$voice_dont" ]; do
echo "❌ Please provide at least one DON'T guideline"
read -p "DON'T (comma-separated): " voice_dont
done
# Generate JSON
echo ""
echo "📄 Generating configuration..."
# Create .spec directory
mkdir -p .spec
# Convert comma-separated strings to JSON arrays
voice_do_json=$(echo "$voice_do" | sed 's/,\s*/","/g' | sed 's/^/"/' | sed 's/$/"/')
voice_dont_json=$(echo "$voice_dont" | sed 's/,\s*/","/g' | sed 's/^/"/' | sed 's/$/"/')
languages_json=$(echo "$languages" | sed 's/,\s*/","/g' | sed 's/^/"/' | sed 's/$/"/')
# Generate timestamp
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Create JSON file
cat > .spec/blog.spec.json <<JSON_EOF
{
"version": "1.0.0",
"blog": {
"name": "$blog_name",
"context": "$context",
"objective": "$objective",
"tone": "$tone",
"languages": [$languages_json],
"content_directory": "$content_dir",
"brand_rules": {
"voice_do": [$voice_do_json],
"voice_dont": [$voice_dont_json]
}
},
"workflow": {
"review_rules": {
"must_have": [
"Executive summary",
"Source citations",
"Actionable insights"
],
"must_avoid": [
"Unsourced claims",
"Keyword stuffing",
"Vague recommendations"
]
}
},
"generated_at": "$timestamp"
}
JSON_EOF
# Validate JSON
echo ""
if command -v python3 >/dev/null 2>&1; then
if python3 -m json.tool .spec/blog.spec.json > /dev/null 2>&1; then
echo "✅ JSON validation passed"
else
echo "❌ JSON validation failed"
echo "Please check .spec/blog.spec.json manually"
exit 1
fi
else
echo "⚠️ python3 not found, skipping JSON validation"
echo " (Validation will happen when agents run)"
fi
# Generate CLAUDE.md in content directory
echo ""
echo "📄 Generating CLAUDE.md in content directory..."
# Create content directory if it doesn't exist
mkdir -p "$content_dir"
# Determine tone behavior based on selected tone
case $tone in
"expert")
tone_behavior="Technical depth, assumes reader knowledge, industry terminology"
;;
"pédagogique")
tone_behavior="Educational approach, step-by-step explanations, learning-focused"
;;
"convivial")
tone_behavior="Friendly and approachable, conversational style, personal touch"
;;
"corporate")
tone_behavior="Professional and formal, business-oriented, ROI-focused"
;;
esac
# Generate CLAUDE.md with constitution as source of truth
cat > "$content_dir/CLAUDE.md" <<CLAUDE_EOF
# Blog Content Directory
**Blog Name**: $blog_name
**Tone**: $tone
## Source of Truth: blog.spec.json
**IMPORTANT**: All content in this directory MUST follow \`.spec/blog.spec.json\` guidelines.
This file is your blog constitution - it defines:
- Voice and tone
- Brand rules (DO/DON'T)
- Content structure requirements
- Review and validation criteria
### Always Check Constitution First
Before creating or editing any article:
1. **Load Constitution**: \`cat .spec/blog.spec.json\`
2. **Verify tone matches**: $tone ($tone_behavior)
3. **Follow voice guidelines** (see below)
4. **Run validation**: \`/blog-optimize "lang/article-slug"\`
## Voice Guidelines (from Constitution)
### ✅ DO
$(echo "$voice_do" | sed 's/,\s*/\n- ✅ /g' | sed 's/^/- ✅ /')
### ❌ DON'T
$(echo "$voice_dont" | sed 's/,\s*/\n- ❌ /g' | sed 's/^/- ❌ /')
## Tone: $tone
**What this means**:
$tone_behavior
**How to apply**:
- Every article must reflect this tone consistently
- Use vocabulary and phrasing appropriate to this tone
- Maintain tone across all languages ($(echo "$languages" | sed 's/,/, /g'))
## Article Structure
Every article must include:
1. **Frontmatter** (YAML):
- title
- description
- date
- language
- tags/categories
2. **Executive Summary**:
- Key takeaways upfront
- Clear value proposition
3. **Main Content**:
- H2/H3 structured headings
- Code examples (for technical topics)
- Source citations (3-5 credible sources)
4. **Actionable Insights**:
- 3-5 specific recommendations
- Next steps for readers
5. **Images**:
- Descriptive alt text (SEO + accessibility)
- Optimized format (WebP recommended)
## Validation Workflow
**Before Publishing**:
\`\`\`bash
# Validate single article
/blog-optimize "lang/article-slug"
# Check translation coverage (if i18n)
/blog-translate "lang/article-slug" "target-lang"
# Optimize images
/blog-optimize-images "lang/article-slug"
\`\`\`
**Commands that Use Constitution**:
- \`/blog-generate\` - Generates content following constitution
- \`/blog-copywrite\` - Writes article using spec-kit + constitution
- \`/blog-optimize\` - Validates against constitution rules
- \`/blog-marketing\` - Creates marketing content with brand voice
## Updating Constitution
To update blog guidelines:
1. Edit \`.spec/blog.spec.json\` manually
2. Or run \`/blog-setup\` again (overwrites file)
3. Or run \`/blog-analyse\` to regenerate from existing content
**After updating constitution**:
- This CLAUDE.md file should be regenerated
- Validate existing articles: \`/blog-optimize\`
- Update voice guidelines as needed
## Important Notes
⚠️ **Never Deviate from Constitution**
All agents (research-intelligence, seo-specialist, marketing-specialist, etc.) are instructed to:
- Load \`.spec/blog.spec.json\` before generating content
- Apply voice_do/voice_dont guidelines strictly
- Match the specified tone: $tone
- Follow review_rules for validation
If constitution conflicts with a specific request, **constitution always wins**.
If you need different guidelines for a specific article, update the constitution first.
---
**Context**: $context
**Objective**: $objective
**Languages**: $(echo "$languages" | sed 's/,/, /g')
**Content Directory**: $content_dir
Generated by: \`/blog-setup\` command
Constitution: \`.spec/blog.spec.json\`
CLAUDE_EOF
echo "✅ CLAUDE.md created in $content_dir/"
# Success message
echo ""
echo "╔════════════════════════════════════════╗"
echo "║ ✅ Setup Complete! ║"
echo "╚════════════════════════════════════════╝"
echo ""
echo "Files created:"
echo " ✅ .spec/blog.spec.json (constitution)"
echo " ✅ $content_dir/CLAUDE.md (content guidelines)"
echo ""
echo "Your blog: $blog_name"
echo "Tone: $tone"
echo "Content directory: $content_dir"
echo "Voice DO: $voice_do"
echo "Voice DON'T: $voice_dont"
echo ""
echo "Next steps:"
echo " 1. Review .spec/blog.spec.json"
echo " 2. Check $content_dir/CLAUDE.md for content guidelines"
echo " 3. Generate your first article: /blog-generate \"Your topic\""
echo ""
echo "All agents will use blog.spec.json as source of truth! 🎨"
echo ""
SCRIPT_EOF
# Make script executable
chmod +x "$SCRIPT"
# Execute script
bash "$SCRIPT"
# Capture exit code
EXIT_CODE=$?
# Clean up
rm "$SCRIPT"
# Report result
if [ $EXIT_CODE -eq 0 ]; then
echo "✅ Blog constitution and content guidelines created successfully!"
echo ""
echo "View your configuration:"
echo " cat .spec/blog.spec.json # Constitution"
echo " cat [content-dir]/CLAUDE.md # Content guidelines"
else
echo "❌ Setup failed with exit code $EXIT_CODE"
exit $EXIT_CODE
fi
Expected Output
After running /blog-setup, you'll have:
File 1: .spec/blog.spec.json (Constitution)
Example content:
{
"version": "1.0.0",
"blog": {
"name": "Tech Insights",
"context": "Technical blog for software developers",
"objective": "Generate qualified leads and establish thought leadership",
"tone": "pédagogique",
"languages": ["fr", "en"],
"content_directory": "articles",
"brand_rules": {
"voice_do": [
"Clear",
"Actionable",
"Technical",
"Data-driven"
],
"voice_dont": [
"Jargon without explanation",
"Vague claims",
"Salesy language"
]
}
},
"workflow": {
"review_rules": {
"must_have": [
"Executive summary",
"Source citations",
"Actionable insights"
],
"must_avoid": [
"Unsourced claims",
"Keyword stuffing",
"Vague recommendations"
]
}
},
"generated_at": "2025-10-12T10:30:00Z"
}
File 2: articles/CLAUDE.md (Content Guidelines)
Example content:
# Blog Content Directory
**Blog Name**: Tech Insights
**Tone**: pédagogique
## Source of Truth: blog.spec.json
**IMPORTANT**: All content in this directory MUST follow `.spec/blog.spec.json` guidelines.
### Always Check Constitution First
Before creating or editing any article:
1. **Load Constitution**: `cat .spec/blog.spec.json`
2. **Verify tone matches**: pédagogique (Educational approach, step-by-step explanations, learning-focused)
3. **Follow voice guidelines** (see below)
4. **Run validation**: `/blog-optimize "lang/article-slug"`
## Voice Guidelines (from Constitution)
### ✅ DO
- ✅ Clear
- ✅ Actionable
- ✅ Technical
- ✅ Data-driven
### ❌ DON'T
- ❌ Jargon without explanation
- ❌ Vague claims
- ❌ Salesy language
## Tone: pédagogique
**What this means**: Educational approach, step-by-step explanations, learning-focused
**How to apply**:
- Every article must reflect this tone consistently
- Use vocabulary and phrasing appropriate to this tone
- Maintain tone across all languages (fr, en)
## Article Structure
Every article must include:
1. **Frontmatter** (YAML): title, description, date, language, tags
2. **Executive Summary**: Key takeaways upfront
3. **Main Content**: H2/H3 structured headings, code examples, source citations
4. **Actionable Insights**: 3-5 specific recommendations
5. **Images**: Descriptive alt text (SEO + accessibility)
## Validation Workflow
**Before Publishing**:
```bash
/blog-optimize "lang/article-slug"
/blog-translate "lang/article-slug" "target-lang"
/blog-optimize-images "lang/article-slug"
Commands that Use Constitution:
/blog-generate- Generates content following constitution/blog-copywrite- Writes article using spec-kit + constitution/blog-optimize- Validates against constitution rules/blog-marketing- Creates marketing content with brand voice
⚠️ Never Deviate from Constitution
All agents are instructed to load .spec/blog.spec.json and follow it strictly.
If constitution conflicts with a request, constitution always wins.
## What Happens Next
When you run `/blog-generate`, agents will automatically:
1. Check if `.spec/blog.spec.json` exists
2. Load brand rules (voice do/don't)
3. Apply your tone preference
4. Follow review rules
5. Generate content consistent with your brand
**No manual configuration needed!** ✨
## Updating Configuration
To update your configuration:
1. Edit `.spec/blog.spec.json` manually, or
2. Run `/blog-setup` again (overwrites existing file)
## Validation
The script validates JSON automatically if `python3` is available. If validation fails, agents will catch errors when loading the constitution.
## Tips
1. **Be specific with voice guidelines**: "Avoid jargon" → "Avoid jargon without explanation"
2. **Balance DO/DON'T**: Provide both positive and negative guidelines
3. **Test tone**: Generate a test article after setup to verify tone matches expectations
4. **Iterate**: Don't worry about perfection - you can edit `.spec/blog.spec.json` anytime
---
**Ready to set up your blog?** Run `/blog-setup` now!