I run three brands: BMX content (@billy_kennedy_bmx and @bmx4beginners), Axon — my AI tools business at axon.nepa-ai.com, and NEPA AI — the agency that sells automation to local businesses. Each brand has its own social accounts, its own content pipeline, its own audience. All of it runs on one machine, one codebase, one agent stack.
Here's the exact architecture.
The Orchestrator: brand_cron.py
Everything starts with brand_cron.py. It's a Python script that fires on cron — 9 AM for BMX, noon for Axon. Each invocation takes a --brand flag and runs the full posting pipeline for that brand.
Inside, it uses a ThreadPoolExecutor to post to multiple platforms concurrently. Instagram, Pinterest, X, LinkedIn, Threads, Facebook — each platform gets its own thread, its own browser session, its own error handling. If Instagram fails, Pinterest still posts. No single platform blocks the others.
from concurrent.futures import ThreadPoolExecutor
def run_brand(brand: str):
platforms = load_platforms(brand)
with ThreadPoolExecutor(max_workers=len(platforms)) as executor:
futures = {executor.submit(post, brand, p): p for p in platforms}
for future in futures:
try:
future.result(timeout=120)
except Exception as e:
log_error(brand, futures[future], e)
The Hands: social_poster.py
social_poster.py is the module that actually touches the platforms. Each platform has its own function: post_instagram(), post_twitter(), post_pinterest(), post_linkedin().
All of them use Playwright connected to Chrome via CDP (Chrome DevTools Protocol). No platform APIs. The browser keeps login sessions persistent, so the agent reuses cookies from manual logins.
I run two Chrome instances:
- Port 9222: Chrome with Google/Instagram sessions
- Port 9223: Brave with X/Twitter sessions
This keeps sessions isolated. An Instagram cookie issue doesn't affect X posting.
Platform-Specific Fixes
Each platform has its quirks, and I've solved them all:
- Instagram Create: Walk up DOM to
<A>ancestor of the "New post" SVG — clicking the SVG directly navigates to Stories - Instagram Share: Tab navigation + Enter only —
mouse.click()never works on the Share button - Instagram Account Switching: More → Switch accounts → find DOM row by text content
- File Upload: Use
wait_for(state="attached")notstate="visible"— the input is hidden - Video Thumbnails: Auto-extracted from .mp4 via ffmpeg before upload
The Brain: GPT-4.1
Content generation runs through GPT-4.1 via an Azure proxy. But here's the thing — most posts don't need real-time generation. I batch-generate captions and store them in a JSON content queue. The cron pulls from the queue. The LLM only fires for fresh content or when the queue runs dry.
For the bounty pipeline, GPT-4.1 writes proposals. For X replies, it drafts contextual responses to tech influencer tweets. For blog content, it generates drafts that I review.
Total LLM cost: ~$20-25/month across all three brands.
The Creative Stack: 28 C++ Libraries
This is the part most people don't have. I compiled 28 C++ static libraries — omni_audio through omni_robotics — that handle heavy creative processing: audio stem separation, image upscaling, 3D model manipulation, video processing.
12 Python bridge modules connect to these libraries via ctypes. A single MCP (Model Context Protocol) server exposes all 79 tools to any AI client. The entire pipeline was verified end-to-end: 169/169 demo steps passed on real BMX video, photos, and OBJ files.
Real file in → C++ processes → real file out. All local GPU, zero cloud API cost per operation.
The Scanners
Bounty Monitor
bounty_monitor.py scans GitHub repos every 5 minutes during SF peak hours (10-11 AM, 5-7 PM ET) and every 15 minutes off-peak. When it finds an open bounty:
- Auto-claims with a comment
- GPT-4.1 generates a technical proposal
- Delegates the fix to a coding agent
- Pings me on Telegram when the PR is ready
Currently have 10 PRs open worth ~$2,275 across FinMind and claude-builders repos.
X Reply Monitor
x_reply_monitor.py watches tweets from tech influencers (@mckaywrigley, @therundownai, @swyx) and auto-drafts contextual replies. Recently switched from draft queue to auto-send — 6 replies went out in a single day. Has a politics filter to avoid engaging with anything off-brand.
Lead Engine
Runs twice daily. Scrapes business directories, researches contacts, scores leads, adds to the master pool. Currently at 474 leads across automotive, legal, and real estate verticals.
The Image Pipeline
batch_image_gen.py generates images in bulk. Last session: 353 images in one run — 174 Axon blog heroes (dark tech aesthetic), 71 BMX blog heroes (action lifestyle), 108 game assets across 6 style-isolated batches.
Style bleed prevention: each batch runs with a different style prefix and cooldowns between batches. The game assets (pets, tiles, buildings, icons, UI, marketing pieces) came out clean enough to use directly.
Why One Stack, Not Three
I tried running separate systems per brand. It was a maintenance disaster. Every bug fix had to be applied three times. Every platform change required three updates.
One codebase means one place to fix Instagram's DOM changes, one place to update the posting logic, one set of logs to review. The --brand flag is the only thing that changes between invocations.
The Daily Reality
I spend about 30 minutes a day on this. Read the memory file, check the error log, glance at state files. If everything looks clean, I go ride.
The system posts to 8+ platform/account combinations, scans for bounties, generates leads, monitors X, and produces images — all while I'm at the skatepark or sleeping.
That's the stack. If you want to build something similar, the tools are at axon.nepa-ai.com.
