- Replaces the create-next-app boilerplate README with a real one: what the project does, the 8-agent pipeline table, tech stack, local dev, configuration via the Settings UI, multi-tenant App model, Unraid deployment, and repo layout. - CLAUDE.md "Claude Auth in Docker" no longer claims .env is the only way to set the OAuth token — describes the Settings page as primary, .env as bootstrap fallback, mentions the Test button, and notes that Anthropic exposes no UI to list/revoke setup-tokens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Marketing Command Center
A Next.js dashboard that turns the Claude Code CLI into a marketing team.
Spawns claude as a subprocess to run an 8-agent pipeline that researches
trends, writes ad scripts, generates static and video creatives, drafts
platform-tuned copy, and prepares a publish manifest — all per campaign,
per app, per platform.
Used internally to drive social campaigns for the 88Oak app portfolio
(honeyDue, Reflect, etc.). Deployed on an Unraid server at
marketing.88oakapps.com.
What it does
You create a Campaign in the UI. The web app spawns
claude -p <prompt> --output-format stream-json once per agent, in order:
| # | Agent | Output |
|---|---|---|
| 1 | Trend Scout | trend_report.json — viral hooks, competitor angles, formats (Tavily searches) |
| 2 | Marketing Research | research_results.json + research_brief.md (deep Tavily) |
| 3 | Script Writer | Hook/body/CTA scripts per platform, timed for video |
| 4 | Gemini Ad Designer | Photo-real static ads via NanoBanana MCP (Google Gemini) |
| 5 | Poster Ad Designer | "Museum-quality" HTML→PNG posters via Playwright |
| 6 | Video Ad Producer | Remotion compositions rendered to MP4 (Reels, TikTok) |
| 7 | Copywriter | Platform-tuned captions with hashtags |
| 8 | Distribution | Publish_manifest.md — never auto-publishes |
Each agent reads its pipeline/skills/<name>/SKILL.md and the campaign's
brand/product knowledge files before producing output. Progress streams
back to the UI over SSE; completed assets are scanned into the DB and
shown in the campaign's asset gallery.
From there: thumbs-up/down to teach style preferences (fed back into
future Gemini prompts as reference_images), spawn variations of a
winner, repurpose to other dimensions, or push individual assets to
Postiz for scheduling.
For the agent details and folder conventions, see
pipeline/CLAUDE.md.
Tech stack
- Next.js 16 (App Router) + React 19 + TypeScript 5
- Tailwind 4 + shadcn/ui
- Prisma 7 over SQLite (
better-sqlite3adapter) - NextAuth 5 (credentials provider,
trustHost: truefor the reverse proxy) - Playwright (HTML→PNG)
- Remotion (video rendering, project at
pipeline/remotion-ad/) - Claude Code CLI spawned via
child_process.spawn(NOT the Anthropic SDK) - NanoBanana MCP for Gemini image generation
- Tavily for web research
Local development
npm install
npx prisma db push
npx prisma db seed # creates admin user + honeyDue app
npm run dev # http://localhost:3000
Default login: admin@localhost / admin123 (override with ADMIN_EMAIL
/ ADMIN_PASSWORD env vars). The Claude Max OAuth flow on your dev
machine handles auth automatically — no token needed locally as long as
you've signed into the claude CLI once.
Configuration
Every third-party credential is configured at Settings (/settings)
and stored in the Setting DB table. DB values override .env at
runtime. Each integration card has a Test button that hits the real
API to verify the credential.
| Integration | What it's for |
|---|---|
| Claude | OAuth access token for the claude CLI subprocess. Token expires (~1 year) — refresh here when launches start failing with auth errors. |
| Tavily | Web research for the Trend Scout and Research agents. |
| Gemini | Google Gemini powers NanoBanana MCP for static ad generation. |
| Postiz | Self-hosted social scheduling (Instagram, TikTok). |
| Nextdoor | Direct Nextdoor Ads API integration. |
To mint a Claude Code OAuth token (for headless / Docker use):
claude setup-token
# extract the access token from your keychain:
security find-generic-password -s "Claude Code-credentials" -a "$(whoami)" -w \
| python3 -c 'import sys,json; print(json.load(sys.stdin)["claudeAiOauth"]["accessToken"])'
Paste the result into Settings → Claude → Save. There is no Anthropic UI
to list or revoke setup-token outputs — treat each one like a password.
Apps (multi-tenant)
The same pipeline serves multiple products. Each App row in the DB
carries its own brand colors, brand identity markdown, product info,
platform guidelines, and learned style preferences. At launch time,
launchPipeline writes the active app's knowledge into
pipeline/_knowledge/ and copies the app's icon.png / phone.png
into Remotion's public/ directory. Switch active apps from the
sidebar.
Per-app assets live at pipeline/apps/<slug>/.
Deployment (Unraid)
The app runs in a single Docker container behind Nginx Proxy Manager at
marketing.88oakapps.com. Source lives at
/mnt/user/appdata/marketing/ (disposable, rsynced from dev).
Persistent data is bind-mounted from /mnt/user/downloads/marketing/
(db/, outputs/, knowledge/).
# Sync source (preserves Unraid-specific .env and docker-compose.yml)
rsync -avz \
--exclude='node_modules' --exclude='.next' --exclude='prisma/data' \
--exclude='pipeline/outputs' --exclude='pipeline/remotion-ad/.next' \
--exclude='pipeline/remotion-ad/node_modules' \
--exclude='.env' --exclude='.env.local' --exclude='docker-compose.yml' \
--delete \
./ unraid:/mnt/user/appdata/marketing/
# Rebuild + restart
ssh unraid "cd /mnt/user/appdata/marketing && docker compose down \
&& docker compose build app && docker compose up -d"
Full deployment notes (docker-compose.yml shape, volume permissions,
Dockerfile quirks) are in CLAUDE.md.
Repo layout
app/ Next.js App Router
(auth)/ Login
(dashboard)/ UI: campaigns, assets, apps, settings, trends
api/ REST endpoints (campaigns, assets, settings, files)
components/ React components incl. shadcn/ui
lib/
claude.ts Subprocess orchestration, prompt building
scanner.ts Walks pipeline outputs into Asset rows
settings.ts DB-backed config + per-integration health checks
postiz.ts Postiz publishing
variations.ts "More like this" via Gemini
repurpose.ts Reformat to other aspect ratios
nextdoor.ts Direct Nextdoor Ads API
prisma/
schema.prisma User, App, Campaign, AgentRun, Asset, ...
seed.ts Admin user + default app
pipeline/
CLAUDE.md Agent pipeline architecture (read this)
skills/<agent>/SKILL.md Per-agent instructions the spawned Claude reads
apps/<slug>/ Per-app assets (icon, phone frame, screenshots)
knowledge/ Default knowledge (overridden per-app at runtime)
outputs/<task>_<date>/ Generated campaign deliverables
remotion-ad/ Remotion video project
License
Private / internal.