From 75168f7678c4f47b9c3fbaf9a6e57208dff77970 Mon Sep 17 00:00:00 2001 From: Nicholai Date: Sat, 24 Jan 2026 03:27:11 -0700 Subject: [PATCH] init: agent event bus + state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit structure: state/CURRENT.md — 2-4 line session state (rewritten each session) events/ — json event bus (pull-based, optional context) persistent/ — important decisions (one doc per decision) emit — helper script for emitting events --- .gitignore | 1 + emit | 18 + ...25-clawdbot-configured-discord-server.json | 1 + ...5-clawdbot-deployed-discord-feed-bots.json | 1 + ...25-clawdbot-installed-audio-separator.json | 1 + ...69250425-clawdbot-installed-image-gen.json | 1 + ...250425-clawdbot-setup-agent-event-bus.json | 1 + .../ask-questions-if-underspecified/SKILL.md | 85 + skills/kpi-dashboard-design/SKILL.md | 428 +++ skills/meme-factory/SKILL.md | 331 ++ skills/meme-factory/references/examples.md | 457 +++ .../references/markdown-memes-guide.md | 1082 +++++++ skills/meme-factory/scripts/meme_generator.py | 244 ++ skills/remotion-best-practices/SKILL.md | 43 + skills/remotion-best-practices/rules/3d.md | 86 + .../rules/animations.md | 29 + .../remotion-best-practices/rules/assets.md | 78 + .../rules/assets/charts-bar-chart.tsx | 173 ++ .../assets/text-animations-typewriter.tsx | 100 + .../assets/text-animations-word-highlight.tsx | 108 + skills/remotion-best-practices/rules/audio.md | 172 ++ .../rules/calculate-metadata.md | 104 + .../rules/can-decode.md | 75 + .../remotion-best-practices/rules/charts.md | 58 + .../rules/compositions.md | 146 + .../rules/display-captions.md | 126 + .../rules/extract-frames.md | 229 ++ skills/remotion-best-practices/rules/fonts.md | 152 + .../rules/get-audio-duration.md | 58 + .../rules/get-video-dimensions.md | 68 + .../rules/get-video-duration.md | 58 + skills/remotion-best-practices/rules/gifs.md | 138 + .../remotion-best-practices/rules/images.md | 130 + .../rules/import-srt-captions.md | 67 + .../remotion-best-practices/rules/lottie.md | 68 + .../rules/measuring-dom-nodes.md | 35 + .../rules/measuring-text.md | 143 + .../rules/sequencing.md | 106 + .../remotion-best-practices/rules/tailwind.md | 11 + .../rules/text-animations.md | 20 + .../remotion-best-practices/rules/timing.md | 179 ++ .../rules/transcribe-captions.md | 19 + .../rules/transitions.md | 122 + .../remotion-best-practices/rules/trimming.md | 53 + .../remotion-best-practices/rules/videos.md | 171 ++ skills/reverse-engineering-tools/SKILL.md | 142 + skills/skill-creator/LICENSE.txt | 202 ++ skills/skill-creator/SKILL.md | 356 +++ .../references/output-patterns.md | 82 + skills/skill-creator/references/workflows.md | 28 + skills/skill-creator/scripts/init_skill.py | 303 ++ skills/skill-creator/scripts/package_skill.py | 110 + .../skill-creator/scripts/quick_validate.py | 95 + skills/skills-installer/SKILL.md | 56 + skills/vercel-react-best-practices/AGENTS.md | 2719 +++++++++++++++++ skills/vercel-react-best-practices/SKILL.md | 125 + .../rules/advanced-event-handler-refs.md | 55 + .../rules/advanced-use-latest.md | 39 + .../rules/async-api-routes.md | 38 + .../rules/async-defer-await.md | 80 + .../rules/async-dependencies.md | 51 + .../rules/async-parallel.md | 28 + .../rules/async-suspense-boundaries.md | 99 + .../rules/bundle-barrel-imports.md | 59 + .../rules/bundle-conditional.md | 31 + .../rules/bundle-defer-third-party.md | 49 + .../rules/bundle-dynamic-imports.md | 35 + .../rules/bundle-preload.md | 50 + .../rules/client-event-listeners.md | 74 + .../rules/client-localstorage-schema.md | 71 + .../rules/client-passive-event-listeners.md | 48 + .../rules/client-swr-dedup.md | 56 + .../rules/js-batch-dom-css.md | 107 + .../rules/js-cache-function-results.md | 80 + .../rules/js-cache-property-access.md | 28 + .../rules/js-cache-storage.md | 70 + .../rules/js-combine-iterations.md | 32 + .../rules/js-early-exit.md | 50 + .../rules/js-hoist-regexp.md | 45 + .../rules/js-index-maps.md | 37 + .../rules/js-length-check-first.md | 49 + .../rules/js-min-max-loop.md | 82 + .../rules/js-set-map-lookups.md | 24 + .../rules/js-tosorted-immutable.md | 57 + .../rules/rendering-activity.md | 26 + .../rules/rendering-animate-svg-wrapper.md | 47 + .../rules/rendering-conditional-render.md | 40 + .../rules/rendering-content-visibility.md | 38 + .../rules/rendering-hoist-jsx.md | 46 + .../rules/rendering-hydration-no-flicker.md | 82 + .../rules/rendering-svg-precision.md | 28 + .../rules/rendering-usetransition-loading.md | 75 + .../rules/rerender-defer-reads.md | 39 + .../rules/rerender-dependencies.md | 45 + .../rules/rerender-derived-state.md | 29 + .../rules/rerender-functional-setstate.md | 74 + .../rules/rerender-lazy-state-init.md | 58 + .../rules/rerender-memo-with-default-value.md | 38 + .../rules/rerender-memo.md | 44 + .../rerender-simple-expression-in-memo.md | 35 + .../rules/rerender-transitions.md | 40 + .../rules/server-after-nonblocking.md | 73 + .../rules/server-auth-actions.md | 96 + .../rules/server-cache-lru.md | 41 + .../rules/server-cache-react.md | 76 + .../rules/server-dedup-props.md | 65 + .../rules/server-parallel-fetching.md | 83 + .../rules/server-serialization.md | 38 + skills/web-perf/SKILL.md | 193 ++ skills/wrangler/SKILL.md | 887 ++++++ state/CURRENT.md | 3 + 111 files changed, 13857 insertions(+) create mode 100644 .gitignore create mode 100755 emit create mode 100644 events/1769250425-clawdbot-configured-discord-server.json create mode 100644 events/1769250425-clawdbot-deployed-discord-feed-bots.json create mode 100644 events/1769250425-clawdbot-installed-audio-separator.json create mode 100644 events/1769250425-clawdbot-installed-image-gen.json create mode 100644 events/1769250425-clawdbot-setup-agent-event-bus.json create mode 100644 skills/ask-questions-if-underspecified/SKILL.md create mode 100644 skills/kpi-dashboard-design/SKILL.md create mode 100644 skills/meme-factory/SKILL.md create mode 100644 skills/meme-factory/references/examples.md create mode 100644 skills/meme-factory/references/markdown-memes-guide.md create mode 100644 skills/meme-factory/scripts/meme_generator.py create mode 100644 skills/remotion-best-practices/SKILL.md create mode 100644 skills/remotion-best-practices/rules/3d.md create mode 100644 skills/remotion-best-practices/rules/animations.md create mode 100644 skills/remotion-best-practices/rules/assets.md create mode 100644 skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx create mode 100644 skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx create mode 100644 skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx create mode 100644 skills/remotion-best-practices/rules/audio.md create mode 100644 skills/remotion-best-practices/rules/calculate-metadata.md create mode 100644 skills/remotion-best-practices/rules/can-decode.md create mode 100644 skills/remotion-best-practices/rules/charts.md create mode 100644 skills/remotion-best-practices/rules/compositions.md create mode 100644 skills/remotion-best-practices/rules/display-captions.md create mode 100644 skills/remotion-best-practices/rules/extract-frames.md create mode 100644 skills/remotion-best-practices/rules/fonts.md create mode 100644 skills/remotion-best-practices/rules/get-audio-duration.md create mode 100644 skills/remotion-best-practices/rules/get-video-dimensions.md create mode 100644 skills/remotion-best-practices/rules/get-video-duration.md create mode 100644 skills/remotion-best-practices/rules/gifs.md create mode 100644 skills/remotion-best-practices/rules/images.md create mode 100644 skills/remotion-best-practices/rules/import-srt-captions.md create mode 100644 skills/remotion-best-practices/rules/lottie.md create mode 100644 skills/remotion-best-practices/rules/measuring-dom-nodes.md create mode 100644 skills/remotion-best-practices/rules/measuring-text.md create mode 100644 skills/remotion-best-practices/rules/sequencing.md create mode 100644 skills/remotion-best-practices/rules/tailwind.md create mode 100644 skills/remotion-best-practices/rules/text-animations.md create mode 100644 skills/remotion-best-practices/rules/timing.md create mode 100644 skills/remotion-best-practices/rules/transcribe-captions.md create mode 100644 skills/remotion-best-practices/rules/transitions.md create mode 100644 skills/remotion-best-practices/rules/trimming.md create mode 100644 skills/remotion-best-practices/rules/videos.md create mode 100644 skills/reverse-engineering-tools/SKILL.md create mode 100644 skills/skill-creator/LICENSE.txt create mode 100644 skills/skill-creator/SKILL.md create mode 100644 skills/skill-creator/references/output-patterns.md create mode 100644 skills/skill-creator/references/workflows.md create mode 100755 skills/skill-creator/scripts/init_skill.py create mode 100755 skills/skill-creator/scripts/package_skill.py create mode 100755 skills/skill-creator/scripts/quick_validate.py create mode 100644 skills/skills-installer/SKILL.md create mode 100644 skills/vercel-react-best-practices/AGENTS.md create mode 100644 skills/vercel-react-best-practices/SKILL.md create mode 100644 skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md create mode 100644 skills/vercel-react-best-practices/rules/advanced-use-latest.md create mode 100644 skills/vercel-react-best-practices/rules/async-api-routes.md create mode 100644 skills/vercel-react-best-practices/rules/async-defer-await.md create mode 100644 skills/vercel-react-best-practices/rules/async-dependencies.md create mode 100644 skills/vercel-react-best-practices/rules/async-parallel.md create mode 100644 skills/vercel-react-best-practices/rules/async-suspense-boundaries.md create mode 100644 skills/vercel-react-best-practices/rules/bundle-barrel-imports.md create mode 100644 skills/vercel-react-best-practices/rules/bundle-conditional.md create mode 100644 skills/vercel-react-best-practices/rules/bundle-defer-third-party.md create mode 100644 skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md create mode 100644 skills/vercel-react-best-practices/rules/bundle-preload.md create mode 100644 skills/vercel-react-best-practices/rules/client-event-listeners.md create mode 100644 skills/vercel-react-best-practices/rules/client-localstorage-schema.md create mode 100644 skills/vercel-react-best-practices/rules/client-passive-event-listeners.md create mode 100644 skills/vercel-react-best-practices/rules/client-swr-dedup.md create mode 100644 skills/vercel-react-best-practices/rules/js-batch-dom-css.md create mode 100644 skills/vercel-react-best-practices/rules/js-cache-function-results.md create mode 100644 skills/vercel-react-best-practices/rules/js-cache-property-access.md create mode 100644 skills/vercel-react-best-practices/rules/js-cache-storage.md create mode 100644 skills/vercel-react-best-practices/rules/js-combine-iterations.md create mode 100644 skills/vercel-react-best-practices/rules/js-early-exit.md create mode 100644 skills/vercel-react-best-practices/rules/js-hoist-regexp.md create mode 100644 skills/vercel-react-best-practices/rules/js-index-maps.md create mode 100644 skills/vercel-react-best-practices/rules/js-length-check-first.md create mode 100644 skills/vercel-react-best-practices/rules/js-min-max-loop.md create mode 100644 skills/vercel-react-best-practices/rules/js-set-map-lookups.md create mode 100644 skills/vercel-react-best-practices/rules/js-tosorted-immutable.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-activity.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-conditional-render.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-content-visibility.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-svg-precision.md create mode 100644 skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-defer-reads.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-dependencies.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-derived-state.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-functional-setstate.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-memo.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md create mode 100644 skills/vercel-react-best-practices/rules/rerender-transitions.md create mode 100644 skills/vercel-react-best-practices/rules/server-after-nonblocking.md create mode 100644 skills/vercel-react-best-practices/rules/server-auth-actions.md create mode 100644 skills/vercel-react-best-practices/rules/server-cache-lru.md create mode 100644 skills/vercel-react-best-practices/rules/server-cache-react.md create mode 100644 skills/vercel-react-best-practices/rules/server-dedup-props.md create mode 100644 skills/vercel-react-best-practices/rules/server-parallel-fetching.md create mode 100644 skills/vercel-react-best-practices/rules/server-serialization.md create mode 100644 skills/web-perf/SKILL.md create mode 100644 skills/wrangler/SKILL.md create mode 100644 state/CURRENT.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..4f7717528 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +# no ignores, track everything diff --git a/emit b/emit new file mode 100755 index 000000000..0f0fe8576 --- /dev/null +++ b/emit @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Emit an event to the agent event bus +# Usage: emit [summary] +# Example: emit clawdbot deployed discord-feed-bots "5 feeds live" + +AGENT="${1:?usage: emit [summary]}" +ACTION="${2:?}" +SUBJECT="${3:?}" +SUMMARY="${4:-}" +TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) +EPOCH=$(date +%s) +FILE="$HOME/.agents/events/${EPOCH}-${AGENT}-${ACTION}-${SUBJECT}.json" + +cat > "$FILE" << EOF +{"agent":"$AGENT","action":"$ACTION","subject":"$SUBJECT","summary":"$SUMMARY","timestamp":"$TIMESTAMP"} +EOF + +echo "$FILE" diff --git a/events/1769250425-clawdbot-configured-discord-server.json b/events/1769250425-clawdbot-configured-discord-server.json new file mode 100644 index 000000000..f892ca963 --- /dev/null +++ b/events/1769250425-clawdbot-configured-discord-server.json @@ -0,0 +1 @@ +{"agent":"clawdbot","action":"configured","subject":"discord-server","summary":"feeds category, server category, welcome + announcements channels","timestamp":"2026-01-24T10:27:05Z"} diff --git a/events/1769250425-clawdbot-deployed-discord-feed-bots.json b/events/1769250425-clawdbot-deployed-discord-feed-bots.json new file mode 100644 index 000000000..546f621af --- /dev/null +++ b/events/1769250425-clawdbot-deployed-discord-feed-bots.json @@ -0,0 +1 @@ +{"agent":"clawdbot","action":"deployed","subject":"discord-feed-bots","summary":"reddit, github, twitter, claude releases, weekly trends — systemd timers + webhooks","timestamp":"2026-01-24T10:27:05Z"} diff --git a/events/1769250425-clawdbot-installed-audio-separator.json b/events/1769250425-clawdbot-installed-audio-separator.json new file mode 100644 index 000000000..9ed73d0d7 --- /dev/null +++ b/events/1769250425-clawdbot-installed-audio-separator.json @@ -0,0 +1 @@ +{"agent":"clawdbot","action":"installed","subject":"audio-separator","summary":"UVR5 stem splitting + yt-dlp","timestamp":"2026-01-24T10:27:05Z"} diff --git a/events/1769250425-clawdbot-installed-image-gen.json b/events/1769250425-clawdbot-installed-image-gen.json new file mode 100644 index 000000000..c57453738 --- /dev/null +++ b/events/1769250425-clawdbot-installed-image-gen.json @@ -0,0 +1 @@ +{"agent":"clawdbot","action":"installed","subject":"image-gen","summary":"gemini-3-pro-image-preview via google AI","timestamp":"2026-01-24T10:27:05Z"} diff --git a/events/1769250425-clawdbot-setup-agent-event-bus.json b/events/1769250425-clawdbot-setup-agent-event-bus.json new file mode 100644 index 000000000..be67ee952 --- /dev/null +++ b/events/1769250425-clawdbot-setup-agent-event-bus.json @@ -0,0 +1 @@ +{"agent":"clawdbot","action":"setup","subject":"agent-event-bus","summary":"~/.agents/ with state, events, persistent","timestamp":"2026-01-24T10:27:05Z"} diff --git a/skills/ask-questions-if-underspecified/SKILL.md b/skills/ask-questions-if-underspecified/SKILL.md new file mode 100644 index 000000000..12ceca780 --- /dev/null +++ b/skills/ask-questions-if-underspecified/SKILL.md @@ -0,0 +1,85 @@ +--- +name: ask-questions-if-underspecified +description: Clarify requirements before implementing. Use when serious doubts araise. +--- + +# Ask Questions If Underspecified + +## When to Use + +Use this skill when a request has multiple plausible interpretations or key details (objective, scope, constraints, environment, or safety) are unclear. + +## When NOT to Use + +Do not use this skill when the request is already clear, or when a quick, low-risk discovery read can answer the missing details. + +## Goal + +Ask the minimum set of clarifying questions needed to avoid wrong work; do not start implementing until the must-have questions are answered (or the user explicitly approves proceeding with stated assumptions). + +## Workflow + +### 1) Decide whether the request is underspecified + +Treat a request as underspecified if after exploring how to perform the work, some or all of the following are not clear: +- Define the objective (what should change vs stay the same) +- Define "done" (acceptance criteria, examples, edge cases) +- Define scope (which files/components/users are in/out) +- Define constraints (compatibility, performance, style, deps, time) +- Identify environment (language/runtime versions, OS, build/test runner) +- Clarify safety/reversibility (data migration, rollout/rollback, risk) + +If multiple plausible interpretations exist, assume it is underspecified. + +### 2) Ask must-have questions first (keep it small) + +Ask 1-5 questions in the first pass. Prefer questions that eliminate whole branches of work. + +Make questions easy to answer: +- Optimize for scannability (short, numbered questions; avoid paragraphs) +- Offer multiple-choice options when possible +- Suggest reasonable defaults when appropriate (mark them clearly as the default/recommended choice; bold the recommended choice in the list, or if you present options in a code block, put a bold "Recommended" line immediately above the block and also tag defaults inside the block) +- Include a fast-path response (e.g., reply `defaults` to accept all recommended/default choices) +- Include a low-friction "not sure" option when helpful (e.g., "Not sure - use default") +- Separate "Need to know" from "Nice to know" if that reduces friction +- Structure options so the user can respond with compact decisions (e.g., `1b 2a 3c`); restate the chosen options in plain language to confirm + +### 3) Pause before acting + +Until must-have answers arrive: +- Do not run commands, edit files, or produce a detailed plan that depends on unknowns +- Do perform a clearly labeled, low-risk discovery step only if it does not commit you to a direction (e.g., inspect repo structure, read relevant config files) + +If the user explicitly asks you to proceed without answers: +- State your assumptions as a short numbered list +- Ask for confirmation; proceed only after they confirm or correct them + +### 4) Confirm interpretation, then proceed + +Once you have answers, restate the requirements in 1-3 sentences (including key constraints and what success looks like), then start work. + +## Question templates + +- "Before I start, I need: (1) ..., (2) ..., (3) .... If you don't care about (2), I will assume ...." +- "Which of these should it be? A) ... B) ... C) ... (pick one)" +- "What would you consider 'done'? For example: ..." +- "Any constraints I must follow (versions, performance, style, deps)? If none, I will target the existing project defaults." +- Use numbered questions with lettered options and a clear reply format + +```text +1) Scope? +a) Minimal change (default) +b) Refactor while touching the area +c) Not sure - use default +2) Compatibility target? +a) Current project defaults (default) +b) Also support older versions: +c) Not sure - use default + +Reply with: defaults (or 1a 2a) +``` + +## Anti-patterns + +- Don't ask questions you can answer with a quick, low-risk discovery read (e.g., configs, existing patterns, docs). +- Don't ask open-ended questions if a tight multiple-choice or yes/no would eliminate ambiguity faster. diff --git a/skills/kpi-dashboard-design/SKILL.md b/skills/kpi-dashboard-design/SKILL.md new file mode 100644 index 000000000..2aaa4011b --- /dev/null +++ b/skills/kpi-dashboard-design/SKILL.md @@ -0,0 +1,428 @@ +--- +name: kpi-dashboard-design +description: Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts. +--- + +# KPI Dashboard Design + +Comprehensive patterns for designing effective Key Performance Indicator (KPI) dashboards that drive business decisions. + +## When to Use This Skill + +- Designing executive dashboards +- Selecting meaningful KPIs +- Building real-time monitoring displays +- Creating department-specific metrics views +- Improving existing dashboard layouts +- Establishing metric governance + +## Core Concepts + +### 1. KPI Framework + +| Level | Focus | Update Frequency | Audience | +| --------------- | ---------------- | ----------------- | ---------- | +| **Strategic** | Long-term goals | Monthly/Quarterly | Executives | +| **Tactical** | Department goals | Weekly/Monthly | Managers | +| **Operational** | Day-to-day | Real-time/Daily | Teams | + +### 2. SMART KPIs + +``` +Specific: Clear definition +Measurable: Quantifiable +Achievable: Realistic targets +Relevant: Aligned to goals +Time-bound: Defined period +``` + +### 3. Dashboard Hierarchy + +``` +├── Executive Summary (1 page) +│ ├── 4-6 headline KPIs +│ ├── Trend indicators +│ └── Key alerts +├── Department Views +│ ├── Sales Dashboard +│ ├── Marketing Dashboard +│ ├── Operations Dashboard +│ └── Finance Dashboard +└── Detailed Drilldowns + ├── Individual metrics + └── Root cause analysis +``` + +## Common KPIs by Department + +### Sales KPIs + +```yaml +Revenue Metrics: + - Monthly Recurring Revenue (MRR) + - Annual Recurring Revenue (ARR) + - Average Revenue Per User (ARPU) + - Revenue Growth Rate + +Pipeline Metrics: + - Sales Pipeline Value + - Win Rate + - Average Deal Size + - Sales Cycle Length + +Activity Metrics: + - Calls/Emails per Rep + - Demos Scheduled + - Proposals Sent + - Close Rate +``` + +### Marketing KPIs + +```yaml +Acquisition: + - Cost Per Acquisition (CPA) + - Customer Acquisition Cost (CAC) + - Lead Volume + - Marketing Qualified Leads (MQL) + +Engagement: + - Website Traffic + - Conversion Rate + - Email Open/Click Rate + - Social Engagement + +ROI: + - Marketing ROI + - Campaign Performance + - Channel Attribution + - CAC Payback Period +``` + +### Product KPIs + +```yaml +Usage: + - Daily/Monthly Active Users (DAU/MAU) + - Session Duration + - Feature Adoption Rate + - Stickiness (DAU/MAU) + +Quality: + - Net Promoter Score (NPS) + - Customer Satisfaction (CSAT) + - Bug/Issue Count + - Time to Resolution + +Growth: + - User Growth Rate + - Activation Rate + - Retention Rate + - Churn Rate +``` + +### Finance KPIs + +```yaml +Profitability: + - Gross Margin + - Net Profit Margin + - EBITDA + - Operating Margin + +Liquidity: + - Current Ratio + - Quick Ratio + - Cash Flow + - Working Capital + +Efficiency: + - Revenue per Employee + - Operating Expense Ratio + - Days Sales Outstanding + - Inventory Turnover +``` + +## Dashboard Layout Patterns + +### Pattern 1: Executive Summary + +``` +┌─────────────────────────────────────────────────────────────┐ +│ EXECUTIVE DASHBOARD [Date Range ▼] │ +├─────────────┬─────────────┬─────────────┬─────────────────┤ +│ REVENUE │ PROFIT │ CUSTOMERS │ NPS SCORE │ +│ $2.4M │ $450K │ 12,450 │ 72 │ +│ ▲ 12% │ ▲ 8% │ ▲ 15% │ ▲ 5pts │ +├─────────────┴─────────────┴─────────────┴─────────────────┤ +│ │ +│ Revenue Trend │ Revenue by Product │ +│ ┌───────────────────────┐ │ ┌──────────────────┐ │ +│ │ /\ /\ │ │ │ ████████ 45% │ │ +│ │ / \ / \ /\ │ │ │ ██████ 32% │ │ +│ │ / \/ \ / \ │ │ │ ████ 18% │ │ +│ │ / \/ \ │ │ │ ██ 5% │ │ +│ └───────────────────────┘ │ └──────────────────┘ │ +│ │ +├─────────────────────────────────────────────────────────────┤ +│ 🔴 Alert: Churn rate exceeded threshold (>5%) │ +│ 🟡 Warning: Support ticket volume 20% above average │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Pattern 2: SaaS Metrics Dashboard + +``` +┌─────────────────────────────────────────────────────────────┐ +│ SAAS METRICS Jan 2024 [Monthly ▼] │ +├──────────────────────┬──────────────────────────────────────┤ +│ ┌────────────────┐ │ MRR GROWTH │ +│ │ MRR │ │ ┌────────────────────────────────┐ │ +│ │ $125,000 │ │ │ /── │ │ +│ │ ▲ 8% │ │ │ /────/ │ │ +│ └────────────────┘ │ │ /────/ │ │ +│ ┌────────────────┐ │ │ /────/ │ │ +│ │ ARR │ │ │ /────/ │ │ +│ │ $1,500,000 │ │ └────────────────────────────────┘ │ +│ │ ▲ 15% │ │ J F M A M J J A S O N D │ +│ └────────────────┘ │ │ +├──────────────────────┼──────────────────────────────────────┤ +│ UNIT ECONOMICS │ COHORT RETENTION │ +│ │ │ +│ CAC: $450 │ Month 1: ████████████████████ 100% │ +│ LTV: $2,700 │ Month 3: █████████████████ 85% │ +│ LTV/CAC: 6.0x │ Month 6: ████████████████ 80% │ +│ │ Month 12: ██████████████ 72% │ +│ Payback: 4 months │ │ +├──────────────────────┴──────────────────────────────────────┤ +│ CHURN ANALYSIS │ +│ ┌──────────┬──────────┬──────────┬──────────────────────┐ │ +│ │ Gross │ Net │ Logo │ Expansion │ │ +│ │ 4.2% │ 1.8% │ 3.1% │ 2.4% │ │ +│ └──────────┴──────────┴──────────┴──────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Pattern 3: Real-time Operations + +``` +┌─────────────────────────────────────────────────────────────┐ +│ OPERATIONS CENTER Live ● Last: 10:42:15 │ +├────────────────────────────┬────────────────────────────────┤ +│ SYSTEM HEALTH │ SERVICE STATUS │ +│ ┌──────────────────────┐ │ │ +│ │ CPU MEM DISK │ │ ● API Gateway Healthy │ +│ │ 45% 72% 58% │ │ ● User Service Healthy │ +│ │ ███ ████ ███ │ │ ● Payment Service Degraded │ +│ │ ███ ████ ███ │ │ ● Database Healthy │ +│ │ ███ ████ ███ │ │ ● Cache Healthy │ +│ └──────────────────────┘ │ │ +├────────────────────────────┼────────────────────────────────┤ +│ REQUEST THROUGHPUT │ ERROR RATE │ +│ ┌──────────────────────┐ │ ┌──────────────────────────┐ │ +│ │ ▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅ │ │ │ ▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ │ │ +│ └──────────────────────┘ │ └──────────────────────────┘ │ +│ Current: 12,450 req/s │ Current: 0.02% │ +│ Peak: 18,200 req/s │ Threshold: 1.0% │ +├────────────────────────────┴────────────────────────────────┤ +│ RECENT ALERTS │ +│ 10:40 🟡 High latency on payment-service (p99 > 500ms) │ +│ 10:35 🟢 Resolved: Database connection pool recovered │ +│ 10:22 🔴 Payment service circuit breaker tripped │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Implementation Patterns + +### SQL for KPI Calculations + +```sql +-- Monthly Recurring Revenue (MRR) +WITH mrr_calculation AS ( + SELECT + DATE_TRUNC('month', billing_date) AS month, + SUM( + CASE subscription_interval + WHEN 'monthly' THEN amount + WHEN 'yearly' THEN amount / 12 + WHEN 'quarterly' THEN amount / 3 + END + ) AS mrr + FROM subscriptions + WHERE status = 'active' + GROUP BY DATE_TRUNC('month', billing_date) +) +SELECT + month, + mrr, + LAG(mrr) OVER (ORDER BY month) AS prev_mrr, + (mrr - LAG(mrr) OVER (ORDER BY month)) / LAG(mrr) OVER (ORDER BY month) * 100 AS growth_pct +FROM mrr_calculation; + +-- Cohort Retention +WITH cohorts AS ( + SELECT + user_id, + DATE_TRUNC('month', created_at) AS cohort_month + FROM users +), +activity AS ( + SELECT + user_id, + DATE_TRUNC('month', event_date) AS activity_month + FROM user_events + WHERE event_type = 'active_session' +) +SELECT + c.cohort_month, + EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month)) AS months_since_signup, + COUNT(DISTINCT a.user_id) AS active_users, + COUNT(DISTINCT a.user_id)::FLOAT / COUNT(DISTINCT c.user_id) * 100 AS retention_rate +FROM cohorts c +LEFT JOIN activity a ON c.user_id = a.user_id + AND a.activity_month >= c.cohort_month +GROUP BY c.cohort_month, EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month)) +ORDER BY c.cohort_month, months_since_signup; + +-- Customer Acquisition Cost (CAC) +SELECT + DATE_TRUNC('month', acquired_date) AS month, + SUM(marketing_spend) / NULLIF(COUNT(new_customers), 0) AS cac, + SUM(marketing_spend) AS total_spend, + COUNT(new_customers) AS customers_acquired +FROM ( + SELECT + DATE_TRUNC('month', u.created_at) AS acquired_date, + u.id AS new_customers, + m.spend AS marketing_spend + FROM users u + JOIN marketing_spend m ON DATE_TRUNC('month', u.created_at) = m.month + WHERE u.source = 'marketing' +) acquisition +GROUP BY DATE_TRUNC('month', acquired_date); +``` + +### Python Dashboard Code (Streamlit) + +```python +import streamlit as st +import pandas as pd +import plotly.express as px +import plotly.graph_objects as go + +st.set_page_config(page_title="KPI Dashboard", layout="wide") + +# Header with date filter +col1, col2 = st.columns([3, 1]) +with col1: + st.title("Executive Dashboard") +with col2: + date_range = st.selectbox( + "Period", + ["Last 7 Days", "Last 30 Days", "Last Quarter", "YTD"] + ) + +# KPI Cards +def metric_card(label, value, delta, prefix="", suffix=""): + delta_color = "green" if delta >= 0 else "red" + delta_arrow = "▲" if delta >= 0 else "▼" + st.metric( + label=label, + value=f"{prefix}{value:,.0f}{suffix}", + delta=f"{delta_arrow} {abs(delta):.1f}%" + ) + +col1, col2, col3, col4 = st.columns(4) +with col1: + metric_card("Revenue", 2400000, 12.5, prefix="$") +with col2: + metric_card("Customers", 12450, 15.2) +with col3: + metric_card("NPS Score", 72, 5.0) +with col4: + metric_card("Churn Rate", 4.2, -0.8, suffix="%") + +# Charts +col1, col2 = st.columns(2) + +with col1: + st.subheader("Revenue Trend") + revenue_data = pd.DataFrame({ + 'Month': pd.date_range('2024-01-01', periods=12, freq='M'), + 'Revenue': [180000, 195000, 210000, 225000, 240000, 255000, + 270000, 285000, 300000, 315000, 330000, 345000] + }) + fig = px.line(revenue_data, x='Month', y='Revenue', + line_shape='spline', markers=True) + fig.update_layout(height=300) + st.plotly_chart(fig, use_container_width=True) + +with col2: + st.subheader("Revenue by Product") + product_data = pd.DataFrame({ + 'Product': ['Enterprise', 'Professional', 'Starter', 'Other'], + 'Revenue': [45, 32, 18, 5] + }) + fig = px.pie(product_data, values='Revenue', names='Product', + hole=0.4) + fig.update_layout(height=300) + st.plotly_chart(fig, use_container_width=True) + +# Cohort Heatmap +st.subheader("Cohort Retention") +cohort_data = pd.DataFrame({ + 'Cohort': ['Jan', 'Feb', 'Mar', 'Apr', 'May'], + 'M0': [100, 100, 100, 100, 100], + 'M1': [85, 87, 84, 86, 88], + 'M2': [78, 80, 76, 79, None], + 'M3': [72, 74, 70, None, None], + 'M4': [68, 70, None, None, None], +}) +fig = go.Figure(data=go.Heatmap( + z=cohort_data.iloc[:, 1:].values, + x=['M0', 'M1', 'M2', 'M3', 'M4'], + y=cohort_data['Cohort'], + colorscale='Blues', + text=cohort_data.iloc[:, 1:].values, + texttemplate='%{text}%', + textfont={"size": 12}, +)) +fig.update_layout(height=250) +st.plotly_chart(fig, use_container_width=True) + +# Alerts Section +st.subheader("Alerts") +alerts = [ + {"level": "error", "message": "Churn rate exceeded threshold (>5%)"}, + {"level": "warning", "message": "Support ticket volume 20% above average"}, +] +for alert in alerts: + if alert["level"] == "error": + st.error(f"🔴 {alert['message']}") + elif alert["level"] == "warning": + st.warning(f"🟡 {alert['message']}") +``` + +## Best Practices + +### Do's + +- **Limit to 5-7 KPIs** - Focus on what matters +- **Show context** - Comparisons, trends, targets +- **Use consistent colors** - Red=bad, green=good +- **Enable drilldown** - From summary to detail +- **Update appropriately** - Match metric frequency + +### Don'ts + +- **Don't show vanity metrics** - Focus on actionable data +- **Don't overcrowd** - White space aids comprehension +- **Don't use 3D charts** - They distort perception +- **Don't hide methodology** - Document calculations +- **Don't ignore mobile** - Ensure responsive design + +## Resources + +- [Stephen Few's Dashboard Design](https://www.perceptualedge.com/articles/visual_business_intelligence/rules_for_using_color.pdf) +- [Edward Tufte's Principles](https://www.edwardtufte.com/tufte/) +- [Google Data Studio Gallery](https://datastudio.google.com/gallery) diff --git a/skills/meme-factory/SKILL.md b/skills/meme-factory/SKILL.md new file mode 100644 index 000000000..37163c618 --- /dev/null +++ b/skills/meme-factory/SKILL.md @@ -0,0 +1,331 @@ +--- +name: meme-factory +description: Generate memes using the memegen.link API. Use when users request memes, want to add humor to content, or need visual aids for social media. Supports 100+ popular templates with custom text and styling. +--- + +# Meme Factory + +Create memes using the free memegen.link API and textual meme formats. + +--- + +## Triggers + +| Trigger | Description | +|---------|-------------| +| `/meme-factory` | Manual invocation | +| `/meme-factory {template} {top} {bottom}` | Direct meme generation | +| `meme-factory: create a meme about X` | Natural language request | + +--- + +## Quick Reference + +| Action | Format | +|--------|--------| +| Basic meme | `https://api.memegen.link/images/{template}/{top}/{bottom}.png` | +| With sizing | `?width=1200&height=630` | +| Custom background | `?style=https://example.com/image.jpg` | +| All templates | https://api.memegen.link/templates/ | +| Interactive docs | https://api.memegen.link/docs/ | + +**Additional Resources:** +- [Markdown Memes Guide](references/markdown-memes-guide.md) - 15+ textual meme formats +- [Examples](references/examples.md) - Practical usage examples +- [meme_generator.py](scripts/meme_generator.py) - Python helper script + +--- + +## Quick Start + +### Basic Meme Structure + +``` +https://api.memegen.link/images/{template}/{top_text}/{bottom_text}.{extension} +``` + +**Example:** +``` +https://api.memegen.link/images/buzz/memes/memes_everywhere.png +``` + +Result: Buzz Lightyear meme with "memes" at top and "memes everywhere" at bottom. + +### Text Formatting + +| Character | Encoding | +|-----------|----------| +| Space | `_` or `-` | +| Newline | `~n` | +| Question mark | `~q` | +| Percent | `~p` | +| Slash | `~s` | +| Hash | `~h` | +| Single quote | `''` | +| Double quote | `""` | + +--- + +## Popular Templates + +| Template | Use Case | Example | +|----------|----------|---------| +| `buzz` | X, X everywhere | bugs/bugs_everywhere | +| `drake` | Comparisons | manual_testing/automated_testing | +| `success` | Victories | deployed/no_errors | +| `fine` | Things going wrong | server_on_fire/this_is_fine | +| `fry` | Uncertainty | not_sure_if_bug/or_feature | +| `changemind` | Hot takes | tabs_are_better_than_spaces | +| `distracted` | Priorities | my_code/new_framework/current_project | +| `mordor` | One does not simply | one_does_not_simply/deploy_on_friday | + +--- + +## Template Selection Guide + +| Context | Template | Why | +|---------|----------|-----| +| Comparing options | `drake` | Two-panel reject/approve format | +| Celebrating wins | `success` | Positive outcome emphasis | +| Problems ignored | `fine` | Ironic "everything is fine" | +| Uncertainty | `fry` | "Not sure if X or Y" format | +| Controversial opinion | `changemind` | Statement + challenge | +| Ubiquitous things | `buzz` | "X, X everywhere" | +| Bad ideas | `mordor` | "One does not simply..." | + +--- + +## Validation + +After generating a meme: + +- [ ] URL returns valid image (test in browser) +- [ ] Text is readable (not too long) +- [ ] Template matches the message context +- [ ] Special characters properly encoded +- [ ] Dimensions appropriate for platform + +### Platform Dimensions + +| Platform | Dimensions | +|----------|------------| +| Social media (Open Graph) | 1200x630 | +| Slack/Discord | 800x600 | +| GitHub | Default | + +--- + +## Anti-Patterns + +| Avoid | Why | Instead | +|-------|-----|---------| +| Spaces without encoding | URL breaks | Use `_` or `-` | +| Too much text | Unreadable | 2-6 words per line | +| Wrong template | Message mismatch | Match template to context | +| Missing extension | Invalid URL | Always include `.png`, `.jpg`, etc. | +| Unencoded special chars | URL breaks | Use `~q`, `~s`, `~p`, etc. | +| Assuming template exists | 404 error | Check templates list first | + +--- + +## Verification + +Meme generation is successful when: + +1. **URL is valid** - Returns HTTP 200 +2. **Image renders** - Displays correctly in markdown +3. **Text is visible** - Properly formatted on image +4. **Context matches** - Template fits the message + +**Test command:** +```bash +curl -I "https://api.memegen.link/images/buzz/test/test.png" +# Should return: HTTP/2 200 +``` + +--- + +
+Deep Dive: Advanced Features + +### Image Formats + +| Extension | Use Case | +|-----------|----------| +| `.png` | Best quality, default | +| `.jpg` | Smaller file size | +| `.webp` | Modern, good compression | +| `.gif` | Animated templates | + +### Dimensions + +``` +?width=800 +?height=600 +?width=800&height=600 (padded to exact) +``` + +### Layout Options + +``` +?layout=top # Text at top only +?layout=bottom # Text at bottom only +?layout=default # Standard top/bottom +``` + +### Custom Fonts + +View available: https://api.memegen.link/fonts/ + +``` +?font=impact (default) +``` + +### Custom Images + +Use any image as background: + +``` +https://api.memegen.link/images/custom/hello/world.png?style=https://example.com/image.jpg +``` + +
+ +
+Deep Dive: Contextual Memes + +### Code Reviews + +``` +Template: fry +https://api.memegen.link/images/fry/not_sure_if_feature/or_bug.png +``` + +### Deployments + +``` +Template: interesting +https://api.memegen.link/images/interesting/i_dont_always_test/but_when_i_do_i_do_it_in_production.png +``` + +### Documentation + +``` +Template: yodawg +https://api.memegen.link/images/yodawg/yo_dawg_i_heard_you_like_docs/so_i_documented_the_documentation.png +``` + +### Performance Issues + +``` +Template: fine +https://api.memegen.link/images/fine/memory_usage_at_99~/this_is_fine.png +``` + +### Successful Deploy + +``` +Template: success +https://api.memegen.link/images/success/deployed_to_production/zero_downtime.png +``` + +
+ +
+Deep Dive: Workflow Integration + +### Generating Memes in Response + +```markdown +Here's a relevant meme: + +![Meme](https://api.memegen.link/images/buzz/bugs/bugs_everywhere.png) +``` + +### Dynamic Generation (Python) + +```python +def generate_status_meme(status: str, message: str): + template_map = { + "success": "success", + "failure": "fine", + "review": "fry", + "deploy": "interesting" + } + + template = template_map.get(status, "buzz") + words = message.split() + top = "_".join(words[0:3]) + bottom = "_".join(words[3:6]) + + return f"https://api.memegen.link/images/{template}/{top}/{bottom}.png" +``` + +### Using the Helper Script + +```python +from meme_generator import MemeGenerator + +meme = MemeGenerator() +url = meme.generate("buzz", "features", "features everywhere") +print(url) +``` + +
+ +
+Deep Dive: API Reference + +### Endpoints + +| Endpoint | Purpose | +|----------|---------| +| `/templates/` | List all templates | +| `/templates/{id}` | Template details | +| `/fonts/` | Available fonts | +| `/images/{template}/{top}/{bottom}.{ext}` | Generate meme | + +### API Characteristics + +- Free and open-source +- No API key required +- No rate limiting (normal use) +- Stateless (all info in URL) +- Images generated on-demand + +### Error Handling + +1. Check template at https://api.memegen.link/templates/ +2. Verify text formatting (underscores for spaces) +3. Check special character encoding +4. Ensure valid extension +5. Test URL in browser + +
+ +--- + +## References + +| Document | Content | +|----------|---------| +| [markdown-memes-guide.md](references/markdown-memes-guide.md) | 15+ textual meme formats (greentext, copypasta, ASCII, etc.) | +| [examples.md](references/examples.md) | Practical usage examples | + +### Scripts + +| Script | Purpose | +|--------|---------| +| [meme_generator.py](scripts/meme_generator.py) | Python helper for meme generation | + +--- + +## Summary + +Generate contextual memes to: +- Add humor to conversations +- Create social media visuals +- Make code reviews engaging +- Celebrate successes + +**Golden rule:** Keep text concise, match template to context. diff --git a/skills/meme-factory/references/examples.md b/skills/meme-factory/references/examples.md new file mode 100644 index 000000000..3357e7716 --- /dev/null +++ b/skills/meme-factory/references/examples.md @@ -0,0 +1,457 @@ +# Meme Generation Examples + +This document provides practical examples of using the meme generation skill in various contexts. + +## Basic Examples + +### Example 1: Simple Meme + +**Request:** +"Create a meme about bugs everywhere" + +**Response:** +``` +Here's a Buzz Lightyear meme about bugs: + +![Bugs Everywhere](https://api.memegen.link/images/buzz/bugs/bugs_everywhere.png) +``` + +### Example 2: Drake Comparison Meme + +**Request:** +"Make a Drake meme comparing manual testing vs automated testing" + +**Response:** +``` +Here's a Drake meme comparing testing approaches: + +![Testing Comparison](https://api.memegen.link/images/drake/manual_testing/automated_testing.png) +``` + +### Example 3: Success Meme + +**Request:** +"Generate a success kid meme about all tests passing" + +**Response:** +``` +Here's a success meme: + +![Tests Passing](https://api.memegen.link/images/success/all_tests_passing/on_the_first_try.png) +``` + +## Programming Examples + +### Python Script Example + +```python +from meme_generator import MemeGenerator + +# Initialize generator +meme = MemeGenerator() + +# Generate a basic meme +url = meme.generate( + template="buzz", + top_text="features", + bottom_text="features everywhere" +) +print(f"Meme URL: {url}") + +# Generate with custom dimensions for social media +url = meme.generate( + template="drake", + top_text="writing tests later", + bottom_text="writing tests first", + width=1200, + height=630 +) +print(f"Social media meme: {url}") + +# Get markdown for embedding +markdown = meme.get_markdown_image(url, alt_text="TDD Meme") +print(f"Markdown: {markdown}") +``` + +### CLI Example + +```bash +# Generate a basic meme +python meme_generator.py generate buzz "features" "features everywhere" + +# Generate with markdown output +python meme_generator.py generate success "deployed" "no errors" --markdown + +# Generate with custom dimensions +python meme_generator.py generate drake "old way" "new way" --width 1200 --height 630 + +# List all available templates +python meme_generator.py list-templates + +# Suggest template for context +python meme_generator.py suggest "deployment success" +``` + +## Context-Specific Examples + +### Code Review Context + +**Scenario:** Reviewing pull request with many changes + +```python +# Not sure if improvements or over-engineering +url = meme.generate("fry", "not sure if improvements", "or over engineering") +``` + +**Result:** +``` +https://api.memegen.link/images/fry/not_sure_if_improvements/or_over_engineering.png +``` + +### Deployment Context + +**Scenario:** Successful production deployment + +```python +# Success kid meme +url = meme.generate("success", "deployed to production", "zero downtime") +``` + +**Result:** +``` +https://api.memegen.link/images/success/deployed_to_production/zero_downtime.png +``` + +### Incident Response Context + +**Scenario:** Production fire + +```python +# This is fine meme +url = meme.generate("fine", "production is down", "this is fine") +``` + +**Result:** +``` +https://api.memegen.link/images/fine/production_is_down/this_is_fine.png +``` + +### Documentation Context + +**Scenario:** Documentation improvements + +```python +# Yo dawg meme +url = meme.generate( + "yodawg", + "yo dawg i heard you like docs", + "so i documented the documentation" +) +``` + +**Result:** +``` +https://api.memegen.link/images/yodawg/yo_dawg_i_heard_you_like_docs/so_i_documented_the_documentation.png +``` + +## Advanced Examples + +### Custom Dimensions for Social Media + +**Open Graph (1200x630)** + +```python +url = meme.generate( + "buzz", + "features", + "features everywhere", + width=1200, + height=630 +) +``` + +### Custom Layout + +**Top-only text** + +```python +url = meme.generate( + "rollsafe", + "cant have bugs in production", + layout="top" +) +``` + +### Multiple Format Generation + +```python +formats = ["png", "jpg", "webp"] +for fmt in formats: + url = meme.generate( + "success", + "all tests passing", + "first try", + extension=fmt + ) + print(f"{fmt.upper()}: {url}") +``` + +## Integration Examples + +### Slack Bot Integration + +```python +def send_deployment_meme(channel: str, status: str): + """Send a meme to Slack based on deployment status.""" + meme = MemeGenerator() + + if status == "success": + url = meme.generate("success", "deployed", "no errors") + message = "Deployment successful!" + elif status == "failure": + url = meme.generate("fine", "deployment failed", "this is fine") + message = "Deployment needs attention" + else: + url = meme.generate("fry", "not sure if deployed", "or still deploying") + message = "Deployment status unclear" + + # Send to Slack (pseudo-code) + slack_client.chat_postMessage( + channel=channel, + text=message, + attachments=[{"image_url": url}] + ) +``` + +### GitHub PR Comments + +```python +def comment_pr_review(pr_number: int, review_type: str): + """Add a meme to PR comments based on review.""" + meme = MemeGenerator() + + review_memes = { + "approved": meme.generate("success", "lgtm", "ship it"), + "changes_requested": meme.generate("yuno", "y u no", "write tests"), + "complex": meme.generate("fry", "not sure if feature", "or bug") + } + + url = review_memes.get(review_type) + markdown = meme.get_markdown_image(url, alt_text="Code Review Meme") + + # Post comment (pseudo-code) + github_client.issues.create_comment( + pr_number, + f"Code review complete!\n\n{markdown}" + ) +``` + +### Discord Bot Integration + +```python +@bot.command() +async def deploy_meme(ctx, status: str): + """Generate deployment meme for Discord.""" + meme = MemeGenerator() + + if status == "success": + url = meme.generate("success", "deployed", "zero downtime") + elif status == "fail": + url = meme.generate("fine", "servers on fire", "this is fine") + + await ctx.send(f"Deployment Status: {status}") + await ctx.send(url) +``` + +## Batch Generation Examples + +### Generate Multiple Memes for a Topic + +```python +def generate_testing_memes(): + """Generate a collection of testing-related memes.""" + meme = MemeGenerator() + + memes = [ + meme.generate("drake", "manual testing", "automated testing"), + meme.generate("success", "all tests passing", "on first try"), + meme.generate("fry", "not sure if bug", "or feature"), + meme.generate("interesting", "i dont always test", "but when i do i test in production"), + ] + + print("Testing Meme Collection:\n") + for i, url in enumerate(memes, 1): + print(f"{i}. {url}") + +generate_testing_memes() +``` + +### Generate Memes for Documentation + +```python +def generate_docs_memes(): + """Generate documentation-related memes.""" + meme = MemeGenerator() + + topics = [ + ("yodawg", "yo dawg i heard you like docs", "so i documented your docs"), + ("buzz", "documentation", "documentation everywhere"), + ("wonka", "oh you write documentation", "tell me more about this fantasy"), + ("ancient", "documentation", "documentation"), + ] + + for template, top, bottom in topics: + url = meme.generate(template, top, bottom) + markdown = meme.get_markdown_image(url) + print(markdown) + +generate_docs_memes() +``` + +## Error Handling Examples + +### Check Template Validity + +```python +def generate_safe_meme(template: str, top: str, bottom: str): + """Generate meme with error handling.""" + meme = MemeGenerator() + + # Check if template exists + if template not in meme.TEMPLATES: + print(f"Warning: '{template}' not in known templates") + print(f"Falling back to 'buzz'") + template = "buzz" + + url = meme.generate(template, top, bottom) + return url +``` + +### Context-Based Template Selection + +```python +def smart_meme_generation(context: str, top: str, bottom: str): + """Generate meme with automatic template selection.""" + meme = MemeGenerator() + + # Suggest template based on context + suggested_template = meme.suggest_template_for_context(context) + + print(f"Context: {context}") + print(f"Suggested template: {suggested_template}") + + url = meme.generate(suggested_template, top, bottom) + return url + +# Examples +url1 = smart_meme_generation("deployment success", "deployed", "no errors") +url2 = smart_meme_generation("debugging nightmare", "bugs", "bugs everywhere") +url3 = smart_meme_generation("code comparison", "old code", "new code") +``` + +## Tips for Effective Memes + +### Good Examples + +```python +# ✅ Concise text +meme.generate("buzz", "bugs", "bugs everywhere") + +# ✅ Relevant template +meme.generate("drake", "manual work", "automation") + +# ✅ Clear message +meme.generate("success", "deployed", "zero errors") +``` + +### Bad Examples + +```python +# ❌ Too much text +meme.generate( + "buzz", + "there are way too many bugs in this codebase", + "seriously there are bugs absolutely everywhere i look" +) + +# ❌ Wrong template choice +meme.generate("success", "production is down", "servers crashed") # Should use 'fine' + +# ❌ Unclear message +meme.generate("buzz", "stuff", "things") +``` + +## Testing Your Memes + +```python +def test_meme_generation(): + """Test meme generation with various inputs.""" + meme = MemeGenerator() + + test_cases = [ + ("buzz", "test", "test everywhere", "png"), + ("drake", "bugs", "features", "jpg"), + ("success", "deployed", "working", "webp"), + ] + + print("Testing meme generation:\n") + for template, top, bottom, ext in test_cases: + url = meme.generate(template, top, bottom, extension=ext) + print(f"✓ {template} ({ext}): {url}") + +test_meme_generation() +``` + +## Real-World Workflow Example + +```python +def deployment_workflow_with_memes(deployment_result: dict): + """Complete deployment workflow with contextual memes.""" + meme = MemeGenerator() + + # Pre-deployment + pre_deploy = meme.generate("buzz", "deployments", "deployments incoming") + print(f"Pre-deployment: {pre_deploy}") + + # During deployment + if deployment_result["status"] == "in_progress": + during = meme.generate("fry", "not sure if deploying", "or already deployed") + print(f"During: {during}") + + # Post-deployment + if deployment_result["success"]: + post = meme.generate( + "success", + "deployed to production", + "zero downtime", + width=1200, + height=630 + ) + slack_message = f"Deployment successful! {post}" + else: + post = meme.generate("fine", "deployment failed", "this is fine") + slack_message = f"Deployment needs attention: {post}" + + print(f"Post-deployment: {slack_message}") + +# Example usage +deployment_workflow_with_memes({ + "status": "completed", + "success": True, + "duration": "5m 32s" +}) +``` + +## Summary + +These examples demonstrate: +- Basic meme generation +- Context-aware template selection +- Integration with popular platforms +- Error handling and validation +- Batch generation workflows +- Real-world use cases + +For more examples and templates, visit: +- https://api.memegen.link/docs/ +- https://api.memegen.link/templates/ diff --git a/skills/meme-factory/references/markdown-memes-guide.md b/skills/meme-factory/references/markdown-memes-guide.md new file mode 100644 index 000000000..e873c6061 --- /dev/null +++ b/skills/meme-factory/references/markdown-memes-guide.md @@ -0,0 +1,1082 @@ +# The Complete Practical Guide to Memes in Markdown Blog Posts + +*A comprehensive toolbox for creating textual and image memes in Markdown-based blogs (MkDocs, Jekyll, Hugo, Astro, etc.)* + +--- + +## 📖 Table of Contents + +1. [Why Markdown for Memes?](#why-markdown-for-memes) +2. [Core Markdown Techniques](#core-markdown-techniques) +3. [Layout Patterns for Text Memes](#layout-patterns-for-text-memes) +4. [Textual Meme Formats](#textual-meme-formats) +5. [Image Memes via Pure URL](#image-memes-via-pure-url) +6. [Mixing Text + Image Memes](#mixing-text--image-memes) +7. [Advanced Features](#advanced-features) +8. [Production Tips](#production-tips) +9. [Complete Blog Example](#complete-blog-example) + +--- + +## 🎯 Why Markdown for Memes? + +Markdown is deceptively powerful for meme creation: + +- **Preserves formatting** - Code blocks maintain spacing, ASCII art, and alignment +- **Readable source** - Plain text is portable and version-controllable +- **Native structure** - Blockquotes, emphasis, and spacing create rhythm naturally +- **No uploads needed** - Text memes live in your content, image memes via URL +- **Accessible** - Screen readers handle text better than image-text +- **Fast** - No external dependencies for textual memes + +With a few tricks—code fences, blockquotes, emphasis, spacing—you can reproduce nearly any textual meme format inside a blog post. + +--- + +## 🧱 Core Markdown Techniques + +Master these building blocks first: + +### ✅ Code Fences + +Use triple backticks to preserve whitespace, arrows, emoji alignment, ASCII art, and raw text. + +````markdown +```text +>be me +>perfect spacing preserved +>mfw markdown just works +``` +```` + +**Use for:** Greentext, ASCII art, chat logs, anything needing exact spacing. + +### ✅ Blockquotes + +Use `>` for layered dialogue (Tumblr chains, ironic replies, greentext variants). + +```markdown +> Person A: this is fine +>> Person B: no it's not +>>> Person C: *concern intensifies* +``` + +**Use for:** Tumblr chains, Twitter-style replies, nested irony. + +### ✅ Hard Line Breaks + +Two spaces at end of line or `
` for poetic timing. + +```markdown +roses are red +markdown is neat +two trailing spaces +make formatting sweet +``` + +**Use for:** Poetry, dramatic pauses, controlled pacing. + +### ✅ Horizontal Rules + +Use `---` to reset comedic pacing or transition between bits. + +```markdown +this joke is good + +--- + +this joke is completely unrelated +``` + +**Use for:** Section breaks, punchline separation, tempo control. + +### ✅ Emphasis + +Use `*italics*` and `**bold**` to simulate tone, stage directions, or emotional beats. + +```markdown +**me:** i'm fine +*narrator:* he was not fine +``` + +**Use for:** Stage directions, emphasis, emotional subtext. + +--- + +## 🎨 Layout Patterns for Text Memes + +### ✅ Choose a Meme Container + +Each meme should have a clear "block" form for readability: + +- **Code block** - Greentext, ASCII art, chat logs +- **Blockquote** - Tumblr chains, Twitter style +- **Heading + narrative** - Reddit AITA/TIFU, fake documentation +- **List** - Corporate satire, fake legal notices +- **Plain paragraph** - Emojicore, slang mutations + +### ✅ Aim for Three Layers + +Good textual memes read as: + +1. **Setup** - Establish context +2. **Pattern / Rhythm** - Build expectation +3. **Punchline or twist** - Subvert or amplify + +### ✅ Use Spacing as a Comedic Tool + +Memes breathe through white space. Don't be afraid to isolate lines. + +```markdown +this is fine + +this is also fine + +*nothing is fine* +``` + +--- + +## 📝 Textual Meme Formats + +### 💚 1. Greentext + +**Requirements:** Code fence with literal `>` characters + +**How to do it:** + +````markdown +```text +>be me +>writing markdown memes +>turn blog into 4chan but cleaner +>mfw it actually works +``` +```` + +**Renders as:** + +```text +>be me +>writing markdown memes +>turn blog into 4chan but cleaner +>mfw it actually works +``` + +**Tips:** + +- Keep sentence fragments +- Use anticlimax for humor +- Monospace evokes "anon culture" immediately +- Works great for technical narratives + +--- + +### 📦 2. Copypasta (Dramatic Walls of Text) + +**Requirements:** Code fence for preservation + +**How to do it:** + +````markdown +```text +What the fuck did you just fucking say about Markdown, you little bitch? +I'll have you know I graduated top of my class in the Navy Seals of Documentation, +and I've been involved in numerous secret raids on WordPress blogs... +``` +```` + +**Tips:** + +- Let it be long - that's the point +- Overblown emotion is essential +- Preserve original formatting for authenticity +- Consider using collapsible sections for very long copypastas + +--- + +### ✍️ 3. Shitpost Poetry & Micro-poems + +**Requirements:** Hard line breaks (two spaces or `
`) + +**How to do it:** + +```markdown +roses are red +markdown is sly +press two spaces +to force a new line + +violets are blue +syntax highlighting is lit +code fences preserve +every last bit +``` + +**Tips:** + +- Lean into minimalism +- Add `
` if a theme strips trailing whitespace +- Break expectations with sudden philosophical turns +- Lowercase adds casual authenticity + +--- + +### 🅰️ 4. ASCII Art & ASCII Storytelling + +**Requirements:** Monospaced code fence + +**How to do it:** + +````markdown +```text +(╯°□°)╯︵ ┻━┻ +┬─┬ノ( º _ ºノ) + + ___ + / \ + | o o | <- me reading documentation + \___/ + ||| +``` +```` + +**Tips:** + +- Use `text` or no language to avoid syntax coloring +- Test in multiple fonts +- Center using HTML `
` if needed +- Keep it simple for broad compatibility + +--- + +### 🌀 5. Surreal / Absurdist Text Memes + +**Requirements:** Markdown + strategic spacing + +**How to do it:** + +```markdown +you awaken in the hallway of beans + +the moon whispers: *not again* + +--- + +**OPTION 1:** accept the beans +**OPTION 2:** become the beans + +you choose Option 3 + +*there was no Option 3* +``` + +**Tips:** + +- Use italics for dream-logic emphasis +- Insert `---` to create uncanny jumps +- Be playful with lowercase/capitalization +- Treat whitespace as tension + +--- + +### 🗨️ 6. Tumblrisms (Multi-Speaker Chains) + +**Requirements:** Nested blockquotes + +**How to do it:** + +```markdown +> **Person A:** frogs are neat +>> **Person B:** frogs are powerful +>>> **Person C:** I aspire to frog +>>>> **Person D:** this post is making me lose my mind +>>>>> **Person A:** good +``` + +**Tips:** + +- Increase `>` depth to show escalation +- Add italics for emotional chaos +- Bold names for clarity +- Peak at 5 levels deep for readability + +--- + +### 🐦 7. Twitter / X-style Micro-memes + +**Requirements:** Blockquote or plain markdown + +**How to do it:** + +```markdown +> me: i'm productive +> also me: alphabetizes rocks by emotional energy + +--- + +**me at 3am:** what if bread could read + +**bread:** *softly* "help" +``` + +**Tips:** + +- Keep it tight (2–4 lines) +- Use italics for "stage directions" +- Short exaggeration = comedy +- Em dash works great: "me: — also me:" + +--- + +### 🧾 8. Reddit AITA / TIFU / Narrative Memes + +**Requirements:** Markdown headings + paragraphs + +**How to do it:** + +```markdown +### TIFU by enabling Markdown features too much + +**Context:** I work in documentation. + +**What Happened:** Today I formatted a shopping list with H3 headings, +bullet points, and citation links. My family staged an intervention. + +**Update:** They've hidden the Markdown guide. I'm formatting this from memory. + +**AITA?** +``` + +**Tips:** + +- Use headings for "post titles" +- Sincere tone + mild absurdity = gold +- Include typical Reddit formatting (bold labels) +- The more mundane the subject, the funnier + +--- + +### 🗿 9. Wojak-style Dialogues (Text-Only) + +**Requirements:** Bold names + minimal dialogue + +**How to do it:** + +```markdown +**Doomer:** nothing matters +**Zoomer:** drink water bro +**Wojak:** *internal screaming* +**Chad:** have you tried not caring +**Doomer:** ...wait that's actually helpful +**Chad:** i know +``` + +**Tips:** + +- Keep dialogue short +- Rely on archetypes for instant recognition +- Tone = half-honest, half-ironic +- Works great in code blocks too + +--- + +### 💬 10. Discord / Chat Log Memes + +**Requirements:** Code fence with timestamp format + +**How to do it:** + +````markdown +```text +[12:41] user123: you up? +[12:42] system: error: feelings.exe not found +[12:42] user123: same +[12:43] bot: did you try turning your emotions off and on again? +[12:44] user123: yes +[12:44] system: critical error: emotions.dll missing since 2019 +``` +```` + +**Tips:** + +- Timestamps add realism +- Use usernames to amplify the joke +- System messages = comedic gold +- Maintain deadpan delivery + +--- + +### 😀 11. Emojicore Memes + +**Requirements:** Just good spacing + +**How to do it:** + +```markdown +🚶💨 leaving my responsibilities + +😔👉👈 wondering if coffee counts as a personality + +🎯 hitting the target (the target is rock bottom) + +✨ manifesting ✨ (chaos) +``` + +**Tips:** + +- Use emojis as syntax, not decoration +- Vertical stacking works great +- Pair emoji with understated text +- Less is more + +--- + +### 📚 12. Fake Wiki / Manual Pages + +**Requirements:** Markdown headings + bold labels + +**How to do it:** + +```markdown +## Bread.exe + +**Category:** Deprecated Carbohydrate +**Status:** Unstable +**Introduced:** ~8000 BCE +**Last Update:** Never + +### Known Issues + +- Becomes stale without manual intervention +- Incompatible with lactose-intolerant systems +- Memory leak when toasted incorrectly + +### Workarounds + +See: `butter.dll` documentation +``` + +**Tips:** + +- Keep the tone pseudo-academic +- Use definition-style formatting +- Technical jargon for mundane objects = peak comedy +- Cross-reference other fake docs + +--- + +### 🐕 13. Slang-Mutation Text Memes + +**Requirements:** Markdown paragraphs with stylized orthography + +**How to do it:** + +```markdown +how 2 markdown: + +1. make text smol +2. add sparklez ✨ +3. u done it + +**congrations** u did a format + +no take backsies +``` + +**Tips:** + +- Lean into childlike spelling +- Use emoji to exaggerate tone +- Mix formal structure (lists) with informal language +- "Congrations" beats "congratulations" every time + +--- + +### 👶 14. ELI5 But Wrong + +**Requirements:** Heading + confident incorrect explanation + +**How to do it:** + +```markdown +### ELI5: Why do volcanoes erupt? + +Volcanoes are mountains that get too excited and sneeze the earth. +The rocks fly out because they want to be birds but forgot how. +This is called "geology." + +**Follow-up:** Why is lava hot? + +Because it's embarrassed about the whole situation. +``` + +**Tips:** + +- Confidence + incorrectness = humor +- Keep explanation "plausible" sounding +- Use actual ELI5 structure for authenticity +- Works great for tech concepts too + +--- + +### 📄 15. Corporate / Legalese Satire + +**Requirements:** Lists + bold labels + +**How to do it:** + +```markdown +## Notice of Emotional Noncompliance + +**Issued to:** You +**Date:** Whenever +**Reason:** Your vibe is irregular + +### Required Actions + +- [ ] Submit Form 42-B "Vibe Correction Protocol" within 5 business days +- [ ] Attend mandatory "Feeling Feelings Appropriately" training +- [ ] Provide written documentation of three (3) genuine smiles + +**Failure to comply will result in:** + +1. Passive-aggressive Slack messages +2. A pizza party (no pizza will be provided) +3. Being asked to "circle back" indefinitely + +--- + +*This notice has been automatically generated by the Department of Vibes.* +``` + +**Tips:** + +- Official tone for trivial things +- Short, concise bullet points increase contrast +- Use checkboxes for "action items" +- Footer disclaimers are pure gold + +--- + +## 🖼️ Image Memes via Pure URL + +Sometimes you want a visual punchline next to your textual meme. With **memegen.link**, you can generate classic image memes just by crafting a URL—no uploads, no editors. Then embed it in your Markdown with standard image syntax. + +### 🚀 Quick Start + +```markdown +![Drake meme about Markdown](https://api.memegen.link/images/drake/using_word_art/using_markdown.png) +``` + +That's it—your post renders the Drake format with top "using word art" and bottom "using markdown". + +--- + +### 🔧 URL Anatomy + +``` +https://api.memegen.link/images/{template}/{top_text}/{bottom_text}.{ext}?{options} +``` + +**Components:** + +- `template`: meme name (e.g., `drake`, `two-buttons`, `distracted-boyfriend`) +- `top_text` / `bottom_text`: your captions +- `ext`: `png` (default), `jpg`, or `webp` (good for lighter pages) +- `options`: query params (e.g., `font`, `width`, `watermark`) + +**Example:** + +```markdown +![Top/Bottom meme](https://api.memegen.link/images/two-buttons/write_tests/document_everything.png) +``` + +--- + +### 📝 Text Encoding Cheatsheet + +Memegen uses compact encoding so URLs stay readable: + +| Character | Encoding | Example | +|-----------|----------|---------| +| Space | `_` | `hello world` → `hello_world` | +| Hyphen | `--` | `foo-bar` → `foo--bar` | +| Underscore | `__` | `foo_bar` → `foo__bar` | +| Question mark | `~q` | `why?` → `why~q` | +| Percent | `~p` | `50%` → `50~p` | +| Hash | `~h` | `#tag` → `~htag` | +| Slash (literal) | `~s` | `foo/bar` → `foo~sbar` | +| Quotes | `''` | `he said "hi"` → `he_said_''hi''` | + +**Line breaks:** Use `%0A` (URL-encoded newline) inside a caption. + +**Example:** +``` +top_line%0Asecond_line +``` + +--- + +### ⚙️ Common Options (Query String) + +Append with `?` after the file extension: + +```markdown +?font=impact # Default is already impact; try notosans +?width=600&height=600 # Size control; height optional +?watermark=none # Remove tiny watermark +?background=URL # Custom template; URL-encode it +``` + +**Example:** + +```markdown +![Clean meme](https://api.memegen.link/images/drake/write_specs/rely_on_vibes.webp?width=640&watermark=none) +``` + +--- + +### 🎭 Popular Templates + +Quick reference for common meme formats: + +| Template | Use Case | +|----------|----------| +| `drake` | Rejecting one thing, approving another | +| `two-buttons` | Difficult choice between two options | +| `distracted-boyfriend` | Being distracted by something new | +| `gru-plan` | Plan that goes wrong at the end | +| `change-my-mind` | Stating an opinion confidently | +| `mocking-spongebob` | Mocking someone's statement | +| `is-this-a-pigeon` | Misidentifying something obvious | +| `surprised-pikachu` | Shocked by predictable outcome | +| `success-kid` | Celebrating small victories | +| `uno-draw-25` | Refusing to do something even if costly | +| `custom` | Use with `?background=` for any image | + +--- + +### 🎯 Blank Sides & One-Sided Captions + +Leave a side blank with `_` (single underscore). + +**Top only:** + +```markdown +![Top-only](https://api.memegen.link/images/change-my-mind/markdown_is_a_meme_engine/_.png) +``` + +**Bottom only:** + +```markdown +![Bottom-only](https://api.memegen.link/images/success-kid/_/finally_fixed_the_build.png) +``` + +--- + +### 📏 Multiline Captions + +Use `%0A` for line breaks inside a side: + +```markdown +![Multiline](https://api.memegen.link/images/gru-plan/plan_the_feature%0Adeliver_the_feature/forget_the_docs%0Awrite_them_later.png) +``` + +--- + +### 🎨 Custom Backgrounds (Brand or Screenshot) + +Use the `custom` template + `background` parameter. The background must be publicly reachable. + +```markdown +![Custom background meme](https://api.memegen.link/images/custom/top_text/bottom_text.png?background=https%3A%2F%2Fexample.com%2Fimage.png&watermark=none) +``` + +**Tip:** Pair a screenshot of your app/graph as background to comment on it memetically in the post. + +--- + +### ♿ Accessibility & SEO + +**Always provide descriptive alt text:** + +```markdown +![Drake rejecting "manual edits", approving "Markdown memegen URLs"](https://api.memegen.link/images/drake/manual_edits/markdown_memegen_urls.png?watermark=none) +``` + +Screen readers will read your alt text, making the joke accessible to everyone. + +--- + +### 📦 Quick Copy-Paste Recipes + +**Drake (top/bottom):** +```markdown +![Drake](https://api.memegen.link/images/drake/write_docs/write_memes.png?watermark=none) +``` + +**Two Buttons (multiline with %0A):** +```markdown +![Two buttons](https://api.memegen.link/images/two-buttons/fix_the_build%0A_now_/add_more_features%0A_today_.png) +``` + +**Change My Mind (top only):** +```markdown +![Change my mind](https://api.memegen.link/images/change-my-mind/markdown_is_a_design_tool/_.png) +``` + +**Surprised Pikachu (bottom only):** +```markdown +![Pikachu](https://api.memegen.link/images/surprised-pikachu/_/forgot_to_escape_slash~sagain.png) +``` + +**Custom background (brand screenshot):** +```markdown +![Custom](https://api.memegen.link/images/custom/ship_it/friday_release.webp?background=https%3A%2F%2Fyour.cdn%2Fapp_screenshot.png&width=720&watermark=none) +``` + +--- + +## 🎭 Mixing Text + Image Memes + +Blend text-only formats and image memes to pace a post effectively. + +### ✅ Rhythm Pattern + +**1. Start with text** to set up context: + +````markdown +### The Day I Realized Markdown Is Too Powerful + +```text +>be me +>ship blog revamp +>marketing wants "fun" +>accidentally create meme culture +``` +```` + +**2. Follow with a visual** to amplify the punchline: + +```markdown +![Two buttons](https://api.memegen.link/images/two-buttons/make_it_fun/make_it_accessible.png) +``` + +**3. Close with another text format** for resolution: + +```markdown +**Status:** fun achieved +**Risk:** puns leaked to production +**Next Steps:** embrace chaos +``` + +### ✅ Strategic Placement + +**Good patterns:** + +- Greentext → Image → Corporate satire +- Tumblr chain → ASCII art → Image +- Chat log → Image → Shitpost poetry + +**Avoid:** + +- 5 images in a row (visual fatigue) +- 3 long copypastas back-to-back (reader exhaustion) +- Image without context (confusing) + +### ✅ Complementary Pairs + +Match text and image memes thematically: + +| Text Format | Image Format | Why It Works | +|-------------|--------------|--------------| +| Greentext | Drake | Both are format-specific classics | +| Corporate satire | Two buttons | Amplifies "decision paralysis" theme | +| Chat log | Surprised Pikachu | Both capture reactions | +| Reddit AITA | Distracted boyfriend | Narrative + visual work together | +| Wojak dialogue | Custom background | Text provides context for visual | + +--- + +## 🔥 Advanced Features + +### 🎨 Custom CSS for Greentext (MkDocs / Hugo) + +Add custom styling for greentext blocks: + +```css +.greentext { + color: #789922; + font-family: 'Courier New', monospace; + background-color: #f0f0f0; + padding: 1rem; + border-left: 4px solid #789922; +} +``` + +Then wrap greentext in HTML: + +```html +
+ +>be you +>styling markdown like a pro +>mfw it actually looks good + +
+``` + +--- + +### 📢 Admonitions (MkDocs Material, Docusaurus) + +Use admonition blocks for "official" memes or mock disclaimers: + +```markdown +!!! warning "System Alert" + Your snacks have been revoked pending performance review. + +!!! danger "Critical Error" + `feelings.exe` has stopped responding. + Would you like to send an error report? [Yes] [Yes] +``` + +--- + +### 🗂️ Collapsible Sections + +Great for long copypastas and Tumblr chains: + +```markdown +
+Click to expand the legendary copypasta + +What the fuck did you just fucking say about Markdown... +(rest of copypasta) + +
+``` + +--- + +### 🎯 Tabs (Docusaurus, MkDocs) + +Show multiple meme variations side-by-side: + +```markdown +=== "Greentext" + + ```text + >be me + >tabs are cool + ``` + +=== "Corporate" + + **Notice:** Tabs have been deemed acceptable for meme deployment. + +=== "Image" + + ![Drake](https://api.memegen.link/images/drake/regular_text/tabs.png) +``` + +--- + +## 🚀 Production Tips + +### ⚡ Performance + +**For text memes:** +- Already optimal (it's just text!) +- No external dependencies +- Fast rendering + +**For image memes:** +- Prefer `webp` format for 30-50% smaller files +- Set consistent `?width=640` for predictable layout +- Consider lazy loading: `loading="lazy"` on `` tags +- Cache memegen.link URLs (they're stable) + +### ♿ Accessibility + +**Text memes:** +- Already screen-reader friendly +- Use semantic HTML where appropriate +- Avoid ASCII art for critical information + +**Image memes:** +- Always provide descriptive alt text +- Describe the joke, not just "meme image" +- Good: `![Drake rejecting documentation, approving memes]` +- Bad: `![funny meme]` + +### 🔍 SEO + +**Text memes:** +- Search engines index text content +- Use semantic HTML for structure +- Don't hide important information in ASCII art + +**Image memes:** +- Alt text provides indexable content +- Descriptive filenames help (though memegen URLs are generated) +- Consider adding captions below images for context + +--- + +## 📚 Complete Blog Example + +Here's a full blog post example mixing multiple meme formats: + +```markdown +--- +title: "The Deployment Chronicles" +date: 2025-01-11 +tags: [devops, humor, deployments] +--- + +# The Deployment Chronicles + +## Pre-Deployment Anxiety + +```text +>be me +>friday afternoon +>manager: "quick deploy?" +>mfw "quick" and "deploy" in same sentence +``` + +**Narrator:** *It was not quick.* + +--- + +## The Planning Phase + +### Decision Matrix + +![Two Buttons](https://api.memegen.link/images/two-buttons/test_thoroughly/deploy_on_friday.png?watermark=none) + +**Status:** We chose poorly. + +--- + +## During Deployment + +```text +[15:42] devops_bot: deployment started +[15:43] engineer1: looks good +[15:44] engineer2: why is prod slow +[15:45] system: ERROR: connection timeout +[15:46] engineer1: this is fine +[15:47] system: CRITICAL: database locked +[15:48] engineer1: THIS IS NOT FINE +``` + +![This is Fine](https://api.memegen.link/images/fine/production_is_down/this_is_fine.png) + +--- + +## Post-Mortem + +### Incident Report #2847 + +**Issued to:** Engineering Team +**Date:** 2025-01-11 18:30 UTC +**Reason:** Premature optimization of deployment strategy + +#### Required Actions + +- [ ] Never deploy on Friday again +- [ ] Actually read the deployment checklist +- [ ] Stop trusting "it works on my machine" + +**Consequences:** + +1. Mandatory attendance at "Why Friday Deploys Are Bad" training +2. Team pizza party (cancelled due to incident) +3. Existential dread + +--- + +*This incident report has been automatically generated by the Department of Preventable Disasters.* + +--- + +## Lessons Learned + +**me:** let's deploy carefully next time +*also me next Friday:* what could go wrong + +--- + +## Success Metrics + +After fixing everything: + +![Success Kid](https://api.memegen.link/images/success/deployed_successfully/only_took_4_hours.png?watermark=none) + +🎯 hitting targets (the target was "don't break prod permanently") +✨ manifesting ✨ (working deployments) +😅 lessons learned (until next time) + +--- + +## ELI5: What is a deployment? + +A deployment is when you tell the computer to use your new code. +Sometimes the computer listens. +Sometimes the computer decides chaos is more fun. +This is called "DevOps." + +**Follow-up:** Why do deployments fail? + +Because the computer has feelings and Friday afternoon hurts those feelings. + +--- + +## Conclusion + +roses are red +deploys cause pain +test in production +again and again + +--- + +*Want more deployment horror stories? Subscribe to our RSS feed of suffering.* +``` + +--- + +## 🎓 Summary + +This guide covered: + +1. **Why Markdown** - Preserves formatting, accessible, version-controllable +2. **Core techniques** - Code fences, blockquotes, spacing, emphasis +3. **15 textual formats** - From greentext to corporate satire +4. **Image memes** - Using memegen.link URLs +5. **Mixing formats** - Strategic pacing and rhythm +6. **Advanced features** - CSS, admonitions, tabs +7. **Production tips** - Performance, accessibility, SEO +8. **Complete example** - Real-world blog post + +**Key takeaways:** + +- Text memes are fast, accessible, and version-controllable +- Image memes via URL require no uploads or storage +- Mix formats strategically for comedic pacing +- Always provide alt text for accessibility +- Use spacing and whitespace as a comedic tool +- Keep text concise for maximum impact + +**Resources:** + +- Memegen API: https://api.memegen.link/docs/ +- Templates: https://api.memegen.link/templates/ +- MkDocs Material: https://squidfunk.github.io/mkdocs-material/ + +--- + +*This guide is a living document. Contributions welcome.* diff --git a/skills/meme-factory/scripts/meme_generator.py b/skills/meme-factory/scripts/meme_generator.py new file mode 100644 index 000000000..4c3552515 --- /dev/null +++ b/skills/meme-factory/scripts/meme_generator.py @@ -0,0 +1,244 @@ +#!/usr/bin/env python3 +"""Meme Generator Helper. + +A Python interface for the memegen.link API to generate memes programmatically. + +Usage: + python meme_generator.py generate buzz "memes" "memes everywhere" + python meme_generator.py list-templates + python meme_generator.py suggest "deployment success" + +Or import as a module: + from meme_generator import MemeGenerator + meme = MemeGenerator() + url = meme.generate("buzz", "hello", "world") +""" + +import argparse +import urllib.parse + + +class MemeGenerator: + """Generate memes using the memegen.link API.""" + + BASE_URL = "https://api.memegen.link" + + # Popular templates with their use cases + TEMPLATES = { + "buzz": "X, X everywhere (Buzz Lightyear)", + "drake": "Comparing two options (Drake Hotline Bling)", + "success": "Celebrating wins (Success Kid)", + "fine": "Things going wrong (This is Fine Dog)", + "fry": "Uncertainty (Futurama Fry)", + "changemind": "Controversial opinions (Change My Mind)", + "distracted": "Priorities/distractions (Distracted Boyfriend)", + "yodawg": "Yo dawg, I heard you like X (Xzibit)", + "interesting": "I don't always X (Most Interesting Man)", + "mordor": "One does not simply X (Boromir)", + "yuno": "Y U NO (Y U NO Guy)", + "doge": "Much X, very Y (Doge)", + "wonka": "Condescending statements (Wonka)", + "ancient": "Aliens/conspiracy (Ancient Aliens Guy)", + "skeptical": "Skeptical reactions (Third World Skeptical Kid)", + "awesome": "Good/bad situations (Awesome/Awkward Penguin)", + "rollsafe": "Can't X if Y (Roll Safe)", + "surprised": "Surprised reactions (Surprised Pikachu)", + "thinking": "Thinking/pondering (Thinking Guy)", + "boardroom": "Bad suggestions (Boardroom Meeting)", + } + + # Context-based template suggestions + CONTEXT_MAP = { + "success": ["success", "awesome"], + "failure": ["fine", "yuno"], + "comparison": ["drake", "awesome", "distracted"], + "uncertainty": ["fry", "suspicious"], + "statement": ["buzz", "yodawg", "interesting", "mordor", "changemind"], + "reaction": ["success", "fine", "surprised", "thinking"], + "humor": ["doge", "wonka", "ancient", "rollsafe"], + "deployment": ["success", "fine", "interesting"], + "testing": ["success", "fry", "interesting"], + "debugging": ["fine", "fry", "buzz"], + "documentation": ["yodawg", "buzz", "wonka"], + } + + def __init__(self) -> None: + """Initialize the meme generator.""" + + def _format_text(self, text: str) -> str: + """Format text for URL inclusion following memegen rules.""" + replacements = { + " ": "_", + "-": "--", + "_": "__", + "?": "~q", + "%": "~p", + "#": "~h", + "/": "~s", + '"': "''", + } + + escaped = "".join(replacements.get(char, char) for char in text) + + # Percent-encode any remaining reserved characters while preserving + # memegen's escape sequences and allowed characters. + return urllib.parse.quote(escaped, safe="-_~") + + def generate( # noqa: PLR0913 + self, + template: str, + top_text: str = "", + bottom_text: str = "", + extension: str = "png", + width: int | None = None, + height: int | None = None, + layout: str | None = None, + style: str | None = None, + font: str | None = None, + ) -> str: + """Generate a meme URL. + + Args: + template: Template name (e.g., 'buzz', 'drake') + top_text: Text for the top of the meme + bottom_text: Text for the bottom of the meme + extension: Image format ('png', 'jpg', 'webp', 'gif') + width: Optional width in pixels + height: Optional height in pixels + layout: Optional layout ('top', 'bottom', 'default') + style: Optional style or custom background URL + font: Optional font name + + Returns: + URL to the generated meme + + """ + # Format text + top = self._format_text(top_text) if top_text else "_" + bottom = self._format_text(bottom_text) if bottom_text else "_" + + # Build base URL + url = f"{self.BASE_URL}/images/{template}/{top}/{bottom}.{extension}" + + # Add query parameters + params = {} + if width: + params["width"] = str(width) + if height: + params["height"] = str(height) + if layout: + params["layout"] = layout + if style: + params["style"] = style + if font: + params["font"] = font + + if params: + query_string = urllib.parse.urlencode(params) + url = f"{url}?{query_string}" + + return url + + def suggest_template_for_context(self, context: str) -> str: + """Suggest a template based on context. + + Args: + context: Description of the situation (e.g., 'deployment success') + + Returns: + Suggested template name + + """ + context_lower = context.lower() + + # Check for keyword matches + for key, templates in self.CONTEXT_MAP.items(): + if key in context_lower: + return templates[0] + + # Default fallback + return "buzz" + + def list_templates(self) -> dict[str, str]: + """List all available templates with descriptions. + + Returns: + Dictionary of template names and descriptions + + """ + return self.TEMPLATES + + def get_markdown_image(self, url: str, alt_text: str = "Meme", width: int | None = None) -> str: + """Generate markdown for embedding the meme image. + + Args: + url: The meme URL + alt_text: Alternative text for the image + width: Optional width specification + + Returns: + Markdown image syntax + + """ + if width: + return f'{alt_text}' + return f"![{alt_text}]({url})" + + +def main() -> None: + """CLI interface for the meme generator.""" + parser = argparse.ArgumentParser(description="Generate memes using memegen.link") + subparsers = parser.add_subparsers(dest="command", help="Command to run") + + # Generate command + generate_parser = subparsers.add_parser("generate", help="Generate a meme") + generate_parser.add_argument("template", help="Template name (e.g., buzz, drake)") + generate_parser.add_argument("top", help="Top text") + generate_parser.add_argument("bottom", nargs="?", default="", help="Bottom text") + generate_parser.add_argument( + "--extension", "-e", default="png", help="Image format (png, jpg, webp, gif)" + ) + generate_parser.add_argument("--width", "-w", type=int, help="Image width") + generate_parser.add_argument("--height", type=int, help="Image height") + generate_parser.add_argument("--layout", "-l", help="Layout (top, bottom, default)") + generate_parser.add_argument("--markdown", "-m", action="store_true", help="Output as markdown") + + # List templates command + subparsers.add_parser("list-templates", help="List all available templates") + + # Suggest template command + suggest_parser = subparsers.add_parser("suggest", help="Suggest template for context") + suggest_parser.add_argument("context", help="Context description") + + args = parser.parse_args() + generator = MemeGenerator() + + if args.command == "generate": + generator.generate( + template=args.template, + top_text=args.top, + bottom_text=args.bottom, + extension=args.extension, + width=args.width, + height=getattr(args, "height", None), + layout=args.layout, + ) + if args.markdown: + pass + else: + pass + + elif args.command == "list-templates": + templates = generator.list_templates() + for _name, _description in sorted(templates.items()): + pass + + elif args.command == "suggest": + generator.suggest_template_for_context(args.context) + + else: + parser.print_help() + + +if __name__ == "__main__": + main() diff --git a/skills/remotion-best-practices/SKILL.md b/skills/remotion-best-practices/SKILL.md new file mode 100644 index 000000000..80d72fe42 --- /dev/null +++ b/skills/remotion-best-practices/SKILL.md @@ -0,0 +1,43 @@ +--- +name: remotion-best-practices +description: Best practices for Remotion - Video creation in React +metadata: + tags: remotion, video, react, animation, composition +--- + +## When to use + +Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge. + +## How to use + +Read individual rule files for detailed explanations and code examples: + +- [rules/3d.md](rules/3d.md) - 3D content in Remotion using Three.js and React Three Fiber +- [rules/animations.md](rules/animations.md) - Fundamental animation skills for Remotion +- [rules/assets.md](rules/assets.md) - Importing images, videos, audio, and fonts into Remotion +- [rules/audio.md](rules/audio.md) - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch +- [rules/calculate-metadata.md](rules/calculate-metadata.md) - Dynamically set composition duration, dimensions, and props +- [rules/can-decode.md](rules/can-decode.md) - Check if a video can be decoded by the browser using Mediabunny +- [rules/charts.md](rules/charts.md) - Chart and data visualization patterns for Remotion +- [rules/compositions.md](rules/compositions.md) - Defining compositions, stills, folders, default props and dynamic metadata +- [rules/display-captions.md](rules/display-captions.md) - Displaying captions in Remotion with TikTok-style pages and word highlighting +- [rules/extract-frames.md](rules/extract-frames.md) - Extract frames from videos at specific timestamps using Mediabunny +- [rules/fonts.md](rules/fonts.md) - Loading Google Fonts and local fonts in Remotion +- [rules/get-audio-duration.md](rules/get-audio-duration.md) - Getting the duration of an audio file in seconds with Mediabunny +- [rules/get-video-dimensions.md](rules/get-video-dimensions.md) - Getting the width and height of a video file with Mediabunny +- [rules/get-video-duration.md](rules/get-video-duration.md) - Getting the duration of a video file in seconds with Mediabunny +- [rules/gifs.md](rules/gifs.md) - Displaying GIFs synchronized with Remotion's timeline +- [rules/images.md](rules/images.md) - Embedding images in Remotion using the Img component +- [rules/import-srt-captions.md](rules/import-srt-captions.md) - Importing .srt subtitle files into Remotion using @remotion/captions +- [rules/lottie.md](rules/lottie.md) - Embedding Lottie animations in Remotion +- [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) - Measuring DOM element dimensions in Remotion +- [rules/measuring-text.md](rules/measuring-text.md) - Measuring text dimensions, fitting text to containers, and checking overflow +- [rules/sequencing.md](rules/sequencing.md) - Sequencing patterns for Remotion - delay, trim, limit duration of items +- [rules/tailwind.md](rules/tailwind.md) - Using TailwindCSS in Remotion +- [rules/text-animations.md](rules/text-animations.md) - Typography and text animation patterns for Remotion +- [rules/timing.md](rules/timing.md) - Interpolation curves in Remotion - linear, easing, spring animations +- [rules/transcribe-captions.md](rules/transcribe-captions.md) - Transcribing audio to generate captions in Remotion +- [rules/transitions.md](rules/transitions.md) - Scene transition patterns for Remotion +- [rules/trimming.md](rules/trimming.md) - Trimming patterns for Remotion - cut the beginning or end of animations +- [rules/videos.md](rules/videos.md) - Embedding videos in Remotion - trimming, volume, speed, looping, pitch diff --git a/skills/remotion-best-practices/rules/3d.md b/skills/remotion-best-practices/rules/3d.md new file mode 100644 index 000000000..31fa5c677 --- /dev/null +++ b/skills/remotion-best-practices/rules/3d.md @@ -0,0 +1,86 @@ +--- +name: 3d +description: 3D content in Remotion using Three.js and React Three Fiber. +metadata: + tags: 3d, three, threejs +--- + +# Using Three.js and React Three Fiber in Remotion + +Follow React Three Fiber and Three.js best practices. +Only the following Remotion-specific rules need to be followed: + +## Prerequisites + +First, the `@remotion/three` package needs to be installed. +If it is not, use the following command: + +```bash +npx remotion add @remotion/three # If project uses npm +bunx remotion add @remotion/three # If project uses bun +yarn remotion add @remotion/three # If project uses yarn +pnpm exec remotion add @remotion/three # If project uses pnpm +``` + +## Using ThreeCanvas + +You MUST wrap 3D content in `` and include proper lighting. +`` MUST have a `width` and `height` prop. + +```tsx +import { ThreeCanvas } from "@remotion/three"; +import { useVideoConfig } from "remotion"; + +const { width, height } = useVideoConfig(); + + + + + + + + + +``` + +## No animations not driven by `useCurrentFrame()` + +Shaders, models etc MUST NOT animate by themselves. +No animations are allowed unless they are driven by `useCurrentFrame()`. +Otherwise, it will cause flickering during rendering. + +Using `useFrame()` from `@react-three/fiber` is forbidden. + +## Animate using `useCurrentFrame()` + +Use `useCurrentFrame()` to perform animations. + +```tsx +const frame = useCurrentFrame(); +const rotationY = frame * 0.02; + + + + + +``` + +## Using `` inside `` + +The `layout` prop of any `` inside a `` must be set to `none`. + +```tsx +import { Sequence } from "remotion"; +import { ThreeCanvas } from "@remotion/three"; + +const { width, height } = useVideoConfig(); + + + + + + + + + +``` \ No newline at end of file diff --git a/skills/remotion-best-practices/rules/animations.md b/skills/remotion-best-practices/rules/animations.md new file mode 100644 index 000000000..7e15623f8 --- /dev/null +++ b/skills/remotion-best-practices/rules/animations.md @@ -0,0 +1,29 @@ +--- +name: animations +description: Fundamental animation skills for Remotion +metadata: + tags: animations, transitions, frames, useCurrentFrame +--- + +All animations MUST be driven by the `useCurrentFrame()` hook. +Write animations in seconds and multiply them by the `fps` value from `useVideoConfig()`. + +```tsx +import { useCurrentFrame } from "remotion"; + +export const FadeIn = () => { + const frame = useCurrentFrame(); + const { fps } = useVideoConfig(); + + const opacity = interpolate(frame, [0, 2 * fps], [0, 1], { + extrapolateRight: 'clamp', + }); + + return ( +
Hello World!
+ ); +}; +``` + +CSS transitions or animations are FORBIDDEN - they will not render correctly. +Tailwind animation class names are FORBIDDEN - they will not render correctly. \ No newline at end of file diff --git a/skills/remotion-best-practices/rules/assets.md b/skills/remotion-best-practices/rules/assets.md new file mode 100644 index 000000000..04c8ad590 --- /dev/null +++ b/skills/remotion-best-practices/rules/assets.md @@ -0,0 +1,78 @@ +--- +name: assets +description: Importing images, videos, audio, and fonts into Remotion +metadata: + tags: assets, staticFile, images, fonts, public +--- + +# Importing assets in Remotion + +## The public folder + +Place assets in the `public/` folder at your project root. + +## Using staticFile() + +You MUST use `staticFile()` to reference files from the `public/` folder: + +```tsx +import {Img, staticFile} from 'remotion'; + +export const MyComposition = () => { + return ; +}; +``` + +The function returns an encoded URL that works correctly when deploying to subdirectories. + +## Using with components + +**Images:** + +```tsx +import {Img, staticFile} from 'remotion'; + +; +``` + +**Videos:** + +```tsx +import {Video} from '@remotion/media'; +import {staticFile} from 'remotion'; + +