Générer des cartes sociales d'événement Pulumi

VérifiéSûr

Génère des cartes sociales de marque pour les événements Pulumi en cinq tailles via Satori, avec enrichissement par co-présentateurs et logos.

Spar Skills Guide Bot
ContenuIntermédiaire
31/07/2026
Claude Code
#social-cards#opengraph#image-generation#satori#pulumi

Recommandé pour

Synthèse automatique

Génère des cartes sociales de marque pour un événement ou un atelier Pulumi en cinq formats, via le moteur de rendu Satori partagé avec le build du site.

Points forts

  • Produit cinq tailles en une passe (1200x628 OG, 1200x675, 628x628, 1080x1080, 540x960) avec le même rendu que la carte par défaut du build.
  • Enrichit la carte avec des intervenants absents du frontmatter (co-présentateurs externes et leurs photos) et des logos partenaires.
  • Deux modes clairs : rattaché à un événement (écrit dans le bundle et met à jour meta_image / meta_image_square) ou autonome (PNG dans un dossier).
  • Mode non interactif (-y / --non-interactive) qui résout automatiquement les personnes et logos et ignore un asset introuvable au lieu de bloquer.

Limites

  • Fortement couplé au dépôt Pulumi : chemins scripts/meta-images/render-event.mjs et structure content/events/<slug>/ supposés présents.
  • La résolution des photos et logos dépend de recherches web et peut échouer silencieusement en mode non interactif (asset ignoré avec un simple avertissement).
  • Ne couvre pas tous les besoins : pour beaucoup d'événements la carte générée automatiquement au build suffit, et aucun bouton Register n'est ajouté sans demande explicite.
Quand l'utiliser

À utiliser quand il faut produire ou enrichir rapidement la carte sociale d'un événement Pulumi avec des intervenants ou des logos absents du frontmatter.

Quand l'éviter

À éviter sur un projet qui n'utilise pas le dépôt et le moteur de rendu Pulumi, ou lorsqu'une carte par défaut générée au build suffit.

Analyse de sécurité

Sûr
Score qualité88/100

The skill instructs running a local Node/Satori renderer script to generate image files and optionally update frontmatter and write PNGs into a repo bundle. It uses WebSearch/WebFetch to resolve people and logos, which is a legitimate network use for asset lookup, but no destructive commands, exfiltration, obfuscation, or credential handling are present. Writing files and updating frontmatter is a normal authoring action.

Aucun point d'attention détecté

Comment cette analyse est faite

Exemples

Event-bound regeneration
/event-meta-image content/events/seattle-kubernetes-workshop — regenerate the social cards and add our external co-presenter Jane Doe with her photo, plus the Microsoft partner logo.
Unattended run
/event-meta-image -y for the upcoming workshop event: derive the presenters and partner logos automatically and skip anything you can't resolve.
Standalone images
Generate event social card images for a Pulumi + Datadog workshop called 'Shipping Infra with TypeScript' — just emit the five PNGs to .context/event-images/infra-ts/, no frontmatter changes.

name: event-meta-image description: "Generate on-brand social cards for a Pulumi event/workshop in five sizes (1200x628 OG, 1200x675, 628x628, 1080x1080, 540x960) using the shared Satori events renderer. Enriches the build-time default with people not in frontmatter (external co-presenters + their photos) and company/partner logos (Pulumi + e.g. Microsoft). Runs event-bound (writes into a content/events/<slug>/ bundle + sets meta_image / meta_image_square) or standalone (just emit the five PNGs to a folder). Use when the user types /event-meta-image or asks to create, generate, regenerate, or enrich an event's meta image, social card, OpenGraph image, or speaker/workshop card. Pass -y / --yes / --non-interactive (or 'no questions') to run end-to-end with sensible defaults and no prompts. A Register button is never added unless explicitly requested."

/event-meta-image — Generate event / workshop social cards

You generate the branded event card (the Figma "Workshop / event images" component) in five sizes via the shared Node/Satori renderer — the same renderer the build uses for the automatic default, so output is identical to what ships, just enriched with inputs that aren't in frontmatter (external co-presenters, their photos, partner logos).

Skill directory: .claude/commands/event-meta-image/ — paths below are relative to the repo root unless noted. Renderer CLI: scripts/meta-images/render-event.mjs (shared with the build). One JSON config → one PNG per size.

