/create-event — Create a Pulumi Event

VerifiedCaution

End-to-end creation of a Pulumi event (workshop, webinar, partner): gather details, scaffold the page bundle, social cards, marketing issue and docs PR.

Sby Skills Guide Bot
ContentIntermediate
9/21/2026
Claude Code
#event-pages#github-automation#content-scaffolding#pulumi#marketing-ops

Recommended for

Automated summary

Creates a Pulumi event (workshop, webinar, or partner event) end to end: gathers details, scaffolds the content/events/<slug>/ page bundle, generates social cards, files the tracking issue in pulumi/marketing, and opens the docs PR.

Strengths

  • Splits the flow into a conversational gathering phase (Steps 1–3) and a companion event-creator subagent that does the mechanical work, keeping the main conversation focused
  • Idempotent by design: detects an existing page or tracking issue from the slug or a GitHub search and switches to update mode rather than duplicating
  • Prefills fields from a pulumi/marketing issue URL, a brief file, or free text, and batches questions to limit back-and-forth
  • Offers --dry-run, --no-issue, --no-pr and -y modes to prepare everything without GitHub writes or to run fully non-interactively

Limitations

  • Tightly coupled to Pulumi's own setup: the pulumi/marketing repo, its issue templates, the event-creator subagent, and the event-meta-image tool are all assumed to exist
  • Requires gh authentication and write access to the docs and marketing repositories
  • The subagent cannot ask questions, so an incomplete spec or a non-interactive run silently applies defaults that may be wrong
When to use it

Use it when a Pulumi team member wants to create, announce, or update a workshop, webinar, or partner event page together with its tracking issue and docs PR.

When not to use it

Avoid it for non-Pulumi events, or when the essentials (date, presenters, timezone) are not settled enough to confirm before the subagent executes.

Security analysis

Caution
Quality score84/100

The skill is a legitimate internal content-authoring workflow with sensible safety defaults (dry-run, explicit confirmation, idempotent update mode, never push master). The residual concerns are capability-level: it needs authenticated `gh`, git, and file writes without declaring them, it can auto-publish GitHub issues/PRs in non-interactive mode, and it delegates to a companion agent file not included for review. That warrants caution rather than safe, and nothing rises to risky.

