.claude/skills/pinterest-pin/SKILL.md
Fully autonomous Pinterest pin production for Clarido. Auto-selects topics from blog gaps, generates content with pre-render validation, visual-reviews rendered PNGs via agent, publishes via Chrome automation, and emails results. No approval gates. Supports batch mode.
npx skillsauth add Abhi5415/clarido-marketing pinterest-pinInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fully autonomous end-to-end workflow for producing and publishing SEO-optimized Pinterest pins (1000x1500 PNG) for @claridoapp. Auto-selects topics, generates content, validates text against layout limits, renders via Remotion, visually reviews via agent, publishes via Chrome automation, and emails results. No human approval gates.
Invoked by the user with /pinterest-pin or when asked to create Pinterest content.
The full method with render specs, props format, and SEO guidelines is in docs/pinterest-pin-method.md. Read that file before starting.
All phases run without user intervention. The visual review agent is the critical quality gate replacing human review.
The user may invoke this skill in two ways:
Two modes, selected automatically:
content/pinterest/*/brief.md files to see which topics already have pins.~/dev/clarido-landing-page/content/blog/ to find published articles.When ALL blog posts already have pins:
Proceed immediately. Do NOT present topics or wait for approval.
For each pin in the batch:
Write SEO-optimized content:
https://clarido.app/blog/slug). Only fall back to https://clarido.app if no blog post exists for this topic. Published pins cannot have their destination URL edited after posting.Create content folder (content/pinterest/YYYY-MM-DD_HHMM_slug/) and save brief.md.
Before rendering, validate ALL text fields against character limits derived from the Remotion component layouts. This catches overflow before spending time on illustration generation and rendering.
Tips format limits (from PinterestTipsPin/index.tsx — 1000px wide canvas, 44px side padding):
| Field | Max Chars | Derivation |
|-------|-----------|------------|
| title | 55 | 40px uppercase, ~32 chars/line at this font size, 2 lines max before pushing illustration down |
| subtitle | 25 | 18px uppercase with letter-spacing 4 inside a small yellow pill |
| tip.headline | 30 | 28px bold, single line in the space beside the 48px number badge |
| tip.description | 85 | 22px, 2 lines in the remaining horizontal space after badge + gap |
| tip.citation | 30 | 17px italic, "Author, Year" format — single line |
| Tips count | 4-5 | Flex layout distributes evenly with justifyContent: space-between; 6+ overflows the canvas |
Comparison format limits (from PinterestComparisonPin/index.tsx — two half-width columns with gap and divider):
| Field | Max Chars | Derivation |
|-------|-----------|------------|
| leftTitle / rightTitle | 15 | 38px uppercase in a half-width column (~456px usable) |
| leftDescription / rightDescription | 55 | 22px centered text, 2 lines max in half column |
| section.header | 20 | 20px uppercase with letter-spacing 4 inside yellow pill |
| Bullet items (leftItems / rightItems) | 50 | 24px in half column, 2 lines max |
| Items per section | 5 max | More items overflow the canvas below the footer |
Validation loop (max 2 retries):
Write illustrations.json to {content-folder}/assets/illustrations.json:
[{"name": "pin-{concept}-icon", "prompt": "Scene description for illustration"}]
Generate illustrations (run from repo root):
pipenv run python3 scripts/tiktok/illustrations.py {content-folder}/assets/illustrations.json {content-folder}/assets/illustrations/
Copy illustrations to Remotion public: cp {content-folder}/assets/illustrations/*.png videos/public/
Write props.json to content folder. Icon filenames must match the generated illustration names exactly.
Render the still:
cd videos && npx remotion still PinterestTipsPin out/{slug}.png --props=../{content-folder}/props.json
(or PinterestComparisonPin for comparison format)
Copy PNG back to content folder.
For batch mode: Parallelize steps 10-15 across all pins in the batch (illustration generation, rendering). Each pin is independent.
For each rendered pin, launch a separate Opus agent to evaluate the rendered PNG. This replaces human visual review.
subagent_type: "general-purpose" and model: "opus". Pass the following prompt:You are a visual quality reviewer for Pinterest pin images. Review this rendered pin and determine if it meets publication quality standards.
## Files to Read
1. **Rendered PNG**: `{path-to-rendered-png}` — Read this file (it's an image, the Read tool supports images)
2. **Brief**: `{path-to-brief.md}` — Read for context on what this pin should contain
3. **Props**: `{path-to-props.json}` — Read for the exact text that should appear on the pin
## Brand Guidelines
- Simple white character with black outlines, gray watercolor shading
- Yellow (#FFD60A) as the ONLY color accent
- Clean, minimal, conceptual illustrations (not literal/photographic)
- Off-white/cream background (#FAFAF8)
- Professional, polished, save-worthy quality
## Review Criteria
Evaluate each criterion and rate as PASS or FAIL:
### CRITICAL (any failure = overall FAIL)
1. **Text Readability**: All text must be fully visible, not truncated, not cut off at edges, not overlapping other elements. Every word in the props.json must be readable on the pin.
2. **Layout Balance**: Proper spacing between all elements. Illustration positioned correctly (not overlapping text, not pushed off-canvas). No content overflowing below the footer or off the sides. Tips/bullets evenly distributed.
### IMPORTANT (2+ failures = overall FAIL)
3. **Illustration Quality**: The illustration should match the pin's concept (e.g., a pin about "brain dumping" should show someone writing/journaling, not an unrelated scene). Must follow brand style (white character, black outlines, gray shading, yellow accents only). Should be recognizable at thumbnail size (Pinterest users browse small).
4. **Overall Professional Quality**: The pin should look polished, intentional, and save-worthy. No rendering artifacts, no misaligned elements, no awkward whitespace gaps. Would a real Pinterest user save this?
## Output Format
Respond with EXACTLY this structure:
VERDICT: PASS or FAIL
TEXT_READABILITY: PASS/FAIL — [1-sentence explanation]
LAYOUT_BALANCE: PASS/FAIL — [1-sentence explanation]
ILLUSTRATION_QUALITY: PASS/FAIL — [1-sentence explanation]
PROFESSIONAL_QUALITY: PASS/FAIL — [1-sentence explanation]
ISSUES: [If FAIL, list specific issues that need fixing. Be precise: "title text is truncated after word X", "illustration overlaps the first tip", "bullet 3 text overflows to a third line". If PASS, write "None".]
FIX_SUGGESTIONS: [If FAIL, list specific fixes: "Shorten title to X characters", "Revise illustration prompt to show Y instead of Z". If PASS, write "None".]
On FAIL, apply fixes based on the agent's FIX_SUGGESTIONS:
| Failure Type | Fix Action |
|-------------|------------|
| Text truncation/overlap | Shorten the offending field in props.json, re-validate against char limits, re-render (~5s) |
| Illustration wrong concept/style | Revise the prompt in illustrations.json, regenerate illustration (~30s), copy to videos/public/, re-render |
| Layout overflow | Reduce content (fewer tips, shorter bullets), update props.json, re-render |
| Both text and illustration issues | Fix text first (faster), then illustration if still failing |
After fixing, re-render and re-launch the visual review agent.
After 3 failed attempts: skip this pin. Log the failure with the agent's last feedback summary. Continue to the next pin in the batch. Report all failures in the final email.
Publish each pin that passed visual review. One pin at a time (Chrome can only handle one tab interaction at once).
Prerequisites: Load Chrome tools via ToolSearch before using them.
Upload image to Supabase (the post_pin.py script uploads to Supabase before hitting the API 403):
pipenv run python3 scripts/pinterest/post_pin.py {image-path} \
--title "..." --description "..." --alt-text "..." --link "..."
Note the Supabase public URL from the output.
Get browser tab context: Call tabs_context_mcp with createIfEmpty: true.
Create a new tab and navigate to https://www.pinterest.com/pin-creation-tool/.
Click "Save from URL" link (visible at bottom of the upload area).
Type the Supabase public URL into the "Enter website" field and press Enter.
Wait 3 seconds for Pinterest to fetch and display the image thumbnail.
Click the image thumbnail to select it (checkmark appears).
Click "Add 1 Pin" button (bottom right).
Fill in SEO fields on the pin editor page:
form_input on the title textbox ref.<div> (combobox), NOT a standard input. Use left_click on the field, then type to enter the text.form_input on the revealed textarea ref.form_input with the destination link ref to replace the auto-populated Supabase URL with the blog post URL (e.g., https://clarido.app/blog/slug). Do NOT use cmd+a to select. Use read_page with filter: "interactive" to find the link textbox ref, then form_input to set the value.Verify with a screenshot, then click Publish button (red, top right).
Confirm success: Pinterest shows "You created a Pin!" modal. Click "See your Pin" to get the pin URL. Save the URL to the pin's brief.md.
Clean up Supabase: Delete the temporary image file after publishing.
Repeat steps 21-32 for each remaining pin in the batch.
After the entire batch completes (all pins published or skipped), send a single summary email.
Send email via mcp__google-workspace__send_gmail_message:
[email protected][email protected]{N} Pinterest Pins Published — {YYYY-MM-DD}{N} Pinterest pins published for @claridoapp.
PUBLISHED:
1. {Pin Title}
Pinterest: {pin URL}
Links to: {blog URL}
Format: {Tips/Comparison}
Visual review: passed on attempt {1/2/3}
2. ...
FAILED (if any):
1. {Pin Title}
Reason: {agent's last feedback summary}
Draft saved: {content folder path}
---
Sent by Clarido Marketing Automation
Report to user — Share the batch summary: number published, number failed, Pinterest URLs, and confirmation that the email was sent.
When invoked without a specific topic, the skill finds ALL gaps (blog posts without matching pins) and produces them in batch:
When invoked with a specific topic, produce a single pin end-to-end.
content/pinterest/YYYY-MM-DD_HHMM_slug/
├── brief.md # SEO fields, tips/comparison content, keywords
├── assets/
│ ├── illustrations/ # 1-2 PNGs (brand style icons)
│ └── illustrations.json
├── props.json # Remotion render props
├── performance.md # Analytics (filled after posting)
└── slug.png # Final 1000×1500 image
The Pinterest API app is on Trial access, which blocks pin creation in production (403 error). The Chrome automation "Save from URL" flow is the workaround.
upload_image tool: Screenshots are viewport-resolution JPEG, not the original 1000x1500 PNG.PinterestTipsPin and PinterestComparisonPin — registered in Root.tsx under <Folder name="Pinterest">npx remotion still, NOT npx remotion renderillustrations.json names, props.json icon fields, and files in videos/public/pipenv run python3 scripts/pinterest/refresh_token.pydocs/pinterest-pin-method.mdvideos/src/PinterestTipsPin/index.tsxvideos/src/PinterestComparisonPin/index.tsxscripts/pinterest/post_pin.pyscripts/pinterest/get_boards.pyscripts/tiktok/illustrations.pyassets/illustrations/overwhelmed-filing-cabinet.png, floating-yellow-balloon.png, planting-yellow-seedling.pngdevelopment
Best practices for Remotion - Video creation in React
development
Produce an Instagram Reel for Clarido — remix an existing TikTok concept with a deeper script, new voiceover, and expanded illustrations, then publish via the Instagram API. Use when creating new Instagram Reels content.
data-ai
Pull cross-channel GTM performance data from Meta Ads, Instagram, Pinterest, Blog, GA4, and Search Console — generate a unified report with analysis and recommendations.
business
End-to-end ad creative generation for Clarido — from performance analysis to rendered video variants. Use when creating new ad creatives, video ads, or marketing content.