You do not need a custom card for most events. Every event already gets an on-brand landscape + square card automatically at build time from its frontmatter (scripts/generate-meta-images.mjs). Use this skill only to (a) enrich a card with people/logos not in frontmatter, (b) override the auto default, or (c) grab the extra social sizes (square-large, portrait, tall) for manual use. (For a plain default with no enrichment, scripts/meta-images/render-event-cards.mjs <slug> renders all five sizes from frontmatter without a config.)


[Step 0/6] Pick the mode

  • Event-bound — there is a target content/events/<slug>/ page. Triggered when $ARGUMENTS names an event path/slug, when git status shows a changed event, or when the user points at one. Writes the PNGs into the page bundle and updates frontmatter.
  • Standalone — the user just wants images ("generate event images for …", no event attached). Collect inputs directly (Steps 3–5), skip frontmatter, and write the PNGs to an output dir (default .context/event-images/<slug>/, or a path the user gives). No frontmatter or bundle writes.

Everything below applies to both modes except the bundle/frontmatter writes in Step 6 (event-bound only).

Interaction mode — when to ask questions

Orthogonal to event-bound/standalone, pick how much to prompt. Default to searching, not asking: in both modes you still auto-resolve people and logos via the ladders in Steps 3–4 (including WebSearch/WebFetch). The modes differ only in what happens when something can't be resolved or is genuinely ambiguous.

  • Unattended — never ask. Trigger when $ARGUMENTS contains -y, --yes, --non-interactive, --no-input, no questions, or "just do it" (and automatically whenever you're running non-interactively, e.g. under claude -p or the eval, where AskUserQuestion can't be answered). Skip every AskUserQuestion. Derive all inputs automatically:
    • overline = event_type; title = frontmatter title; speakers = frontmatter presenters[].photo; additionalText = the derived "With …" line.
    • people = frontmatter presenters plus any external co-presenter named in the title/body.
    • logos = ["pulumi"] plus any partner company named in the title/body.
    • Auto-resolve each derived photo/logo via the Step 3 / Step 4 ladders. On a resolution miss, skip that one asset with a warning and keep going — never block. No button, no secondary title.
  • Default — ask only when needed. Same automatic derivation and search as unattended mode, but fall back to a single targeted AskUserQuestion only when an asset can't be resolved, or an input is genuinely ambiguous (multiple candidate events, missing title, a partner named but not identifiable). Do not ask to confirm things already known from frontmatter or $ARGUMENTS.

