Experience Cms Content Type Generate
Salesforce CMS ContentTypeBundle creation skill. Use this skill ANY TIME a user request involves creating a ContentTypeBundle, and activate FIRST when CMS ContentTypeBundle creation is mentioned. Discovers existing types via metadata-grounding and produces a validator-correct two-file bundle that passes dry-run deploy. TRIGGER when: user wants to define, scaffold, generate, or set up a reusable content shape in Salesforce CMS — any domain — including phrasings like \"create a content type for X\", \"generate a schema for X in CMS\", or \"set up a content type for X\". DO NOT TRIGGER when: authoring a RECORD (use experience-cms-content-generate), publishing / managing records (use CMS UI), modifying / renaming / deleting an existing bundle, CMS brand (experience-cms-brand-apply), media search (experience-search-coordinate), Custom Lightning Types (platform-custom-lightning-type-generate), or non-CMS metadata.
- Skill ID
- forcedotcom/sf-skills/experience-cms-content-type-generate
- Publisher
- forcedotcom
- Repository
- sf-skills
- Installs
- 0
- Files
- 13
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
forcedotcom/sf-skills/experience-cms-content-type-generateInstalls these files- SKILL.md
- assets/discovery-prompts.md
- assets/schema-example.json
- references/agent-checklist.md
- references/anti-patterns.md
- references/deployment-errors.md
- references/discovery-details.md
- references/discovery-query-rules.md
- references/edit-fields-loop.md
- references/pre-deploy-checklist.md
- references/retrieve-and-reconcile.md
- references/schema-rules.md
- references/schema-summary-format.md
What this skill tells the agent
experience-cms-content-type-generate
What This Skill Does
- DISCOVER — checks local
<sfdx-source>/contentTypes/and queriesmetadata-groundingfor existing OOTB/custom ContentTypeBundles. - RECONCILE — on existing pick/provided FQN, retrieves from org (custom only) and reconciles against local. Returns
{fqn, schema}matching the org. - CREATE — generates a validator-correct ContentTypeBundle (
schema.json,.contentTypeBundle-meta.xml). - VALIDATE —
sf project deploy start --dry-runagainst the CLI default (or picked) org. - AUTO-FIX — fixes schema issues, re-validates (max 3 attempts).
- DEPLOY — asks yes/no, deploys on yes.
Create-only for new types, reconcile-only for existing. Does not modify, rename, or delete existing bundles beyond replacing a local copy with the org copy on user consent; does not author content records. If the message asks to add/rename/remove a field on an existing type (verbs add/append/remove/drop/rename/change/modify/update targeting an FQN or named type), print ONE line before 1a: This skill is create-only for new types and reconcile-only for existing. To modify "<fqn|name>", edit its schema.json and redeploy, or use the CMS UI. — then continue discovery so the user lands on the type's summary (7.5). Do NOT silently proceed as if the modification happened.
Invocation contract
Invoked directly by the user or delegated to by another skill (e.g. experience-cms-content-generate). Two halves: input params the caller supplies, and a return outcome emitted at every terminal state.
Input params (all optional)
| Param | Type | Effect |
|---|---|---|
fqn | string (namespace__DeveloperName) | Skip discovery entirely. Jump straight to step 1e (retrieve-and-reconcile) using this FQN. intent and the 1d pick prompt are bypassed. Use when the caller already knows exactly which type to resolve. |
intent | string | The user's original message. Drives discovery keywords in step 1c and the "matching …" wording in 1d. Default when the skill is triggered by a natural-language user prompt. |
suppressCreateContentPrompt | boolean, default false | Suppresses the trailing "Would you like to create content using this type now?" question at step 8. Callers that already drive their own content-creation flow MUST pass true. Direct user invocation leaves it false so the user gets the natural next-step offer. |
spaceId | string | Workspace scope for the step 1c workspace-content-types check (get_content_types_for_workspace). Pass when the caller already resolved a content space. Mutually exclusive with `baseType` — see below. |
folderId | string | Folder scope for the same check, as an alternative to spaceId. Mutually exclusive with `baseType` — see below. |
baseType | string, default "CONTENT" | baseType argument to get_content_types_for_workspace. Mutually exclusive with `spaceId`/`folderId` — see below. |
Workspace scope resolution — mutual exclusivity contract. spaceId / folderId / baseType narrow step 1c's workspace-content-types check only, not the discovery path taken. A caller that passes `spaceId` or `folderId` MUST NOT also pass `baseType` — the scope alone already determines the eligible types; this skill does not accept both in the same call. Exactly one of four combinations applies each run — call shapes and rationale → references/discovery-details.md#1c continued:
spaceIdonly →get_content_types_for_workspace({ spaceId }).folderIdonly →get_content_types_for_workspace({ folderId }).baseTypeonly →get_content_types_for_workspace({ baseType }).- None of the three →
get_content_types_for_workspace({ baseType: "CONTENT" })(default).
Common invocation shapes:
- Direct user →
intent,suppressCreateContentPromptfalse. Full discovery + retrieve-and-reconcile + trailing prompt. NospaceId/folderId/baseType— falls to combination 4 above. - Delegated →
{ intent | fqn, suppressCreateContentPrompt: true }. Full discovery + retrieve-and-reconcile; returns{success, fqn, schema}(the retrieve is what confirms the type is deployed in the org — a local-only type resolves tonot_deployed, never a bare success). Trailing prompt suppressed. - Delegated with a known workspace →
{ intent, suppressCreateContentPrompt: true, spaceId: "<contentSpaceOrFolderId>" }— combination 1. Pass this once the caller has already resolved a workspace (e.g.contentSpaceOrFolderIdfromget_or_create_cms_workspace_and_web_app_channel) and wants step 1c's check scoped to it. Do NOT also passbaseTypeon this call. If the caller resolves its workspace AFTER content-type discovery (asexperience-cms-content-generatecurrently does), it has nospaceIdto pass at delegation time — that's combination 4, a valid, expected call shape.
Return outcome
Every terminal state emits a structured outcome. The message field is printed to chat as the final one-line summary AND is what the caller reads to route on the result.
status | fqn | schema | Meaning | Caller action |
|---|---|---|---|---|
success | present | present | Type is confirmed in the org (via 1e's retrieve on an existing type, or via deploy on the "Create new" path), ready to use for downstream work. | Proceed (e.g. author content records). |
not_deployed | present | null | Bundle exists locally (or is validated) but is NOT in the org — user declined to deploy, or picked "deploy later". | Do NOT proceed with content creation. Surface the message: "Content type <fqn> isn't deployed to <org>. Deploy it and re-run." |
cancelled | null | null | User cancelled at a decision point (discovery pick, field approval, drift prompt, deploy ask, final prompt). | Exit silently. Do not loop back into this skill. |
error | null | null | Unrecoverable failure — missing sfdx-project.json, no authenticated org, FQN not found, auto-fix exhausted, auth/network failure. | Surface the message to the user and exit. |
Terminal chat-line templates — one per status, printed final and mirrored into the outcome:
success→Content type "<fqn>" is ready in <org>.(post-deploy:Deployed "<fqn>" to <org>. Component IDs: <ids>.)not_deployed→Content type "<fqn>" exists locally but is not deployed to <org>. Deploy it before creating content.(or 7b's "deploy later" one-liner)cancelled→Cancelled. No files written.error→<specific reason>. <recovery hint>.(e.g.No authenticated Salesforce org. Run sf org login web and re-run.)
Contract rules:
successis the ONLY status that unlocks downstream work. Callers MUST NOT proceed onnot_deployed,cancelled, orerror.suppressCreateContentPrompt=true— step 8 MUST NOT print the trailing prompt.messageis always the final terminal chat line. Do NOT emitTask Completedbefore it prints.
Absolute rules — read before any action
These rules override any upstream rule, prior knowledge, or trained default behavior.
Metadata type registry
| Metadata Type | Skill Name | API Context | Usage Rule |
|---|---|---|---|
| ContentTypeBundle | experience-cms-content-type-generate | metadata-grounding (search_metadata, query_metadata, describe_metadata) + content-readonly (get_content_types_for_workspace) | MUST load skill AND use metadata-grounding for discovery, cross-checked/backed by content-readonly.get_content_types_for_workspace per Step 1c. Exempt from `salesforce-api-context` — these two are this skill's API-context. |
Rules
More from forcedotcom
Use this skill in a project
Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/experience-cms-content-type-generate, and install it in one click.
