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 pa

By forcedotcom · 599 installs

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

Source repository · Upstream listing

experience cms content type generate What This Skill Does DISCOVER — checks local <sfdx source /contentTypes/ and queries metadata grounding for 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 run against 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 : 1. spaceId only → get content types for workspace({ spaceId }) . 2. folderId only → get content types for workspace({ folderId }) . 3. baseType only → get content types for workspace({ baseType }) . 4. None of the three → get content types for workspace({ baseType: "CONTENT" }) (default). Common invocation shapes: Direct user → intent , suppressCreateContentPrompt false . Full discovery + retrieve and reconcile + trailing prompt. No spaceId / 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 to not 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. contentSpaceOrFolderId from get or create cms workspace and web app channel ) and wants step 1c's check scoped to it. Do NOT also pass baseType on this call. If the caller resolves its workspace AFTER content type discovery (as experience cms content generate currently does), it has no spaceId to 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: success is the ONLY status that unlocks downstream work. Callers MUST NOT proceed on not deployed , cancelled , or error . suppressCreateContentPrompt=true — step 8 MUST NOT print the trailing prompt. message is always the final terminal chat line. Do NOT emit Task Completed before 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 1. Discovery uses metadata grounding (plus content readonly.get content types for workspace ) and ONLY these. Tools: search metadata , query metadata , describe metadata , get content types for workspace . Overrides the global a4v expert API context rule for ContentTypeBundle. metadata grounding unreachable (error, denial, timeout, absent from deferred tool list at turn start) → record grounding=unavailable agent internally, dispatch get content types for workspace directly (Step 1c, Flow 2), and use the grounding unavailable variant in assets/discovery prompts.md . Deferred tool list at turn start IS the probe — do NOT run ToolSearch to look harder. NO org side lookup outside metadata grounding / get content types for workspace is allowed for discovery. Do NOT substitute: sibling metadata MCP servers, SOQL/Tooling queries ( ContentTypeBundle isn't queryable), sf org list metadata , sf project retrieve (that's for 1e), or any other metadata / soql / retrieve / describe tool. Substitutes return wrong shape data. Hard rule break. 2. Step order is fixed: 1a 1d (silent discovery + pick) → 1e (retrieve and reconcile, when user picked existing / provided FQN / caller supplied fqn) → 2 (resolve org) → 3 (propose, only on Create new or zero match auto proceed) → 4 (create) → 5 (dry run) → 6 (auto fix) → 7 (deploy ask) → 7.5 (schema summary) → 8 (trailing prompt) . Step 1e returns {fqn, schema} and skips to 7.5; 2–7 do NOT run on that path. 7.5 runs whenever {fqn, schema} was resolved. Step 8 is gated by suppressCreateContentPrompt . Under direct invocation with zero matches, 1d auto proceeds to 2 → 3. 3. Steps 5 and 7 are mandatory on every "Create new" path. Pre step 5 exits: (a) Use existing / Provide an FQN / caller supplied fqn → route through 1e which returns {fqn, schema} with no files written; (b) Cancel at any pick. Do NOT emit Task Completed between steps 4 and 7's resolution. 1e's drift "Deploy local to org" branch also routes through 5 and 7. 4. Task Completed is the LAST action — skill is over once emitted. Deploy JSON's deployUrl is for reference, not an action prompt. Forbidden after: open <deployUrl , xdg open , sf org open , sf project deploy report , browser tabs, URL echo, "next step" prose. 5. Step 1e retrieve is destructive for schema.json ; drift MUST prompt the user. sf project retrieve start metadata ContentTypeBundle:<Name overwrites local schema.json . Snapshot it into localSchemaBefore BEFORE every 1e retrieve (never meta.xml). Drift = parsed JSON compare of localSchemaBefore vs. post retrieve schema.json , left side ALWAYS localSchemaBefore — never diff the post retrieve file against itself. On drift, the drift prompt is MANDATORY (chat diff, then ask user tool : Deploy local to org / Overwrite local with org / Cancel ) — never reconcile silently. Cancel and Deploy local to org MUST restore schema.json from localSchemaBefore before emitting the outcome. Full snapshot/restore procedure + drift prompt template → references/retrieve and reconcile.md . 6. Step 1d — show top 5 in a table, then ask. Row count = min(combined.length, 5) , always — combined is local matches + every grounding row, deduped (Location local, org ), never dropped as "irrelevant." Row 1 sort: OOTB first ( sfdc cms or grounding isOOTB ), custom ( c ) follows in grounding rank. Row 1's FQN names the Use existing: option. 1+ rows → table ( FQN Description Location ) then ask user tool : Use existing: <row 1 FQN / Provide an FQN / Create new: <newName / Cancel ( <newName avoids colliding with any FQN in combined ). Empty combined → NO TABLE, just ask user tool : Create new: <contentTypeName / Cancel (+ Provide an FQN when delegated/ fqn supplied). Never mix "no matches" wording with a table; no preamble; no / Name / Label columns; never claim a type is "not in the org" — only 1e's retrieve is authoritative. Full prompt templates → assets/discovery prompts.md . Full agent checklist and tripwire list → references/agent checklist.md . File paths (strict) Bundle directory: <sfdx source /contentTypes/<ContentTypeName / — NOT contentTypeBundles/<ContentTypeName / . Two files only: schema.json and <ContentTypeName .contentTypeBundle meta.xml . Output discipline The user reads the chat. Most of this skill's machinery is for