From Planable SMM
Analyze top-performing posts across three performance lenses — engagement, impressions, and engagement rate — to identify content patterns and give the user specific hypotheses to test in their next posts. Use this skill whenever the user asks things like "what's working in my content", "what should I post more of", "why are some posts doing better", "what patterns do you see", "give me content ideas based on my best posts", "what content works best for [client]", "analyze my top posts", or "what should I try next month". Also activate when the user wants to understand performance beyond just numbers — when they're asking for creative direction, not just a report. Always use this skill instead of a generic performance summary when the user's goal is to improve future content.
How this skill is triggered — by the user, by Claude, or both
Slash command
/planable-smm:content-pattern-intelligenceThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Look at what's actually working — then tell the user why, and what to try next.
Look at what's actually working — then tell the user why, and what to try next.
This skill analyzes top posts across three performance lenses, finds patterns in the content itself (format, hook, topic, tone, structure), and translates them into specific, testable hypotheses for future posts.
This is not a performance report. It's a content brief grounded in data.
Mode A — Planable connector User has Planable connected and wants to pull live post data.
Mode B — CSV upload User has uploaded a CSV export with post-level data (text, date, platform, metrics).
How to detect:
Instagram metrics sync is async and slow. Always follow this sequence to avoid timeouts.
Always call get_post_metrics with exactly one pageId per request. Multi-page calls compound timeouts — never bundle multiple pages into a single call.
list_workspaces → find workspaceId
list_pages(workspaceId) → get pageIds
get_page_metrics(workspaceId, pageIds, startDate, endDate)
For each page in the response, check lastMetricAt (the timestamp of the last successful metrics fetch).
lastMetricAt is within the last 3 hours — data is fresh. Skip the refresh entirely. Proceed to Step 2c.lastMetricAt is older than 3 hours or missing — data is stale. Proceed to Step 2b.The posts field in the get_page_metrics response tells you the post count per page for the window. Record it now — use it to plan chunk size in Step 2c so you're not choosing a strategy inside the fetch loop.
Call refresh_page_metrics for the stale pages.
For Instagram pages specifically, tell the user before refreshing:
"Instagram metrics are syncing — this can take 1-2 minutes. I'll check back once the data is ready."
Then wait before re-reading:
get_page_metrics againAfter waiting, call get_page_metrics again and re-check lastMetricAt:
lastMetricAt is now more recent than the refresh call — sync completed. Proceed to Step 2c.lastMetricAt is still older — sync is still in progress. Wait another 30 seconds and retry once more.Process each page individually — never bundle multiple pages in one call.
For each page, follow this sequence:
1. Check post volume
Use the posts field already captured in Step 2a for this page. If it wasn't available there, call:
get_post_metrics_summary(workspaceId, [pageId], startDate, endDate)
→ read totalPosts for the window.
2. Choose chunk size based on totalPosts
| Posts in window | Strategy |
|---|---|
| ≤ 20 | Fetch full window in one call |
| 21–40 | Two 45-day chunks |
| 41–80 | ~6 chunks of 2 weeks each |
| 80+ | 1-week chunks |
3. Run all chunks for that page in parallel.
4. On timeout for any chunk — bisect:
Repeat for each page before moving on to Step 3.
If no file uploaded yet: "Please upload a CSV with your post data — it should include post text, platform, and at least one of: likes, comments, shares, impressions, or engagement rate."
Supported sources: Planable Analytics export, Meta Business Suite, LinkedIn Analytics, Hootsuite, Sprout Social, or any post-level CSV.
Identify:
text, caption, message, content, or similarplatform, channel, network, pageimpressions, reach, viewsengagement_rate, eng_rate, or calculate as total_engagement / impressionsIf post text is missing or too short to analyze (under 10 chars average), tell the user — pattern analysis won't be meaningful without the actual content.
Take all posts with available data and produce:
If fewer than 10 posts exist for a lens, use all available. Minimum 5 posts per lens to draw patterns. Fewer than 5 → note the limitation but still try.
For each ranked list, read the actual post text and look for recurring patterns across the top performers. Analyze along these dimensions:
Format signals
Hook patterns
Topic/theme signals
Tone signals
Timing / context signals (if date data is available)
Compare the top-performing posts against the bottom performers (or average performers) in the dataset. What do the worst posts have that the best ones don't? What's missing?
This is the most valuable part — patterns only matter if they're actually differentiating.
Produce the analysis in this format:
Based on [X] posts analyzed across [date range]
Open with this section every time, before any pattern detail. It should be readable in 20 seconds.
What's working:
Try these next:
Skip more of:
Keep the TL;DR to 8–10 lines max. No examples, no explanations — just the signal. The detail sections below support every point made here.
Top posts by total likes, comments, shares, and saves
Assign each pattern a descriptive emoji that reflects its nature. Pick the emoji based on what the pattern actually is — don't default to generic ones. Examples: 🙋 for question-openers, 📋 for list formats, 💬 for conversational tone, 📊 for data/stats posts, 🎭 for storytelling, 🔥 for opinionated takes, 🪞 for audience-mirror posts (about the reader, not the brand), 🧵 for thread-style structure, 🎯 for direct CTAs. Choose what fits — these are examples, not a fixed list.
[emoji] Pattern [#]: [Short name for the pattern] What it is: [One sentence describing the pattern] Example: "[First 80 chars of a top post that shows this]..." Why it likely works: [One sentence of honest reasoning — don't overclaim] ➡️ Try this: [Specific, actionable thing to test in the next post or batch]
(Repeat for each distinct pattern found — aim for 2–4 patterns per lens, not more)
Top posts by reach and views
Same emoji logic as above — pick one per pattern that reflects what that pattern actually is.
[emoji] Pattern [#]: [Short name] What it is: [One sentence] Example: "[Post preview]..." Why it likely works: [One sentence] ➡️ Try this: [Specific test]
(2–4 patterns)
Top posts by engagement relative to reach — the best signal for content that genuinely resonates
Same emoji logic — one per pattern, chosen to reflect the pattern's nature.
[emoji] Pattern [#]: [Short name] What it is: [One sentence] Example: "[Post preview]..." Why it likely works: [One sentence] ➡️ Try this: [Specific test]
(2–4 patterns)
1–2 observations from the lower performers. Keep it honest and specific.
Always include all of the following in this section:
Plus flag anything else that affects confidence: small sample size, one platform only, missing post text, etc.
Emoji usage rule: Emojis appear in two places only — (1) once per pattern label, chosen to reflect the pattern's content, and (2) in section headers. Never inline within sentences or used decoratively. The TL;DR has no emojis except the ⚡ header.
After delivering the in-chat text analysis, generate a self-contained HTML file saved to /mnt/user-data/outputs/[client]-content-patterns-[month].html and present it with present_files.
The HTML report is the visual companion to the text output — same structure, same data, but charts replace walls of text. Design it to be shareable with a client or team lead.
Aesthetic: Clean, modern, data-forward. Use Planable green #3BBA7B as the primary accent. Card layout. Clear hierarchy. Feels like a real agency deliverable, not a generated doc.
Font: Load Plus Jakarta Sans from Google Fonts for body; Bricolage Grotesque for headings.
Color palette:
:root {
--green: #3BBA7B;
--green-light: #EAF7F0;
--green-mid: #2a9d63;
--amber: #F59E0B;
--amber-light: #FEF3C7;
--red: #EF4444;
--red-light: #FEE2E2;
--blue: #3B82F6;
--blue-light: #EFF6FF;
--purple: #8B5CF6;
--purple-light: #F5F3FF;
--text: #1A1A2E;
--text-muted: #6B7280;
--bg: #F8FAFC;
--card: #FFFFFF;
--border: #E5E7EB;
}
1. Header
2. ⚡ TL;DR card Render the TL;DR as a highlighted card — green left border, slightly tinted background. Three columns: "What's working" / "Try next" / "Skip more of." This is the first thing a client sees.
3. 📣 Engagement patterns — bar chart
Horizontal bar chart comparing average engagement per post for each pattern identified.
Data to use: calculate average engagement for posts that match each pattern vs. posts that don't. If exact pattern-level data isn't available, use the top-10 vs. bottom-10 split as a proxy and label it clearly.
4. 👀 Impressions patterns — bar chart
Same structure as above but for impressions data.
--blue) for top patterns, muted for lower5. 💡 Engagement rate patterns — horizontal comparison bars
For engagement rate, use a visual that shows relative performance — e.g. grouped bars or a dot/lollipop chart showing engagement rate % per pattern.
--purple) for this lens6. 🏆 Triple performers (if any)
If any posts appear in all three top-10 lists, give them a dedicated card with a gold/amber treatment. Show the post text, and its scores across all three metrics. Label clearly: "This post did everything right."
7. ⚠️ What's not working
Two-column layout: left side shows the underperforming pattern with its average metric; right side shows the contrast against the top pattern in the same lens. Makes the gap visible.
8. 🧪 What to test next
Three action cards in a row. Each card:
9. Footer "Generated with Planable + Claude · [date]"
Build all charts in pure HTML/CSS — no external JS chart libraries. Use CSS-only techniques:
Bar charts: div elements with width set as a percentage of the max value, using CSS variables. Animate bars on load with a width transition from 0 to final value (animation: grow 0.8s ease-out forwards with animation-delay staggered per bar).
@keyframes grow {
from { width: 0; }
to { width: var(--bar-width); }
}
Set --bar-width as an inline style per bar based on the actual data values.
Lollipop / dot chart for engagement rate: horizontal line (border-top: 2px dashed) with a dot at the end (border-radius: 50%), same CSS animation approach.
Reference line: a vertical div with position: absolute and border-left: 2px dashed var(--text-muted) to mark the platform average.
Labels: always show the actual number on or beside each bar. Don't make users guess from axis position alone.
Responsive: bars scale correctly at 600px–1200px. Cards wrap to single column below 700px.
.html file — no external dependencies except Google Fonts@media print block: hides nothing, keeps colors (use -webkit-print-color-adjust: exact)aria-label on chart containers, sufficient color contrastBe specific. "Posts that start with a question get more comments" beats "engaging content performs well." If you can't be specific, you don't have enough data — say so.
Show the evidence. Every pattern must reference actual posts from the data. Don't name a pattern you can't point to.
Honest about uncertainty. These are hypotheses, not conclusions. Use "likely", "seems to", "worth testing" — not "definitely" or "proven."
One actionable test per pattern. The ➡️ Try this line must be something the user could actually put in a brief tomorrow. Not "post more questions" — but "open your next LinkedIn post with a direct question to your audience, and end with a second question in the last line."
Don't invent patterns. If the top posts have nothing in common, say so. Sometimes the data is noisy.
Length: As long as the data warrants. 3 lenses × 2–4 patterns each = typically 600–1,000 words of output. Don't pad; don't compress if the patterns are real.
npx claudepluginhub planable/smm-skills --plugin planable-smmProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.