experience-cms-content-generate

Creates, edits, and publishes Salesforce CMS content of any kind — any domain, any topic. Single and bulk: create many in parallel, edit one or many, publish all or a subset. Use this skill ANY TIME a user asks to create, generate, write, draft, author, or add content, OR to update, edit, or revise

By forcedotcom · 649 installs

npx skills add forcedotcom/sf-skills --skill experience-cms-content-generate

Source repository · Upstream listing

Creating CMS Content Universal skill for creating Salesforce CMS content records — orchestrates type discovery, workspace resolution, and create cms content dispatch against an existing ContentTypeBundle . Content generation is server side, always. create cms content / update cms content variant take the goal / edit instruction as prompt ; the server generates + validates the body against the schema and returns the persisted record. Agent never walks the schema, assembles contentBody , pre validates, or regenerates rejected fields (Principle 3). Scope Creates managed content records in Salesforce CMS — instances authored against an existing ContentTypeBundle . Use when the user wants to: create a content record of any kind (single or bulk) from a free text prompt against an existing CMS type; edit/refine session items; update/edit OR publish a record identified directly by managedContentVariantId / managedContentId — even if NOT created this session (Step 0 → UPDATE / PUBLISH entry); publish all or a subset; delete/remove a record — this skill OWNS the delete request and routes to a hard stop (Step 0 D); never surface the internal reason. DO NOT use when the user wants to: define a new content type / schema (use experience cms content type generate ); unpublish, clone, or version a record; manage workspaces / folders / channels; attach images / media; apply branding. "Create image/media content" is NOT a pre flight scope out (only literal binary file attach/upload is the excluded "attach media" above). Creating an image/video content record (e.g. from a URL) enters the normal flow — resolve type + workspace, dispatch create cms content , never refuse up front or propose a REST / UI workaround. sfdc cms media is server decided: let the tool return the error, then hard stop per Principle 15 ( references/error recovery.md ). Before You Start Follow steps in order — do not skip or reorder. Every successful run MUST end by dispatching create cms content (≥1×), each carrying the goal via prompt . Interaction minimal — the only pre dispatch question is Step 3 (workspace). Never ask for goal refinement, mode, or body details. Step 1 is silent. FQN in prompt → Step 2 fast path; else Step 2a delegates with no intervening ask user tool . Bulk exception: Step 4 presents topic prompts for approval. VERBATIM QUESTION CONTRACT — EVERY ask user tool , no exceptions. Full rule → references/ux rules.md . Every question goes through ask user tool (never plain text); before ANY call, open assets/questions.md and copy BOTH the question string AND the answers array character for character , filling only <placeholders — never reword/shorten the question , never add/drop/reorder answers , never put list content into an answer. No template covers it? STOP and re read assets/questions.md — never compose one ad hoc. Workflow Overview Step 0: Route the Intent (run FIRST, always) Before Step 1, classify into exactly one intent and route. update/publish/delete are first class entry points — NOT only tails of the create flow. Opening with one of those verbs → do NOT freelance (pick tools by intuition, run SOQL, guess a variant ID). Read the opening verb and route: User intent (opening verb) Route to create, generate, write, draft, author, post, add, compose; "create N <things " CREATE — continue to Step 1 update, edit, change, modify, revise an existing record UPDATE entry — Step 0 U publish an existing record PUBLISH entry — Step 0 P delete, remove, destroy a record DELETE — Step 0 D (hard stop) ambiguous (can't tell create vs update vs publish) ask user tool disambiguation (Create new / Update existing / Publish existing / Cancel), route on the answer No drift STOP rule (every route). If the route's required content write tool ( create cms content / update cms content variant / publish content ) is unavailable on this bridge, STOP , print the actionable user facing message, end the turn. Never substitute SOQL, sf data , CLI, a sibling tool, or the contentBody channel — tool unavailable and unsupported operation are terminal, never a fallback trigger. Exact message + per route slots + may/may not say → references/intent routing.md § No drift STOP rule. Step 0 U (UPDATE) and Step 0 P (PUBLISH) — direct entry paths Full procedural detail → references/intent routing.md . Direct entry counterparts to in session Step 8 (edit) / Step 9 (publish) — a record identified directly, possibly from a prior session or another user (editing/publishing is NOT session only). Load bearing invariants: Hard identifier gate — BEFORE any tool call. Target managedContentVariantId comes ONLY from (a) the session registry or (b) a user typed identifier ( MC… / 20Y… / 9Ps ). Name only, no ID, not in registry → STOP and ask via ask user tool ("Which record should I work with?" question, copied EXACTLY, answers ["Cancel"] ). You may NOT locate the record yourself — no search content , discovery/listing tool, SOQL, or guessed ID. Resolve by prefix + validate before acting → references/identifier resolution.md ( 9Ps → get content variant ; MC… / 20Y… → get content ). Read fails → STOP; never edit/publish blindly. 0 U → Step 8c (after MANDATORY full body display + edit instructions prompt), closes via Step 7 dialog. 0 P → Step 9b, closes with publish confirmation and ends the turn (no Step 10 — no session context). Neither runs Steps 1–5. Step 0 D: DELETE (hard stop) Delete is not available (no delete capability — internal detail, do NOT surface). Print exactly and only this message, nothing else: Say NOTHING before or after — no preamble, reasoning, rule restatement, tool/server names, or meta narration; the user sees only the plain message. End the turn. Do NOT offer unpublish content , SOQL, or CLI as a substitute — the CMS UI is the only path to surface. Step 1: Understand Intent Silent step — NEVER ask anything here. Extract agent internally, then go straight to Step 2. No "Let me clarify…" turn, no ask user tool , no content type menu — even a vague prompt ( generate new content for Q4 launch ) has everything Step 2 needs. About to dispatch a question in Step 1 (clarify, content type menu, "type in mind?", "how many?")? That IS the bug — move to Step 2. Parse the message for: Content domain (article, blog, news, FAQ, …) — inferred as is; no domain named is fine. Quantity — explicit count → that number; "multiple"/"several"/"a few"/"some" → agent chooses 4–5; no indicator → single. Content type reference — capture any token that looks like a content type name (exact FQN, single underscore near miss, bare developer name, natural language name) verbatim. Do NOT classify here — Step 2 assigns the bucket. Do not strip or rewrite the message — the original is the creative direction for Step 4 topic prompts and what Step 2a passes to the sibling verbatim as intent . Multi type gate — the ONE question Step 1 may raise. If the prompt spans ≥2 distinct content TYPES (each its own ContentTypeBundle , e.g. grooming packages AND service area coverage ), you MUST ask the user to pick ONE before Step 2 (one type per run; two corrupts the delegation contract). Dispatch the Step 1 multi type prompt VERBATIM (answers = distinct domains in the user's words + Cancel ), carry ONLY the chosen domain forward as intent . SOLE exception to "never ask" — fires only on ≥2 distinct types, never goal/mode/quantity. Multiple topics of ONE type ( 5 blog posts ) do NOT trigger it (bulk). Rule + examples → references/content type classification.md § Multi type gate. Step 2: Resolve the Content Type Classify Step 1's captured content type reference into one of four buckets — full detection rules, examples, routing → references/content type classification.md . Summary: Bucket 1 — Exact FQN. Matches ^[a zA Z ][a zA Z0 9 ] [A Za z][A Za z0 9 ] $ ( c BlogPost ). Capture contentTypeFqn , Step 3. Silent. Bucket 2 — Auto correctable near miss. Single underscore between known namespace and name ( c news → c news ). Auto correct, announce in chat (no ask user tool ), Step 3. Bucket 3 — Low confidence FQN ish. Bare name ( BlogPost →propose c BlogPost ) or unknown namespace single underscore. Dispatch the Step 2 FQN correction prompt, route on the answer. Invalid FQN gate. Token meant as FQN (has ) but malformed, not a Bucket 2 near miss ( c , Foo , c Blog Post , c 123 ) → do NOT delegate as free text; dispatch the FQN correction prompt ( Let me provide a different FQN / Cancel ), restart Step 2 on the new string. Bucket 4 — Natural language or no token ( blog post ). Delegate — Step 2a. Fast path invariants (Buckets 1/2/3): once the FQN is captured, do NOT verify it in the org, delegate, scan contentTypes/ , dispatch metadata grounding , retrieve, or read schema.json . A bad FQN fails deterministically as INVALID TYPE at Step 5. On the delegated path the sibling owns scan, grounding, pick question, create new + deploy, FQN construction, retrieve and reconcile. 2a–2d. Delegate to the sibling (Bucket 4 only) Full protocol → references/delegation protocol.md . In short: 2a resolve workspace FIRST (Step 3 → contentSpaceOrFolderId ), print banner Resolving the content type for your request… , invoke via mcp skill bridge load skill("experience cms content type generate") (NOT built in Skill — returns Unknown skill ), pass { intent: "<user message verbatim ", suppressCreateContentPrompt: true, <scope } ( <scope = spaceId 0Zu OR folderId 9Pu , exactly one, never baseType ); no pre delegation question. 2b — while the sibling runs this skill is PAUSED (no Step 4+ call until a terminal outcome; interleaving corrupts its state machine). Consume { status, fqn, message } (ignore any schema ), route strictly on status : status Action for this skill success ( fqn present) Print the sibling's message verbatim (carries type + deploy line); if empty, print Using content type \ <fqn \ . Then Step 2c. not deployed ( fqn present) STOP. Print message verbatim. Do NOT continue to Step 3 — create cms content fails INVALID TYPE against a local only bundle. cancelled STOP silently. Print Session ended. and exit. Do NOT loop back into the sibling. error STOP. Print message verbatim (carries reason + recovery hint). Do NOT retry or work around. load failed (bridge Unknown skill /error — sibling never ran) STOP per references/delegation protocol.md § 2b (terminal, NOT a fallback — no local scan, grounding, or workspace call). Retry once via search skills → load skill first. 2c (only on success ) — verify fqn matches the FQN regex; missing/malformed → surface re run message + ask user tool ( Retry with an explicit FQN / Cancel ); then capture contentTypeFqn , Step 3. 2d — never call metadata grounding , sf project retrieve , re present/re pick, or build FQNs from folder names (sibling owns all of that); five drift signals → hard stop to the load failed row; never downgrade not deployed to success . On a manual space the 2a call is the Layer 2 confirmation — invalid/not found → HARD STOP, re ask via the invalid ID template. Step 3: Resolve the Workspace — Question 1 When Step 3 runs depends on how Step 2 resolved the type: fast path (Buckets 1/2/3) → run it here, after Step 2. Delegation path (Bucket 4) → runs EARLY, first action of Step 2a before the sibling is dispatched, so contentSpaceOrFolderId scopes the sibling's discovery; do NOT re run or re ask after the sibling returns. Same resolution steps both cases. Silently scan the local project for UIBundle directories, then present a single ask user tool question with all options. Full discovery + routing + validati