Year-end wrapped experience - stats, story, achievements, and community belonging. A personalized reflection on the user's year with the agent.
This plugin is NOT a dashboard. It's a story.
Dashboards dump data. Stories create emotion. We want users to feel:
| Emotion | Example | Why It Matters |
|---|---|---|
| VALIDATED | "847 messages - that's a lot!" | Confirms their engagement was meaningful |
| NOSTALGIC | "Remember your first question?" | Creates emotional anchor to the past |
| PROUD | "You're in the Top 10%!" | Identity and social proof |
| BELONGING | "You contributed 4.2% of this room" | Part of something larger |
Every stat, every chapter, every achievement serves an emotional purpose.
The opening line is the MOST important part. Different users deserve different hooks:
Power user: "Top contributor. You're not just here. You're part of this."
Night owl: "847 messages. Most of them after dark."
Veteran: "One year ago, you typed your first message."
Curious mind: "423 questions in one year. Never stop asking."
A generic "Here are your stats!" fails to create the "they SEE me" moment.
We use Unicode box-drawing characters because:
- Works everywhere - Any chat platform, any font
- Copy-pasteable - Users can share in text
- Retro aesthetic - Intentional visual choice
- Zero dependencies - Pure text, no images
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β 847 β β 23,456 β β 156 β
β MESSAGES β β WORDS β β CONVOS β
β Power user! β β ~47 pages β β 1 per 2 daysβ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
"CHAPTER 2: THE JOURNEY" tells a story. "Section 2: Activity Data" dumps data.
The narrative structure creates emotional investment. Users read left-to-right, top-to-bottom, experiencing a journey through their year.
Achievements serve multiple purposes:
- Identity - "I'm a Night Owl" becomes part of self-concept
- Validation - Recognition for effort
- Aspiration - Locked badges create goals
- Shareability - "I got the legendary badge!" is social content
Easter eggs (42, 69, 420, 1337) reward attention and create shareable moments. They turn stats into stories. "I got 'The Answer'!" is a conversation starter.
- π The Numbers: Personal stats with prominent display - message counts, time patterns, records
- π Story Chapters: Narrative journey through the year
- Chapter 1: The Beginning - First message, origin story
- Chapter 2: The Journey - Monthly rhythm, patterns, streaks
- Chapter 3: The Growth - Q1 vs Q4 evolution, question complexity
- Chapter 4: Your Place - Community belonging, rank, contribution
- π Achievements: 18 unlockable badges based on activity
- π² Fun Facts & Trivia: Quirky observations and easter eggs
- π± Shareable Card: Compact summary for sharing
- πΌοΈ Shareable Image Cards: 10 beautiful PNG cards for social media (NEW!)
The plugin now generates beautiful PNG image cards that users can download and share on social media. Each card is designed to:
- Look premium (dark mode, modern typography)
- Work across all social platforms
- Make users proud to share
- Promote ElizaOS and the community
| Card | Purpose | Eligibility |
|---|---|---|
| Headline | Main stats (messages, conversations, streak) | Always |
| Rank | Community standing (TOP X%) | Top 25% only |
| Vibe | Archetype (Night Owl, Question Machine, etc.) | Clear pattern |
| Signature | Monthly activity "DNA" visualization | 50+ messages |
| Origin | First message quote | Safe quote exists |
| Evolution | Q1 vs Q4 quote comparison | Growth + quotes |
| 3AM | Late night quote | Safe late-night quote |
| Plot Twist | Unexpected stat (humor) | Interesting anomaly |
| Trophy | Achievement badges | 2+ badges |
| Invitation | Community promo | Always |
TEXT WRAPPED: "You sent 847 messages"
IMAGE CARD: [Beautiful PNG showing 847 in giant typography]
TEXT WRAPPED: Gets copied, loses formatting, looks generic
IMAGE CARD: Gets shared as-is, looks premium, goes viral
"Digital Artifact" - Not trying to copy Spotify. Our vibe:
- Dark mode native (works everywhere, feels premium)
- Generous whitespace (cards breathe)
- One hero element (each card has ONE thing that pops)
- Typography hierarchy (big numbers, subtle labels)
Cards are rendered using:
- satori: JSX β SVG (React-like syntax)
- resvg: SVG β PNG (Rust-based, high quality)
- Base64 data URLs: No file hosting needed
// Each card is sent as a message with an image attachment
await callback({
text: 'Chapter 1: The Numbers',
attachments: [{
url: card.dataUrl, // Base64 PNG
contentType: ContentType.IMAGE
}]
});bun add @elizaos/plugin-wrappedimport { wrappedPlugin } from '@elizaos/plugin-wrapped';
const agent = {
plugins: [wrappedPlugin],
};Users can trigger wrapped with phrases like:
- "show me my wrapped"
- "what was our year like"
- "give me my year in review"
- "how much have we talked"
- "my stats"
The output follows a deliberate emotional arc:
1. HOOK β Grab attention ("Remember...?")
2. THE NUMBERS β Validate importance (big stats in boxes)
3. CHAPTER 1 β Origin story (nostalgia)
4. CHAPTER 2 β The journey (rhythm, streaks)
5. CHAPTER 3 β Growth (evolution, progress)
6. CHAPTER 4 β Belonging (community, rank)
7. ACHIEVEMENTS β Identity (badges earned)
8. TRIVIA β Delight (fun facts, easter eggs)
9. CLOSE β Forward momentum ("Here's to next year")
10. CARD β Shareability (compact summary)
π YOUR 2024 WRAPPED
ββββββββββββββββββββ
Remember "Can you help me debug this?"?
Look at you now.
π YOUR 2024 BY THE NUMBERS
βββββββββββββββββββββββββββ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β 847 β β 23,456 β β 156 β
β MESSAGES β β WORDS β β CONVOS β
β Power user! β β ~47 pages β β 1 per 2 daysβ
βββββββββββββββ βββββββββββββββ βββββββββββββββ
YOUR RECORDS
ββββββββββββ
π Longest conversation 67 msgs Oct 23
π Longest message 312 words Oct 15
π₯ Longest streak 23 days Mar 3-26
π Latest night owl 3:47 AM Feb 14
π CHAPTER 2: THE JOURNEY
βββββββββββββββββββββββββ
From January to December, 156 conversations.
Once every 2.3 days, on average.
But averages hide the real story:
Jan ββββββββββ 45 Jul ββββββββββ 23
Feb ββββββββββ 67 Aug ββββββββββ 48
Mar ββββββββββ 89 Sep ββββββββββ 76
Apr ββββββββββ 72 Oct ββββββββββ 127 β your peak
May ββββββββββ 54 Nov ββββββββββ 94
Jun ββββββββββ 31 Dec ββββββββββ 71
October. 127 messages. Something was happening.
π ACHIEVEMENTS UNLOCKED (9/18)
ββββββββββββββββββββββββββββββ
EARNED
β
Year One π 365+ days
β
Night Owl π¦ 50+ msgs after midnight
β
Curious Mind π§ 200+ questions asked
β
Streak Master π₯ 20+ day streak
| Badge | Name | Description | Rarity |
|---|---|---|---|
| π | Year One | Been here 365+ days | Uncommon |
| π± | Early Adopter | Joined in first 30 days | Rare |
| ποΈ | Founding Member | One of first 10 in room | Legendary |
| Badge | Name | Description | Rarity |
|---|---|---|---|
| π¬ | Conversation Starter | 50+ conversations | Common |
| π€Ώ | Deep Diver | 10+ deep conversations | Uncommon |
| π― | Centurion | 100+ messages in one month | Rare |
| π | Marathon | 50+ message conversation | Rare |
| Badge | Name | Description | Rarity |
|---|---|---|---|
| π¦ | Night Owl | 50+ messages after midnight | Uncommon |
| π¦ | Early Bird | 50+ messages before 8am | Uncommon |
| βοΈ | Weekend Warrior | 60%+ on weekends | Uncommon |
| π | Night Shift | 100+ messages 12am-5am | Epic |
| Badge | Name | Description | Rarity |
|---|---|---|---|
| π§ | Curious Mind | 200+ questions | Uncommon |
| π | Storyteller | Average 40+ words/message | Uncommon |
| Badge | Name | Description | Rarity |
|---|---|---|---|
| π | Top Contributor | Top 10% in room | Rare |
| ποΈ | Community Pillar | Top 10% + 6mo tenure | Epic |
| Badge | Name | Description | Rarity |
|---|---|---|---|
| β‘ | Streak Starter | 7+ day streak | Common |
| π₯ | Streak Master | 20+ day streak | Uncommon |
| π | The Streak | 100+ day streak | Legendary |
The plugin detects special numbers and patterns:
- π₯ Nice. - Exactly 69 messages in a month
- π₯ The Answer - 42-day streak (Hitchhiker's Guide reference)
- π₯ Blaze It - Exactly 420 messages
- π₯ L33T - 1337 messages
- π₯ Palindrome - Message count reads the same backwards (e.g., 121)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ACTION LAYER β
β GET_WRAPPED action handles triggers β
β Orchestrates: data β text output β card gallery β
ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββ΄ββββββββββββββββββββ
βΌ βΌ
ββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββ
β DATA LAYER β β CARD LAYER (NEW!) β
β β β β
β collector.ts - Raw msgs β β generator.ts - PNG rendering β
β personal.ts - User stats β β selector.ts - Eligibility β
β community.ts - Rankings β β quotes.ts - Safe quotes β
β growth.ts - Evolution β β colors.ts - Theming β
β streaks.ts - Streaks β β fonts.ts - Font loading β
β β β β
ββββββββββββββ¬ββββββββββββββββ β designs/ β
β β headline.tsx - Stats card β
βΌ β rank.tsx - TOP X% β
ββββββββββββββββββββββββββββββ β trophy.tsx - Badges β
β COMPOSER LAYER β β vibe.tsx - Archetype β
β β β signature.tsx - DNA viz β
β hook.ts - Opening β β origin.tsx - First msg β
β numbers.ts - Stats β β evolution.tsx - Q1 vs Q4 β
β beginning.ts - Ch. 1 β β threeAm.tsx - Late night β
β journey.ts - Ch. 2 β β plotTwist.tsx - Humor β
β growth.ts - Ch. 3 β β invitation.tsx- Promo β
β belonging.ts - Ch. 4 β β β
β achievements - Badges β ββββββββββββββββββββββββββββββββββ
β trivia.ts - Fun facts β
β close.ts - Ending β
β card.ts - Text card β
ββββββββββββββ¬ββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββ
β UTILITY LAYER β
β β
β formatters.ts - ASCII art β
β time.ts - Dates β
β text.ts - Analysis β
ββββββββββββββββββββββββββββββ
USER DATA (PersonalStats, StreakData, etc.)
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β ELIGIBILITY CHECK β
β selector.ts: Which cards qualify? β
β β
β β’ Has enough messages? β
β β’ In top 25%? β
β β’ Safe quotes available? β
β β’ Interesting anomaly found? β
βββββββββββββββββββ¬ββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β CARD GENERATION β
β β
β For each eligible card: β
β 1. Create JSX component β
β 2. satori: JSX β SVG β
β 3. resvg: SVG β PNG Buffer β
β 4. Convert to Base64 data URL β
βββββββββββββββββββ¬ββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β GALLERY OUTPUT β
β β
β Send cards in chapters: β
β Ch 1: Numbers (Headline, Rank) β
β Ch 2: Identity (Vibe, Signature) β
β Ch 3: Story (Origin, Evolution...) β
β Ch 4: Fun (Plot Twist, Trophy) β
β Ch 5: Promo (Invitation) β
βββββββββββββββββββββββββββββββββββββββ
import { wrappedPlugin } from '@elizaos/plugin-wrapped';import {
collectUserMessages, // Get all messages for a user
computePersonalStats, // Calculate personal metrics
computeStreaks, // Calculate streak data
computeCommunityStats, // Calculate room rankings
computeGrowthStats, // Compare Q1 to Q4
evaluateAchievements, // Check which badges earned
} from '@elizaos/plugin-wrapped';import {
composeHookSection, // Opening line
composeNumbersSection, // Stats with comparisons
composeBeginningSection, // Chapter 1
composeJourneySection, // Chapter 2
composeGrowthSection, // Chapter 3
composeBelongingSection, // Chapter 4
composeAchievementsSection, // Badges
composeTriviaSection, // Fun facts
composeCloseSection, // Ending
composeCardSection, // Shareable card
} from '@elizaos/plugin-wrapped';import type {
PersonalStats, // User's message stats
StreakData, // Streak information
CommunityStats, // Room rankings
GrowthStats, // Q1 vs Q4 comparison
ComparisonStats, // Percentiles and averages
Achievement, // Badge definition
AchievementResult, // Badge evaluation result
WrappedData, // Complete wrapped bundle
FunFact, // Trivia item
EasterEgg, // Special number detection
} from '@elizaos/plugin-wrapped';import {
// Core rendering
renderCard, // Render JSX to PNG buffer
renderCards, // Render multiple cards in parallel
// Card components
HeadlineCard, // Main stats card
RankCard, // Community ranking card
TrophyCard, // Achievements card
VibeCard, // Archetype card
SignatureCard, // Activity DNA card
OriginCard, // First message card
EvolutionCard, // Q1 vs Q4 card
ThreeAmCard, // Late night card
PlotTwistCard, // Humor card
InvitationCard, // Promo card
// Eligibility
checkCardEligibility, // Check which cards user qualifies for
getEligibleCards, // Get list of eligible card types
// Quote safety
selectSafeQuote, // Find a safe quote to display
selectFirstSafeQuote, // Get first safe message
selectLateNightQuote, // Get safe 3AM quote
isQuoteSafe, // Check if text is safe to share
// Theming
selectTheme, // Choose theme based on behavior
themes, // Available theme presets
} from '@elizaos/plugin-wrapped';import type {
CardFormat, // 'square' | 'story' | 'wide'
RenderedCard, // { buffer, width, height, dataUrl }
CardType, // All card type names
CardEligibility, // Eligibility result for one card
EligibilityResult, // All eligibility results
QuoteCriteria, // Quote selection options
SelectedQuote, // Selected quote with metadata
VibeData, // Archetype information
PlotTwistData, // Plot twist headline/subtext
Theme, // Color theme
} from '@elizaos/plugin-wrapped';MIT