feat: scaffold Next.js 15 project with TypeScript and Tailwind
@@ -0,0 +1,435 @@
|
||||
# The Autonomous Marketing Team — Full Plan
|
||||
|
||||
**Your role:** Gatekeeper. You approve or reject. That's it.
|
||||
**The system:** Researches trends, writes scripts, generates images, creates videos, writes copy, schedules posts — all autonomously.
|
||||
**Goal:** Drive app downloads on Instagram, TikTok, and Nextdoor.
|
||||
|
||||
---
|
||||
|
||||
## How Image & Video Generation Actually Works
|
||||
|
||||
### Image Generation (Static Ads)
|
||||
|
||||
You're not designing anything. Here's what happens under the hood:
|
||||
|
||||
```
|
||||
You say: "Create a campaign for [feature X]"
|
||||
|
||||
1. Research Agent finds trending angles, competitor hooks, keywords
|
||||
2. Ad Creative Designer reads research + brand knowledge files
|
||||
3. Claude writes a prompt → sends to NanoBanana MCP
|
||||
4. NanoBanana (powered by Gemini) generates the image INSIDE your Claude session
|
||||
5. Claude builds an HTML/CSS layout around the image:
|
||||
- Your headline, subtext, CTA button
|
||||
- Brand colors, fonts, spacing from knowledge files
|
||||
- Sized to exact platform dimensions
|
||||
6. Playwright opens a headless browser → loads the HTML → screenshots it
|
||||
7. You get a pixel-perfect PNG ad ready to upload
|
||||
|
||||
Cost: ~$0.04-0.13 per image
|
||||
Time: ~30-60 seconds
|
||||
```
|
||||
|
||||
**What you control:** The knowledge files dictate brand colors, fonts, CTA style, tone. Change the knowledge files = change every ad the system produces.
|
||||
|
||||
**What Claude controls:** Layout decisions, image prompts, copy placement, visual hierarchy — all guided by your brand rules.
|
||||
|
||||
### Video Generation (Remotion)
|
||||
|
||||
Remotion turns React code into video. Think of it as After Effects but written in code:
|
||||
|
||||
```
|
||||
You say: "Create a TikTok ad for [feature X]"
|
||||
|
||||
1. Research Agent finds pain points + trending hooks
|
||||
2. Video Ad Specialist reads research + brand knowledge
|
||||
3. Claude writes a scene plan (JSON):
|
||||
{
|
||||
"scenes": [
|
||||
{ "type": "hook", "duration": 3, "text": "Still doing X the hard way?", "animation": "scale-in" },
|
||||
{ "type": "problem", "duration": 4, "text": "The old way is broken", "animation": "slide-left" },
|
||||
{ "type": "solution", "duration": 5, "text": "Meet [Your App]", "animation": "fade-in" },
|
||||
{ "type": "proof", "duration": 3, "text": "50K+ downloads", "animation": "bounce" },
|
||||
{ "type": "cta", "duration": 3, "text": "Download Free", "animation": "pulse" }
|
||||
]
|
||||
}
|
||||
4. Claude generates React components for each scene:
|
||||
- SVG icons, text overlays, transitions
|
||||
- Motion via Remotion's interpolate() and spring() functions
|
||||
- Brand colors/fonts from knowledge files
|
||||
5. Remotion renders frame-by-frame → outputs MP4
|
||||
6. No manual step — video goes straight to outputs/
|
||||
|
||||
Cost: Free (Remotion is open source)
|
||||
Time: ~2-5 minutes for a 15-30s video
|
||||
```
|
||||
|
||||
**The style parameter matters:**
|
||||
- `style: "polished"` → clean motion graphics, brand colors (Instagram Reels)
|
||||
- `style: "authentic"` → rougher cuts, text-heavy, trend-pacing (TikTok)
|
||||
- `style: "local"` → warm, simple, community feel (Nextdoor)
|
||||
|
||||
### AI UGC Videos (The Next Level)
|
||||
|
||||
For ads that look like a real person talking about your app, add one of these:
|
||||
|
||||
| Tool | What It Does | Cost | API? |
|
||||
|------|-------------|------|------|
|
||||
| **[HeyGen](https://heygen.com)** | AI avatars that talk — 500+ looks/voices | ~$24/mo | Yes |
|
||||
| **[Arcads](https://arcads.ai)** | Real human footage + AI lip-sync (most authentic) | ~$100/mo | Yes |
|
||||
| **[MakeUGC](https://makeugc.ai)** | Cheapest per-video, 200+ avatars | ~$10/video | Limited |
|
||||
|
||||
**These are optional but powerful** — UGC-style content gets 2-3x higher engagement than polished brand ads on TikTok/Instagram because the algorithms treat it like creator content, not advertising.
|
||||
|
||||
---
|
||||
|
||||
## The Ad Creative Framework That Drives Downloads
|
||||
|
||||
### The Hook-Body-CTA Formula
|
||||
|
||||
Every ad your system produces follows this structure:
|
||||
|
||||
```
|
||||
HOOK (0-3 seconds) — Stop the scroll
|
||||
"Still doing [painful thing] the hard way?"
|
||||
"I found the app everyone's been hiding from you"
|
||||
"POV: you just discovered [your app]"
|
||||
|
||||
BODY (3-15 seconds) — Show the value
|
||||
Problem → Solution → Proof
|
||||
"The old way: [pain]. The new way: [your app does X]"
|
||||
Show the app in action (screen recording or motion graphic)
|
||||
Social proof: "50K downloads", "4.8★ rated", "Featured in [X]"
|
||||
|
||||
CTA (15-20 seconds) — Drive the action
|
||||
"Download free — link in bio"
|
||||
"Try it today" + app store badge animation
|
||||
"Your morning/workflow/life just got an upgrade"
|
||||
```
|
||||
|
||||
### The 10-20 Variations Rule
|
||||
|
||||
**You don't create one ad. You create 10-20 variations** with different hooks on the same concept and let the platforms test winners:
|
||||
|
||||
```
|
||||
Same body/CTA, but rotate hooks:
|
||||
Hook A: "Stop scrolling if you [pain point]..."
|
||||
Hook B: "I need to talk about this app..."
|
||||
Hook C: "Why is nobody talking about this?"
|
||||
Hook D: "POV: you just found [app name]"
|
||||
Hook E: "[Stat] people already switched to this"
|
||||
```
|
||||
|
||||
The Research Agent identifies which hook angles are trending. The Video Ad Specialist generates all variations. You approve the batch.
|
||||
|
||||
### What Makes People Download (Ranked by Impact)
|
||||
|
||||
1. **Show the app in action** — screen recordings / animated mockups of the actual UI
|
||||
2. **Lead with the problem, not the product** — "Your [problem] is about to be solved"
|
||||
3. **Social proof** — download numbers, ratings, testimonials, "as seen in"
|
||||
4. **Urgency without being salesy** — "just launched", "early access", "free for now"
|
||||
5. **Platform-native feel** — looks like organic content, not an ad
|
||||
|
||||
---
|
||||
|
||||
## The 7-Agent Autonomous System
|
||||
|
||||
Here's your expanded pipeline. The original video used 5 agents. You need 7 for a truly autonomous system:
|
||||
|
||||
### Agent 1: Trend Scout (NEW)
|
||||
```
|
||||
Runs: Daily or every few days (automated via cron)
|
||||
Does: Monitors trending content, competitor ads, viral hooks
|
||||
Tools: Tavily AI + Exa AI for semantic search
|
||||
Output: trend_report.json with:
|
||||
- Trending hooks on TikTok/Instagram this week
|
||||
- Competitor ad angles (what's working for similar apps)
|
||||
- Emerging content formats/sounds
|
||||
- Recommended content themes for next batch
|
||||
```
|
||||
|
||||
### Agent 2: Research & Strategy Agent
|
||||
```
|
||||
Runs: Per campaign
|
||||
Does: Deep research on specific campaign topic
|
||||
Tools: Tavily AI (5 targeted queries)
|
||||
Output: research_results.json + research_brief.md + interactive_report.html
|
||||
- Market data, audience insights
|
||||
- Content topics, marketing angles, keywords
|
||||
- Video concepts (mapped to Video Agent input format)
|
||||
- Ad hooks ranked by predicted scroll-stop rate
|
||||
```
|
||||
|
||||
### Agent 3: Script Writer (NEW)
|
||||
```
|
||||
Runs: Per campaign
|
||||
Does: Writes ad scripts from research output
|
||||
Tools: Knowledge files only
|
||||
Output: scripts/ folder with:
|
||||
- 5 hook variations per concept
|
||||
- Full scene-by-scene scripts (hook/body/CTA timed)
|
||||
- Platform-adapted versions (polished for IG, raw for TikTok, local for Nextdoor)
|
||||
- Voiceover text (if using HeyGen/Arcads)
|
||||
```
|
||||
|
||||
### Agent 4: Ad Creative Designer (Static)
|
||||
```
|
||||
Runs: Per campaign
|
||||
Does: Generates static image ads
|
||||
Tools: NanoBanana MCP + Playwright
|
||||
Output: ads/ folder with platform-specific PNGs:
|
||||
- instagram_feed_1080x1080.png
|
||||
- instagram_stories_1080x1920.png
|
||||
- nextdoor_spotlight_1200x1200.png
|
||||
- nextdoor_display_1200x628.png
|
||||
- Multiple variations per format (different hooks/visuals)
|
||||
```
|
||||
|
||||
### Agent 5: Video Ad Producer
|
||||
```
|
||||
Runs: Per campaign
|
||||
Does: Creates video ads from scripts
|
||||
Tools: Remotion (motion graphics) + optionally HeyGen/Arcads (UGC-style)
|
||||
Output: video/ folder with:
|
||||
- instagram_reel_1080x1920.mp4 (polished style)
|
||||
- tiktok_ad_1080x1920.mp4 (authentic style)
|
||||
- nextdoor_video_1080x1080.mp4 (local/warm style)
|
||||
- scene_plan.json per video
|
||||
- 3-5 hook variations per platform
|
||||
```
|
||||
|
||||
### Agent 6: Copywriter Agent
|
||||
```
|
||||
Runs: Per campaign
|
||||
Does: Writes all text/captions
|
||||
Tools: Knowledge files + research output
|
||||
Output: copy/ folder with:
|
||||
- instagram_captions.json (multiple variations)
|
||||
- tiktok_captions.json (with trending hashtags)
|
||||
- nextdoor_posts.json (neighborly tone, no hashtags)
|
||||
- copy_matrix.json (all variations mapped to all creatives)
|
||||
```
|
||||
|
||||
### Agent 7: Distribution Agent
|
||||
```
|
||||
Runs: Per campaign (after your approval)
|
||||
Does: Uploads media + publishes
|
||||
Tools: Postiz API (Instagram + TikTok) + Nextdoor API (direct)
|
||||
Output:
|
||||
- media_urls.json (Supabase public URLs)
|
||||
- Publish_{campaign}_{date}.md (the manifest YOU review)
|
||||
- Published post IDs per platform
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Your Daily/Weekly Workflow
|
||||
|
||||
### Automated (No Action from You)
|
||||
|
||||
```
|
||||
Every 2-3 days:
|
||||
┌─ Trend Scout runs automatically (cron/scheduled)
|
||||
│ Scans trending hooks, competitor ads, viral formats
|
||||
│ Saves trend_report.json
|
||||
└─ You get a Slack/email notification: "New trend report ready"
|
||||
```
|
||||
|
||||
### Semi-Automated (You Trigger, System Executes)
|
||||
|
||||
```
|
||||
When you're ready to create content:
|
||||
|
||||
Step 1: You type ONE prompt into Claude Code:
|
||||
"Create a campaign batch for [app feature X].
|
||||
Target: app downloads.
|
||||
Platforms: Instagram, TikTok, Nextdoor.
|
||||
Variations: 5 hooks per platform.
|
||||
Use latest trend report."
|
||||
|
||||
Step 2: System runs autonomously (~15-20 minutes):
|
||||
Research Agent → market insights, hooks (~2 min)
|
||||
Script Writer → 15 ad scripts (5 per platform) (~3 min)
|
||||
Ad Creative → 8-10 static ad variants (~3 min)
|
||||
Video Producer → 5-8 video variants (~5 min)
|
||||
Copywriter → captions for all variants (~2 min)
|
||||
Distribution Agent → uploads to Supabase, writes Publish MD (~2 min)
|
||||
|
||||
Step 3: YOU review the Publish MD manifest:
|
||||
- Preview all creatives in outputs/ folder
|
||||
- Check copy for each platform
|
||||
- See recommended posting schedule
|
||||
- Approve, reject, or request changes
|
||||
|
||||
Step 4: You say "Publish" → system posts everything via Postiz + Nextdoor API
|
||||
```
|
||||
|
||||
### What You're Actually Doing
|
||||
|
||||
| Task | Time | Frequency |
|
||||
|------|------|-----------|
|
||||
| Review trend reports | 5 min | Every few days |
|
||||
| Write campaign trigger prompt | 2 min | Per campaign |
|
||||
| Review outputs + approve/reject | 10-15 min | Per campaign |
|
||||
| **Total time per campaign** | **~20 min** | — |
|
||||
|
||||
Everything else — research, scripting, design, video production, copywriting, scheduling, publishing — is handled by the agents.
|
||||
|
||||
---
|
||||
|
||||
## The Job Payload (What You Actually Type)
|
||||
|
||||
Here's a real example of what triggers a full campaign:
|
||||
|
||||
```
|
||||
Create a campaign batch for our app's new [feature name].
|
||||
|
||||
Campaign goal: Drive app downloads
|
||||
Target audience: [your audience]
|
||||
Platforms: Instagram (Reels + Feed), TikTok, Nextdoor
|
||||
|
||||
Content requirements:
|
||||
- Use the latest trend report for hook inspiration
|
||||
- 5 hook variations per platform
|
||||
- Static ads: Instagram feed (1080x1080) + Nextdoor spotlight (1200x1200)
|
||||
- Video ads: Instagram Reel (9:16, polished) + TikTok (9:16, authentic/raw)
|
||||
- Nextdoor: static image ad only (local/warm tone)
|
||||
|
||||
Key message: [What problem does this feature solve?]
|
||||
Social proof: [Download count, rating, press mentions]
|
||||
CTA: "Download free" / "Try it now"
|
||||
|
||||
Safety: dry_run: false, publish via Postiz for IG/TikTok
|
||||
Output: outputs/[feature_name]_campaign_[date]/
|
||||
```
|
||||
|
||||
That's it. One prompt. The system handles the rest.
|
||||
|
||||
---
|
||||
|
||||
## The Content Machine: What Gets Produced Per Campaign
|
||||
|
||||
| Asset | Quantity | Platforms |
|
||||
|-------|----------|-----------|
|
||||
| Static image ads | 6-10 variants | Instagram Feed, Nextdoor |
|
||||
| Video ads (motion graphic) | 5-8 variants | Instagram Reels, TikTok |
|
||||
| Video ads (UGC-style) | 3-5 variants (if HeyGen/Arcads added) | TikTok, Instagram Stories |
|
||||
| Captions | 1 per creative per platform | All |
|
||||
| Hashtag sets | 3-5 per platform | Instagram, TikTok |
|
||||
| Research report | 1 interactive HTML dashboard | Internal use |
|
||||
| Publish manifest | 1 per campaign | Internal review |
|
||||
| **Total assets per campaign** | **~20-30 pieces** | — |
|
||||
|
||||
---
|
||||
|
||||
## Making Ads That Actually Drive Downloads
|
||||
|
||||
### The Three Ad Types That Convert for Apps
|
||||
|
||||
**Type 1: Problem-Solution (Highest conversion for cold audiences)**
|
||||
```
|
||||
Scene 1: "Still [doing painful thing]?" (3s)
|
||||
Scene 2: Show the frustration visually (3s)
|
||||
Scene 3: "There's an app for that." + app UI demo (5s)
|
||||
Scene 4: "[X]K downloads. 4.8★ rated." (3s)
|
||||
Scene 5: "Download free — link in bio" + app store badge (3s)
|
||||
```
|
||||
|
||||
**Type 2: UGC/Testimonial (Highest trust signal)**
|
||||
```
|
||||
AI avatar or screen recording:
|
||||
"Okay I HAVE to share this app with you guys..."
|
||||
"I've been using [app] for 2 weeks and honestly..."
|
||||
[Shows app in use]
|
||||
"It completely changed how I [benefit]"
|
||||
"Link in bio, you'll thank me later"
|
||||
```
|
||||
|
||||
**Type 3: Trend-Jacking (Highest organic reach on TikTok)**
|
||||
```
|
||||
Use a trending sound/format
|
||||
Adapt it to your app's value prop
|
||||
"When [trending format] but you have [your app]"
|
||||
Keep it under 15 seconds
|
||||
CTA in caption only (not in video)
|
||||
```
|
||||
|
||||
### Platform-Specific Creative Rules
|
||||
|
||||
| Rule | Instagram | TikTok | Nextdoor |
|
||||
|------|-----------|--------|----------|
|
||||
| **First 3 seconds** | Hook with motion | Hook with text overlay | Headline in image |
|
||||
| **Sound** | Optional (80% watch muted) | Required (93% use sound) | N/A (mostly static) |
|
||||
| **Style** | Polished, branded | Raw, authentic, creator-feel | Warm, local, neighborly |
|
||||
| **CTA** | "Link in bio" / "Shop Now" | "Link in bio" / soft CTA | "Learn More" / "Visit Us" |
|
||||
| **Hashtags** | 3-5 required | 3-5 trending + niche | None |
|
||||
| **Length (video)** | 15-30s | 9-15s sweet spot | ≤30s |
|
||||
| **Text on screen** | Minimal, clean | Bold, large, ≤6 words/frame | Clear headline |
|
||||
| **What wins** | Aesthetic + value | Entertainment + authenticity | Trust + local relevance |
|
||||
|
||||
---
|
||||
|
||||
## Recommended Phased Rollout
|
||||
|
||||
### Phase 1: Foundation (Week 1)
|
||||
- [ ] Set up project structure (folders, knowledge files, CLAUDE.md)
|
||||
- [ ] Write brand_identity.md, platform_guidelines.md, product_campaign.md
|
||||
- [ ] Install tools: Remotion, Playwright, Tavily, NanoBanana MCP
|
||||
- [ ] Set up Supabase bucket + API keys (Instagram, TikTok)
|
||||
- [ ] Apply for Nextdoor Ads API partnership
|
||||
- [ ] Create the "Ultimate Skills Framework" doc
|
||||
|
||||
### Phase 2: Build Agents (Week 2)
|
||||
- [ ] Build + test Research Agent individually
|
||||
- [ ] Build + test Script Writer individually
|
||||
- [ ] Build + test Ad Creative Designer individually
|
||||
- [ ] Build + test Video Ad Producer individually
|
||||
- [ ] Build + test Copywriter Agent individually
|
||||
- [ ] Build + test Distribution Agent individually
|
||||
- [ ] Update CLAUDE.md with all agents
|
||||
|
||||
### Phase 3: Connect Pipeline (Week 3)
|
||||
- [ ] Wire up the full pipeline (single job payload → all agents in sequence)
|
||||
- [ ] Set up Postiz (self-hosted or cloud) for Instagram + TikTok publishing
|
||||
- [ ] Connect Nextdoor API directly
|
||||
- [ ] Run first dry-run campaign end-to-end
|
||||
- [ ] Review outputs, refine skills based on quality
|
||||
|
||||
### Phase 4: Go Live (Week 4)
|
||||
- [ ] Run first real campaign with live publishing
|
||||
- [ ] Set up Trend Scout on automated schedule
|
||||
- [ ] Set up token refresh automation (TikTok daily, Instagram 60-day)
|
||||
- [ ] Establish your review rhythm (approve batches 2-3x/week)
|
||||
|
||||
### Phase 5: Scale (Ongoing)
|
||||
- [ ] Add HeyGen or Arcads for UGC-style video ads
|
||||
- [ ] Add Creatomate for template-based video batch generation
|
||||
- [ ] Build A/B testing feedback loop (which hooks win → feed back to Research Agent)
|
||||
- [ ] Add more platforms as needed (YouTube, Threads, LinkedIn)
|
||||
|
||||
---
|
||||
|
||||
## Summary: Your Marketing Team
|
||||
|
||||
| Role | Agent | Runs Autonomously? |
|
||||
|------|-------|--------------------|
|
||||
| Trend Analyst | Trend Scout | Yes (scheduled) |
|
||||
| Market Researcher | Research Agent | Yes (per campaign) |
|
||||
| Creative Director / Scriptwriter | Script Writer | Yes (per campaign) |
|
||||
| Graphic Designer | Ad Creative Designer | Yes (per campaign) |
|
||||
| Video Producer | Video Ad Producer | Yes (per campaign) |
|
||||
| Copywriter | Copywriter Agent | Yes (per campaign) |
|
||||
| Social Media Manager | Distribution Agent + Postiz | Yes (after your approval) |
|
||||
| **Marketing Director** | **You** | **Approve/reject only** |
|
||||
|
||||
Sources:
|
||||
- [TikTok Ads Complete Guide 2026](https://creatify.ai/blog/tiktok-ads-complete-guide-to-creating-high-performing-creatives-in-2026)
|
||||
- [12 Proven Ad Creative Frameworks 2026](https://www.modernmarketinginstitute.com/blog/12-proven-frameworks-for-building-high-roi-ad-creative-that-converts-in-2026)
|
||||
- [Hook Rate to Hold Rate Guide](https://getkoro.app/blog/koro-hook-rate-to-hold-rate)
|
||||
- [UGC Video Guide 2026](https://getkoro.app/blog/ugc-video-guide-2026)
|
||||
- [Hook Stacking Strategy](https://ugcsocial.substack.com/p/hook-stacking-the-secret-to-longer)
|
||||
- [Hook-Body-CTA Video Editor Guide](https://sovran.ai/blog/hook-body-cta-video-editor-the-ultimate-guide-to-creating-high-converting-video-ads-in-2025)
|
||||
- [Remotion Fundamentals](https://www.remotion.dev/docs/the-fundamentals)
|
||||
- [HeyGen UGC Avatars](https://www.heygen.com/avatars/ugc)
|
||||
- [MakeUGC](https://www.makeugc.ai/)
|
||||
- [Best AI UGC Generators 2026](https://videoai.me/blog/best-ai-ugc-generators-2026)
|
||||
@@ -0,0 +1,768 @@
|
||||
# Best Practices Guide: Building an AI Marketing Pipeline with Claude Code
|
||||
|
||||
**Purpose:** A comprehensive reference for building a multi-agent marketing content system using Claude Code skills. Synthesized from the AndyNoCode video analysis, official Anthropic documentation, open-source projects, and industry best practices.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Architecture Overview](#1-architecture-overview)
|
||||
2. [Project Structure & CLAUDE.md](#2-project-structure--claudemd)
|
||||
3. [Knowledge Files — The Brand Brain](#3-knowledge-files--the-brand-brain)
|
||||
4. [Skill Authoring Best Practices](#4-skill-authoring-best-practices)
|
||||
5. [Agent Design — The 5-Agent Pipeline](#5-agent-design--the-5-agent-pipeline)
|
||||
6. [Tool Integrations & Setup](#6-tool-integrations--setup)
|
||||
7. [Inter-Agent Communication](#7-inter-agent-communication)
|
||||
8. [Publishing & Distribution](#8-publishing--distribution)
|
||||
9. [Testing & Iteration](#9-testing--iteration)
|
||||
10. [Cost Optimization](#10-cost-optimization)
|
||||
11. [Security & Secrets Management](#11-security--secrets-management)
|
||||
12. [Alternative Frameworks & Comparisons](#12-alternative-frameworks--comparisons)
|
||||
13. [Key Resources & Sources](#13-key-resources--sources)
|
||||
|
||||
---
|
||||
|
||||
## 1. Architecture Overview
|
||||
|
||||
### The Pipeline Pattern
|
||||
|
||||
The most effective architecture for AI marketing systems is a **sequential pipeline** where each agent has a single responsibility and passes structured output to the next:
|
||||
|
||||
```
|
||||
Research → Creative (Static + Video) → Copy → Distribution
|
||||
```
|
||||
|
||||
This maps to the "Pipeline/Sequential" multi-agent pattern documented across industry best practices. Each agent:
|
||||
- Has a dedicated SKILL.md defining its behavior
|
||||
- Reads from shared knowledge files for brand consistency
|
||||
- Outputs machine-readable structured data (JSON) for downstream agents
|
||||
- Operates within a gate-protected publishing workflow
|
||||
|
||||
### Why Claude Code Skills (vs. Other Frameworks)
|
||||
|
||||
| Approach | Strengths | Weaknesses |
|
||||
|----------|-----------|------------|
|
||||
| **Claude Code Skills** | Native integration, progressive disclosure, low overhead, SKILL.md standard works across tools | Tied to Claude ecosystem, token-based costs |
|
||||
| **CrewAI** | Python-native, good for complex delegation, 600+ inbound leads case study | Heavier setup, separate runtime |
|
||||
| **LangGraph** | Flexible graph-based orchestration, good for complex routing | More complex, steeper learning curve |
|
||||
| **AutoGen** | Multi-model support, conversation-based | More enterprise-focused, complex config |
|
||||
|
||||
**Recommendation:** For a marketing pipeline, Claude Code skills offer the simplest path because the skills are just markdown files, they load progressively (saving tokens), and they integrate directly with the IDE and terminal. Use CrewAI or LangGraph if you need more complex agent delegation patterns or multi-model support.
|
||||
|
||||
---
|
||||
|
||||
## 2. Project Structure & CLAUDE.md
|
||||
|
||||
### Recommended Folder Structure
|
||||
|
||||
```
|
||||
your-brand/
|
||||
├── .claude/ # Claude Code configuration
|
||||
├── assets/ # Creative references (mood board)
|
||||
│ ├── logo.png
|
||||
│ ├── product-hero.png
|
||||
│ └── lifestyle-shots/
|
||||
├── knowledge/ # Brand brain — the 3 essential files
|
||||
│ ├── brand_identity.md
|
||||
│ ├── platform_guidelines.md
|
||||
│ └── product_campaign.md
|
||||
├── outputs/ # All generated content (per-campaign)
|
||||
│ └── {task_name}_{date}/
|
||||
│ ├── ads/
|
||||
│ ├── copy/
|
||||
│ ├── video/
|
||||
│ └── Publish {task_name} {date}.md
|
||||
├── pipeline/ # Automation scripts
|
||||
│ └── publish_now.js
|
||||
├── remotion-ad/ # Remotion video project
|
||||
│ ├── src/
|
||||
│ └── package.json
|
||||
├── skills/ # All agent skills
|
||||
│ ├── marketing-research-agent/
|
||||
│ │ └── SKILL.md
|
||||
│ ├── ad-creative-designer/
|
||||
│ │ └── SKILL.md
|
||||
│ ├── video-ad-specialist/
|
||||
│ │ └── SKILL.md
|
||||
│ ├── copywriter-agent/
|
||||
│ │ └── SKILL.md
|
||||
│ └── distribution-agent/
|
||||
│ └── SKILL.md
|
||||
├── .env # Real API keys (gitignored)
|
||||
├── .env.example # Template for collaborators
|
||||
├── .gitignore
|
||||
├── CLAUDE.md # Project source of truth
|
||||
├── package.json
|
||||
└── Ultimate Claude Skills & Plugins Prompt.md # Skill creation framework
|
||||
```
|
||||
|
||||
### CLAUDE.md — The Source of Truth
|
||||
|
||||
Your CLAUDE.md is the most important file. It tells Claude what the project is, how folders are structured, what files are available, and what rules to follow. Without it, Claude is just guessing.
|
||||
|
||||
**Best practices from official docs:**
|
||||
- A well-structured CLAUDE.md with module boundaries reduces per-agent exploration costs significantly
|
||||
- Include a **sub-agent routing decision framework** specifying when to use parallel vs. sequential dispatch
|
||||
- Keep it focused — don't duplicate what's in knowledge files
|
||||
|
||||
**Recommended CLAUDE.md structure:**
|
||||
|
||||
```markdown
|
||||
# Project Overview
|
||||
This project implements an AI-powered Social Media Content Automation System.
|
||||
The system uses five specialized AI agents to research, generate, render, and
|
||||
distribute marketing content for [YOUR BRAND].
|
||||
|
||||
# System Architecture
|
||||
Five agents running in sequence:
|
||||
1. Marketing Research Agent — web research via Tavily
|
||||
2. Ad Creative Designer — static ads via NanoBanana + Playwright
|
||||
3. Video Ad Specialist — video ads via Remotion
|
||||
4. Copywriter Agent — platform-specific copy
|
||||
5. Distribution Agent — Supabase upload + API publishing
|
||||
|
||||
# Folder Structure
|
||||
- assets/ — brand images, logos, product shots (mood board)
|
||||
- knowledge/ — brand identity, platform guidelines, product/campaign info
|
||||
- skills/ — all 5 agent skills (each has SKILL.md)
|
||||
- outputs/ — generated content per campaign
|
||||
- pipeline/ — publishing automation scripts
|
||||
- remotion-ad/ — Remotion video project
|
||||
|
||||
# Knowledge Files (READ FIRST)
|
||||
Every agent MUST read these before generating ANY content:
|
||||
- knowledge/brand_identity.md — tone, voice, personality, CTA patterns
|
||||
- knowledge/platform_guidelines.md — per-platform specs and formatting
|
||||
- knowledge/product_campaign.md — product details, features, campaign direction
|
||||
|
||||
# Pipeline Execution Order
|
||||
research → static_ad → video_ad → copywriting → distribution
|
||||
|
||||
# Output Convention
|
||||
outputs/{task_name}_{YYYYMMDD}/
|
||||
├── ads/ (static ad files)
|
||||
├── copy/ (platform-specific copy)
|
||||
├── video/ (Remotion output)
|
||||
└── Publish {task_name} {date}.md
|
||||
|
||||
# Safety Rules
|
||||
- No live API posting without explicit user approval
|
||||
- Distribution agent uses gate-protected publishing
|
||||
- All media must be uploaded to Supabase before Instagram API calls
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Knowledge Files — The Brand Brain
|
||||
|
||||
### Why This Matters
|
||||
|
||||
The #1 differentiator between generic AI output and on-brand content is knowledge files. Every agent reads these before generating anything. This is the "CRITICAL: Before Generating" pattern used in the AndyNoCode system.
|
||||
|
||||
**From the official best practices:** "Only add context Claude doesn't already have. Challenge each piece: Does Claude really need this explanation?"
|
||||
|
||||
### brand_identity.md (~100-150 lines)
|
||||
|
||||
**Purpose:** Personality, tone, voice, CTA patterns, emoji/hashtag strategy.
|
||||
|
||||
**Template structure:**
|
||||
```markdown
|
||||
# Brand Identity: [Your Brand]
|
||||
|
||||
## 1. Brand Personality
|
||||
[2-3 sentences defining the brand's character]
|
||||
|
||||
Core traits:
|
||||
- [Trait 1 with description]
|
||||
- [Trait 2]
|
||||
- [Trait 3]
|
||||
- [Trait 4]
|
||||
|
||||
## 2. Tone & Voice
|
||||
| Attribute | Guidance |
|
||||
|-----------|----------|
|
||||
| Register | [Casual/Formal/etc.] |
|
||||
| Energy | [Upbeat/Measured/etc.] |
|
||||
| Humor | [Level and guidelines] |
|
||||
| Confidence| [How assertive] |
|
||||
| Length | [Sentence/paragraph style] |
|
||||
|
||||
Write like this: "[Example of good copy]"
|
||||
Not like this: "[Example of bad copy]"
|
||||
|
||||
## 3. CTA Patterns
|
||||
- Always start CTAs with action verbs
|
||||
- Approved CTAs: [list]
|
||||
- Never use: [list]
|
||||
|
||||
## 4. Emoji Usage
|
||||
- Approved emojis: [list with usage context]
|
||||
- Max per post: [number]
|
||||
|
||||
## 5. Hashtag Strategy
|
||||
- Primary hashtags (always include): [list]
|
||||
- Secondary (rotate): [list]
|
||||
- Never use: [list]
|
||||
```
|
||||
|
||||
### platform_guidelines.md (~100-150 lines)
|
||||
|
||||
**Purpose:** Per-platform formatting specs, tone adjustments, dimension requirements.
|
||||
|
||||
**Template structure:**
|
||||
```markdown
|
||||
# Platform Guidelines: [Your Brand]
|
||||
|
||||
## 1. Platform Overview
|
||||
| Platform | Content Type | Primary Tone | Hashtags |
|
||||
|----------|-------------|--------------|----------|
|
||||
| Instagram | Image posts, Stories, Reels | [tone] | Required (3-5) |
|
||||
| YouTube | Long & short video | [tone] | Via tags/description |
|
||||
| Threads | Short text posts | [tone] | Optional |
|
||||
|
||||
## 2. Instagram
|
||||
### Specs
|
||||
| Format | Dimensions | Aspect Ratio |
|
||||
|--------|-----------|--------------|
|
||||
| Feed Post | 1080x1080 px | 1:1 |
|
||||
| Story | 1080x1920 px | 9:16 |
|
||||
| Reel | 1080x1920 px | 9:16 |
|
||||
|
||||
### Caption Guidelines
|
||||
- Length: [rules]
|
||||
- Structure: Hook + Value + CTA + line break + Hashtags
|
||||
- Emojis: [rules]
|
||||
|
||||
## 3. YouTube
|
||||
### Specs
|
||||
[dimensions, thumbnail specs, description format]
|
||||
|
||||
### Metadata
|
||||
- Title format: [pattern]
|
||||
- Description structure: [pattern]
|
||||
- Tags: [strategy]
|
||||
|
||||
## 4. Threads
|
||||
### Specs
|
||||
- Text only (images optional), 500 char max
|
||||
### Tone
|
||||
- Most conversational platform — witty, punchy
|
||||
```
|
||||
|
||||
### product_campaign.md (~150-200 lines)
|
||||
|
||||
**Purpose:** Product details, selling points, visual references, campaign direction.
|
||||
|
||||
```markdown
|
||||
# Product & Campaign Knowledge: [Your Brand]
|
||||
|
||||
## 1. Product Overview
|
||||
| Attribute | Details |
|
||||
|-----------|---------|
|
||||
| Product Name | [name] |
|
||||
| Format | [type] |
|
||||
| Target Audience | [segments] |
|
||||
| Brand Positioning | [statement] |
|
||||
|
||||
## 2. Product Features
|
||||
[Table of features with descriptions — the "product truths" all content must reference]
|
||||
|
||||
## 3. Campaign Direction
|
||||
[Current campaign goals, messaging themes, visual direction]
|
||||
|
||||
## 4. Visual Asset References
|
||||
[List of available assets in assets/ folder and when to use each]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Skill Authoring Best Practices
|
||||
|
||||
### Official Anthropic Guidelines (Key Points)
|
||||
|
||||
**From the [official skill authoring docs](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices):**
|
||||
|
||||
1. **Concise is key** — The context window is a shared resource. Only add what Claude doesn't already know.
|
||||
2. **Keep SKILL.md under 500 lines** — Move detailed reference to separate files.
|
||||
3. **Description is critical** — Claude decides whether to load a skill based ONLY on the description. Write in third person. Include what it does AND when to use it AND trigger phrases.
|
||||
4. **Max 1024 characters** for description field.
|
||||
5. **Progressive disclosure** — Metadata (always loaded, ~100 words) → SKILL.md body (loaded when relevant) → Supporting files (loaded on demand).
|
||||
6. **No angle brackets** `< >` in frontmatter (security).
|
||||
7. **Test with multiple models** — What works for Opus may need more detail for Haiku/Sonnet.
|
||||
8. **Build evaluations BEFORE writing docs** — Identify real gaps, don't document imagined ones.
|
||||
|
||||
### SKILL.md Template for Marketing Agents
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: your-agent-name
|
||||
description: >
|
||||
[What it does] + [When to use it] + [Specific trigger phrases].
|
||||
Use when the user asks to [action 1], [action 2], or says
|
||||
"[trigger phrase 1]", "[trigger phrase 2]", "[trigger phrase 3]".
|
||||
Always use this skill when [condition] for [Your Brand].
|
||||
---
|
||||
|
||||
# [Agent Name]
|
||||
|
||||
[One-line description of what this agent produces.]
|
||||
|
||||
## CRITICAL: Before Generating — Read Knowledge Files
|
||||
|
||||
Always reference these files before producing any output:
|
||||
- knowledge/brand_identity.md — tone, voice, CTA patterns
|
||||
- knowledge/platform_guidelines.md — platform specs and formatting
|
||||
- knowledge/product_campaign.md — product features, campaign direction
|
||||
|
||||
## Step 1: Gather Inputs
|
||||
|
||||
| Input | Example |
|
||||
|-------|---------|
|
||||
| [Input 1] | [Example] |
|
||||
| [Input 2] | [Example] |
|
||||
|
||||
If inputs are missing, apply defaults from knowledge files.
|
||||
|
||||
## Step 2: [Core Processing]
|
||||
[Detailed step instructions]
|
||||
|
||||
## Step 3: [Generation/Output]
|
||||
[What to produce and in what format]
|
||||
|
||||
## Step 4: [Validation]
|
||||
[Quality checks before completion]
|
||||
|
||||
## Output Convention
|
||||
All outputs saved to: outputs/{task_name}_{date}/[subfolder]/
|
||||
|
||||
## Troubleshooting
|
||||
- [Common issue 1]: [Solution]
|
||||
- [Common issue 2]: [Solution]
|
||||
|
||||
## Quality Checklist
|
||||
- [ ] Knowledge files read before generation
|
||||
- [ ] Output matches brand voice
|
||||
- [ ] Platform specs followed
|
||||
- [ ] Files saved to correct output path
|
||||
- [ ] Handoff summary provided for next agent
|
||||
```
|
||||
|
||||
### The "Ultimate Skills Framework" Approach
|
||||
|
||||
The video uses a 601-line "Ultimate Claude Skills & Plugins Prompt.md" as the meta-framework for creating all skills. Key elements:
|
||||
|
||||
1. **Plan first with Claude** — Use Claude chat (Sonnet is fine) to brainstorm skill details via interactive Q&A
|
||||
2. **Draft key details** — Purpose, inputs, outputs, workflow, trigger phrases
|
||||
3. **Build in Claude Code** — "Help me create an agent skill. Use @'Ultimate Skills Prompt.md' to create it. Key details: [paste]"
|
||||
4. **Claude builds the SKILL.md** following the framework
|
||||
5. **Test individually** before connecting to the pipeline
|
||||
|
||||
---
|
||||
|
||||
## 5. Agent Design — The 5-Agent Pipeline
|
||||
|
||||
### Agent 1: Marketing Research Agent
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| SKILL.md | ~146 lines |
|
||||
| Tool | Tavily AI (`@tavily/core`) |
|
||||
| Input | Niche/topic, audience, campaign goal |
|
||||
| Output | `research_results.json`, `research_brief.md`, `interactive_report.html` |
|
||||
|
||||
**5 Tavily queries:** trends, competitors, pain points, ad hooks, viral content
|
||||
|
||||
**Output JSON structure:**
|
||||
```json
|
||||
{
|
||||
"content_topics": [...],
|
||||
"marketing_angles": [...],
|
||||
"keywords": [...],
|
||||
"video_concepts": [...],
|
||||
"ad_hooks": [...]
|
||||
}
|
||||
```
|
||||
|
||||
**Best practice:** The `video_concepts` objects should map directly to the Video Ad Specialist's input format. Design your inter-agent JSON schema upfront.
|
||||
|
||||
### Agent 2: Ad Creative Designer
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| SKILL.md | ~191-331 lines |
|
||||
| Tools | NanoBanana MCP (image gen) + Playwright (screenshot) |
|
||||
| Input | Campaign brief, brand assets |
|
||||
| Output | `ad_layout.json`, `ad.html`, `styles.css`, `instagram_ad.png` |
|
||||
|
||||
**Three-step workflow: Generate → Design → Capture**
|
||||
1. Call NanoBanana MCP to generate images using brand knowledge as reference
|
||||
2. Design HTML/CSS layout (1080x1080 for Instagram, with typography scale: 72px headline, 36px subtext, 12px CTA)
|
||||
3. Launch Playwright headless Chromium → screenshot at exact dimensions → save as PNG
|
||||
|
||||
**Layout types:** Product Focus, Split, Lifestyle
|
||||
|
||||
**Copy constraints:** Headline 3-4 words, CTA starts with action verb, Stories safe zone (no text in top/bottom 15%)
|
||||
|
||||
### Agent 3: Video Ad Specialist
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| SKILL.md | ~167 lines |
|
||||
| Tools | Remotion (wraps official skill) |
|
||||
| Input | Product info, campaign objective, platform, length |
|
||||
| Output | `scene_plan.json`, `video_ad.mp4` |
|
||||
|
||||
**Key design:** This skill wraps around the Remotion Best Practices official skill. The Remotion skill handles the technical craft; this skill handles brand strategy.
|
||||
|
||||
**Strategy types:** `product_showcase`, `problem_solution`, `testimonial`, `limited_offer`, `lifestyle`, `meme_style`
|
||||
|
||||
**Auto-render:** Built-in render script — finished video goes straight to outputs folder without manual Remotion Studio steps.
|
||||
|
||||
### Agent 4: Copywriter Agent
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| SKILL.md | ~261 lines |
|
||||
| Tools | Knowledge files only |
|
||||
| Input | Research results, campaign brief |
|
||||
| Output | `instagram_caption.txt`, `threads_post.txt`, `youtube_metadata.json`, `copy_output.json` |
|
||||
|
||||
**Output path:** `outputs/{task_name}_{date}/copy/`
|
||||
|
||||
### Agent 5: Distribution Agent
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| SKILL.md | ~352 lines |
|
||||
| Tools | Supabase, YouTube API, Instagram API, Threads API |
|
||||
| Input | All outputs from previous agents |
|
||||
| Output | `media_urls.json`, `Publish {task_name} {date}.md` |
|
||||
|
||||
**6-step workflow:**
|
||||
1. Gather inputs from campaign folder
|
||||
2. Upload media to Supabase (`campaign-uploads` bucket)
|
||||
3. Assemble metadata from copywriter output
|
||||
4. Generate scheduling advisory
|
||||
5. Write Publish MD manifest
|
||||
6. Execute publishing **(gate-protected — requires explicit user approval)**
|
||||
|
||||
---
|
||||
|
||||
## 6. Tool Integrations & Setup
|
||||
|
||||
### Tavily AI — Web Research
|
||||
|
||||
- **Package:** `npm install @tavily/core` (v0.7.2+)
|
||||
- **Pricing:** 1,000 free API credits/month, no credit card required
|
||||
- **Docs:** https://docs.tavily.com
|
||||
- **GitHub:** https://github.com/tavily-ai/tavily-js
|
||||
- **Setup:** Get API key from dashboard → add to `.env` as `TAVILY_API_KEY`
|
||||
|
||||
### NanoBanana MCP — Image Generation
|
||||
|
||||
- **What:** MCP server powered by Google Gemini (Nano Banana 2 / Pro) for AI image generation
|
||||
- **Cost:** ~$0.04-0.05/image (standard), ~$0.13/image (Pro/2K)
|
||||
- **GitHub:** https://github.com/YCSE/nanobanana-mcp
|
||||
- **Setup:** Configure as MCP server in Claude Code settings
|
||||
- **Key detail:** Works inside Claude conversations — Claude crafts prompts and generates images directly
|
||||
|
||||
### Remotion — Programmatic Video
|
||||
|
||||
- **Official Claude Skill:** Install via Claude Code skill marketplace
|
||||
- **Docs:** https://www.remotion.dev/docs/ai/claude-code
|
||||
- **Key APIs:** `useCurrentFrame`, `interpolate`, `spring`, `<Series.Sequence>`
|
||||
- **Auto-render:** Build render script into your skill so videos go straight to output folder
|
||||
- **Kickstart repo:** https://github.com/jhartquist/claude-remotion-kickstart
|
||||
|
||||
### Playwright — HTML to PNG
|
||||
|
||||
- **Package:** `npm install playwright`
|
||||
- **Docs:** https://playwright.dev/docs/screenshots
|
||||
- **Key pattern:**
|
||||
```javascript
|
||||
const browser = await chromium.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.setViewportSize({ width: 1080, height: 1080 });
|
||||
await page.goto(`file://${path}`, { waitUntil: 'networkidle' });
|
||||
await page.screenshot({ path: 'output.png', clip: { x: 0, y: 0, width: 1080, height: 1080 } });
|
||||
```
|
||||
|
||||
### Supabase Storage — Media Hosting
|
||||
|
||||
- **Why needed:** Instagram API requires media at publicly accessible URLs (local files won't work)
|
||||
- **Bucket:** Create `campaign-uploads` as PUBLIC bucket
|
||||
- **Auth:** Use **service role key** (not anon key) — no user session in server-side pipeline
|
||||
- **File naming:** `{task_name}_{date}_{filename}_{timestamp}.{ext}`
|
||||
- **Docs:** https://supabase.com/docs/guides/storage
|
||||
|
||||
### YouTube Data API v3
|
||||
|
||||
- **Setup:** Google Cloud Console → enable YouTube Data API v3 → create OAuth 2.0 credentials
|
||||
- **4 env vars:** `YOUTUBE_API_KEY` (read-only), `YOUTUBE_CLIENT_ID`, `YOUTUBE_CLIENT_SECRET`, `YOUTUBE_REFRESH_TOKEN`
|
||||
- **Upload method:** `youtube.videos.insert()` via `googleapis` npm package
|
||||
- **Docs:** https://developers.google.com/youtube/v3/quickstart/nodejs
|
||||
|
||||
### Instagram Graph API
|
||||
|
||||
- **Flow:** Create container → wait for FINISHED status → publish container
|
||||
- **Permissions:** `instagram_business_basic` + `instagram_business_content_publish`
|
||||
- **Token expiry:** Long-lived tokens expire after **60 days** — implement refresh logic
|
||||
- **Requirement:** Only Business/Creator accounts (Personal not supported)
|
||||
- **Rate limit:** 200 requests/hour/account
|
||||
- **Docs:** https://developers.facebook.com/docs/instagram-platform
|
||||
|
||||
### Threads API
|
||||
|
||||
- **Status:** Fully available since June 2024, enhanced July 2025 with polls/location/webhooks
|
||||
- **Endpoints:** `/v1.0/{user_id}/threads` (create) → `/v1.0/{user_id}/threads_publish` (publish)
|
||||
- **2026 additions:** GIF support (Feb 2026), oEmbed without token (Mar 2026)
|
||||
- **Docs:** https://developers.facebook.com/docs/threads/posts/
|
||||
|
||||
---
|
||||
|
||||
## 7. Inter-Agent Communication
|
||||
|
||||
### JSON as the Handoff Protocol
|
||||
|
||||
**Critical insight from industry research:** Most "agent failures" are orchestration and context-transfer issues at handoff points, not model capability failures.
|
||||
|
||||
**Best practice:** Design your inter-agent JSON schema upfront. Each agent outputs structured data that downstream agents consume directly — no reformatting needed.
|
||||
|
||||
```
|
||||
Research Agent → research_results.json
|
||||
↓ consumed by
|
||||
Ad Creative Designer (reads marketing_angles, ad_hooks)
|
||||
Video Ad Specialist (reads video_concepts — maps directly to input format)
|
||||
Copywriter Agent (reads content_topics, keywords, marketing_angles)
|
||||
↓ all outputs consumed by
|
||||
Distribution Agent (reads media files + copy outputs)
|
||||
```
|
||||
|
||||
### The Job Payload Pattern
|
||||
|
||||
Trigger the entire pipeline with a single JSON payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"task_name": "spring_campaign_2026",
|
||||
"task_date": "2026-03-22",
|
||||
"brand": "Your Brand",
|
||||
"campaign_goal": "Product launch awareness",
|
||||
"execution_order": ["research", "static_ad", "video_ad", "copywriting", "distribution"],
|
||||
"platform_targets": ["Instagram", "YouTube", "Threads"],
|
||||
"output_folder": "outputs/spring_campaign_2026_20260322",
|
||||
"safety_flags": {
|
||||
"dry_run": false,
|
||||
"simulate_uploads": false,
|
||||
"publish_immediately": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Publishing & Distribution
|
||||
|
||||
### The Gate-Protected Publishing Pattern
|
||||
|
||||
**Never auto-publish.** The distribution agent generates a `Publish MD` manifest with:
|
||||
- Public URLs for all media (from Supabase)
|
||||
- Platform-specific copy (from copywriter)
|
||||
- Metadata (titles, descriptions, tags)
|
||||
- Scheduling recommendations
|
||||
- A checklist for human review
|
||||
|
||||
**Only publish when the user explicitly approves** by naming the Publish MD file.
|
||||
|
||||
### Instagram Two-Step Flow
|
||||
|
||||
```javascript
|
||||
// Step 1: Create container
|
||||
const container = await createMediaContainer({
|
||||
image_url: supabasePublicUrl,
|
||||
caption: caption,
|
||||
access_token: process.env.INSTAGRAM_ACCESS_TOKEN
|
||||
});
|
||||
|
||||
// Step 2: Wait for FINISHED status, then publish
|
||||
await publishContainer(container.id);
|
||||
```
|
||||
|
||||
### Supabase as the Media Bridge
|
||||
|
||||
Instagram's API cannot read local files. The pipeline:
|
||||
1. Agent generates media locally
|
||||
2. Distribution agent uploads to Supabase public bucket
|
||||
3. Gets back public URL
|
||||
4. Passes public URL to Instagram/YouTube APIs
|
||||
|
||||
---
|
||||
|
||||
## 9. Testing & Iteration
|
||||
|
||||
### Test Individually First
|
||||
|
||||
From the video: test each agent in isolation before running the full pipeline. Use a cheaper model/tool for individual tests to save tokens:
|
||||
- Research agent: test with a simple niche query
|
||||
- Ad creative: test with minimal JSON inputs
|
||||
- Video: test with a basic 5-scene prompt
|
||||
- Copywriter: test with sample research output
|
||||
- Distribution: test in dry-run mode (simulate_uploads: true)
|
||||
|
||||
### Evaluation-Driven Development
|
||||
|
||||
**From official Anthropic best practices:**
|
||||
1. Run Claude on representative tasks WITHOUT a skill — document failures
|
||||
2. Create 3+ evaluation scenarios testing those gaps
|
||||
3. Measure baseline performance
|
||||
4. Write minimal SKILL.md content to address gaps
|
||||
5. Iterate: execute evals, compare to baseline, refine
|
||||
|
||||
### The Two-Claude Pattern
|
||||
|
||||
Work with "Claude A" to create/refine skills, test with "Claude B" (fresh instance):
|
||||
1. Complete task with Claude A using normal prompting
|
||||
2. Identify reusable pattern
|
||||
3. Ask Claude A to create a skill
|
||||
4. Test with Claude B on similar tasks
|
||||
5. Bring observations back to Claude A for refinement
|
||||
|
||||
---
|
||||
|
||||
## 10. Cost Optimization
|
||||
|
||||
### Token Management
|
||||
|
||||
- **Use Sonnet 4.6 for skill creation** — "not a complex task, don't need Opus"
|
||||
- **Test individual agents outside Claude Code** — use Claude.ai or alternative tools for isolated tests
|
||||
- **Progressive disclosure saves tokens** — only skill descriptions are always loaded (~100 words each), full SKILL.md only loads when relevant
|
||||
- **Agent Teams multiply tokens linearly** — 3 parallel agents ≈ 3-4x tokens of solo session
|
||||
- **Keep SKILL.md under 500 lines** — move reference material to separate files
|
||||
|
||||
### Cost Estimates
|
||||
|
||||
- **Tavily:** Free tier = 1,000 credits/month
|
||||
- **NanoBanana:** ~$0.04-0.13/image
|
||||
- **Supabase:** Free tier includes 1GB storage
|
||||
- **YouTube/Instagram/Threads APIs:** Free (with rate limits)
|
||||
- **Claude Code:** Pro subscription + token usage per pipeline run
|
||||
|
||||
---
|
||||
|
||||
## 11. Security & Secrets Management
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# .gitignore
|
||||
.env
|
||||
node_modules/
|
||||
```
|
||||
|
||||
```bash
|
||||
# .env.example (safe to commit)
|
||||
TAVILY_API_KEY=tvly-YOUR_API_KEY
|
||||
YOUTUBE_API_KEY=YOUR_KEY
|
||||
YOUTUBE_CLIENT_ID=YOUR_ID
|
||||
YOUTUBE_CLIENT_SECRET=YOUR_SECRET
|
||||
YOUTUBE_REFRESH_TOKEN=YOUR_TOKEN
|
||||
INSTAGRAM_ACCOUNT_ID=YOUR_ID
|
||||
INSTAGRAM_ACCESS_TOKEN=YOUR_TOKEN
|
||||
SUPABASE_URL=YOUR_URL
|
||||
SUPABASE_SERVICE_ROLE_KEY=YOUR_KEY
|
||||
```
|
||||
|
||||
### Supabase Service Role Key
|
||||
|
||||
- **Use service role key** for server-side automation (no user session)
|
||||
- **Never expose client-side** — bypasses Row Level Security
|
||||
- **If you add a frontend later**, switch to anon key + RLS policies
|
||||
|
||||
### Instagram Token Refresh
|
||||
|
||||
- Long-lived tokens expire after **60 days**
|
||||
- Implement automated refresh before expiry
|
||||
- Store refresh timestamps and alert when approaching expiry
|
||||
|
||||
---
|
||||
|
||||
## 12. Alternative Frameworks & Comparisons
|
||||
|
||||
### Pre-Built Marketing Skills
|
||||
|
||||
- **[marketingskills](https://github.com/coreyhaines31/marketingskills)** — 35+ marketing skills for Claude Code covering CRO, copywriting, SEO, analytics, growth engineering. Install: `npx skills add coreyhaines31/marketingskills`
|
||||
- **[claude-skills](https://github.com/alirezarezvani/claude-skills)** — 192+ skills for Claude Code covering engineering, marketing, product, compliance
|
||||
- **[awesome-agent-skills](https://github.com/VoltAgent/awesome-agent-skills)** — 500+ curated skills from official dev teams and community
|
||||
|
||||
### CrewAI Alternative
|
||||
|
||||
CrewAI offers a Python-based multi-agent framework with similar capabilities:
|
||||
- 6 specialized agents (Researcher, Writer, Editor, SEO Specialist, etc.)
|
||||
- Autonomous collaboration with delegation
|
||||
- 70% reduction in content production time
|
||||
- Built-in Ghost CMS integration for auto-publishing
|
||||
|
||||
**Best for:** Python-native teams, complex delegation patterns, when you need agents to delegate back to each other.
|
||||
|
||||
### Video Generation Alternatives
|
||||
|
||||
- **[Claude-Code-Video-Toolkit](https://github.com/wilwaldon/Claude-Code-Video-Toolkit)** — Skills, MCP servers, and tools for video production covering Remotion, Manim, screen recording, YouTube clipping, FFmpeg
|
||||
- **[claude-remotion-kickstart](https://github.com/jhartquist/claude-remotion-kickstart)** — Starter project for Claude Code + Remotion
|
||||
- **[remotion-video-skill](https://github.com/wshuyi/remotion-video-skill)** — Community Claude Code skill for Remotion
|
||||
|
||||
---
|
||||
|
||||
## 13. Key Resources & Sources
|
||||
|
||||
### Official Documentation
|
||||
- [Claude Code Skills Docs](https://code.claude.com/docs/en/skills) — complete skill creation reference
|
||||
- [Skill Authoring Best Practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) — official Anthropic guide
|
||||
- [The Complete Guide to Building Skills for Claude (PDF)](https://resources.anthropic.com/hubfs/The-Complete-Guide-to-Building-Skill-for-Claude.pdf) — Anthropic's comprehensive guide
|
||||
- [Agent Skills Overview](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) — conceptual background
|
||||
- [Anthropic Official Skills Repo](https://github.com/anthropics/skills) — including skill-creator skill
|
||||
- [Agent Teams Docs](https://code.claude.com/docs/en/agent-teams) — multi-agent orchestration
|
||||
|
||||
### Skill Marketplaces & Collections
|
||||
- [awesome-agent-skills](https://github.com/VoltAgent/awesome-agent-skills) — 500+ curated skills
|
||||
- [awesome-claude-skills](https://github.com/travisvn/awesome-claude-skills) — curated list with resources
|
||||
- [SkillsMP](https://skillsmp.com/) — Agent Skills marketplace
|
||||
- [SkillHub](https://www.skillhub.club) — Claude Skills marketplace
|
||||
- [marketingskills](https://github.com/coreyhaines31/marketingskills) — 35+ marketing-specific skills
|
||||
|
||||
### Tool Documentation
|
||||
- [Remotion + Claude Code](https://www.remotion.dev/docs/ai/claude-code) — official integration guide
|
||||
- [Remotion Agent Skills](https://www.remotion.dev/docs/ai/skills) — skill marketplace listing
|
||||
- [Tavily JS SDK](https://github.com/tavily-ai/tavily-js) — web research API
|
||||
- [Tavily Docs](https://docs.tavily.com/welcome) — full API reference
|
||||
- [NanoBanana MCP](https://github.com/YCSE/nanobanana-mcp) — Gemini-powered image generation
|
||||
- [Playwright Screenshots](https://playwright.dev/docs/screenshots) — HTML-to-image guide
|
||||
- [Supabase Storage](https://supabase.com/docs/guides/storage) — file hosting
|
||||
- [Instagram Graph API](https://developers.facebook.com/docs/instagram-platform) — content publishing
|
||||
- [YouTube Data API v3](https://developers.google.com/youtube/v3/quickstart/nodejs) — Node.js quickstart
|
||||
- [Threads API](https://developers.facebook.com/docs/threads/posts/) — posting endpoint
|
||||
|
||||
### Tutorials & Guides
|
||||
- [How to Use Claude Code for Growth Marketing Automation](https://stormy.ai/blog/claude-code-growth-marketing-automation-2026) — 2026 guide
|
||||
- [What 4 Marketers Are Building with Claude Code](https://newsletter.mkt1.co/p/real-marketers-claude-code-builds) — real-world case studies
|
||||
- [How I Use Claude to Automate Developer Marketing](https://www.strategicnerds.com/blog/automate-pmm-with-claude) — PMM automation
|
||||
- [Marketing Skills for Claude Code (Medium)](https://medium.com/coding-nexus/marketing-skills-for-claude-code-f4618e4ded5b) — skill pack overview
|
||||
- [CrewAI Blog Automation](https://christianmendieta.ca/crewai-blog-automation-building-a-multi-agent-content-creation-system-with-python/) — multi-agent content system
|
||||
- [CrewAI Marketing Research](https://dev.to/jamesli/building-an-intelligent-marketing-research-system-creating-a-multi-agent-collaboration-framework-h66) — multi-agent collaboration
|
||||
- [From Zero to YouTube Upload](https://medium.com/@dorangao/from-zero-to-first-upload-a-from-scratch-guide-to-publishing-videos-to-youtube-via-api-2025-73251a9324bd) — YouTube API guide
|
||||
- [Threads API Posting Guide](https://getlate.dev/blog/threads-posting-api) — programmatic posting
|
||||
|
||||
### Architecture & Best Practices
|
||||
- [How to Build Multi-Agent Systems (2026)](https://dev.to/eira-wexford/how-to-build-multi-agent-systems-complete-2026-guide-1io6) — complete guide
|
||||
- [Choosing the Right Multi-Agent Architecture (LangChain)](https://blog.langchain.com/choosing-the-right-multi-agent-architecture/) — pattern selection
|
||||
- [AI Agent Orchestration Patterns (Microsoft)](https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/ai-agent-design-patterns) — enterprise patterns
|
||||
- [Claude Code Best Practices](https://github.com/shanraisshan/claude-code-best-practice) — community guide
|
||||
- [Claude Code Sub-Agent Patterns](https://claudefa.st/blog/guide/agents/sub-agent-best-practices) — parallel vs sequential
|
||||
- [Claude Agent Skills Deep Dive](https://leehanchung.github.io/blogs/2025/10/26/claude-skills-deep-dive/) — first principles analysis
|
||||
- [Equipping Agents for the Real World (Anthropic)](https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills) — engineering blog
|
||||
|
||||
### Video Reference
|
||||
- [I Built a Fully Autonomous Marketing Team with Claude Code & Claude Skills](https://www.youtube.com/watch?v=iVbsl60t0oA) — AndyNoCode (source video)
|
||||
|
||||
---
|
||||
|
||||
*Guide compiled March 2026. Verify all URLs and API versions before implementation.*
|
||||
@@ -0,0 +1,832 @@
|
||||
# Marketing Command Center — Frontend Architecture
|
||||
|
||||
**What you want:** A self-hosted web dashboard where you log in, see everything your agents produced, cherry-pick ads to push to Postiz, and drop into a Claude session to give feedback — all from the browser. Everything runs in Docker. No external services except Postiz and Claude API.
|
||||
|
||||
---
|
||||
|
||||
## System Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ YOUR BROWSER │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────┐ ┌───────────────────┐ │
|
||||
│ │ Campaign │ │ Asset │ │ Claude Chat │ │
|
||||
│ │ Dashboard │ │ Gallery │ │ (feedback/edits) │ │
|
||||
│ └──────┬───────┘ └────┬─────┘ └────────┬──────────┘ │
|
||||
└─────────┼───────────────┼─────────────────┼──────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ NEXT.JS APP (Docker Container) │
|
||||
│ │
|
||||
│ API Routes: │
|
||||
│ /api/campaigns /api/assets /api/claude │
|
||||
│ /api/publish /api/agents /api/auth │
|
||||
│ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌───────────────────────┐ │
|
||||
│ │ SQLite │ │ Local │ │ Claude Agent SDK (TS) │ │
|
||||
│ │ Database │ │ File │ │ Spawns Claude Code │ │
|
||||
│ │ (Prisma) │ │ Storage │ │ as subprocess │ │
|
||||
│ └──────────┘ └──────────┘ └───────────┬───────────┘ │
|
||||
└──────────────────────────────────────────┼───────────────┘
|
||||
│
|
||||
┌──────────────────────┼──────────┐
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────┐ ┌──────────┐ ┌────────┐
|
||||
│ Postiz │ │ Tavily │ │Nextdoor│
|
||||
│ (Docker) │ │ API │ │ API │
|
||||
│ IG+TikTok│ │ Research │ │ Direct │
|
||||
│ +Media │ └──────────┘ └────────┘
|
||||
│ Hosting │
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
**Zero external services for core functionality.** Postiz and your Next.js app both run in Docker on your machine. The only outbound calls are to Tavily (research), Nextdoor API (publishing), and Anthropic (Claude).
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Technology | Why |
|
||||
|-------|-----------|-----|
|
||||
| **Framework** | Next.js 15+ (App Router) | Full-stack React, API routes, SSR |
|
||||
| **UI** | shadcn/ui + Tailwind CSS | Clean components, fast to build |
|
||||
| **Auth** | NextAuth.js (Auth.js v5) | Self-contained — credentials provider, no external auth service |
|
||||
| **Database** | SQLite via Prisma | Zero infrastructure — single file, runs in Docker volume |
|
||||
| **File Storage** | Local filesystem (Docker volume) | Pipeline outputs stored locally, Postiz handles public hosting |
|
||||
| **Claude** | Claude Agent SDK (TypeScript) | Spawn Claude sessions, stream responses |
|
||||
| **Publishing** | Postiz (@postiz/node SDK) | Media upload + hosting + scheduling + IG/TikTok publishing |
|
||||
| **Realtime** | Server-Sent Events (SSE) | Pipeline progress streaming — no Redis/WebSocket service needed |
|
||||
| **Deployment** | Docker Compose | Everything self-hosted, single `docker compose up` |
|
||||
|
||||
---
|
||||
|
||||
## Database Schema (SQLite via Prisma)
|
||||
|
||||
```prisma
|
||||
// prisma/schema.prisma
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = "file:./data/marketing.db"
|
||||
}
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
password String // bcrypt hashed
|
||||
name String?
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Campaign {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
status String @default("draft") // draft, running, review, approved, published
|
||||
prompt String? // the trigger prompt
|
||||
platforms String // JSON array: ["instagram","tiktok","nextdoor"]
|
||||
config String? // JSON: full campaign config from form
|
||||
outputPath String? // local path to outputs/
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
agentRuns AgentRun[]
|
||||
assets Asset[]
|
||||
claudeSessions ClaudeSession[]
|
||||
}
|
||||
|
||||
model AgentRun {
|
||||
id String @id @default(cuid())
|
||||
campaignId String
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
agentName String // trend-scout, research, script-writer, etc.
|
||||
status String @default("pending") // pending, running, completed, failed
|
||||
startedAt DateTime?
|
||||
completedAt DateTime?
|
||||
durationMs Int?
|
||||
outputSummary String?
|
||||
outputPath String?
|
||||
tokenUsage Int?
|
||||
error String?
|
||||
assets Asset[]
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Asset {
|
||||
id String @id @default(cuid())
|
||||
campaignId String
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
agentRunId String?
|
||||
agentRun AgentRun? @relation(fields: [agentRunId], references: [id])
|
||||
type String // image, video, copy, research, script
|
||||
platform String? // instagram, tiktok, nextdoor, all
|
||||
format String? // png, mp4, json, txt, html, md
|
||||
filePath String // local path in outputs/
|
||||
fileName String
|
||||
dimensions String? // 1080x1080, 1080x1920, etc.
|
||||
metadata String? // JSON: caption, hashtags, hook text, scene plan
|
||||
status String @default("draft") // draft, approved, rejected, published
|
||||
publishedTo String? // JSON array of platforms published to
|
||||
postizPostId String? // ID from Postiz after scheduling
|
||||
postizMediaId String? // media ID from Postiz upload
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model ClaudeSession {
|
||||
id String @id @default(cuid())
|
||||
campaignId String
|
||||
campaign Campaign @relation(fields: [campaignId], references: [id])
|
||||
sessionId String? // Claude Code session ID for --resume
|
||||
messages String? // JSON array of conversation history
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model TrendReport {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
filePath String // path to the HTML/JSON report
|
||||
summary String? // brief description
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
```
|
||||
|
||||
**Why SQLite over Postgres:**
|
||||
- Zero config — no separate database container
|
||||
- Single file — easy to backup (just copy `marketing.db`)
|
||||
- Fast enough for a single-user dashboard
|
||||
- Runs anywhere Docker runs
|
||||
- Prisma makes it trivial to switch to Postgres later if needed
|
||||
|
||||
---
|
||||
|
||||
## Authentication (NextAuth.js — Self-Contained)
|
||||
|
||||
```typescript
|
||||
// lib/auth.ts
|
||||
import NextAuth from "next-auth";
|
||||
import Credentials from "next-auth/providers/credentials";
|
||||
import { PrismaAdapter } from "@auth/prisma-adapter";
|
||||
import bcrypt from "bcryptjs";
|
||||
import { prisma } from "./prisma";
|
||||
|
||||
export const { handlers, signIn, signOut, auth } = NextAuth({
|
||||
adapter: PrismaAdapter(prisma),
|
||||
providers: [
|
||||
Credentials({
|
||||
credentials: {
|
||||
email: { label: "Email", type: "email" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
async authorize(credentials) {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email: credentials.email as string },
|
||||
});
|
||||
if (!user) return null;
|
||||
const valid = await bcrypt.compare(
|
||||
credentials.password as string,
|
||||
user.password
|
||||
);
|
||||
return valid ? user : null;
|
||||
},
|
||||
}),
|
||||
],
|
||||
session: { strategy: "jwt" },
|
||||
secret: process.env.NEXTAUTH_SECRET,
|
||||
});
|
||||
```
|
||||
|
||||
**First-run setup:** A seed script creates your admin user. No external auth provider needed.
|
||||
|
||||
```typescript
|
||||
// prisma/seed.ts
|
||||
import bcrypt from "bcryptjs";
|
||||
import { prisma } from "../lib/prisma";
|
||||
|
||||
async function main() {
|
||||
await prisma.user.upsert({
|
||||
where: { email: process.env.ADMIN_EMAIL! },
|
||||
update: {},
|
||||
create: {
|
||||
email: process.env.ADMIN_EMAIL!,
|
||||
password: await bcrypt.hash(process.env.ADMIN_PASSWORD!, 12),
|
||||
name: "Admin",
|
||||
},
|
||||
});
|
||||
}
|
||||
main();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real-Time Pipeline Progress (Server-Sent Events)
|
||||
|
||||
No Redis, no WebSocket server, no Supabase Realtime. Just native SSE from a Next.js API route:
|
||||
|
||||
```typescript
|
||||
// app/api/campaigns/[id]/stream/route.ts
|
||||
export async function GET(req: Request, { params }: { params: { id: string } }) {
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
const stream = new ReadableStream({
|
||||
async start(controller) {
|
||||
// Subscribe to pipeline events for this campaign
|
||||
const unsubscribe = pipelineEvents.subscribe(params.id, (event) => {
|
||||
controller.enqueue(
|
||||
encoder.encode(`data: ${JSON.stringify(event)}\n\n`)
|
||||
);
|
||||
});
|
||||
|
||||
// Keep connection alive
|
||||
const keepAlive = setInterval(() => {
|
||||
controller.enqueue(encoder.encode(`: keepalive\n\n`));
|
||||
}, 15000);
|
||||
|
||||
req.signal.addEventListener("abort", () => {
|
||||
unsubscribe();
|
||||
clearInterval(keepAlive);
|
||||
controller.close();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return new Response(stream, {
|
||||
headers: {
|
||||
"Content-Type": "text/event-stream",
|
||||
"Cache-Control": "no-cache",
|
||||
Connection: "keep-alive",
|
||||
},
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Frontend hook:
|
||||
|
||||
```typescript
|
||||
// hooks/usePipelineProgress.ts
|
||||
export function usePipelineProgress(campaignId: string) {
|
||||
const [agents, setAgents] = useState<AgentRun[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const source = new EventSource(`/api/campaigns/${campaignId}/stream`);
|
||||
source.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
setAgents((prev) => updateAgentStatus(prev, data));
|
||||
};
|
||||
return () => source.close();
|
||||
}, [campaignId]);
|
||||
|
||||
return agents;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Claude Integration
|
||||
|
||||
```typescript
|
||||
// lib/claude.ts
|
||||
import { spawn } from "child_process";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
export const pipelineEvents = new EventEmitter();
|
||||
|
||||
export async function launchPipeline(campaignId: string, prompt: string, cwd: string) {
|
||||
// Update campaign status
|
||||
await prisma.campaign.update({
|
||||
where: { id: campaignId },
|
||||
data: { status: "running" },
|
||||
});
|
||||
|
||||
const claude = spawn("claude", [
|
||||
"-p", prompt,
|
||||
"--output-format", "stream-json",
|
||||
"--verbose",
|
||||
"--allowedTools", "Read,Edit,Write,Bash,Grep,Glob",
|
||||
], { cwd, env: { ...process.env } });
|
||||
|
||||
claude.stdout.on("data", async (chunk) => {
|
||||
const lines = chunk.toString().split("\n").filter(Boolean);
|
||||
for (const line of lines) {
|
||||
try {
|
||||
const event = JSON.parse(line);
|
||||
|
||||
// Detect agent starts/completions from tool use events
|
||||
const agentEvent = parseAgentEvent(event);
|
||||
if (agentEvent) {
|
||||
// Save to database
|
||||
await upsertAgentRun(campaignId, agentEvent);
|
||||
// Broadcast to SSE clients
|
||||
pipelineEvents.emit(campaignId, agentEvent);
|
||||
}
|
||||
|
||||
// Detect new files created
|
||||
const fileEvent = parseFileCreatedEvent(event);
|
||||
if (fileEvent) {
|
||||
await createAsset(campaignId, fileEvent);
|
||||
pipelineEvents.emit(campaignId, { type: "asset_created", ...fileEvent });
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
});
|
||||
|
||||
claude.on("close", async (code) => {
|
||||
const status = code === 0 ? "review" : "failed";
|
||||
await prisma.campaign.update({
|
||||
where: { id: campaignId },
|
||||
data: { status },
|
||||
});
|
||||
pipelineEvents.emit(campaignId, { type: "pipeline_complete", status });
|
||||
});
|
||||
}
|
||||
|
||||
// Claude chat session for feedback
|
||||
export async function sendChatMessage(
|
||||
sessionId: string | null,
|
||||
message: string,
|
||||
cwd: string
|
||||
): AsyncGenerator<string> {
|
||||
const args = ["-p", message, "--output-format", "stream-json", "--verbose"];
|
||||
if (sessionId) args.push("--resume", sessionId);
|
||||
args.push("--allowedTools", "Read,Edit,Write,Bash,Grep,Glob");
|
||||
|
||||
const claude = spawn("claude", args, { cwd, env: { ...process.env } });
|
||||
|
||||
// Stream text deltas back
|
||||
for await (const chunk of claude.stdout) {
|
||||
yield chunk.toString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Postiz Integration (Media Upload + Publishing)
|
||||
|
||||
```typescript
|
||||
// lib/postiz.ts
|
||||
import { Postiz } from "@postiz/node";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import FormData from "form-data";
|
||||
|
||||
const postiz = new Postiz({
|
||||
apiKey: process.env.POSTIZ_API_KEY!,
|
||||
baseUrl: process.env.POSTIZ_URL!,
|
||||
});
|
||||
|
||||
// Upload a local file to Postiz and get back a hosted URL + media ID
|
||||
export async function uploadToPostiz(filePath: string) {
|
||||
const form = new FormData();
|
||||
form.append("file", fs.createReadStream(filePath));
|
||||
|
||||
const res = await fetch(`${process.env.POSTIZ_URL}/public/v1/upload`, {
|
||||
method: "POST",
|
||||
headers: { Authorization: process.env.POSTIZ_API_KEY! },
|
||||
body: form,
|
||||
});
|
||||
|
||||
const { id, path: publicUrl } = await res.json();
|
||||
return { mediaId: id, publicUrl };
|
||||
}
|
||||
|
||||
// Push an approved asset to Postiz for scheduling
|
||||
export async function pushToPostiz(asset: Asset, scheduledAt: string) {
|
||||
// Upload media first
|
||||
const { mediaId, publicUrl } = await uploadToPostiz(asset.filePath);
|
||||
|
||||
// Get the right Postiz integration (channel) ID
|
||||
const integrations = await postiz.integrations.list();
|
||||
const integration = integrations.find(
|
||||
(i) => i.providerIdentifier === asset.platform
|
||||
);
|
||||
|
||||
if (!integration) throw new Error(`No Postiz channel for ${asset.platform}`);
|
||||
|
||||
// Parse caption from asset metadata
|
||||
const metadata = JSON.parse(asset.metadata || "{}");
|
||||
|
||||
// Create the scheduled post
|
||||
const post = await postiz.posts.create({
|
||||
type: "schedule",
|
||||
date: scheduledAt,
|
||||
integration: integration.id,
|
||||
content: metadata.caption || "",
|
||||
image: [{ id: mediaId, path: publicUrl }],
|
||||
});
|
||||
|
||||
return post;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Serving (Local Assets → Browser Preview)
|
||||
|
||||
Your pipeline outputs (images, videos) live on the local filesystem. The dashboard needs to serve them for preview:
|
||||
|
||||
```typescript
|
||||
// app/api/files/[...path]/route.ts
|
||||
import { readFile } from "fs/promises";
|
||||
import path from "path";
|
||||
import { auth } from "@/lib/auth";
|
||||
|
||||
const PIPELINE_ROOT = process.env.PIPELINE_ROOT || "/app/pipeline";
|
||||
|
||||
export async function GET(req: Request, { params }: { params: { path: string[] } }) {
|
||||
// Auth check — only logged-in users can view files
|
||||
const session = await auth();
|
||||
if (!session) return new Response("Unauthorized", { status: 401 });
|
||||
|
||||
const filePath = path.join(PIPELINE_ROOT, ...params.path);
|
||||
|
||||
// Security: prevent path traversal
|
||||
if (!filePath.startsWith(PIPELINE_ROOT)) {
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
}
|
||||
|
||||
try {
|
||||
const buffer = await readFile(filePath);
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
const contentType =
|
||||
{ ".png": "image/png", ".jpg": "image/jpeg", ".mp4": "video/mp4",
|
||||
".html": "text/html", ".json": "application/json", ".md": "text/markdown",
|
||||
".txt": "text/plain", ".css": "text/css" }[ext] || "application/octet-stream";
|
||||
|
||||
return new Response(buffer, { headers: { "Content-Type": contentType } });
|
||||
} catch {
|
||||
return new Response("Not found", { status: 404 });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Asset gallery uses: `<img src="/api/files/outputs/campaign_123/ads/instagram_feed.png" />`
|
||||
|
||||
Video preview uses: `<video src="/api/files/outputs/campaign_123/video/tiktok_ad.mp4" />`
|
||||
|
||||
---
|
||||
|
||||
## Docker Setup
|
||||
|
||||
### Dockerfile (Next.js App)
|
||||
|
||||
```dockerfile
|
||||
# Dockerfile
|
||||
FROM node:20-alpine AS base
|
||||
|
||||
# Install Claude Code CLI
|
||||
RUN npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# Install Playwright browsers (for ad creative generation)
|
||||
RUN npx playwright install chromium --with-deps
|
||||
|
||||
FROM base AS deps
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
|
||||
|
||||
# Copy the marketing pipeline
|
||||
COPY pipeline/ ./pipeline/
|
||||
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
### Docker Compose (Full Stack)
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Your marketing dashboard + pipeline
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NEXTAUTH_URL=http://localhost:3000
|
||||
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
|
||||
- ADMIN_EMAIL=${ADMIN_EMAIL}
|
||||
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
|
||||
- TAVILY_API_KEY=${TAVILY_API_KEY}
|
||||
- POSTIZ_URL=http://postiz:5000
|
||||
- POSTIZ_API_KEY=${POSTIZ_API_KEY}
|
||||
- NEXTDOOR_API_TOKEN=${NEXTDOOR_API_TOKEN}
|
||||
- NEXTDOOR_ADVERTISER_ID=${NEXTDOOR_ADVERTISER_ID}
|
||||
- PIPELINE_ROOT=/app/pipeline
|
||||
volumes:
|
||||
- app-data:/app/prisma/data # SQLite database
|
||||
- pipeline-outputs:/app/pipeline/outputs # Generated content
|
||||
- pipeline-knowledge:/app/pipeline/knowledge # Brand files (editable)
|
||||
depends_on:
|
||||
- postiz
|
||||
|
||||
# Self-hosted Postiz (social media scheduling + media hosting)
|
||||
postiz:
|
||||
image: ghcr.io/gitroomhq/postiz-app:latest
|
||||
ports:
|
||||
- "5000:5000"
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postiz-db:5432/postiz
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- NEXT_PUBLIC_BACKEND_URL=http://postiz:5000
|
||||
- STORAGE_PROVIDER=local
|
||||
- UPLOAD_DIRECTORY=/uploads
|
||||
volumes:
|
||||
- postiz-uploads:/uploads
|
||||
- postiz-config:/config
|
||||
depends_on:
|
||||
- postiz-db
|
||||
- redis
|
||||
|
||||
# Postiz database (Postgres — required by Postiz, not by your app)
|
||||
postiz-db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- POSTGRES_DB=postiz
|
||||
volumes:
|
||||
- postiz-pgdata:/var/lib/postgresql/data
|
||||
|
||||
# Postiz cache (Redis — required by Postiz, not by your app)
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
|
||||
volumes:
|
||||
app-data: # Your SQLite database
|
||||
pipeline-outputs: # All generated content (images, videos, reports)
|
||||
pipeline-knowledge: # Brand identity, platform guidelines, campaign docs
|
||||
postiz-uploads: # Postiz media storage
|
||||
postiz-config: # Postiz configuration
|
||||
postiz-pgdata: # Postiz database
|
||||
redis-data: # Postiz cache
|
||||
```
|
||||
|
||||
### Environment File
|
||||
|
||||
```bash
|
||||
# .env
|
||||
|
||||
# --- Your App ---
|
||||
NEXTAUTH_SECRET=generate-a-random-32-char-string-here
|
||||
ADMIN_EMAIL=you@yourdomain.com
|
||||
ADMIN_PASSWORD=your-secure-password
|
||||
|
||||
# --- Claude (pipeline engine) ---
|
||||
ANTHROPIC_API_KEY=sk-ant-your-key
|
||||
|
||||
# --- Research ---
|
||||
TAVILY_API_KEY=tvly-your-key
|
||||
|
||||
# --- Postiz (publishing + media hosting) ---
|
||||
POSTIZ_API_KEY=your-postiz-key
|
||||
POSTGRES_PASSWORD=a-secure-password-for-postiz-db
|
||||
|
||||
# --- Nextdoor (direct API — Postiz doesn't support it) ---
|
||||
NEXTDOOR_API_TOKEN=your-token
|
||||
NEXTDOOR_ADVERTISER_ID=your-id
|
||||
```
|
||||
|
||||
### Startup
|
||||
|
||||
```bash
|
||||
# First run
|
||||
docker compose up -d
|
||||
docker compose exec app npx prisma db push # Create tables
|
||||
docker compose exec app npx prisma db seed # Create admin user
|
||||
|
||||
# Open in browser
|
||||
open http://localhost:3000
|
||||
```
|
||||
|
||||
After first run, just `docker compose up -d` and everything starts.
|
||||
|
||||
---
|
||||
|
||||
## Project Folder Structure
|
||||
|
||||
```
|
||||
marketing-command-center/
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── (auth)/
|
||||
│ │ ├── login/page.tsx
|
||||
│ │ └── layout.tsx
|
||||
│ ├── (dashboard)/
|
||||
│ │ ├── layout.tsx # Sidebar + header
|
||||
│ │ ├── page.tsx # Dashboard home
|
||||
│ │ ├── campaigns/
|
||||
│ │ │ ├── page.tsx # Campaign list
|
||||
│ │ │ ├── new/page.tsx # New campaign form
|
||||
│ │ │ └── [id]/
|
||||
│ │ │ ├── page.tsx # Pipeline progress tab
|
||||
│ │ │ ├── assets/page.tsx # Asset gallery tab
|
||||
│ │ │ └── chat/page.tsx # Claude feedback tab
|
||||
│ │ ├── assets/page.tsx # Global asset library
|
||||
│ │ ├── trends/page.tsx # Trend reports
|
||||
│ │ └── queue/page.tsx # Postiz queue / calendar
|
||||
│ └── api/
|
||||
│ ├── auth/[...nextauth]/route.ts
|
||||
│ ├── campaigns/
|
||||
│ │ ├── route.ts # CRUD
|
||||
│ │ ├── [id]/
|
||||
│ │ │ ├── launch/route.ts # Trigger pipeline
|
||||
│ │ │ └── stream/route.ts # SSE pipeline progress
|
||||
│ ├── assets/
|
||||
│ │ └── route.ts # Asset CRUD + filtering
|
||||
│ ├── claude/
|
||||
│ │ └── route.ts # Chat sessions (stream)
|
||||
│ ├── postiz/
|
||||
│ │ └── route.ts # Upload + schedule to Postiz
|
||||
│ └── files/
|
||||
│ └── [...path]/route.ts # Serve local pipeline files
|
||||
├── components/
|
||||
│ ├── ui/ # shadcn/ui
|
||||
│ ├── campaign-card.tsx
|
||||
│ ├── asset-gallery.tsx
|
||||
│ ├── asset-card.tsx
|
||||
│ ├── pipeline-progress.tsx
|
||||
│ ├── claude-chat.tsx
|
||||
│ ├── postiz-push-modal.tsx
|
||||
│ ├── trend-report-viewer.tsx
|
||||
│ └── campaign-form.tsx
|
||||
├── hooks/
|
||||
│ ├── usePipelineProgress.ts # SSE hook
|
||||
│ └── useClaudeChat.ts # Chat streaming hook
|
||||
├── lib/
|
||||
│ ├── auth.ts # NextAuth config
|
||||
│ ├── prisma.ts # Prisma client
|
||||
│ ├── claude.ts # Claude SDK wrapper
|
||||
│ ├── postiz.ts # Postiz SDK wrapper
|
||||
│ └── utils.ts
|
||||
├── prisma/
|
||||
│ ├── schema.prisma # Database schema
|
||||
│ ├── seed.ts # Admin user creation
|
||||
│ └── data/ # SQLite file lives here
|
||||
│ └── marketing.db
|
||||
├── pipeline/ # Your marketing pipeline
|
||||
│ ├── .claude/
|
||||
│ ├── skills/
|
||||
│ │ ├── trend-scout/SKILL.md
|
||||
│ │ ├── marketing-research-agent/SKILL.md
|
||||
│ │ ├── script-writer/SKILL.md
|
||||
│ │ ├── ad-creative-designer/SKILL.md
|
||||
│ │ ├── video-ad-producer/SKILL.md
|
||||
│ │ ├── copywriter-agent/SKILL.md
|
||||
│ │ └── distribution-agent/SKILL.md
|
||||
│ ├── knowledge/
|
||||
│ │ ├── brand_identity.md
|
||||
│ │ ├── platform_guidelines.md
|
||||
│ │ └── product_campaign.md
|
||||
│ ├── assets/ # Brand images, logos
|
||||
│ ├── outputs/ # All generated content
|
||||
│ ├── remotion-ad/ # Remotion video project
|
||||
│ ├── CLAUDE.md
|
||||
│ └── package.json
|
||||
├── public/
|
||||
├── .env
|
||||
├── docker-compose.yml
|
||||
├── Dockerfile
|
||||
├── next.config.ts
|
||||
├── tailwind.config.ts
|
||||
├── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pages & Features
|
||||
|
||||
### 1. Dashboard Home (`/`)
|
||||
|
||||
- Active campaigns with status badges (Running / Review Needed / Published)
|
||||
- Recent trend reports from Trend Scout
|
||||
- Quick stats: assets created, published this week, pending review
|
||||
- "New Campaign" button
|
||||
|
||||
### 2. Campaign View (`/campaigns/[id]`)
|
||||
|
||||
**Pipeline Tab** — real-time agent execution progress via SSE:
|
||||
```
|
||||
✅ Trend Scout 12s "5 trending hooks found"
|
||||
✅ Research Agent 2m "Market report generated"
|
||||
✅ Script Writer 3m "15 scripts written"
|
||||
🔄 Ad Creative 1m... "Generating static ads..."
|
||||
⏳ Video Producer — waiting
|
||||
⏳ Copywriter — waiting
|
||||
⏳ Distribution — waiting (pending approval)
|
||||
```
|
||||
|
||||
**Assets Tab** — gallery of everything produced:
|
||||
- Grid of image/video previews with platform badges
|
||||
- Filter by: platform, type (image/video/copy), status
|
||||
- Click to expand: full preview + caption + metadata
|
||||
- Approve / Reject buttons per asset
|
||||
- "Push to Postiz" on approved assets
|
||||
|
||||
**Claude Tab** — live feedback chat:
|
||||
- Streaming chat interface connected to Claude Code
|
||||
- Session persists via `--resume`
|
||||
- Type: "make it snarkier", "add competitor X to research", "regenerate hook B"
|
||||
- New/updated assets auto-appear in the gallery
|
||||
|
||||
### 3. Asset Library (`/assets`)
|
||||
|
||||
- All assets across all campaigns
|
||||
- Search by hook text, caption, platform
|
||||
- Bulk approve / reject / push to Postiz
|
||||
|
||||
### 4. Trend Reports (`/trends`)
|
||||
|
||||
- Auto-generated trend reports (iframe HTML viewer)
|
||||
- "Create Campaign from This Report" button
|
||||
|
||||
### 5. Postiz Queue (`/queue`)
|
||||
|
||||
- Everything pushed to Postiz with status (scheduled / published / failed)
|
||||
- Calendar view of upcoming posts
|
||||
- Link to Postiz dashboard at `localhost:5000` for visual calendar
|
||||
|
||||
---
|
||||
|
||||
## What Runs Where
|
||||
|
||||
| Component | Runs In | External Calls |
|
||||
|-----------|---------|---------------|
|
||||
| Next.js dashboard | Docker (your machine) | None — fully self-contained |
|
||||
| SQLite database | Docker volume | None |
|
||||
| Auth (NextAuth) | Docker (your machine) | None |
|
||||
| File serving | Docker (your machine) | None |
|
||||
| Pipeline progress (SSE) | Docker (your machine) | None |
|
||||
| Claude Code sessions | Docker (spawns subprocess) | → Anthropic API |
|
||||
| Research agent | Claude subprocess | → Tavily API |
|
||||
| Image generation | Claude subprocess | → NanoBanana (Gemini API) |
|
||||
| Video rendering | Claude subprocess | → Local Remotion render |
|
||||
| Postiz | Docker (your machine) | → Instagram API, TikTok API |
|
||||
| Nextdoor publishing | Your app API route | → Nextdoor API |
|
||||
|
||||
**Outbound network calls:** Anthropic, Tavily, Gemini (NanoBanana), Instagram (via Postiz), TikTok (via Postiz), Nextdoor. Everything else is local.
|
||||
|
||||
---
|
||||
|
||||
## Build Phases
|
||||
|
||||
### Phase 1: Scaffold (Week 1)
|
||||
- [ ] Next.js + shadcn/ui + Tailwind setup
|
||||
- [ ] Prisma + SQLite schema
|
||||
- [ ] NextAuth credentials provider
|
||||
- [ ] Docker Compose with Postiz
|
||||
- [ ] Basic dashboard layout with sidebar nav
|
||||
|
||||
### Phase 2: Pipeline Integration (Week 2)
|
||||
- [ ] Campaign CRUD pages
|
||||
- [ ] Campaign launch form → spawns Claude Code subprocess
|
||||
- [ ] SSE pipeline progress streaming
|
||||
- [ ] File serving API route for asset preview
|
||||
- [ ] Auto-scan outputs folder → populate assets table
|
||||
|
||||
### Phase 3: Asset Gallery + Claude Chat (Week 3)
|
||||
- [ ] Asset gallery with grid view + filtering
|
||||
- [ ] Image/video inline preview
|
||||
- [ ] Approve / reject workflow
|
||||
- [ ] Claude chat component with streaming
|
||||
- [ ] Session persistence (--resume)
|
||||
|
||||
### Phase 4: Postiz Publishing (Week 4)
|
||||
- [ ] Postiz upload integration
|
||||
- [ ] "Push to Postiz" modal (select → schedule → confirm)
|
||||
- [ ] Queue page with Postiz status sync
|
||||
- [ ] Nextdoor direct API publishing
|
||||
- [ ] Trend report viewer
|
||||
|
||||
### Phase 5: Polish (Week 5)
|
||||
- [ ] Bulk actions (approve all, reject all, push batch)
|
||||
- [ ] Asset search
|
||||
- [ ] Mobile-responsive
|
||||
- [ ] Trend Scout auto-scheduling (cron in Docker)
|
||||
- [ ] Error handling + retry logic
|
||||
@@ -0,0 +1,540 @@
|
||||
# Fully Autonomous Marketing Team — Complete System Analysis
|
||||
|
||||
**Source:** "I Built a Fully Autonomous Marketing Team with Claude Code & Claude Skills" by Andy (AndyNoCode)
|
||||
**Video:** https://www.youtube.com/watch?v=iVbsl60t0oA
|
||||
**Demo Brand:** Cold Brew Coffee Co.
|
||||
**Creator's Account:** proxa_official (Instagram), Dark Eve (YouTube)
|
||||
|
||||
---
|
||||
|
||||
## 1. Complete Folder/File Structure
|
||||
|
||||
```
|
||||
Cold Brew Coffee Co/
|
||||
├── .claude/ # Claude Code configuration
|
||||
├── assets/ # Creative references / mood board
|
||||
│ ├── coffee_can.png.jpeg # Branded cold brew can with water droplets
|
||||
│ ├── coffee_glass.png.jpeg # Iced coffee in glass
|
||||
│ └── morning_cafe.png.jpeg # Warm cafe lifestyle scene
|
||||
├── knowledge/ # Brand brain — 3 files
|
||||
│ ├── brand_identity.md # 128 lines — personality, tone, voice, emoji/hashtag strategy
|
||||
│ ├── platform_guidelines.md # 142 lines — per-platform specs, formatting, caption rules
|
||||
│ └── product_campaign.md # 199 lines — product details, features, campaign direction
|
||||
├── node_modules/ # NPM dependencies
|
||||
│ └── @tavily/ # Tavily AI SDK (v0.7.2)
|
||||
├── outputs/ # All generated content
|
||||
│ ├── market_research_2025/ # Research agent test output
|
||||
│ │ ├── cold_brew_market_research_2025.html
|
||||
│ │ └── cold_brew_market_research_2025.md
|
||||
│ ├── remotion_test_video/ # Video agent test output
|
||||
│ │ └── cold_brew_ad.mp4 # 15s test video, 2MB
|
||||
│ ├── test_playwright_ad/ # Static ad agent test output
|
||||
│ │ └── ads/
|
||||
│ │ ├── coffee_can.png
|
||||
│ │ ├── lifestyle_morning.png
|
||||
│ │ ├── styles.css
|
||||
│ │ └── instagram_ad.png # 1080x1080 final ad
|
||||
│ └── test_job_payload_1_20260315/ # Full pipeline run output
|
||||
│ ├── ads/
|
||||
│ │ ├── ad_layout.json
|
||||
│ │ ├── ad.html
|
||||
│ │ ├── styles.css
|
||||
│ │ └── instagram_ad.png # 1080x1080, 949.5KB
|
||||
│ ├── copy/
|
||||
│ │ ├── instagram_caption.txt
|
||||
│ │ ├── threads_post.txt
|
||||
│ │ ├── youtube_metadata.json
|
||||
│ │ └── copy_output.json
|
||||
│ ├── video/
|
||||
│ │ ├── scene_plan.json
|
||||
│ │ └── video_ad.mp4 # 20s, 600 frames, 2.15MB
|
||||
│ ├── interactive_report.html # Campaign Intelligence Dashboard
|
||||
│ ├── media_urls.json # Supabase public URLs
|
||||
│ ├── Publish test_job_payload_1 2026-03-15.md # Publishing manifest
|
||||
│ ├── research_brief.md
|
||||
│ └── research_results.json
|
||||
├── pipeline/
|
||||
│ └── publish_now.js # Node.js publishing script
|
||||
├── remotion-ad/ # Remotion video project
|
||||
│ ├── public/
|
||||
│ ├── src/ # Video compositions, SVG components
|
||||
│ ├── .gitignore
|
||||
│ ├── entry1.mjs
|
||||
│ ├── package.json
|
||||
│ └── package-lock.json
|
||||
├── skills/ # All 5 agent skills
|
||||
│ ├── ad-creative-designer/
|
||||
│ │ └── SKILL.md # 191 lines (later extended to 331 lines with Steps 7-9)
|
||||
│ ├── copywriter-agent/
|
||||
│ │ └── SKILL.md # 261 lines
|
||||
│ ├── distribution-agent/
|
||||
│ │ └── SKILL.md # 352 lines
|
||||
│ ├── marketing-research-agent/
|
||||
│ │ └── SKILL.md # 146 lines
|
||||
│ └── video-ad-specialist/
|
||||
│ └── SKILL.md # 167 lines
|
||||
├── .env # Real API keys (gitignored)
|
||||
├── .env.example # Template showing required keys
|
||||
├── .gitignore # Excludes .env and node_modules/
|
||||
├── CLAUDE.md # Project source of truth for Claude Code
|
||||
├── package.json # 18 lines, NPM project config
|
||||
├── package-lock.json
|
||||
├── render_ad_test.js # 36 lines, Remotion render test script
|
||||
├── tavily_results.json # Cached Tavily research results
|
||||
├── tavily-search.js # Tavily search script
|
||||
└── Ultimate Claude Skills & Plugins Prompt.md # 601 lines — skill creation framework
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Every Agent and What It Does
|
||||
|
||||
### Agent 1: Marketing Research Agent
|
||||
**Skill file:** `skills/marketing-research-agent/SKILL.md` (146 lines)
|
||||
**Pipeline position:** First stage — feeds all downstream agents
|
||||
**Trigger phrases:** "research a market", "generate campaign insights", "find ad hooks", "start the pipeline"
|
||||
|
||||
**What it does:**
|
||||
1. Collects niche/topic, optional audience, and campaign goal
|
||||
2. Runs **5 targeted Tavily queries** covering: trends, competitors, pain points, ad hooks, viral content
|
||||
3. Synthesizes findings across 5 categories
|
||||
4. Outputs machine-readable JSON with: `content_topics`, `marketing_angles`, `keywords`, `video_concepts`, `ad_hooks`
|
||||
5. Provides plain-language handoff summary pointing to next agent
|
||||
|
||||
**Key design:** The `video_concepts` objects map directly to the Video Ad Specialist's input format. Output is structured data, not just text — downstream agents consume it programmatically.
|
||||
|
||||
**Output files:**
|
||||
- `research_results.json` — structured JSON for other agents
|
||||
- `research_brief.md` — human-readable markdown report
|
||||
- `interactive_report.html` — Campaign Intelligence Dashboard with charts, competitor analysis, keyword lists
|
||||
|
||||
### Agent 2: Video Ad Specialist
|
||||
**Skill file:** `skills/video-ad-specialist/SKILL.md` (167 lines)
|
||||
**Pipeline position:** Third stage (after research)
|
||||
**Category:** `creative-production` (v1.0.0)
|
||||
**Trigger phrases:** "create a video ad", "generate ad scenes", "build a video campaign", "make a Remotion video"
|
||||
|
||||
**What it does:**
|
||||
1. Gathers inputs (product, goal, platform, length)
|
||||
2. **Reads knowledge files first** (CRITICAL rule) — brand_identity.md, product_campaign.md, platform_guidelines.md
|
||||
3. Generates creative brief with ad strategy (types: `product_showcase`, `problem_solution`, `testimonial`, `limited_offer`, `lifestyle`, `meme_style`)
|
||||
4. Creates scene-by-scene breakdown with platform-specific pacing
|
||||
5. Outputs scene JSON in Remotion-ready structure
|
||||
6. Wraps around the **Remotion Best Practices** official skill — this skill handles the brand, Remotion handles the craft
|
||||
|
||||
**Platform-specific pacing:**
|
||||
- Instagram Reels: Hook ~2s, Product ~5s, Benefit ~3s, CTA ~2s = 10-12s total
|
||||
- YouTube Shorts: Similar with slightly longer holds
|
||||
|
||||
**Audit checklist enforced:**
|
||||
- Hook starts with motion at frame 0 (not static)
|
||||
- Hook copy ≤6 words
|
||||
- CTA scene exists, 2-3s minimum
|
||||
- Logo + CTA visible in final scene
|
||||
- No scene holds static >1.5s (except CTA)
|
||||
- Ratio variants via props, not hardcoded px
|
||||
- Text overlay: 5 words max
|
||||
|
||||
**Output files:**
|
||||
- `scene_plan.json` — scene structure for Remotion
|
||||
- `video_ad.mp4` — auto-rendered (no manual Remotion Studio step)
|
||||
|
||||
### Agent 3: Ad Creative Designer
|
||||
**Skill file:** `skills/ad-creative-designer/SKILL.md` (191→331 lines after extension)
|
||||
**Pipeline position:** Second stage (after research)
|
||||
**Trigger phrases:** "create an ad", "design a social ad", "generate ad layout", "make an image creative", "build a static ad"
|
||||
|
||||
**What it does (9-step workflow):**
|
||||
1. **Gather Inputs** — product, campaign goal, platform, image assets, layout type
|
||||
2. **Select Ad Layout Type** — three types:
|
||||
- **Product Focus:** headline top, product image center, CTA bottom
|
||||
- **Split Layout:** image left, copy right (or reversed)
|
||||
- **Lifestyle:** full-bleed background, text overlay
|
||||
3. Steps 3-6: Generate design JSON with layout, typography, spacing, colors
|
||||
4. **Step 7 — HTML Rendering:** Layout-specific HTML templates, CSS with typography scale (72px headline, 36px subtext, 12px CTA), 1080x1080 container, pulls brand colors from brand_identity.md
|
||||
5. **Step 8 — Playwright Screenshot:** Headless Chromium, `file://` path, networkidle wait, exact 1080x1080 clip
|
||||
6. **Step 9 — Output Storage:** `outputs/TASKNAME_DATE/ads/`, task not complete until all 3 files exist
|
||||
|
||||
**Three-step workflow: Generate (NanoBanana MCP) → Design (HTML/CSS) → Capture (Playwright)**
|
||||
|
||||
**Copy constraints:**
|
||||
- Headline: 3-4 words
|
||||
- CTA: must start with action verb
|
||||
- Instagram Stories safe zone: no text in top/bottom 15%
|
||||
|
||||
**Output files:**
|
||||
- `ad_layout.json` — design spec
|
||||
- `ad.html` + `styles.css` — rendered ad layout
|
||||
- `instagram_ad.png` — 1080x1080 pixel-accurate screenshot
|
||||
|
||||
### Agent 4: Copywriter Agent
|
||||
**Skill file:** `skills/copywriter-agent/SKILL.md` (261 lines)
|
||||
**Pipeline position:** Fourth stage (after creative agents)
|
||||
**Trigger phrases:** Related to writing captions, descriptions, platform-specific copy
|
||||
|
||||
**What it does:**
|
||||
- Handles all marketing copy: captions, descriptions, platform-specific writing
|
||||
- Knows brand voice from knowledge folder
|
||||
- Knows platform formats from guidelines
|
||||
- Generates separate files per platform
|
||||
- YouTube metadata includes: title, description, tags (as JSON)
|
||||
|
||||
**Output structure:** `outputs/{task_name}_{date}/copy/`
|
||||
|
||||
**Output files:**
|
||||
- `instagram_caption.txt` — Hook + value/vibe + CTA + hashtags
|
||||
- `threads_post.txt` — Witty, conversational, 500 chars max
|
||||
- `youtube_metadata.json` — title, description, tags
|
||||
- `copy_output.json` — consolidated copy data
|
||||
|
||||
### Agent 5: Distribution Agent
|
||||
**Skill file:** `skills/distribution-agent/SKILL.md` (352 lines)
|
||||
**Pipeline position:** Final stage — consumes outputs from Research + Copywriter agents
|
||||
|
||||
**6-step workflow:**
|
||||
1. **Gather inputs** — locates media files, research JSON, and copy outputs in campaign folder
|
||||
2. **Upload to Supabase** — all media → `campaign-uploads` bucket with unique filenames (`{task_name}/{date}_{filename}`), saves `media_urls.json` map
|
||||
3. **Assemble metadata** — pulls captions/titles/tags from copy outputs, validates against brand + platform guidelines
|
||||
4. **Scheduling advisory** — recommends posting windows per platform, cross-referenced with research audience data
|
||||
5. **Write Publish MD** — generates `Publish <task_name>-<date>.md` with full metadata, URLs, schedule, and checklist
|
||||
6. **Execute publishing (gate-protected)** — only fires when user explicitly names the Publish MD file; Instagram uses two-step container→publish flow; YouTube uses OAuth; Threads logs manual note (no public API)
|
||||
|
||||
**Safety:** No posting without explicit user approval. Gate-protected publishing.
|
||||
|
||||
**Output files:**
|
||||
- `media_urls.json` — Supabase public URLs
|
||||
- `Publish <task_name> <date>.md` — publishing manifest with URLs, copy, metadata, scheduling
|
||||
- Published content via `pipeline/publish_now.js`
|
||||
|
||||
---
|
||||
|
||||
## 3. All External Tools and How They Connect
|
||||
|
||||
### Core Development Tools
|
||||
| Tool | Purpose | Details |
|
||||
|------|---------|---------|
|
||||
| **Claude Code** | IDE agent orchestration | v2.1.76, Sonnet 4.6 / Claude Pro |
|
||||
| **Antigravity** | VS Code-based IDE | "Open Agent Manager" feature, multi-model support |
|
||||
| **Claude.ai** | Planning/brainstorming | Used to draft skill descriptions before building in Claude Code |
|
||||
|
||||
### Content Generation Tools
|
||||
| Tool | Purpose | How Connected |
|
||||
|------|---------|---------------|
|
||||
| **Remotion** | Programmatic video rendering | Official Claude skill (remotion-best-practices) + custom video-ad-specialist skill wrapping it. React-based. Uses `useCurrentFrame`, `interpolate`, `spring`, `<Series.Sequence>`. Font: `@remotion/google-fonts/Inter` |
|
||||
| **NanoBanana MCP** | AI image generation | Called by ad-creative-designer skill to generate product/lifestyle images using brand knowledge as reference |
|
||||
| **Playwright** | HTML→PNG screenshot | Node.js library, headless Chromium. Captures HTML ad layouts at exact 1080x1080 pixels with networkidle wait |
|
||||
| **Tavily AI** | Web search/research API | `@tavily/core` v0.7.2. 1,000 free credits/month. Marketing-research-agent runs 5 targeted queries per execution |
|
||||
|
||||
### Publishing/Storage Tools
|
||||
| Tool | Purpose | Configuration |
|
||||
|------|---------|---------------|
|
||||
| **Supabase Storage** | Media file hosting | Public bucket: `campaign-uploads`. Files must be at publicly accessible URLs for Instagram API. Service role key (not anon key) for server-side uploads |
|
||||
| **YouTube Data API** | Video upload | OAuth 2.0 required for publishing (API key alone = read-only) |
|
||||
| **Instagram Graph API** | Image/video posting | Two-step flow: create container → publish. Requires `instagram_business_basic` + `instagram_business_content_publish` permissions. Tokens expire every 60 days |
|
||||
| **Threads API** | Text post publishing | Uses `THREADS_ACCESS_TOKEN`. No public upload API at time of video |
|
||||
|
||||
### Optional/Mentioned Tools
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| **BullMQ + Redis** | Automated queuing and scheduled execution (optional extension) |
|
||||
| **Rasterize.io** | Mentioned as having limitations with transparent backgrounds (workaround: CSS round-frame approach) |
|
||||
| **Google Antigravity AI Chat** | Used for individual agent testing to save Claude Code tokens |
|
||||
|
||||
---
|
||||
|
||||
## 4. Environment Variables Required
|
||||
|
||||
```bash
|
||||
# .env.example
|
||||
|
||||
# Tavily AI -- Web Research
|
||||
TAVILY_API_KEY=tvly-YOUR_API_KEY
|
||||
|
||||
# YouTube Data API
|
||||
YOUTUBE_API_KEY=YOUR_YOUTUBE_API_KEY # Read-only operations
|
||||
YOUTUBE_CLIENT_ID=YOUR_YOUTUBE_CLIENT_ID # OAuth 2.0 (required for uploads)
|
||||
YOUTUBE_CLIENT_SECRET=YOUR_YOUTUBE_CLIENT_SECRET # OAuth 2.0
|
||||
YOUTUBE_REFRESH_TOKEN=YOUR_YOUTUBE_REFRESH_TOKEN # Long-lived token
|
||||
|
||||
# Instagram Graph API
|
||||
INSTAGRAM_ACCOUNT_ID=YOUR_INSTAGRAM_PROFESSIONAL_ACCOUNT_ID # Numeric Professional Account ID
|
||||
INSTAGRAM_ACCESS_TOKEN=YOUR_INSTAGRAM_USER_ACCESS_TOKEN # Expires every 60 days!
|
||||
|
||||
# Threads API
|
||||
THREADS_ACCESS_TOKEN=YOUR_THREADS_ACCESS_TOKEN
|
||||
|
||||
# Supabase -- Media Storage
|
||||
SUPABASE_URL=YOUR_SUPABASE_PROJECT_URL # e.g., https://xxx.supabase.co
|
||||
SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY # Server-side only! Bypasses RLS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. End-to-End Workflow
|
||||
|
||||
### Phase 1: Setup (One-Time)
|
||||
1. Create project folder with `assets/`, `knowledge/`, `skills/` structure
|
||||
2. Populate `assets/` with brand images (mood board)
|
||||
3. Write 3 knowledge files: `brand_identity.md`, `platform_guidelines.md`, `product_campaign.md`
|
||||
4. Write `CLAUDE.md` — declares system architecture, agents, responsibilities, folder structure
|
||||
5. Create the "Ultimate Claude Skills & Plugins Prompt.md" (601-line skill creation framework)
|
||||
6. Install dependencies: `npm install @tavily/core`, set up Playwright, set up Remotion project
|
||||
7. Configure Supabase: create `campaign-uploads` public bucket
|
||||
8. Set up API credentials in `.env`
|
||||
|
||||
### Phase 2: Skill Creation (One-Time per Agent)
|
||||
For each of the 5 agents:
|
||||
1. **Plan in Claude.ai** — use Sonnet 4.6 to brainstorm skill details via interactive Q&A
|
||||
2. **Draft key details** — purpose, inputs, outputs, workflow, trigger phrases
|
||||
3. **Build in Claude Code** — prompt: "Help me create an agent skill. I will give you the key details. Use @'Ultimate Claude Skills & Plugins Prompt.md' to create it."
|
||||
4. **Paste key details** — Claude reads the framework doc + key details, generates `SKILL.md`
|
||||
5. **Test individually** — run each agent alone (optionally in Google Antigravity to save tokens)
|
||||
6. **Iterate** — refine skill files based on test results
|
||||
|
||||
### Phase 3: Pipeline Execution (Per Campaign)
|
||||
```
|
||||
Single Job Payload (JSON) → Claude Code
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ 1. RESEARCH AGENT │ ← Tavily API (5 web queries)
|
||||
│ Outputs: │
|
||||
│ - research_results.json (machine-readable)
|
||||
│ - research_brief.md
|
||||
│ - interactive_report.html (dashboard)
|
||||
└──────────┬──────────────┘
|
||||
│ JSON consumed by ↓
|
||||
┌──────────┴──────────────┐
|
||||
│ 2. AD CREATIVE DESIGNER│ ← NanoBanana MCP (image gen)
|
||||
│ Outputs: │ ← Playwright (HTML→PNG)
|
||||
│ - ad_layout.json │
|
||||
│ - ad.html + styles.css
|
||||
│ - instagram_ad.png │
|
||||
└──────────┬──────────────┘
|
||||
│
|
||||
┌──────────┴──────────────┐
|
||||
│ 3. VIDEO AD SPECIALIST │ ← Remotion (video rendering)
|
||||
│ Outputs: │
|
||||
│ - scene_plan.json │
|
||||
│ - video_ad.mp4 │ (auto-rendered, no manual step)
|
||||
└──────────┬──────────────┘
|
||||
│
|
||||
┌──────────┴──────────────┐
|
||||
│ 4. COPYWRITER AGENT │
|
||||
│ Outputs: │
|
||||
│ - instagram_caption.txt
|
||||
│ - threads_post.txt │
|
||||
│ - youtube_metadata.json
|
||||
└──────────┬──────────────┘
|
||||
│
|
||||
┌──────────┴──────────────┐
|
||||
│ 5. DISTRIBUTION AGENT │ ← Supabase (media upload)
|
||||
│ Steps: │ ← YouTube API (video publish)
|
||||
│ - Upload to Supabase│ ← Instagram API (image publish)
|
||||
│ - Assemble metadata │ ← Threads API (text publish)
|
||||
│ - Schedule advisory │
|
||||
│ - Write Publish MD │
|
||||
│ - Execute (gated) │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
### Phase 4: Publishing (Human-Gated)
|
||||
1. Review outputs in `outputs/<task_name>_<date>/` folder
|
||||
2. Check Supabase — files visible in `campaign-uploads` bucket
|
||||
3. Review `Publish <task_name> <date>.md` — contains all URLs, copy, metadata, schedule
|
||||
4. Approve with explicit confirmation prompt
|
||||
5. `pipeline/publish_now.js` executes API calls to YouTube, Instagram, Threads
|
||||
|
||||
---
|
||||
|
||||
## 6. Knowledge File Contents
|
||||
|
||||
### brand_identity.md (128 lines)
|
||||
- **Brand personality:** Bold, witty, unapologetically premium
|
||||
- **Core traits:** Playful & witty, Approachable & casual, Premium without pretension, Lightly humorous
|
||||
- **Tone & Voice table:**
|
||||
- Register: Casual — write like a human, not a press release
|
||||
- Energy: Upbeat, punchy, forward-moving
|
||||
- Humor: Light and occasional; never forced
|
||||
- Confidence: Speak with conviction; avoid hedging
|
||||
- Length: Short sentences. Short paragraphs. White space is your friend.
|
||||
- **Example good copy:** "Your 5AM just got a serious upgrade."
|
||||
- **Emoji usage, hashtag strategy, CTA patterns**
|
||||
|
||||
### platform_guidelines.md (142 lines)
|
||||
- **Platform overview table:** Instagram, Threads, YouTube
|
||||
- **Instagram specs:** Feed 1080x1080 (1:1), Story 1080x1920 (9:16), Reel Cover 1080x1920
|
||||
- **Instagram captions:** 1-3 sentences, structure: Hook + Value/Vibe + CTA + line break + Hashtags
|
||||
- **Approved hashtags:** #ColdBrewCoffee #ColdBrew #MorningGoal #BrewDifferent #CoffeeCulture
|
||||
- **Threads specs:** Text only (images optional), 500 char max, witty/casual, no hard CTA required
|
||||
- **YouTube specs:** Long & short video, informative/energetic/premium tone, tags in description
|
||||
|
||||
### product_campaign.md (199 lines)
|
||||
- **Product:** Cold Brew Coffee, ready-to-drink format
|
||||
- **Target audience:** Busy professionals, coffee enthusiasts, morning routine seekers
|
||||
- **Brand positioning:** Premium coffee experience, accessible at home
|
||||
- **Product features table** with descriptions
|
||||
- **Campaign creative direction, visual asset references**
|
||||
|
||||
---
|
||||
|
||||
## 7. CLAUDE.md Contents
|
||||
|
||||
```markdown
|
||||
# Project Overview
|
||||
|
||||
This project implements an "AI-powered Social Media Content Automation System"
|
||||
built with Claude Code inside the Antigravity IDE.
|
||||
|
||||
The system uses specialized AI agents to generate, render, and distribute
|
||||
marketing content for a demo brand.
|
||||
|
||||
The demo brand used in this project is "Cold Brew Coffee Co."
|
||||
|
||||
# System Architecture
|
||||
|
||||
The system consists of agents:
|
||||
|
||||
1. "Video Ad Agent"
|
||||
2. "Image Ad Agent"
|
||||
3. "Distribution Agent"
|
||||
(Later expanded to include Research Agent and Copywriter Agent)
|
||||
|
||||
Each agent uses a combination of "custom skills, knowledge files, and APIs"
|
||||
to perform its tasks.
|
||||
|
||||
# Agents and Responsibilities
|
||||
|
||||
## 1. Video Ad Agent
|
||||
Purpose: Generate short-form video advertisements using "Remotion".
|
||||
Skills Used:
|
||||
- Remotion Best Practices (official skill)
|
||||
- Video Ad Specialist (custom skill)
|
||||
|
||||
(Additional agents documented similarly)
|
||||
```
|
||||
|
||||
Note: The CLAUDE.md starts with 3 agents declared and is updated as more are built throughout the video.
|
||||
|
||||
---
|
||||
|
||||
## 8. Ultimate Claude Skills & Plugins Prompt.md (601 lines)
|
||||
|
||||
This is the meta-framework used to create all 5 agent skills. Key sections:
|
||||
|
||||
### Skill folder structure:
|
||||
```
|
||||
your-skill-name/
|
||||
├── SKILL.md # REQUIRED. The brain of the skill.
|
||||
├── scripts/ # Optional. Executable Python/Bash code.
|
||||
├── references/ # Optional. Docs Claude loads when needed.
|
||||
└── assets/ # Optional. Templates, fonts, icons.
|
||||
```
|
||||
|
||||
### Three-level progressive disclosure:
|
||||
| Level | What | When Loaded | Token Cost |
|
||||
|-------|------|-------------|------------|
|
||||
| 1 | YAML frontmatter (name + description) | Always, every conversation | ~100 words |
|
||||
| 2 | SKILL.md body (full instructions) | When Claude decides skill is relevant | ~500 lines ideal |
|
||||
| 3 | Bundled files in scripts/references/assets/ | Only when explicitly needed | Unlimited |
|
||||
|
||||
### YAML frontmatter rules:
|
||||
- No underscores in names (kebab-case only)
|
||||
- Cannot start with `claude` or `anthropic` (reserved)
|
||||
- Description must include WHAT + WHEN + trigger phrases
|
||||
- No XML angle brackets `< >` in frontmatter (security)
|
||||
- Max 1024 characters for description
|
||||
- Be "pushy" — Claude tends to under-trigger
|
||||
|
||||
### Description formula:
|
||||
`[What it does] + [When to use it] + [Specific trigger phrases] + [File types if relevant]`
|
||||
|
||||
### Required sections in SKILL.md body:
|
||||
- When to Use This Skill
|
||||
- CRITICAL: Before Generating — Read Knowledge Files
|
||||
- Step-by-step workflow
|
||||
- Troubleshooting
|
||||
- Quality Checklist
|
||||
|
||||
### Cheat sheet rules:
|
||||
- File MUST be named `SKILL.md` (not `SKILL.MD` or `skill.md`)
|
||||
- Test three things: Triggering + Functionality + Performance
|
||||
- Use progressive disclosure (short SKILL.md + references/ for deep docs)
|
||||
|
||||
---
|
||||
|
||||
## 9. Job Payload Format (Pipeline Input)
|
||||
|
||||
The pipeline is triggered by a JSON job payload containing:
|
||||
```json
|
||||
{
|
||||
"task_name": "test_job_payload_1",
|
||||
"task_date": "2026-03-15",
|
||||
"purpose": "Full pipeline execution test",
|
||||
"pipeline_execution_rules": {
|
||||
"execution_order": ["research", "static_ad", "video_ad", "copywriting", "Distribution"]
|
||||
},
|
||||
"platform_targets": ["Instagram", "YouTube"],
|
||||
"output_folder": "outputs/test_job_payload_1_20260315",
|
||||
"safety_flags": {
|
||||
"dry_run": true,
|
||||
"simulate_uploads": true,
|
||||
"publish_immediately": false
|
||||
},
|
||||
"completion_checklist": [
|
||||
"Research outputs saved: research_results.json, research_brief.md, interactive_report.html",
|
||||
"Static ad outputs saved: ad_layout.json, ad.html, styles.css, instagram_ad.png",
|
||||
"Video ad outputs saved: scene_plan.json, video_ad.mp4",
|
||||
"Copy outputs saved: instagram_caption.txt, threads_post.txt, youtube_metadata.json",
|
||||
"Distribution outputs saved: media_urls.json, Publish MD"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Supabase Configuration
|
||||
|
||||
- **Project:** "marketing system" (FREE tier)
|
||||
- **Region:** Southeast Asia (Singapore), `ap-southeast-1`, `t4g.nano`
|
||||
- **URL:** `https://zpthrcqdcmueifnqyvgh.supabase.co`
|
||||
- **Storage bucket:** `campaign-uploads` (PUBLIC)
|
||||
- No file size restriction (default 50MB)
|
||||
- Any MIME type allowed
|
||||
- Public = allows YouTube/Instagram APIs to reach uploaded files
|
||||
- **Auth:** Service role key (not anon key) — no user session in server-side pipeline
|
||||
- **File naming:** `{task_name}_{date}_{filename}_{timestamp}.{ext}`
|
||||
|
||||
---
|
||||
|
||||
## 11. Pipeline Execution Metrics
|
||||
|
||||
| Phase | Duration |
|
||||
|-------|----------|
|
||||
| Skill creation (each) | ~47s - 1m 29s |
|
||||
| Pipeline planning | 2m 25s |
|
||||
| Full pipeline execution | 8m 41s |
|
||||
| Publishing to all platforms | 1m 4s |
|
||||
|
||||
---
|
||||
|
||||
## 12. Published Output Examples
|
||||
|
||||
- **YouTube:** `https://www.youtube.com/watch?v=5dQerc75vC4` — "Upgrade Your Morning with Cold Brew Coffee | Cold Brew Coffee Co."
|
||||
- **Instagram:** Post ID 18895081516880196 on @proxa_official
|
||||
- **Threads:** Post ID 17951637362078664
|
||||
|
||||
---
|
||||
|
||||
## 13. Partially Visible / Flagged Items
|
||||
|
||||
1. **Steps 3-6 of ad-creative-designer** — not fully visible in frames; appear to handle JSON layout generation, color/typography selection, and element positioning
|
||||
2. **platform_guidelines.md YouTube section** — the YouTube-specific formatting rules were cut off after the Threads section
|
||||
3. **CLAUDE.md full contents** — only the top ~30 lines and system architecture section were visible; the complete file likely has more agent documentation
|
||||
4. **NanoBanana MCP configuration** — referenced as the image generation tool but setup/API details not shown
|
||||
5. **pipeline/publish_now.js** — the actual Node.js publishing script contents were not shown, only its execution
|
||||
6. **Threads API setup** — mentioned as having "no public API" in some frames but was successfully published to in the final demo (ID: 17951637362078664)
|
||||
7. **24-page PDF document** — "Agent Skills Key Details and Description" was shown briefly; only pages 1-2 and 8 were readable. Contains detailed specs for all skills
|
||||
8. **Google Antigravity AI Chat** — used for individual agent testing to save Claude Code tokens; appears to be an alternative AI IDE/chat tool
|
||||
9. **Remotion Best Practices** — referenced as an "official" / "globally installed" Claude skill but its contents were not shown
|
||||
10. **BullMQ + Redis integration** — mentioned as optional extension for automated queuing but not implemented in the demo
|
||||
@@ -0,0 +1,578 @@
|
||||
# Platform Specs & Integration Guide: Instagram, TikTok, Nextdoor
|
||||
|
||||
**Target platforms for your pipeline.** This document replaces the generic platform coverage in the original analysis with specific specs, API details, and implementation guidance for your three platforms.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Platform Comparison Matrix](#1-platform-comparison-matrix)
|
||||
2. [Instagram — Full Spec](#2-instagram--full-spec)
|
||||
3. [TikTok — Full Spec](#3-tiktok--full-spec)
|
||||
4. [Nextdoor — Full Spec](#4-nextdoor--full-spec)
|
||||
5. [Updated Knowledge File: platform_guidelines.md](#5-updated-knowledge-file-platform_guidelinesmd)
|
||||
6. [Updated Agent Modifications](#6-updated-agent-modifications)
|
||||
7. [Updated Environment Variables](#7-updated-environment-variables)
|
||||
8. [Publishing Flow Per Platform](#8-publishing-flow-per-platform)
|
||||
9. [Key Differences from Original System](#9-key-differences-from-original-system)
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Comparison Matrix
|
||||
|
||||
| Dimension | Instagram | TikTok | Nextdoor |
|
||||
|-----------|-----------|--------|----------|
|
||||
| **Primary format** | Feed (1:1), Reels (9:16), Stories (9:16) | Vertical video (9:16) | Feed image (1:1), Display (16:9) |
|
||||
| **Video max length** | Reels: 15 min (ads: keep ≤30s) | 10 min (ads: keep 15-30s) | 2-120s (keep ≤30s) |
|
||||
| **Image dimensions** | Feed: 1080x1080, Portrait: 1080x1350 | N/A (video-first) | 1200x1200 (spotlight), 1200x628 (display) |
|
||||
| **Video dimensions** | 1080x1920 (9:16) | 1080x1920 (9:16) | 1080x1920 (9:16) or 1920x1080 (16:9) |
|
||||
| **API type** | Instagram Graph API (REST) | Content Posting API (REST) | Ads API (GraphQL) |
|
||||
| **Auth** | OAuth via Meta Business Login | OAuth 2.0 + PKCE | OAuth2 / Bearer / Basic |
|
||||
| **Publishing flow** | Create container → wait → publish | Init upload → upload video → direct post | Create campaign → ad group → ad → creative |
|
||||
| **Token expiry** | 60 days (long-lived) | 24 hours (refreshable) | Varies |
|
||||
| **Organic posting** | Yes (via Graph API) | Yes (Content Posting API) | Limited (2 free/month for business) |
|
||||
| **Tone** | Aspirational, polished, punchy | Raw, authentic, trend-driven | Neighborly, local, trustworthy |
|
||||
| **Audience** | Broad consumer, visual-first | Gen Z / Millennials, entertainment-first | Homeowners, local community, 25-65 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Instagram — Full Spec
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Duration |
|
||||
|--------|-----------|--------------|---------------|----------|
|
||||
| **Feed Post** | 1080 x 1080 px | 1:1 (square) | 30 MB (image) | — |
|
||||
| **Feed Portrait** | 1080 x 1350 px | 4:5 | 30 MB | — |
|
||||
| **Feed Landscape** | 1080 x 566 px | 1.91:1 | 30 MB | — |
|
||||
| **Stories** | 1080 x 1920 px | 9:16 | 4 GB (video) | ≤15s per clip |
|
||||
| **Reels** | 1080 x 1920 px | 9:16 | 4 GB | ≤90s (API), rec ≤30s for ads |
|
||||
| **Carousel** | 1080 x 1080 px | 1:1 | 30 MB per card | Up to 10 cards |
|
||||
|
||||
### Safe Zones
|
||||
- **Stories/Reels top:** Leave 14% (250px) clear for username/camera icons
|
||||
- **Stories/Reels bottom:** Leave 20% (340px) clear for CTA/swipe-up UI
|
||||
- **Key content:** Center of frame
|
||||
|
||||
### Video Specs
|
||||
- **Format:** MP4 (H.264 codec preferred)
|
||||
- **Frame rate:** 24-30 fps (30 recommended)
|
||||
- **Audio:** AAC, 128kbps+
|
||||
- **Captions:** Recommended (80% of users watch with sound off)
|
||||
|
||||
### Caption Guidelines
|
||||
- **Length:** ≤125 chars for ads (2 lines visible), up to 2200 chars for organic
|
||||
- **Structure:** Hook → Value/Vibe → CTA → line break → Hashtags (3-5)
|
||||
- **Emojis:** 1-2 max
|
||||
|
||||
### API Integration
|
||||
|
||||
**Permissions needed:**
|
||||
- `instagram_business_basic`
|
||||
- `instagram_business_content_publish`
|
||||
|
||||
**Publishing flow (Node.js):**
|
||||
```javascript
|
||||
// Step 1: Create media container
|
||||
const container = await fetch(
|
||||
`https://graph.facebook.com/v20.0/${IG_USER_ID}/media`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
image_url: supabasePublicUrl, // Must be publicly accessible
|
||||
caption: captionText,
|
||||
access_token: INSTAGRAM_ACCESS_TOKEN
|
||||
// For Reels: add media_type: 'REELS', video_url: videoPublicUrl
|
||||
})
|
||||
}
|
||||
);
|
||||
const { id: containerId } = await container.json();
|
||||
|
||||
// Step 2: Check container status (for video)
|
||||
// Poll GET /{containerId}?fields=status_code until status_code === 'FINISHED'
|
||||
|
||||
// Step 3: Publish
|
||||
const publish = await fetch(
|
||||
`https://graph.facebook.com/v20.0/${IG_USER_ID}/media_publish`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
creation_id: containerId,
|
||||
access_token: INSTAGRAM_ACCESS_TOKEN
|
||||
})
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
**Rate limit:** 200 requests/hour/account
|
||||
|
||||
**Token management:**
|
||||
- Long-lived tokens expire after **60 days**
|
||||
- Exchange short-lived → long-lived via `/oauth/access_token`
|
||||
- Set calendar reminder or automated refresh before expiry
|
||||
|
||||
### Sources
|
||||
- [Instagram Graph API Complete Guide 2026](https://elfsight.com/blog/instagram-graph-api-complete-developer-guide-for-2026/)
|
||||
- [Instagram Content Publishing Docs](https://developers.facebook.com/docs/instagram-platform/content-publishing/)
|
||||
- [Instagram Reels API Guide](https://www.getphyllo.com/post/a-complete-guide-to-the-instagram-reels-api)
|
||||
- [Instagram Ad Dimensions 2026](https://admanage.ai/blog/instagram-ad-dimensions)
|
||||
|
||||
---
|
||||
|
||||
## 3. TikTok — Full Spec
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Duration |
|
||||
|--------|-----------|--------------|---------------|----------|
|
||||
| **In-Feed Video** | 1080 x 1920 px | 9:16 (required) | 500 MB | 9-60s (ads), up to 10 min (organic) |
|
||||
| **Square** | 1080 x 1080 px | 1:1 | 500 MB | Same |
|
||||
| **Landscape** | 1920 x 1080 px | 16:9 | 500 MB | Same |
|
||||
|
||||
**9:16 vertical is mandatory for best performance** — square and landscape are technically supported but consistently underperform.
|
||||
|
||||
### Video Specs
|
||||
- **Format:** MP4, MOV, MPEG, 3GP, AVI
|
||||
- **Min resolution:** 540 x 960 (9:16) / 640 x 640 (1:1)
|
||||
- **Bitrate:** ≥516 kbps
|
||||
- **Frame rate:** 24-30 fps
|
||||
- **Audio:** Required (TikTok is sound-on by default)
|
||||
|
||||
### Creative Best Practices
|
||||
- **Hook in first 3 seconds** (not 5 — TikTok scrolls fast)
|
||||
- **On-screen text:** Large, central, ≤6 words per frame
|
||||
- **Keep key elements centered** — description/logo overlay crops edges
|
||||
- **Optimal length:** 15-30s for ads, 21-34s per TikTok's own data
|
||||
- **Style:** Raw/authentic outperforms polished — "made on TikTok, not for TikTok"
|
||||
- **Sound:** Essential — 93% of top-performing TikToks use audio
|
||||
- **Subtitles:** Always include (accessibility + sound-off viewing)
|
||||
|
||||
### Caption Guidelines
|
||||
- **Length:** Up to 4000 chars (but shorter = better for engagement)
|
||||
- **Hashtags:** 3-5 relevant hashtags, mix trending + niche
|
||||
- **Tone:** Casual, conversational, trend-aware, slightly irreverent
|
||||
- **No hard-sell CTAs** — soft CTAs work better ("link in bio", "check this out")
|
||||
|
||||
### API Integration
|
||||
|
||||
**TikTok Content Posting API — OAuth 2.0 + PKCE flow:**
|
||||
|
||||
```javascript
|
||||
// Step 1: Redirect user to TikTok authorization
|
||||
const authUrl = `https://www.tiktok.com/v2/auth/authorize/?` +
|
||||
`client_key=${CLIENT_KEY}&scope=user.info.basic,video.publish` +
|
||||
`&response_type=code&redirect_uri=${REDIRECT_URI}&state=${csrfState}`;
|
||||
|
||||
// Step 2: Exchange code for access token
|
||||
const tokenRes = await fetch('https://open.tiktokapis.com/v2/oauth/token/', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams({
|
||||
client_key: CLIENT_KEY,
|
||||
client_secret: CLIENT_SECRET,
|
||||
code: authCode,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: REDIRECT_URI
|
||||
})
|
||||
});
|
||||
const { access_token, refresh_token } = await tokenRes.json();
|
||||
|
||||
// Step 3: Init video upload
|
||||
const initRes = await fetch('https://open.tiktokapis.com/v2/post/publish/video/init/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${access_token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
post_info: {
|
||||
title: 'Your caption here #hashtag',
|
||||
privacy_level: 'PUBLIC_TO_EVERYONE',
|
||||
disable_duet: false,
|
||||
disable_comment: false,
|
||||
disable_stitch: false
|
||||
},
|
||||
source_info: {
|
||||
source: 'FILE_UPLOAD',
|
||||
video_size: fileSize,
|
||||
chunk_size: fileSize,
|
||||
total_chunk_count: 1
|
||||
}
|
||||
})
|
||||
});
|
||||
const { data: { publish_id, upload_url } } = await initRes.json();
|
||||
|
||||
// Step 4: Upload video binary to upload_url
|
||||
await fetch(upload_url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Range': `bytes 0-${fileSize - 1}/${fileSize}`,
|
||||
'Content-Type': 'video/mp4'
|
||||
},
|
||||
body: videoBuffer
|
||||
});
|
||||
```
|
||||
|
||||
**Token management:**
|
||||
- Access tokens expire in **24 hours**
|
||||
- Refresh tokens last **365 days**
|
||||
- **Must implement auto-refresh** — unlike Instagram's 60-day window, TikTok tokens expire daily
|
||||
|
||||
**Two posting modes:**
|
||||
1. **Direct Post** — content goes live immediately (use for automation)
|
||||
2. **Upload to Inbox** — queues in creator's drafts for manual review
|
||||
|
||||
**No native scheduling** — implement your own via cron/BullMQ/Redis
|
||||
|
||||
### Sources
|
||||
- [TikTok Content Posting API Docs](https://developers.tiktok.com/products/content-posting-api/)
|
||||
- [TikTok Direct Post Reference](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post)
|
||||
- [TikTok OAuth Token Management](https://developers.tiktok.com/doc/oauth-user-access-token-management)
|
||||
- [TikTok Ad Specs 2026](https://admanage.ai/blog/tiktok-ad-specs)
|
||||
- [TikTok Content Posting Developer Guide 2026](https://www.tokportal.com/learn/tiktok-content-posting-api-developer-guide)
|
||||
|
||||
---
|
||||
|
||||
## 4. Nextdoor — Full Spec
|
||||
|
||||
### Important: Nextdoor is Different
|
||||
|
||||
Nextdoor operates fundamentally differently from Instagram/TikTok:
|
||||
- **Audience:** Hyperlocal — homeowners, families, local businesses in verified neighborhoods
|
||||
- **Tone:** Neighborly, trustworthy, community-first (NOT flashy marketing speak)
|
||||
- **API access:** Ads API requires partnership application; organic posting limited to 2 free business posts/month
|
||||
- **Ad format:** Primarily static image ads; video supported but not the primary format
|
||||
- **Targeting:** Geographic (neighborhood-level), demographic, interest-based — leverages 14 years of verified neighbor data
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Notes |
|
||||
|--------|-----------|--------------|---------------|-------|
|
||||
| **Spotlight Ad** | 1200 x 1200 px | 1:1 | 1 MB | JPG/PNG, premium placement |
|
||||
| **Display Ad** | 1200 x 628 px | ~1.91:1 | 150 MB | JPG/PNG/GIF |
|
||||
| **Multi-destination (Carousel)** | 1200 x 1200 px min | 1:1 | 150 MB | 2-10 images, JPG/PNG |
|
||||
| **Video Ad** | Variable | 16:9 or 1:1 | 500 MB | MP4/MOV, 2-120s, rec ≤30s |
|
||||
| **Video Thumbnail** | 1200 x 628 px | ~16:9 | — | Auto-generated or custom |
|
||||
| **Lead Gen (Image)** | 1200 x 628 px | 1.91:1 | 150 MB | JPG/PNG |
|
||||
| **Lead Gen (Video)** | Variable | 16:9 or 1:1 | 500 MB | MP4/MOV |
|
||||
|
||||
### Creative Best Practices
|
||||
- **Subtitles on video** — always (many users browse silently)
|
||||
- **Keep video ≤30 seconds** for best engagement
|
||||
- **Local feel** — avoid stock-photo-corporate look; authentic, neighborhood imagery performs best
|
||||
- **CTA clarity** — "Learn More", "Get a Quote", "Visit Us" (direct, local-action oriented)
|
||||
- **No aggressive sales language** — Nextdoor's community first-ethos; "hard sell" gets reported
|
||||
|
||||
### Tone Guidelines (Critical for Nextdoor)
|
||||
- **DO:** Sound like a helpful neighbor, reference local context, use warm/genuine language
|
||||
- **DON'T:** Sound like a national brand blast, use hype/urgency tactics, be salesy
|
||||
- **Think:** "Hey neighbors, we just launched..." NOT "LIMITED TIME OFFER! ACT NOW!"
|
||||
|
||||
### API Integration
|
||||
|
||||
**Nextdoor Ads API — GraphQL-based:**
|
||||
|
||||
The Ads API is a single GraphQL endpoint supporting queries and mutations across 7 resources: profile, advertiser, campaign, ad group, ad, creative, media, reports.
|
||||
|
||||
**Access:** Requires application through [developer.nextdoor.com](https://developer.nextdoor.com/). Not self-service — you need partnership approval.
|
||||
|
||||
**Auth options:** Basic Auth, Bearer Token, or OAuth2
|
||||
|
||||
**Campaign creation flow:**
|
||||
```
|
||||
1. Create Advertiser account (or use existing)
|
||||
2. Create Campaign (objective, budget, schedule)
|
||||
3. Create Ad Group (targeting, bid strategy)
|
||||
4. Upload Media (image/video creative)
|
||||
5. Create Ad (links creative to ad group)
|
||||
6. Campaign goes into review → approved → live
|
||||
```
|
||||
|
||||
**What must be done in Nextdoor Ads Manager (not API):**
|
||||
- Initial signup
|
||||
- Payment method setup
|
||||
- Custom audience creation
|
||||
- Media archiving
|
||||
|
||||
**Organic posting alternative:**
|
||||
- Nextdoor Publish API allows programmatic organic posts
|
||||
- **Limit:** 2 free business posts/month
|
||||
- Partners like Orlo and ZenCity can schedule and geo-target posts
|
||||
- Best for: local news, community updates, soft-sell brand presence
|
||||
|
||||
### Env Variables Needed
|
||||
|
||||
```bash
|
||||
# Nextdoor Ads API
|
||||
NEXTDOOR_API_TOKEN=YOUR_BEARER_TOKEN # Or use OAuth2 credentials
|
||||
NEXTDOOR_ADVERTISER_ID=YOUR_ADVERTISER_ID # From Ads Manager
|
||||
|
||||
# Nextdoor Publish API (organic)
|
||||
NEXTDOOR_PUBLISH_API_KEY=YOUR_KEY # If using organic posting
|
||||
```
|
||||
|
||||
### Sources
|
||||
- [Nextdoor Ads API Overview](https://developer.nextdoor.com/docs/advertising-overview)
|
||||
- [Nextdoor Developer Portal](https://developer.nextdoor.com/)
|
||||
- [Nextdoor Creative Specs](https://business.nextdoor.com/en-us/nam/nextdoor-ads-manager/creative-specs)
|
||||
- [Nextdoor Ad Specs 2025 (PDF)](https://coegipartners.com/wp-content/uploads/2025/01/NextDoor-Specs-2025.pdf)
|
||||
- [Nextdoor Ads API Launch Announcement](https://about.nextdoor.com/press-releases/nextdoor-launches-ads-api-program-offering-advertisers-an-easier-way-to-extend-their-campaigns-to-nextdoor)
|
||||
|
||||
---
|
||||
|
||||
## 5. Updated Knowledge File: platform_guidelines.md
|
||||
|
||||
Replace the original 3-platform file with this structure:
|
||||
|
||||
```markdown
|
||||
# Platform Guidelines: [Your Brand]
|
||||
|
||||
**Purpose:** Ensures all content is correctly formatted and styled per platform
|
||||
before publishing. Reference before finalizing any post, video, or caption.
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Overview
|
||||
|
||||
| Platform | Content Types | Primary Tone | Hashtags |
|
||||
|----------|--------------|--------------|----------|
|
||||
| **Instagram** | Feed (1:1), Reels (9:16), Stories (9:16), Carousel | Aspirational, polished, punchy | Required (3-5) |
|
||||
| **TikTok** | Vertical video (9:16) only | Raw, authentic, trend-driven | Required (3-5) |
|
||||
| **Nextdoor** | Feed image (1:1), Display (16:9), Video | Neighborly, local, trustworthy | Not used |
|
||||
|
||||
---
|
||||
|
||||
## 2. Instagram
|
||||
|
||||
### Image Specs
|
||||
| Format | Dimensions | Ratio |
|
||||
|--------|-----------|-------|
|
||||
| Feed Post | 1080 x 1080 px | 1:1 |
|
||||
| Feed Portrait | 1080 x 1350 px | 4:5 |
|
||||
| Story/Reel | 1080 x 1920 px | 9:16 |
|
||||
|
||||
### Caption Rules
|
||||
- Length: 1-3 sentences before hashtags
|
||||
- Structure: Hook + Value + CTA + line break + Hashtags
|
||||
- Emojis: 1-2 from approved set
|
||||
- CTA: Always include, place before hashtags
|
||||
|
||||
### Safe Zones (Stories/Reels)
|
||||
- Top 14% (250px) — keep clear
|
||||
- Bottom 20% (340px) — keep clear
|
||||
|
||||
---
|
||||
|
||||
## 3. TikTok
|
||||
|
||||
### Video Specs
|
||||
| Property | Requirement |
|
||||
|----------|------------|
|
||||
| Dimensions | 1080 x 1920 px (9:16 mandatory) |
|
||||
| Length | 15-30s optimal for ads |
|
||||
| Format | MP4, ≥516 kbps |
|
||||
| Audio | Required (sound-on platform) |
|
||||
| Subtitles | Always include |
|
||||
|
||||
### Caption Rules
|
||||
- Tone: Casual, conversational, trend-aware
|
||||
- Hashtags: 3-5 (mix trending + niche)
|
||||
- No hard-sell CTAs — use "link in bio", "check this out"
|
||||
- Hook in first 3 seconds
|
||||
- On-screen text: ≤6 words per frame, large, centered
|
||||
|
||||
### Key Difference from Instagram
|
||||
TikTok rewards authenticity over polish. Content should feel
|
||||
"made on TikTok" — raw, energetic, personality-driven.
|
||||
Overproduced content underperforms.
|
||||
|
||||
---
|
||||
|
||||
## 4. Nextdoor
|
||||
|
||||
### Image Specs
|
||||
| Format | Dimensions | Ratio |
|
||||
|--------|-----------|-------|
|
||||
| Spotlight Ad | 1200 x 1200 px | 1:1 |
|
||||
| Display Ad | 1200 x 628 px | ~1.91:1 |
|
||||
| Video | MP4/MOV | 16:9 or 1:1 |
|
||||
|
||||
### Tone Rules (CRITICAL)
|
||||
- Sound like a helpful neighbor, NOT a national brand
|
||||
- Reference local context when possible
|
||||
- Warm, genuine, community-first language
|
||||
- NO hype, urgency tactics, or aggressive sales language
|
||||
- CTA style: "Learn More", "Get a Quote", "Visit Us"
|
||||
|
||||
### Caption Rules
|
||||
- Keep it conversational and local
|
||||
- No hashtags (Nextdoor doesn't use them)
|
||||
- Focus on community value, not product pushing
|
||||
- Video: ≤30 seconds with subtitles
|
||||
|
||||
### Posting Limits
|
||||
- Organic: 2 free business posts/month
|
||||
- Ads: Via Ads Manager or Ads API (requires partnership)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Updated Agent Modifications
|
||||
|
||||
### Ad Creative Designer — Changes
|
||||
|
||||
The original system only generated 1080x1080 Instagram square ads. For your three platforms, the agent needs to produce **multiple format variants per campaign:**
|
||||
|
||||
| Platform | Static Ad Size | Video Size |
|
||||
|----------|---------------|------------|
|
||||
| Instagram Feed | 1080 x 1080 px | 1080 x 1920 px (Reels) |
|
||||
| Instagram Stories | 1080 x 1920 px | 1080 x 1920 px |
|
||||
| TikTok | N/A (video only) | 1080 x 1920 px |
|
||||
| Nextdoor Spotlight | 1200 x 1200 px | — |
|
||||
| Nextdoor Display | 1200 x 628 px | 1920 x 1080 or 1080 x 1080 |
|
||||
|
||||
**Playwright screenshot configs needed:**
|
||||
```javascript
|
||||
const PLATFORM_CONFIGS = {
|
||||
instagram_feed: { width: 1080, height: 1080 },
|
||||
instagram_stories: { width: 1080, height: 1920 },
|
||||
nextdoor_spotlight: { width: 1200, height: 1200 },
|
||||
nextdoor_display: { width: 1200, height: 628 },
|
||||
};
|
||||
```
|
||||
|
||||
### Video Ad Specialist — Changes
|
||||
|
||||
Must now produce **two video variants:**
|
||||
|
||||
| Platform | Dimensions | Aspect | Length | Style |
|
||||
|----------|-----------|--------|--------|-------|
|
||||
| Instagram Reels | 1080 x 1920 | 9:16 | ≤30s | Polished, branded |
|
||||
| TikTok | 1080 x 1920 | 9:16 | 15-30s | Raw, authentic, trend-driven |
|
||||
| Nextdoor (optional) | 1080 x 1080 or 1920 x 1080 | 1:1 or 16:9 | ≤30s | Local, warm, community feel |
|
||||
|
||||
**Key insight:** Instagram and TikTok share the same 9:16 dimensions but the **creative style should differ significantly.** The Remotion composition should accept a `style` parameter:
|
||||
- `style: "polished"` → clean motion graphics, brand colors, professional typography (Instagram)
|
||||
- `style: "authentic"` → rougher transitions, text overlays, trend-aware pacing (TikTok)
|
||||
- `style: "local"` → warm, simple, community-focused (Nextdoor)
|
||||
|
||||
### Copywriter Agent — Changes
|
||||
|
||||
Must now produce **3 platform-specific copy files** instead of the original 3:
|
||||
|
||||
```
|
||||
outputs/{task_name}_{date}/copy/
|
||||
├── instagram_caption.txt # Hook + Value + CTA + hashtags
|
||||
├── tiktok_caption.txt # Casual, trend-aware, soft CTA + hashtags
|
||||
├── nextdoor_post.txt # Neighborly, local, no hashtags
|
||||
└── copy_output.json # Consolidated structured data
|
||||
```
|
||||
|
||||
### Distribution Agent — Changes
|
||||
|
||||
Now handles **3 different API integrations:**
|
||||
|
||||
| Platform | API | Auth | Publishing Flow |
|
||||
|----------|-----|------|----------------|
|
||||
| Instagram | Graph API (REST) | OAuth, 60-day tokens | Create container → wait FINISHED → publish |
|
||||
| TikTok | Content Posting API (REST) | OAuth 2.0 + PKCE, 24-hour tokens | Init upload → PUT video binary → direct post |
|
||||
| Nextdoor | Ads API (GraphQL) | Bearer/OAuth2, requires partnership | Campaign → Ad Group → Creative → Ad |
|
||||
|
||||
**Token refresh automation is critical:**
|
||||
- Instagram: refresh before 60-day expiry
|
||||
- TikTok: **auto-refresh daily** (24-hour expiry)
|
||||
- Nextdoor: depends on auth method
|
||||
|
||||
---
|
||||
|
||||
## 7. Updated Environment Variables
|
||||
|
||||
```bash
|
||||
# .env.example
|
||||
|
||||
# === Research ===
|
||||
TAVILY_API_KEY=tvly-YOUR_API_KEY
|
||||
|
||||
# === Media Storage ===
|
||||
SUPABASE_URL=YOUR_SUPABASE_PROJECT_URL
|
||||
SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY
|
||||
|
||||
# === Instagram Graph API ===
|
||||
INSTAGRAM_ACCOUNT_ID=YOUR_INSTAGRAM_PROFESSIONAL_ACCOUNT_ID
|
||||
INSTAGRAM_ACCESS_TOKEN=YOUR_INSTAGRAM_USER_ACCESS_TOKEN
|
||||
# Permissions: instagram_business_basic, instagram_business_content_publish
|
||||
# Token expires: 60 days — implement refresh
|
||||
|
||||
# === TikTok Content Posting API ===
|
||||
TIKTOK_CLIENT_KEY=YOUR_TIKTOK_APP_CLIENT_KEY
|
||||
TIKTOK_CLIENT_SECRET=YOUR_TIKTOK_APP_CLIENT_SECRET
|
||||
TIKTOK_ACCESS_TOKEN=YOUR_TIKTOK_USER_ACCESS_TOKEN
|
||||
TIKTOK_REFRESH_TOKEN=YOUR_TIKTOK_REFRESH_TOKEN
|
||||
# Token expires: 24 hours — MUST auto-refresh daily
|
||||
# Refresh token expires: 365 days
|
||||
|
||||
# === Nextdoor Ads API ===
|
||||
NEXTDOOR_API_TOKEN=YOUR_NEXTDOOR_BEARER_TOKEN
|
||||
NEXTDOOR_ADVERTISER_ID=YOUR_NEXTDOOR_ADVERTISER_ID
|
||||
# Requires partnership application at developer.nextdoor.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Publishing Flow Per Platform
|
||||
|
||||
### Instagram
|
||||
```
|
||||
Media generated locally
|
||||
→ Upload to Supabase (public URL required)
|
||||
→ POST /{ig-user-id}/media (create container with public URL)
|
||||
→ Poll container status until FINISHED
|
||||
→ POST /{ig-user-id}/media_publish (publish)
|
||||
→ Return post ID
|
||||
```
|
||||
|
||||
### TikTok
|
||||
```
|
||||
Video generated locally
|
||||
→ POST /v2/post/publish/video/init/ (get upload_url)
|
||||
→ PUT video binary to upload_url
|
||||
→ TikTok processes and publishes
|
||||
→ Return publish_id
|
||||
```
|
||||
Note: TikTok accepts direct file upload — **no Supabase intermediary needed** for TikTok (unlike Instagram). However, keeping Supabase as the central store is still good practice for archival.
|
||||
|
||||
### Nextdoor
|
||||
```
|
||||
For Ads (via Ads API):
|
||||
→ Upload media asset via API
|
||||
→ Create Campaign (objective, budget)
|
||||
→ Create Ad Group (targeting, schedule)
|
||||
→ Create Ad (link creative + copy)
|
||||
→ Submit for review → auto-approved → live
|
||||
|
||||
For Organic (via Publish API):
|
||||
→ POST content via Publish API
|
||||
→ Limited to 2 free posts/month
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Key Differences from Original System
|
||||
|
||||
| Aspect | Original (Andy's System) | Your System |
|
||||
|--------|-------------------------|-------------|
|
||||
| **Platforms** | Instagram, YouTube, Threads | Instagram, TikTok, Nextdoor |
|
||||
| **Video style** | Single polished style | Multiple styles (polished, authentic, local) |
|
||||
| **Static ad sizes** | 1080x1080 only | 1080x1080, 1080x1920, 1200x1200, 1200x628 |
|
||||
| **API complexity** | 3 simple REST APIs | REST + REST + GraphQL (Nextdoor) |
|
||||
| **Token management** | Instagram 60-day only | Instagram 60-day + TikTok daily refresh |
|
||||
| **Tone variation** | Single brand voice | 3 platform-adapted voices from same brand identity |
|
||||
| **Nextdoor** | Not included | Requires partnership application + community-first creative |
|
||||
| **Supabase role** | Required for Instagram | Required for Instagram, optional for TikTok, required for Nextdoor ads |
|
||||
| **YouTube** | Included | Dropped (can add back) |
|
||||
| **Threads** | Included | Dropped (can add back) |
|
||||
| **Scheduling** | Basic advisory | Need custom scheduler for TikTok (no native scheduling API) |
|
||||
|
||||
---
|
||||
|
||||
*Compiled March 2026. Verify API versions and access requirements before implementation.*
|
||||
@@ -0,0 +1,445 @@
|
||||
# The Complete Picture
|
||||
|
||||
---
|
||||
|
||||
## What You're Building
|
||||
|
||||
A self-hosted AI marketing engine that researches trends, writes scripts, generates images, produces videos, writes copy, and publishes to Instagram, TikTok, and Nextdoor — autonomously — with you as the only human in the loop approving what goes live.
|
||||
|
||||
No marketing team. No freelancers. No design tools. No video editors. One prompt per campaign. ~20 minutes of your time. 20-30 ad assets out the other end.
|
||||
|
||||
---
|
||||
|
||||
## Part 1: Setup (One Time)
|
||||
|
||||
### What You Need Before Starting
|
||||
|
||||
- A machine that runs Docker (Mac, Linux, or Windows with WSL)
|
||||
- Claude Max subscription (already have it)
|
||||
- Tavily AI free account (1,000 research credits/month)
|
||||
- Self-hosted Postiz (included in your Docker stack)
|
||||
- Instagram Business/Creator account connected to Postiz
|
||||
- TikTok developer app connected to Postiz
|
||||
- Nextdoor Ads API partnership (apply at developer.nextdoor.com)
|
||||
|
||||
### Step 1: Clone and Configure
|
||||
|
||||
```bash
|
||||
git clone https://github.com/your-repo/marketing-command-center.git
|
||||
cd marketing-command-center
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env`:
|
||||
```bash
|
||||
# Research
|
||||
TAVILY_API_KEY=tvly-your-key
|
||||
|
||||
# Publishing
|
||||
POSTIZ_API_KEY=your-postiz-key
|
||||
POSTGRES_PASSWORD=a-secure-password
|
||||
|
||||
# Nextdoor (direct API — Postiz doesn't support it)
|
||||
NEXTDOOR_API_TOKEN=your-token
|
||||
NEXTDOOR_ADVERTISER_ID=your-id
|
||||
|
||||
# Dashboard login
|
||||
NEXTAUTH_SECRET=generate-random-string
|
||||
ADMIN_EMAIL=you@yourdomain.com
|
||||
ADMIN_PASSWORD=your-password
|
||||
```
|
||||
|
||||
That's it. 5 keys. No Anthropic API key — your Max plan handles Claude.
|
||||
|
||||
### Step 2: Authenticate Claude Code
|
||||
|
||||
```bash
|
||||
claude login
|
||||
# Browser opens → log in with your Max plan → done
|
||||
```
|
||||
|
||||
### Step 3: Launch Everything
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
This starts 4 containers:
|
||||
| Container | What It Does |
|
||||
|-----------|-------------|
|
||||
| **app** | Your Next.js dashboard + Claude Code pipeline |
|
||||
| **postiz** | Social scheduling + media hosting for IG/TikTok |
|
||||
| **postiz-db** | Postgres for Postiz (you never touch this) |
|
||||
| **redis** | Cache for Postiz (you never touch this) |
|
||||
|
||||
### Step 4: Initialize
|
||||
|
||||
```bash
|
||||
docker compose exec app npx prisma db push # Create database tables
|
||||
docker compose exec app npx prisma db seed # Create your admin account
|
||||
```
|
||||
|
||||
### Step 5: Connect Social Accounts in Postiz
|
||||
|
||||
Open `http://localhost:5000` → Postiz dashboard:
|
||||
1. Connect Instagram (OAuth login — Postiz handles tokens forever)
|
||||
2. Connect TikTok (OAuth login — Postiz handles daily token refresh)
|
||||
|
||||
### Step 6: Write Your Brand Files
|
||||
|
||||
Open `http://localhost:3000` → your dashboard, or edit directly:
|
||||
|
||||
```
|
||||
pipeline/knowledge/brand_identity.md ← Who your brand is
|
||||
pipeline/knowledge/platform_guidelines.md ← How content looks per platform
|
||||
pipeline/knowledge/product_campaign.md ← What you're selling
|
||||
pipeline/assets/ ← Drop your logos, product shots, screenshots
|
||||
```
|
||||
|
||||
**You're live.**
|
||||
|
||||
---
|
||||
|
||||
## Part 2: Your Daily Process
|
||||
|
||||
### Morning (~5 minutes)
|
||||
|
||||
```
|
||||
1. Open http://localhost:3000
|
||||
2. Check the Trends page
|
||||
→ Trend Scout ran overnight (automated cron)
|
||||
→ You see: "POV hooks trending on TikTok this week"
|
||||
→ You see: "Competitor X running UGC-style ads about [topic]"
|
||||
→ You see: "Carousel posts outperforming single images on IG this week"
|
||||
3. Decide: "I want to run a campaign around [feature/angle]"
|
||||
```
|
||||
|
||||
### Campaign Creation (~2 minutes)
|
||||
|
||||
```
|
||||
1. Click "New Campaign"
|
||||
2. Fill in the form:
|
||||
- Name: "Snarky Competitor Takedown"
|
||||
- Platforms: ☑ Instagram ☑ TikTok ☐ Nextdoor
|
||||
- Goal: App downloads
|
||||
- Key message: "We do what [competitor] can't"
|
||||
- Social proof: "50K downloads, 4.8★"
|
||||
- Variations: 5 hooks per platform
|
||||
- Use latest trend report: ☑
|
||||
3. Click "Launch Pipeline"
|
||||
```
|
||||
|
||||
### Pipeline Runs (~15-20 minutes, you do nothing)
|
||||
|
||||
You watch the pipeline progress page update in real-time:
|
||||
|
||||
```
|
||||
✅ Trend Scout 12s Pulled 5 trending hooks from this week
|
||||
✅ Research Agent 2m Market report: competitor gaps, audience pain points
|
||||
✅ Script Writer 3m 15 ad scripts (5 hooks × 3 platforms)
|
||||
✅ Ad Creative 3m 8 static ad images across 3 sizes
|
||||
✅ Video Producer 5m 6 video ads (3 IG polished + 3 TikTok raw)
|
||||
✅ Copywriter 2m Captions + hashtags for every asset
|
||||
✅ Distribution 1m Publish manifest ready for review
|
||||
```
|
||||
|
||||
**What each agent actually did:**
|
||||
|
||||
| Agent | Input | What It Did | Output |
|
||||
|-------|-------|-------------|--------|
|
||||
| **Trend Scout** | Automated web scan | Searched TikTok/IG trends, competitor ads, viral hooks | `trend_report.json` |
|
||||
| **Research Agent** | Your campaign brief + trend report | Ran 5 Tavily searches (market, competitors, pain points, hooks, viral) | `research_results.json` + `interactive_report.html` |
|
||||
| **Script Writer** | Research output + brand voice | Wrote 15 ad scripts with timed Hook→Body→CTA structure | `scripts/` folder with 15 scripts |
|
||||
| **Ad Creative** | Scripts + brand assets | Generated images via NanoBanana → built HTML layouts → Playwright screenshotted them | 8 PNGs at platform-exact dimensions |
|
||||
| **Video Producer** | Scripts + brand assets | Built Remotion compositions → rendered frame-by-frame | 6 MP4s (polished IG + raw TikTok styles) |
|
||||
| **Copywriter** | Research + scripts + brand voice | Wrote platform-tuned captions, hashtags, metadata | `instagram_captions.json`, `tiktok_captions.json` |
|
||||
| **Distribution** | All of the above | Assembled the publish manifest | `Publish_campaign_date.md` |
|
||||
|
||||
### Review (~10-15 minutes)
|
||||
|
||||
```
|
||||
1. Click the Assets tab
|
||||
2. Browse the gallery:
|
||||
- 8 static ad images (IG feed 1080x1080, IG Stories 1080x1920, Nextdoor 1200x1200)
|
||||
- 6 video ads (IG Reels 1080x1920 polished, TikTok 1080x1920 raw/authentic)
|
||||
- Each card shows: preview, caption, hashtags, hook text, platform badge
|
||||
3. Click to expand any asset → see full preview + all metadata
|
||||
4. Approve the ones you like (green check)
|
||||
5. Reject the ones you don't (red X)
|
||||
```
|
||||
|
||||
### Give Feedback (Optional, ~5 minutes)
|
||||
|
||||
Switch to the Claude tab if anything needs tweaking:
|
||||
|
||||
```
|
||||
You: "Hook B is too corporate, make it snarkier"
|
||||
Claude: *rewrites script, re-renders video* → new asset appears in gallery
|
||||
|
||||
You: "The colors on the static ads feel off, use more contrast"
|
||||
Claude: *updates HTML/CSS, re-screenshots* → updated PNGs in gallery
|
||||
|
||||
You: "Create one more ad that directly calls out [competitor] by name"
|
||||
Claude: *writes script, generates image + video* → 3 new assets appear
|
||||
|
||||
You: "Here are our actual competitors for future research: [list]"
|
||||
Claude: *updates knowledge/product_campaign.md* → all future campaigns reflect this
|
||||
```
|
||||
|
||||
### Publish (~2 minutes)
|
||||
|
||||
```
|
||||
1. Select approved assets
|
||||
2. Click "Push to Postiz"
|
||||
3. Modal shows:
|
||||
- Which platform each goes to
|
||||
- Caption preview
|
||||
- Suggested schedule time (from research data)
|
||||
4. Adjust schedule if you want
|
||||
5. Click "Confirm"
|
||||
6. Postiz uploads media → schedules posts → handles publishing
|
||||
```
|
||||
|
||||
### What Happens Behind the Scenes
|
||||
|
||||
```
|
||||
Your approved static ad (PNG) for Instagram:
|
||||
→ Your app uploads PNG to Postiz (/upload endpoint)
|
||||
→ Postiz stores it, returns public URL
|
||||
→ Postiz creates scheduled post with caption + image
|
||||
→ At scheduled time: Postiz calls Instagram Graph API
|
||||
→ Instagram creates container → processes → publishes
|
||||
→ Post is live on your Instagram
|
||||
|
||||
Your approved video for TikTok:
|
||||
→ Your app uploads MP4 to Postiz
|
||||
→ Postiz stores it, returns public URL
|
||||
→ Postiz creates scheduled post with caption + video
|
||||
→ At scheduled time: Postiz calls TikTok Content Posting API
|
||||
→ TikTok processes and publishes
|
||||
→ Video is live on TikTok
|
||||
|
||||
Your approved ad for Nextdoor:
|
||||
→ Your app calls Nextdoor Ads API directly (GraphQL)
|
||||
→ Creates campaign → ad group → uploads creative → creates ad
|
||||
→ Nextdoor reviews → approves → ad goes live
|
||||
```
|
||||
|
||||
### Monitor
|
||||
|
||||
```
|
||||
Queue page shows:
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ Scheduled │
|
||||
│ 📷 IG Feed - "Still doing X?" Tue 7:30 AM │
|
||||
│ 🎬 IG Reel - Hook A (polished) Tue 12:00 PM │
|
||||
│ 🎬 TikTok - Hook A (raw) Tue 5:00 PM │
|
||||
│ 📷 IG Feed - "Your app sucks" Wed 7:30 AM │
|
||||
│ │
|
||||
│ Published ✅ │
|
||||
│ 📷 IG Feed - "Upgrade Your..." Mon 7:30 AM │
|
||||
│ 🎬 TikTok - "POV: you found..." Mon 5:00 PM │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 3: What You're Getting
|
||||
|
||||
### Per Campaign (from one prompt)
|
||||
|
||||
| Asset Type | Quantity | Details |
|
||||
|-----------|----------|---------|
|
||||
| Static image ads | 6-10 | IG Feed (1080x1080), IG Stories (1080x1920), Nextdoor (1200x1200, 1200x628) |
|
||||
| Video ads (motion graphic) | 4-6 | IG Reels (polished), TikTok (raw/authentic) — 15-30s each |
|
||||
| Ad scripts | 15+ | 5 hook variations × 3 platform styles |
|
||||
| Captions | 1 per asset per platform | Platform-tuned tone, hashtags, CTAs |
|
||||
| Research report | 1 | Interactive HTML dashboard with market data, competitor analysis, keywords |
|
||||
| Trend report | 1 | What's working right now on each platform |
|
||||
| Publish manifest | 1 | Complete publishing plan with schedule recommendations |
|
||||
|
||||
### Per Week (running 2-3 campaigns)
|
||||
|
||||
| Output | Quantity |
|
||||
|--------|----------|
|
||||
| Static ads | 15-30 |
|
||||
| Video ads | 10-18 |
|
||||
| Unique scripts | 30-45 |
|
||||
| Published posts | 15-25 across platforms |
|
||||
| Your time invested | ~1 hour total |
|
||||
|
||||
### Per Month
|
||||
|
||||
| Output | Quantity |
|
||||
|--------|----------|
|
||||
| Static ads | 60-120 |
|
||||
| Video ads | 40-72 |
|
||||
| Published posts | 60-100 |
|
||||
| Research reports | 8-12 |
|
||||
| Your time invested | ~4 hours total |
|
||||
|
||||
---
|
||||
|
||||
## Part 4: What This Is Supplying
|
||||
|
||||
### The Full Marketing Stack, Replaced
|
||||
|
||||
| Traditional Role | What They Cost | Your System Replaces It With |
|
||||
|-----------------|----------------|------------------------------|
|
||||
| Market Researcher | $60-100/hr | Trend Scout + Research Agent (Tavily, automated) |
|
||||
| Creative Director | $80-150/hr | Script Writer agent (knowledge files drive brand decisions) |
|
||||
| Graphic Designer | $50-100/hr | Ad Creative Designer (NanoBanana + Playwright) |
|
||||
| Video Editor | $50-120/hr | Video Ad Producer (Remotion, auto-rendered) |
|
||||
| Copywriter | $50-100/hr | Copywriter Agent (platform-tuned, brand-voiced) |
|
||||
| Social Media Manager | $40-80/hr | Distribution Agent + Postiz (scheduling, publishing) |
|
||||
| **Total team cost** | **$5,000-15,000/mo** | **~$50/mo** (Max plan + Tavily free + Postiz self-hosted) |
|
||||
|
||||
### What You're Actually Paying
|
||||
|
||||
| Service | Cost | What It Does |
|
||||
|---------|------|-------------|
|
||||
| Claude Max | $100/mo (or $200 for Max 5x) | Powers all 7 agents — research, writing, image gen, video gen, copy, distribution |
|
||||
| Tavily AI | Free (1,000 credits/mo) | Web research for trends + market data |
|
||||
| Postiz | Free (self-hosted) | Media hosting + scheduling + publishing to IG/TikTok |
|
||||
| NanoBanana | ~$5-15/mo (image generation) | AI images for static ads |
|
||||
| Docker hosting | Free (your machine) or ~$5-20/mo (VPS) | Runs everything |
|
||||
| **Total** | **~$110-235/mo** | |
|
||||
|
||||
---
|
||||
|
||||
## Part 5: Your Competitive Advantage
|
||||
|
||||
### 1. Speed
|
||||
|
||||
A human marketing team takes **1-2 weeks** to go from brief to published campaign. You do it in **20 minutes**. That's not an incremental improvement — it's a category change. You can react to trends the same day they emerge.
|
||||
|
||||
### 2. Volume
|
||||
|
||||
Human teams produce 5-10 ad variations per campaign. You produce **20-30 per campaign, 2-3 campaigns per week**. More variations = more data on what works = faster optimization. The platforms reward volume — their algorithms need creative variety to test and optimize delivery.
|
||||
|
||||
### 3. Consistency
|
||||
|
||||
Every asset is generated through the same knowledge files. Brand voice never drifts. Platform specs are never wrong. CTAs always follow the rules. A human team has bad days, misremembers guidelines, and cuts corners under deadline pressure. Your system doesn't.
|
||||
|
||||
### 4. Cost Structure
|
||||
|
||||
Your competitors are paying $5,000-15,000/month for a marketing team or agency. You're paying ~$150/month for the same output volume. That's a **97% cost reduction**. That gap doesn't close as you scale — it widens. More campaigns cost you almost nothing extra.
|
||||
|
||||
### 5. Institutional Memory
|
||||
|
||||
Every trend report, every research finding, every winning hook gets captured. Your knowledge files accumulate intelligence over time. After 3 months, your system knows your market, competitors, and audience better than any new hire could learn in a year.
|
||||
|
||||
### 6. Test Everything
|
||||
|
||||
You can't afford to have a human team create 20 hook variations to find the one that converts. You can. The research says top-performing TikTok ads hit 40-45% hook rates, but finding those hooks requires testing 10-20 variations. Your system generates them in minutes.
|
||||
|
||||
### 7. Platform-Native at Scale
|
||||
|
||||
Each platform gets content optimized for how it actually works:
|
||||
- **Instagram:** Polished, aspirational, branded motion graphics
|
||||
- **TikTok:** Raw, authentic, trend-driven, sounds-on
|
||||
- **Nextdoor:** Neighborly, local, community-first
|
||||
|
||||
A human team tends to create one asset and resize it. Your system creates genuinely different content per platform because each agent applies platform-specific rules from the knowledge files.
|
||||
|
||||
### 8. You Own Everything
|
||||
|
||||
No SaaS vendor lock-in. No monthly platform fees that increase. No API changes that break your workflow overnight. The dashboard is yours. The pipeline is yours. Postiz is self-hosted. The database is a SQLite file you can back up with `cp`. If Postiz dies, you swap in Buffer's API. If Tavily dies, you swap in Exa. The architecture is modular — every piece is replaceable.
|
||||
|
||||
---
|
||||
|
||||
## Part 6: The Architecture (Final State)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ YOUR BROWSER │
|
||||
│ │
|
||||
│ Dashboard → Campaigns → Assets → Claude │
|
||||
│ Gallery Chat Queue │
|
||||
└──────────────────┬──────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────┐
|
||||
│ YOUR DOCKER HOST (single machine) │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────┐ │
|
||||
│ │ Next.js App (port 3000) │ │
|
||||
│ │ ├─ SQLite database (campaigns/assets) │ │
|
||||
│ │ ├─ NextAuth (login) │ │
|
||||
│ │ ├─ SSE (realtime pipeline progress) │ │
|
||||
│ │ ├─ File server (preview outputs) │ │
|
||||
│ │ └─ Claude subprocess spawner │ │
|
||||
│ └─────────────────┬──────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────┼──────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────┐ ┌───────────┐ ┌────────┐ │
|
||||
│ │Claude│ │ Postiz │ │Pipeline│ │
|
||||
│ │Code │ │ (5000) │ │Outputs │ │
|
||||
│ │(Max) │ │ ├─Postgres│ │(volume)│ │
|
||||
│ │ │ │ └─Redis │ │ │ │
|
||||
│ └──┬───┘ └─────┬─────┘ └────────┘ │
|
||||
│ │ │ │
|
||||
└─────┼─────────────┼──────────────────────────┘
|
||||
│ │
|
||||
│ ├──→ Instagram API (posts go live)
|
||||
│ └──→ TikTok API (videos go live)
|
||||
│
|
||||
├──→ Tavily API (research)
|
||||
├──→ NanoBanana/Gemini API (images)
|
||||
└──→ Nextdoor API (ads)
|
||||
```
|
||||
|
||||
### Data Flow: Prompt to Post
|
||||
|
||||
```
|
||||
You type a campaign prompt in the browser
|
||||
│
|
||||
▼
|
||||
Next.js API spawns Claude Code subprocess (uses Max plan)
|
||||
│
|
||||
▼
|
||||
Claude reads CLAUDE.md → loads skills → reads knowledge files
|
||||
│
|
||||
├─→ Trend Scout: scans web via Tavily → trend_report.json
|
||||
├─→ Research Agent: 5 Tavily queries → research_results.json + report.html
|
||||
├─→ Script Writer: reads research → writes 15 scripts
|
||||
├─→ Ad Creative: NanoBanana generates images → Claude builds HTML → Playwright screenshots → PNGs
|
||||
├─→ Video Producer: Claude writes Remotion compositions → renders → MP4s
|
||||
├─→ Copywriter: reads everything → writes platform-tuned captions
|
||||
└─→ Distribution: assembles publish manifest
|
||||
│
|
||||
▼
|
||||
All outputs saved to pipeline/outputs/{campaign}/
|
||||
Next.js detects new files → creates asset records in SQLite
|
||||
SSE pushes updates to your browser in real-time
|
||||
│
|
||||
▼
|
||||
You browse the asset gallery → approve what you like
|
||||
│
|
||||
▼
|
||||
Click "Push to Postiz" → Next.js uploads media to Postiz → schedules post
|
||||
│
|
||||
▼
|
||||
Postiz publishes at scheduled time → content is live on Instagram/TikTok
|
||||
│
|
||||
▼
|
||||
Person scrolling Instagram sees your ad → downloads your app
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 7: What's in Each File
|
||||
|
||||
Here's every document we've built and what to use it for:
|
||||
|
||||
| File | Use It For |
|
||||
|------|-----------|
|
||||
| `FULL_SYSTEM_ANALYSIS.md` | Reference if you want to see how the original AndyNoCode system worked |
|
||||
| `BEST_PRACTICES_GUIDE.md` | Official Anthropic skill-writing guidelines, 60+ linked resources |
|
||||
| `PLATFORM_SPECS.md` | Instagram, TikTok, Nextdoor API details, dimensions, creative specs |
|
||||
| `AUTONOMOUS_MARKETING_PLAN.md` | 7-agent pipeline design, ad creative frameworks, what makes people download |
|
||||
| `FRONTEND_ARCHITECTURE.md` | Next.js dashboard architecture, database schema, Docker Compose, Claude/Postiz integration code |
|
||||
| `THE_COMPLETE_PICTURE.md` | This document — the executive overview of everything |
|
||||
| `transcript_clean.txt` | Original video transcript for reference |
|
||||
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 287 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 175 KiB |
|
After Width: | Height: | Size: 173 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 203 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 145 KiB |
|
After Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 198 KiB |