[Step 1/6] Locate the event (event-bound)

  1. If $ARGUMENTS contains an event path or slug, use content/events/<slug>/index.md.
  2. Otherwise run git status / git diff --name-only for changed content/events/*/index.md.
  3. Multiple candidates → ask with AskUserQuestion. None → ask for the slug/path (or switch to standalone if the user only wants loose images).

Read the full index.md (frontmatter + body).

[Step 2/6] Seed from frontmatter

Pull from frontmatter:

  • title (required — the card's main title; the renderer fits it to the box).
  • event_type → the default overline (uppercased automatically).
  • presenters: presenters: [{ name, role, photo }] — the in-frontmatter speakers. Each photo (e.g. /images/people/<x>.jpg or /images/team/<x>.jpg) resolves under static/.

The build default already uses exactly these. If the user only wants the default look in all five sizes (no new people/logos), you can skip straight to Step 6 with overline, title, the presenters' photo paths as speakers, the "With …" line as additionalText, and ["pulumi"] as logos.

[Step 3/6] Add people not in frontmatter (external co-presenters)

Add anyone beyond the presenters: list — e.g. a partner-company co-host. Derive these from the event first (the title/body and $ARGUMENTS); only fall back to AskUserQuestion per the interaction mode (default: ask when a person is named but you can't identify or resolve them; unattended: skip an unresolvable person with a warning, never ask). For each added person collect name + role/company, then resolve a color photo via this ladder (stop at the first hit):

  1. An existing presenters[].photo (already have it).
  2. static/images/team/<kebab-name>.{jpg,jpeg,png}.
  3. static/images/people/<kebab-name>.{jpg,jpeg,png}.
  4. Web: WebSearch for a headshot / company bio photo, then WebFetch the image. LinkedIn images are usually auth-gated — expect this to fail and fall through.
  5. Ask the user for a photo URL or local file path.

Save any fetched/provided external photo to a real file (e.g. .context/event-images/<slug>/<kebab-name>.jpg) and pass that path in the config — the renderer resolves local files and data: URIs, not remote URLs. Photos render color + circular on a violet ring (the renderer can't reproduce the Figma duotone; the ring keeps them on-brand). Up to 5 speakers display (the renderer shrinks the circles so they fit, stacking vertically on landscape and in a row on square/portrait); the byline lists every name. Beyond 5 is rare — pick the 5 to show in Step 5.

[Step 4/6] Company / partner logos

Pulumi is always included ("pulumi" → the bundled brand mark — never re-color or restyle it). The renderer lays the logos out in a row joined by a muted + (Pulumi + Microsoft + …), so each entry should read as a company on its own.

Add partner/company logos (e.g. Microsoft, GitHub, Google Cloud, NVIDIA) for any partner named in the event's title/body or $ARGUMENTS. Derive them from the event first — only fall back to AskUserQuestion per the interaction mode (default: ask when a partner is named but you can't source a compliant logo; unattended: skip an unresolvable logo with a warning, never ask). Three hard rules when sourcing each one:

  • Default to the WORDMARK — the lockup that includes the company name (e.g. the Microsoft squares plus "Microsoft"), not the bare glyph. A mark-only icon next to "Pulumi" reads as unfinished. Only fall back to a glyph if no wordmark exists or the glyph IS the brand (rare).
  • Prefer the HORIZONTAL variant. The renderer scales every logo to a fixed row height, so a vertical/stacked lockup (mark stacked above the name) renders its text tiny and unbalanced next to Pulumi. Choose the horizontal lockup (mark beside the name, or the wordmark alone). Rule of thumb: check the SVG viewBox / PNG dimensions and prefer an aspect ratio ≳ 3:1; reject stacked or roughly-square lockups (aspect ≲ 2) even when they're technically a wordmark, and keep looking (a company's brand/press page usually offers both a "horizontal" and a "stacked" variant — take the horizontal one).
  • Must be an SVG or a TRANSPARENT PNG. The card background is near-white (#f5f5ff), so a logo with a baked-in white/opaque background shows as an ugly box — never use one. Verify transparency before caching (a PNG reported by file as RGB with no alpha is opaque; RGBA or a colormap with tRNS may be transparent — check the render).

Resolve each via this ladder, stopping at the first hit that satisfies both rules:

  1. .claude/commands/event-meta-image/assets/logos/<name>.svg (cached — see references/logos.md).
  2. static/logos/** (the site's own brand assets — often clean SVG wordmarks).
  3. Web — WebSearch "<company> logo wordmark SVG transparent", then WebFetch/curl the official SVG. Good sources: the company's own brand/press page, Wikimedia Commons (*_logo.svg), and reputable vector libraries. simple-icons (https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/<slug>.svg) is glyph-only and monochrome — use it only as a last resort, and recolor the <path> with fill="#<brandcolor>".
  4. Ask the user for a transparent SVG/PNG wordmark. Prefer asking over shipping a mark-only or white-background logo.

Cache any clean fetched logo to .claude/commands/event-meta-image/assets/logos/<name>.{svg,png} and add a row to references/logos.md. Pass logo paths (absolute, or relative to the config file) in the config; "pulumi" is the one special name.

[Step 5/6] Options

Default every option and move on. Only reach for AskUserQuestion per the interaction mode (and never in unattended mode); never re-confirm what $ARGUMENTS or frontmatter already answered.

  • overline — default event_type (e.g. WORKSHOP, WEBINAR, PANEL); honor an override if $ARGUMENTS gives one.
  • secondary title — hidden. Set it only if the user explicitly asks for a small line above the title.
  • which people / logos to include and their order — when there are more than 5 people, pick the 5 to show; order logos Pulumi-first.

Never add a button. showButton stays false unless the user's prompt explicitly asks for one (e.g. "with a Register button", "add a CTA", "include a sign-up button"). Do not offer it, do not ask about it, and never enable it in unattended mode. Only when explicitly requested, set showButton: true and buttonText accordingly.

[Step 6/6] Render the five sizes

Write one config JSON (e.g. .context/event-images/<slug>/config.json), then loop the renderer over the five sizes.

Config schema (all optional except title):

{
  "overline": "WORKSHOP",
  "title": "Advanced CI/CD for AWS using Pulumi and GitHub Actions",
  "secondaryTitle": "",
  "additionalText": "With Jane Doe - Staff Engineer, Acme and John Roe",
  "showButton": false,
  "buttonText": "Register",         // opt-in only — see below; leave showButton false unless explicitly requested
  "speakers": ["/images/people/jane.jpg", ".context/event-images/<slug>/john-roe.jpg"],
  "logos": ["pulumi", ".claude/commands/event-meta-image/assets/logos/microsoft.svg"]
}
  • additionalText is the literal "With …" line. Compose it yourself: one presenter → With {name} - {role}; many → names only, Oxford comma (With A, B, and C). (Omit to let the CLI derive it from a presenters: [{name, role}] array instead.)
  • showButton is off unless the user explicitly asked for a button (see Step 5). Omit it or leave false in every default and unattended run.
  • speakers / logos resolve as: data: URI → path relative to the config file → repo path (/images/…, static/, assets/fingerprinted/, static/logos/**) → absolute path. Unresolved entries are skipped with a warning.

Render loop — same config, five sizes:

| size | event-bound filename | wired to | |------|----------------------|----------| | 1200x628 | meta.png | meta_image (primary OG + twitter:image) | | 628x628 | meta-square.png | meta_image_square (second og:image) | | 1200x675 | meta-landscape-tall.png | — (manual social) | | 1080x1080| meta-square-large.png | — (manual social) | | 540x960 | meta-portrait.png | — (manual social) |

CFG=.context/event-images/<slug>/config.json
DEST=content/events/<slug>          # event-bound; standalone → .context/event-images/<slug>
node scripts/meta-images/render-event.mjs --config "$CFG" --size 1200x628  --out "$DEST/meta.png"
node scripts/meta-images/render-event.mjs --config "$CFG" --size 628x628   --out "$DEST/meta-square.png"
node scripts/meta-images/render-event.mjs --config "$CFG" --size 1200x675  --out "$DEST/meta-landscape-tall.png"
node scripts/meta-images/render-event.mjs --config "$CFG" --size 1080x1080 --out "$DEST/meta-square-large.png"
node scripts/meta-images/render-event.mjs --config "$CFG" --size 540x960   --out "$DEST/meta-portrait.png"

Event-bound writes (only)

After rendering into content/events/<slug>/, set frontmatter:

meta_image: /events/<slug>/meta.png
meta_image_square: /events/<slug>/meta-square.png

(Optionally set overline: if you customized it.) The three extra sizes are not wired to meta tags — they're for manual social use. Setting meta_image makes the build skip the auto card for this page (the override wins; see layouts/partials/meta-image-url.html).

Standalone writes (only)

Write all five PNGs to the chosen output dir and report their paths. No frontmatter, no bundle.

Wrap-up

Report: mode; the event (event-bound); overline + title used; people shown (and where each photo came from); logos placed; the five output paths; and for event-bound, the frontmatter that was set. Always remind the user to preview the PNGs (and, event-bound, the live page) before committing. Preview the landscape and square first — those are the ones that ship as og:image.

Error handling

  • render-event.mjs prints warning: could not resolve … for any photo/logo it couldn't find — fix the path or re-resolve via the ladder.
  • "Offset is outside the bounds of the DataView" or a decode error → the image is corrupt/truncated; re-fetch it. (Mislabeled extensions like a PNG named .jpg are handled automatically — the renderer sniffs the real type.)
  • No title → ask the user. Long titles auto-shrink to fit; you don't need to trim them.
  • Don't generate or AI-synthesize brand imagery or the Pulumi mascot; use the bundled logo and approved assets only.

References

  • references/logos.md — cached company-logo inventory + the resolution ladder.
  • Renderer internals / layout: scripts/meta-images/events.mjs. Shared CLI: scripts/meta-images/render-event.mjs.

Du fichier au premier essai

Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.

Consulter la source et ses fichiers annexes

Ce téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.

1. Télécharger le fichier

Télécharger SKILL.md

Depuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.

Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.

mkdir -p '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/generate-pulumi-event-social-cards-ms8gxn3n/download' --output '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md.part' && mv '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md.part' '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md'

2. Vérifier les prérequis

Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.

Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.

Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.

3. Charger la skill

Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.

Claude Code
test -f '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md' && test -s '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/event-meta-image' && cp -R '.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n' '.claude/skills/event-meta-image'

OpenSkills

OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.

Installation officielle d’OpenSkills
openskills install './.skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n'

openskills read 'generate-pulumi-event-social-cards-ms8gxn3n'

La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.

Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.

openskills sync

Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.

4. Faire un premier essai

Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :

Lis .skill-downloads/generate-pulumi-event-social-cards-ms8gxn3n/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.

Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.

Skills similaires