Create a Pulumi Event

VerifiedSafe

End-to-end creation of a Pulumi event (workshop, webinar, partner): gathers details, scaffolds the content bundle, generates social cards, opens the docs PR and syncs Linear.

Sby Skills Guide Bot
ContentIntermediate
2010/18/2026
Claude Code
#event-pages#linear-integration#content-scaffolding#pull-requests#social-cards

Recommended for

Our review

Creates a Pulumi event (workshop, webinar, or partner event) end to end: it collects the details, scaffolds the content/events/<slug>/ page bundle, generates social cards, opens the docs pull request, and keeps the Linear tracking issue up to date.

Strengths

  • Prefills details from the prompt, a Linear issue URL or MA-<n> identifier, a brief file, or a legacy marketing GitHub issue, then confirms everything through a batched question wizard.
  • Idempotent by design: checks for prior art on the page and follows find-before-create for the Linear tracking issue and its promotion sub-issues.
  • --dry-run prepares everything and writes PR/Linear previews with zero GitHub, Linear, or Luma writes.
  • Delegates the mechanical work to a companion subagent so the main conversation stays focused on decisions.

Limitations

  • Tightly coupled to Pulumi conventions: the content/events/ layout, the MA-1045 issue blueprint, and the event-meta-image skill for social cards.
  • The subagent cannot ask questions, so any detail not settled in the gather-and-confirm steps is silently defaulted — especially under -y in non-interactive runs.
  • Relies on Linear MCP tools and the gh CLI; fallbacks exist but degrade tracking-issue updates and PR creation.
When to use it

Use it when you need to publish a new workshop, webinar, or partner event page and keep its Linear tracking issue in sync.

When not to use it

Avoid it for editing an already published event page, for non-event marketing content, or when Linear and GitHub access are not configured.

Security analysis

Safe
Quality score88/100

The skill orchestrates creation of event pages, GitHub pull requests, Linear issues, and optional Luma events. It uses read/write APIs for legitimate marketing operations but does not instruct destructive commands, exfiltration, obfuscation, or disabling safety controls. The actions are transparent and scoped to the user's own repositories and services.

No concerns found

Examples

Create from a Linear issue
/create-event MA-1045
New webinar with full details
/create-event Create a webinar page: "Pulumi ESC in Practice", April 16 at 10am PT, 45 minutes, presented by Alice Nguyen, theme platform, abstract about managing secrets and config at scale.
Dry-run from a brief file
/create-event briefs/partner-event-q3.md --dry-run