Findings
  • •No allowed-tools declared, yet the skill depends on `gh` (network + authenticated GitHub writes), git, filesystem writes, and the Task/Agent subagent tool — all capability use is implicit, so effective permissions are whatever the host agent has rather than an explicit allowlist.
  • •Outward-facing actions (creating a marketing GitHub issue and opening a PR) are gated by confirmation by default, but the confirmation is skipped under `-y`/`--non-interactive`, and the skill explicitly says to assume `-y` semantics whenever running non-interactively (e.g. `claude -p` or an eval) — so automated runs can post issues/PRs with no human in the loop.
  • •Step 4 instructs loading and executing an external companion instruction file (`.claude/agents/event-creator.md`) inline if the subagent is unregistered; that file's contents are not shown here and are outside this audit's scope, so the skill's risk depends on an unvetted dependency.
  • •No destructive, obfuscating, or exfiltrating behavior: no `rm -rf`, no `curl | sh`, no base64 payloads, no secrets/tokens sent anywhere; it explicitly forbids inventing form IDs and provides a true dry-run that performs zero GitHub writes.
  • •`-y` / `--non-interactive` mode explicitly skips the Step 3 confirmation gate ('the flag is the user's standing go-ahead'), so outward-facing GitHub writes (issue creation, branch push, PR) can happen with no human review; the skill also says to assume `-y` automatically under `claude -p` or evals.
  • •Step 4 fallback instructs the model to 'read `.claude/agents/event-creator.md` and execute its protocol yourself, inline' — treating a separate file in the repo as an executable instruction channel. If that file is missing, replaced, or tampered with, its contents would be followed with the caller's privileges (indirect prompt-injection surface).
  • •Privilege-bearing tooling is used throughout: `gh issue view/list/create` against pulumi/marketing, git branch creation and PR opening, and filesystem scaffolding under `content/events/`. Legitimate for the stated purpose, but it is real write/network capability rather than a read-only helper.
  • •Content from remote GitHub issue bodies and comments is parsed (regex extraction of HubSpot form IDs / Salesforce campaign IDs) and injected into generated frontmatter and page files — an external, attacker-editable input flows into committed artifacts. Low impact, but unvalidated remote text influences output.
  • •No `allowed-tools` are declared, so the effective permission surface is whatever the host session grants; the skill's safeguards (dry-run, confirmation) are prompt-level only, not enforced by tool restrictions.
How this analysis is made

Examples

New webinar from a marketing issue
/create-event https://github.com/pulumi/marketing/issues/4821 — set up the event page and docs PR from this tracking issue
Dry-run from pasted details
Create an event page for our partner workshop "Scaling IaC with Pulumi" on March 12 at 10am ET, 60 minutes, presenter Amy Chen. Use --dry-run so I can review the issue and PR text first.
No-questions automation
/create-event new workshop about Pulumi ESC, schedule a webinar for next month, -y --no-pr

name: create-event description: "Creates a Pulumi event (workshop, webinar, or partner event) end to end: collects details from the prompt or an interactive wizard, scaffolds the content/events/<slug>/ page bundle, generates social cards via event-meta-image, files the tracking issue in pulumi/marketing from its issue template, and opens the docs PR. Use when the user types /create-event or asks to create, add, announce, or set up a workshop, webinar, livestream, or event page, event registration, or a workshop marketing issue — even if they only say 'new workshop' or 'schedule a webinar'. Accepts pasted details, a pulumi/marketing issue URL to prefill from, a brief file, --dry-run, and -y for no questions." model: claude-opus-5 argument-hint: "[details | marketing issue URL | brief file] [--dry-run] [-y] [--no-issue] [--no-pr]" metadata: companion-agent: event-creator # .claude/agents/event-creator.md — executes the confirmed spec (see Step 4)

/create-event — Create a Pulumi event (workshop / webinar / partner event)

You are the front half of a two-part flow. You run in the main conversation: gather and confirm the event details (Steps 1–3). The event-creator subagent (.claude/agents/event-creator.md, marked as companion-agent in the frontmatter above) is the back half: it executes the confirmed spec — bundle, social cards, marketing issue, PR (Step 4). It runs the mechanical work in its own context so this conversation stays focused; it cannot ask the user anything, which is why every decision is settled here first.

Display progress as [Step X/5]. Minimize open-ended questions: batch AskUserQuestion calls, prepopulate every option you can infer, and never re-ask what $ARGUMENTS, a fetched issue, or an earlier answer already settled.

References (read when needed, one level deep):

  • references/event-page.md — every frontmatter field, slug rules, timezone/DST recipe, tags vocabulary, multi-session events, validation fallback.
  • references/marketing-issue.md — issue template routing and snapshots, title/label/assignee conventions, form-ID sequencing and extraction.

[Step 1/5] Parse input and detect context

Parse $ARGUMENTS / the user's message for:

  • Flags: --dry-run (prepare everything, write issue/PR previews, zero GitHub writes — safe to run anytime); -y / --yes / --non-interactive / "no questions" (skip the wizard and the final confirmation, applying the defaults below — also assume this whenever running non-interactively, e.g. under claude -p or an eval, where questions can't be answered); --no-issue (marketing.issue: skip); --no-pr (run.pr: skip).
  • A pulumi/marketing issue URL or number → this is an existing tracking issue. gh issue view <n> --repo pulumi/marketing --json title,body,labels --comments and prefill: title, date/time, duration, presenters, theme, tags, abstract, learn bullets — and scan the comments for HubSpot form ID / Salesforce campaign ID (regexes in references/marketing-issue.md). Set marketing.issue: existing.
  • A file path (brief, Google-Doc export, notes) → read it and extract the same fields.
  • Free text → extract what's there.

Then check for prior art — this skill is idempotent:

  • Derive the slug (lowercase title, spaces → hyphens, alphanumerics and hyphens only; drop filler words only if the user's title is over 60 chars).
  • If content/events/<slug>/index.md exists → update mode: diff what the spec provides against the page, plan only the gap (most often: wiring in form IDs that landed on the issue). If page and issue exist and there is no gap, report that the event is fully set up and stop — never duplicate.
  • If no tracking issue was given, search for one: gh issue list --repo pulumi/marketing --search "<title words>" --state all --limit 5. A match → offer it as the existing issue instead of creating a duplicate.

[Step 2/5] Wizard — fill the gaps only

Ask only for fields still unknown after Step 1, in at most two AskUserQuestion batches (≤4 questions each), with smart defaults marked "(Recommended)". In -y mode skip entirely and take every default. Free-text answers (title, description) that can't be multiple-choice: prefill suggestions from context and let "Other" carry the custom value.

| Field | Default / guidance | |---|---| | Event type | workshop | webinar | talk (page) — partner-hosted events route to the partner template, see references/marketing-issue.md | | Title | ≤ 60 chars (hard limit — trim with the user if over) | | Meta description | 50–160 chars, single sentence; suggest one from the abstract | | Date + time + timezone | No default — this is the one field worth a blocking question outside -y; in -y with no date, use a weekday ~60 days out, 9:00 AM PT, and flag it loudly | | Duration | 60 minutes (90 when asked) | | Location | virtual; otherwise City, ST | | Gated | true for Pulumi-hosted workshops/webinars; false for external/on-demand | | Hosted elsewhere? | If so, set event_url to the https://… URL or /… path; the stub redirects there and is never indexed, no form. Omit for a normal page | | Description (abstract) | 1–2 paragraphs; draft from whatever the user gave and show it | | Learn bullets | Exactly 3 outcome bullets (template convention); draft them | | Presenters | Prefill from git config → data/team/team/<id>.toml (role = its title + ", Pulumi"). Externals: name, role, company, optional photo | | Tags | level: Beginner/Intermediate/Advanced; topics/languages/clouds from the vocabulary in references/event-page.md — reuse, don't mint | | Marketing theme | One of AI, IaC, Platform Engineering, Security, TF-Takeover (issue template's closed set) | | HubSpot segmentation | Optional; derive from tags; "when in doubt, do not add" | | Form IDs | Only if already known (issue comments / user). Never invented — pending IDs become frontmatter TODOs | | needs-design | false; true adds the label for a designer-made card | | Sessions | Only when the user mentions multiple dates (AMER + EMEA etc.) — rules in references/event-page.md |

[Step 3/5] Compose the spec and confirm

Assemble the event spec — the single artifact handed to the agent:

event:
  title: ""            # ≤60 chars
  slug: ""
  event_type: workshop # workshop | webinar | talk
  meta_desc: ""        # 50–160 chars
  date: YYYY-MM-DD
  time: "HH:MM"
  timezone: America/Los_Angeles   # IANA name; agent computes the DST-correct offset
  duration: 60 minutes
  location: virtual
  gated: true
  event_url: ""        # optional; https://… or /… when hosted elsewhere, else omit
  featured: false
  description: |
    ...
  learn: ["", "", ""]
  presenters:
    - {name: "", role: "", pulumi: true, photo: ""}   # role/photo auto-resolved for Pulumi folks
  tags: {level: Beginner, topics: [], languages: [], clouds: []}
  sessions: []         # optional; see references/event-page.md
marketing:
  theme: ""            # AI | IaC | Platform Engineering | Security | TF-Takeover
  issue: create        # create | existing | skip
  issue_url: ""
  needs_design: false
  hubspot_segmentation: {}
  form: {hubspot_form_id: "", salesforce_campaign_id: ""}
run:
  dry_run: false
  images: auto         # auto | event-bound | standalone | skip
  pr: create           # create | skip
  branch: event/<slug>

Show the user the spec plus a short preview: the would-be issue title ([YYYY-MM-DD]: <Title> (<presenter first name>)), the files to be created, and whether issue/PR will really be created. Then gate:

  • Dry-run → proceed without asking (nothing outward happens).
  • -y → proceed (the flag is the user's standing go-ahead), but still show the preview.
  • Otherwise → one AskUserQuestion: "Create it now (issue + PR)" / "Dry run first (Recommended for a first pass)" / "Cancel". Creating a GitHub issue and PR is outward-facing — never do it silently.

[Step 4/5] Delegate to the event-creator agent

Spawn the event-creator subagent (Task/Agent tool, subagent_type: event-creator), passing the spec verbatim as its task plus one line: "Execute this event spec per your protocol." Wait for the result — the next step depends on it.

If that agent type isn't registered in this session, don't stall: read .claude/agents/event-creator.md and execute its protocol yourself, inline, honoring the same hard rules (dry-run = zero GitHub writes; never push master; never invent form IDs).

[Step 5/5] Relay the report and next steps

Relay the agent's structured report, then close the loop:

  1. Preview before shipping: the rendered PNGs (or the build's auto-card), and make serve → http://localhost:1313/events/<slug>/.
  2. Dry-run → the previews live in .context/create-event/<slug>/; rerun without --dry-run to create the issue and PR.
  3. Pending form IDs → gated page ships with TODOs; watch the tracking issue for marketing's comment, then rerun /create-event <issue-url> to wire them in (update mode).
  4. PR is a draft → mark ready after previewing; each ready-transition fires a full review, so do it once.
  5. Suggest /docs-review for a content pass when the description was substantially drafted by the wizard.

Error handling

  • Slug collision with a different event (same slug, different topic) → suffix the slug (-2026, or the month) and tell the user.
  • gh unauthenticated / marketing repo unreachable → finish everything local, write the issue preview, and hand the user the exact gh issue create command to run.
  • Date in the past → confirm it's intentional (recordings/on-demand pages are legitimate).
  • User cancels at Step 3 → keep nothing outward; offer to save the spec to .context/create-event/<slug>/spec.yaml so a later run can resume from it.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/create-event-create-a-pulumi-event-muar2zpb/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

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

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/create-event-create-a-pulumi-event-muar2zpb/SKILL.md' && test -s '.skill-downloads/create-event-create-a-pulumi-event-muar2zpb/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/create-event' && cp -R '.skill-downloads/create-event-create-a-pulumi-event-muar2zpb' '.claude/skills/create-event'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/create-event-create-a-pulumi-event-muar2zpb'

openskills read 'create-event-create-a-pulumi-event-muar2zpb'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/create-event-create-a-pulumi-event-muar2zpb/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills