
</sentinel carousel pipeline>
Daily pipeline that turns real news into branded Instagram carousels.
90 min → 5 min
per-carousel workflow
2
daily output tracks
0
missed days since launch
SPECIFICATIONS
| ROLE | SOLO BUILD |
|---|---|
| YEAR | 2026 |
| TYPE | AUTOMATION |
| STATUS | IN PRODUCTION |
| STACK | typescript · node 20 · firecrawl · gemini · openai gpt-image-1 · higgsfield · playwright · remotion +4 more |
| LINKS | — |
| AVAILABILITY | in development |
“Marketing a one-person product meant every Instagram carousel was a 90-minute manual flow in Figma.”
Automated content marketing pipeline for the Sentinel iOS app.Scrapes real news with Firecrawl, extracts structured slide content with Gemini, and renders branded 1080×1350 Instagram carousels with Playwright.Optional short-form Reels via Remotion and ElevenLabs.Two daily output types: news-intelligence carousels and Realizations listicles.
== WHAT IS THIS ==
Automated content marketing pipeline for the Sentinel iOS app. Scrapes real news with Firecrawl, extracts structured slide content with Gemini, and renders branded 1080×1350 Instagram carousels with Playwright. Optional short-form Reels via Remotion and ElevenLabs. Two daily output types: news-intelligence carousels and Realizations listicles. Nothing auto-posts. Everything lands in a dated folder for manual review.
== </the problem> ==
Marketing a one-person product meant every Instagram carousel was a 90-minute manual flow in Figma. That was the slowest part of marketing Sentinel, and doing it daily by hand doesn't scale when the same person is also building the app.
== </my approach> ==
I built a daily TypeScript pipeline that runs on a small always-on box: Firecrawl pulls fresh news, Gemini structures the day's stories against Zod schemas matching the renderer's exact data contract, and Playwright renders branded 1080×1350 slides from deterministic HTML templates. Two tracks ship side by side · Type A news-intelligence carousels in Sentinel's dark intel aesthetic, and Type C Realizations listicles with OpenAI gpt-image-1 backgrounds. Nothing auto-posts; every output lands in a dated folder with a preview.html review grid.
== </the story> ==
The Sentinel Carousel Pipeline is the content-marketing engine behind the Sentinel iOS app. It runs daily on a small always-on box, pulls fresh news through Firecrawl, structures the day's stories through Gemini, and renders launch-quality Instagram carousels with Playwright. The pipeline produces two distinct outputs side by side. Type A is news-intelligence carousels that show Sentinel doing its actual job, rendered in the app's dark intel aesthetic on 1080×1350 slides. Type C is Realizations, nine-slide listicles using OpenAI gpt-image-1 backgrounds, written in the voice of a passionate fan overwhelmed by keeping up with their topic.
Nothing auto-posts. Every output lands in output/YYYY-MM-DD/ alongside a generated preview.html review grid so I can scan everything in one browser tab before publishing.
The pipeline replaced the slowest part of marketing a one-person product. Before this, every carousel was a 90-minute manual flow in Figma. After this, the work compresses to a 5-minute approval pass. The system has shipped daily without a missed day since it went live.
== </architecture> ==
TypeScript strict mode, Node 20+, tsx as the runner, scheduled via node-cron in system local time. Firecrawl handles scrape across tiered freshness windows. Gemini structures the slides against Zod schemas that match the renderer's exact data contract. Playwright runs against a pinned Chromium and serves each carousel as a deterministic HTML template hydrated with the slide JSON, then takes a high-DPR screenshot per slide. Sharp post-processes the PNGs for IG-safe color and DPI.
OpenAI gpt-image-1 backgrounds for the Realizations track are generated against a per-slide prompt template that mixes the day's topic with a fixed style frame, so the entire week reads as one set without being repetitive. ElevenLabs handles short voiceovers when the Reels output is enabled; Remotion stitches the video. Winston logs to per-day rotated files. Module boundaries are strict: nothing in the carousel repo can write to or read from the iOS app's repo. No Supabase, no Apple infrastructure, no shared state.
Higgsfield handles the video side. The Reels track runs through a Higgsfield hook for animated character openers, scene transitions, and motion-virality prediction on the generated cuts before they enter manual review. Remotion still owns the deterministic stitch and overlays. The interface keeps the carousel and daily pipelines untouched.
Secrets never live in the repo. A real .env is shared out of band, and an npm check-env script blocks the daily run unless every required key is present.
== </key features> ==
Two daily output tracks
Type A shows Sentinel doing its actual job as news-intelligence carousels. Type C is Realizations, nine-slide listicles written in the voice of a passionate fan overwhelmed by their topic.
Deterministic rendering pipeline
Playwright hydrates HTML templates with slide JSON against a pinned Chromium, screenshots each slide at high DPR, and Sharp post-processes the PNGs for IG-safe color and DPI.
Zod-validated slide contracts
Gemini output is structured against Zod schemas that match the renderer's exact data contract, so a bad generation fails loudly instead of rendering a broken slide.
Manual review as a feature
Everything lands in output/YYYY-MM-DD/ with a generated preview.html grid. The 90-minute Figma flow compresses to a 5-minute approval pass, and nothing publishes without a human look.
Optional Reels track
ElevenLabs voiceovers, Higgsfield animated openers and motion-virality prediction, with Remotion owning the deterministic stitch and overlays before manual review.
Hard repo isolation
The pipeline lives in its own repo and is forbidden from touching the iOS app's repo. A check-env script blocks the daily run unless every required key is present.
== </key decisions> ==
DECISION 01
Manual posting is a feature, not a missing one. Auto-posting to Instagram requires Meta Graph API and a business account, and would shift the system from a content tool into a brand-risk surface. Keeping the human review step costs five minutes per day and pays for itself the first time a slide reads wrong.
DECISION 02
Type B was killed before it shipped. The original PRD specified a persona-story track with Google Imagen, but it never made it into code. Type C replaced it with a sharper voice and a more reliable image model. The PRD now carries a deprecation banner over the Type B sections so the history is preserved without misleading future agents.
DECISION 03
The pipeline lives in its own repo and is forbidden from touching the iOS app's repo. That separation is enforced in CLAUDE.md and is the single most important architectural rule of the project. It keeps the marketing pipeline cheap to iterate on without ever risking the app build.
DECISION 04
Output is always to disk, never to a queue or a CMS. Every carousel is a folder of PNGs plus a preview.html. Renaming, reordering, throwing one away, and publishing only the good ones are all one finder-level operation.
== </what i learned> ==
Manual posting is a feature, not a missing one. The human review step costs five minutes a day and pays for itself the first time a slide reads wrong.
Killing Type B before it shipped and leaving a deprecation banner in the PRD preserves the history without misleading future agents working on the system.
Strict module boundaries are the single most important architectural rule here · the marketing pipeline stays cheap to iterate on without ever risking the app build.
Output to disk beats a queue or CMS at this scale. Renaming, reordering, and publishing only the good ones are all one finder-level operation.
typescript · node 20 · firecrawl · gemini · openai gpt-image-1 · higgsfield · playwright · remotion · elevenlabs · sharp · zod · winston
interactive demo · loads on demand
IN PRODUCTION