# 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 --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//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](https://postiz.com) for scheduling. For the agent details and folder conventions, see [`pipeline/CLAUDE.md`](./pipeline/CLAUDE.md). --- ## Tech stack - Next.js 16 (App Router) + React 19 + TypeScript 5 - Tailwind 4 + shadcn/ui - Prisma 7 over SQLite (`better-sqlite3` adapter) - NextAuth 5 (credentials provider, `trustHost: true` for 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 ```bash 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): ```bash 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//`. --- ## 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/`). ```bash # 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`](./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//SKILL.md Per-agent instructions the spawned Claude reads apps// Per-app assets (icon, phone frame, screenshots) knowledge/ Default knowledge (overridden per-app at runtime) outputs/_/ Generated campaign deliverables remotion-ad/ Remotion video project ``` --- ## License Private / internal.