name: create-event description: "Creates a Pulumi event (workshop, webinar, or partner event) end to end: collects details from the prompt, the Linear tracking issue, or an interactive wizard, scaffolds the content/events/<slug>/ page bundle, generates social cards via event-meta-image, opens the docs PR, and keeps the Linear tracking issue (Marketing team) and its promotion sub-issues up to date — creating the issue from the blueprint only when none exists. 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 tracking issue — even if they only say 'new workshop' or 'schedule a webinar'. Accepts pasted details, a Linear issue URL or MA-<n> identifier to prefill from, a brief file, --dry-run, and -y for no questions." model: claude-opus-5 argument-hint: "[details | Linear issue URL or MA-<n> | brief file] [--dry-run] [-y] [--no-issue] [--no-pr] [--luma]" 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, PR, Linear updates (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, the tracking 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/linear-issue.md — where the tracking issue lives, find-before-create, title and description blueprint (MA-1045), promotion sub-issues, where form IDs come back, lifecycle updates, optional Luma event, and fallbacks when the Linear tools aren't available.

[Step 1/5] Parse input and detect context

Parse $ARGUMENTS / the user's message for:

  • Flags: --dry-run (prepare everything, write PR/Linear previews, zero GitHub, Linear, or Luma 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 (linear.issue: skip); --no-pr (run.pr: skip); --luma (luma.create: true).
  • A Linear issue URL or MA-<n> identifier → the tracking issue. get_issue it, then prefill title, date/time, duration, presenters, theme, tags, abstract, learn bullets, and HubSpot segmentation from its description (the blueprint sections in references/linear-issue.md). List its sub-issues and their comments, plus the parent's comments, for form IDs. Set linear.issue: existing. Fields marked TBD on the issue are still unknown — the wizard fills them.
  • A pulumi/marketing GitHub issue URL (events tracked before Q4 2026) → read-only prefill via gh issue view <n> --repo pulumi/marketing --json title,body --comments. Never create or edit anything there; set linear.issue: skip unless a Linear issue also exists.
  • 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 in Linear or on the PR). If the page is complete and the tracking issue is current, report that the event is fully set up and stop — never duplicate.
  • If no tracking issue was given, search Linear: list_issues with team Marketing, the event quarter's Workshops (Q<n> <yy>) project, and a query of distinctive title words. Most workshops already have a parent issue synced from the Notion schedule; a match → use it as the existing issue instead of creating a duplicate.
  • Check Linear access here, in the main conversation. If the Linear tools are missing or need authentication, tell the user now (they can connect it with /mcp) — the subagent can't prompt for it. Without access, plan linear.issue: preview (see references/linear-issue.md §Tool access).

[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 have no Linear blueprint yet: build the page, set linear.issue: skip, and flag it | | Title | ≤ 60 chars (hard limit — trim with the user if over); sentence case on the page | | Meta description | 50–160 chars, single sentence; suggest one from the abstract (the issue often has it as TBD) | | 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. A Notion-synced issue's date wins over a guess | | 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 | 3 outcome bullets by convention; keep the issue's count when it already lists them | | Presenters | Prefill from the issue, else 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 | | Theme | One of AI, IaC, Platform Engineering, Security, TF-Takeover (the issue's ## Theme) | | HubSpot segmentation | Optional; derive from tags; "when in doubt, do not add" | | Form IDs | Only if already known (Linear sub-issues/comments, a PR suggestion, or the user). Never invented — pending IDs become frontmatter TODOs | | needs-design | false; true adds the needs-design label for a designer-made card | | Luma event | Only with --luma or when the user asks; private until the page is live | | 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, sentence case
  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
linear:
  issue: existing      # existing | create | preview | skip
  id: ""               # MA-<n> when existing
  url: ""
  project: ""          # e.g. "Workshops (Q4 26)" — quarter of the event date
  theme: ""            # AI | IaC | Platform Engineering | Security | TF-Takeover
  needs_design: false
  hubspot_segmentation: []
  tbd_fills: {}        # issue fields marked TBD that this run settles, e.g. {meta_description: "..."}
  form: {hubspot_form_id: "", salesforce_campaign_id: ""}
luma:
  create: false        # true only when asked
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 tracking issue (existing MA-<n> link, or the would-be title [YYYY-MM-DD] <Title> (<presenter first names>) plus the 10 promotion sub-issues), the files to be created, and which outward writes will really happen (PR, Linear, Luma). 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 (PR + Linear updates)" / "Dry run first (Recommended for a first pass)" / "Cancel". Opening a PR, creating or editing Linear issues, and creating a Luma event are outward-facing — never do them 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/Linear/Luma writes; never push master; never invent form IDs; never rewrite Notion-owned fields on the tracking issue).

[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>/ (pr-preview.md, linear-preview.md); rerun without --dry-run to apply them.
  3. Pending form IDs → the gated page ships with TODOs; they come back on the "HubSpot form and Lists" / "SF campaign …" sub-issues, the parent issue, or as a review suggestion on the PR. Rerun /create-event <MA-n> to wire them in (update mode), then comment on the tracking issue.
  4. PR is a draft → mark ready after previewing; each ready-transition fires a full review, so do it once. Then work the review to zero with /address-review, and post the outcome on the tracking issue.
  5. After merge and deploy → confirm /events/<slug>/ is live and listed on /events/, then mark the "Workshop link on /events page" sub-issue Done (lifecycle table in references/linear-issue.md).
  6. 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.
  • Linear unavailable or unauthenticated → finish everything local and in GitHub, write linear-preview.md, and tell the user Linear wasn't updated (they can connect it with /mcp and rerun).
  • Spec disagrees with a Notion-synced issue (title, date, presenter) → Notion is the source of truth; ask (interactive) or flag the mismatch (unattended) instead of editing the issue.
  • No Workshops (Q<n> <yy>) project for the event's quarter → don't create a project; ask, or file without one and flag it.
  • 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.
Related skills