8afbf68f4c
- 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>
180 lines
6.7 KiB
Markdown
180 lines
6.7 KiB
Markdown
# 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](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/<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/`).
|
|
|
|
```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/<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.
|