Viral Scout
Public demo with sample data: two example businesses, real public YouTube posts. Read-only. Source on GitHub

Dashboard

A Next.js app in web/ that shows every business profile: outliers, fastest posts, rising posts and tracked links as cards (thumbnail, labels, metrics, growth sparkline, hook, transcript), plus the AI ideas notes, a swipe-file board and source health.

It runs in two modes:

Local (your PC) Published (Vercel, free Hobby plan)
Start cd web && npm install && npm run dev → http://localhost:3210 scripts/publish.ps1
Data web/data/*.json, refreshed after every run a snapshot uploaded with each deploy
Save / Track / Dismiss / swipe status run the Python CLI and update the vault read-only; the buttons copy the CLI command
Login none (unless SITE_PASSWORD is set) password (SITE_PASSWORD); locked if it's missing

Nothing runs in the cloud. Collection stays on your PC (home IP, yt-dlp, the scheduled task). Vercel only hosts the pages.

Data flow

python -m viral_scout run <profile>      → data/<profile>-latest.json + SQLite
   └─ export (automatic after each run)  → web/data/<profile>.json, web/data/index.json
python -m viral_scout export [profiles]  → the same, by hand
scripts/publish.ps1                      → export + vercel deploy --prod (uploads web/ incl. data/)

web/data/ is git-ignored, so the public repo never contains business data. The deploy uploads it straight from your PC: web/.vercelignore deliberately doesn't exclude it.

Publish to Vercel

One-time setup:

npx vercel login                       # once per PC
scripts/publish.ps1 -SetPassword       # links project "viral-scout", asks for a password, deploys

Afterwards:

scripts/publish.ps1                    # export + production deploy
scripts/publish.ps1 -Preview           # preview URL instead

To publish automatically after the daily run, add a line to your scheduled task after run-daily.ps1: pwsh -File scripts/publish.ps1.

Free plan notes:

  • Vercel Hobby is meant for personal, non-commercial use. If the dashboard becomes a client deliverable, move it to Pro.
  • Vercel's own "Password Protection" is a paid feature, so this app has its own login: an HMAC-signed cookie, valid 30 days. It runs in src/proxy.ts, Next 16's replacement for middleware.
  • Every page is pre-rendered at build time. The only server code that runs is the login check, which fits comfortably in the free limits.

Pages

  • /search: searches titles, hooks, endings, transcripts and captions. Locally it covers the full history of every business through the Python CLI; the published site searches the latest runs in the browser.

  • /new: New research. Pick Quick research (a one-off research-… profile, reports go to the repo's reports/) or New project (reports go to an Obsidian project folder you pick). Describe the business or topic and add search phrases. Hashtags, the topic filter and the spam rules are derived for you, and the first run starts in the background while the page shows its progress. Local only.

  • /setup: every API key with what it unlocks, its cost, how to get it and a docs link. Paste, Save and Test it. Keys go into .env on your PC through stdin (never on the command line) and are always shown masked. Local only; the published site never manages keys.

  • /p/<profile>/performance: Your performance. Your own videos and ads: KPI cards grouped A–E (hover for formula and denominator), an organic / paid toggle, the 5 tests per video, a retention curve with drop-off markers, the diagnosis, priorities, unit economics and CSV import steps. Read-only; data from web/data/perf/<profile>.json. See performance.md.

  • /: one card per business, with posts, outliers, 🔥 mega, saved, and the top thumbnails.

  • /p/<profile> has these tabs:

    • Outliers, Fastest, Rising now, Tracked: card grids with search, a platform filter and "hide saved".
    • Ideas: the <date>-viral-ideas.md notes written by the /viral-scout skill, rendered as HTML.
    • Swipe file: a board with idea → scripted → filmed → posted → skip columns. Changing a card's status locally edits the note's status: in the vault.
    • Sources: skipped sources, suggested hashtags, creators who keep showing up, errors and recent runs.
  • /p/<profile>/ads (the Ads button on the business page): the ads scout (ads-scout.md). It shows an advertiser table (click a row to filter), then ad cards with the creative, advertiser, days running, variants, reach, platforms, hook, offer, CTA, landing domain and labels. You can filter by advertiser, format and offer, sort by score, days, variants or newest, and show only ads that are still running. Below the cards: offers that keep running, coverage, skipped sources (with the key that unlocks each) and lookup links. It's read-only, from web/data/ads/<profile>.json, which python -m viral_scout ads|export writes. Meta snapshot URLs, which carry the access token, are never exported.

Security

  • Local actions only accept requests whose host is localhost or 127.0.0.1. The Python CLI is called with fixed arguments, never through a shell.
  • On Vercel (VERCEL is set) actions are switched off, and the API answers 403.
  • Pages send X-Robots-Tag: noindex and set robots: noindex.