experience-cms-content-generate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Creating CMS Content

创建CMS内容

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).
用于创建Salesforce CMS内容记录的通用技能——协调类型发现、工作区解析,并针对现有
ContentTypeBundle
调度
create_cms_content
内容生成始终在服务器端进行。
create_cms_content
/
update_cms_content_variant
将目标/编辑指令作为
prompt
传入;服务器根据架构生成并验证内容主体,然后返回持久化的记录。Agent无需遍历架构、组装
contentBody
、预验证或重新生成被拒绝的字段(原则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
).
在Salesforce CMS中创建托管内容记录——基于现有
ContentTypeBundle
创作的实例。
当用户需要以下操作时使用: 根据现有CMS类型,通过自由文本提示创建单条或多条内容记录;编辑/优化会话项;更新/编辑发布通过
managedContentVariantId
/
managedContentId
直接标识的记录——即使该记录不是在本次会话中创建的(步骤0 → 更新/发布入口);发布全部或部分内容;删除/移除记录——此技能负责处理删除请求并引导至终止流程(步骤0-D);绝不透露内部原因。
当用户需要以下操作时请勿使用: 定义新的内容类型/架构(请使用
experience-cms-content-type-generate
);取消发布、克隆或版本化记录;管理工作区/文件夹/渠道;附加图片/媒体;应用品牌标识。
“创建图片/媒体内容”不属于预检查排除范围(仅字面意义上的二进制文件附加/上传属于上述排除的“附加媒体”操作)。创建图片/视频内容记录(例如通过URL)属于正常流程——解析类型+工作区,调度
create_cms_content
,绝不预先拒绝或建议REST/UI替代方案。
sfdc_cms__media
由服务器决定:让工具返回错误,然后根据原则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.
请按顺序执行步骤——请勿跳过或重新排序。
每次成功运行必须以调度
create_cms_content
(≥1次)结束,每次调用通过
prompt
传递目标。
尽量减少交互——调度前唯一需要询问的是步骤3(工作区)。绝不询问目标细化、模式或内容主体细节。步骤1为静默步骤。 提示中包含FQN → 步骤2快速路径;否则步骤2a直接委托,无需调用
ask_user_tool
批量操作例外: 步骤4需展示主题提示供用户确认。
严格遵循提问约定——所有
ask_user_tool
调用均需遵守。
完整规则请参考
references/ux-rules.md
。所有问题均通过
ask_user_tool
提出(绝不使用纯文本);在进行任何调用之前,打开
assets/questions.md
逐字复制
question
字符串和
answers
数组,仅填充
<占位符>
——绝不改写/缩短
question
,绝不添加/删除/重新排序
answers
,绝不将列表内容放入答案中。没有合适的模板?请停止操作并重新阅读
assets/questions.md
——绝不自行编写问题。

Workflow Overview

工作流概述

text
- [ ] Step 1: Understand intent (silent — domain, count, FQN if present)
- [ ] Step 2: Resolve content type — fast-path (Buckets 1/2/3) or delegate → contentTypeFqn
- [ ] Step 3: Resolve workspace — UIBundle options or manual ID
- [ ] Step 4: Build payload — single or bulk (topic approval if bulk)
- [ ] Step 5: Dispatch create_cms_content (parallel for bulk)
- [ ] Step 6: Display content body + summary
- [ ] Step 7: Post-action loop — Edit / Publish / End
- [ ] Step 8: Edit — update_cms_content_variant
- [ ] Step 9: Publish — publish_content
- [ ] Step 10: Post-publish — Create more / Render (if UIBundle) / End
text
- [ ] 步骤1:理解意图(静默——领域、数量、是否包含FQN)
- [ ] 步骤2:解析内容类型——快速路径(分类1/2/3)或委托 → contentTypeFqn
- [ ] 步骤3:解析工作区——UIBundle选项或手动输入ID
- [ ] 步骤4:构建请求体——单条或批量(批量操作需确认主题)
- [ ] 步骤5:调度create_cms_content(批量操作并行调度)
- [ ] 步骤6:展示内容主体和摘要
- [ ] 步骤7:操作后循环——编辑/发布/结束
- [ ] 步骤8:编辑——update_cms_content_variant
- [ ] 步骤9:发布——publish_content
- [ ] 步骤10:发布后操作——创建更多内容/渲染(若使用UIBundle)/结束

Step 0: Route the Intent (run FIRST, always)

步骤0:路由意图(始终首先执行)

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 recordUPDATE entry — Step 0-U
publish an existing recordPUBLISH entry — Step 0-P
delete, remove, destroy a recordDELETE — 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.
在步骤1之前,将意图分类为恰好一种并进行路由。 更新/发布/删除是一级入口点——不仅仅是创建流程的后续步骤。以这些动词开头的请求 → 请勿自行操作(凭直觉选择工具、运行SOQL、猜测variant ID)。读取开头动词并路由:
用户意图(开头动词)路由至
create、generate、write、draft、author、post、add、compose;“create N
<内容类型>
创建 → 继续执行步骤1
update、edit、change、modify、revise现有记录更新入口 → 步骤0-U
publish现有记录发布入口 → 步骤0-P
delete、remove、destroy记录删除 → 步骤0-D(终止流程)
模糊不清(无法区分创建/更新/发布)
ask_user_tool
消除歧义(创建新内容/更新现有内容/发布现有内容/取消),根据答案路由
无偏离终止规则(所有路由)。 如果当前桥接器上无法使用路由所需的
content-write
工具(
create_cms_content
/
update_cms_content_variant
/
publish_content
),请停止操作,打印面向用户的可操作消息,结束会话。绝不使用SOQL、
sf data
、CLI、同类工具或
contentBody
通道替代——工具不可用和不支持的操作属于终止性错误,绝无 fallback 方案。确切消息 + 按路由划分的占位符 + 允许/禁止表述 →
references/intent-routing.md
§ 无偏离终止规则。

Step 0-U (UPDATE) and Step 0-P (PUBLISH) — direct-entry paths

步骤0-U(更新)和步骤0-P(发布)——直接入口路径

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.
完整流程细节请参考
references/intent-routing.md
对应会话内步骤8(编辑)/步骤9(发布)的直接入口——直接标识的记录可能来自之前的会话或其他用户(编辑/发布不限于当前会话)。核心约束:
  • 严格标识符检查 — 在任何工具调用之前。 目标
    managedContentVariantId
    只能来自(a)会话注册表或(b)用户输入的标识符(
    MC…
    /
    20Y…
    /
    9Ps
    )。仅提供名称、无ID且不在注册表中 → 停止操作并通过
    ask_user_tool
    询问
    (“我应该处理哪条记录?”问题,需完全复制,答案为
    ["Cancel"]
    )。您不得自行查找记录——禁止使用
    search_content
    、发现/列表工具、SOQL或猜测ID。
  • 通过前缀解析并在操作前验证
    references/identifier-resolution.md
    9Ps
    get_content_variant
    MC…
    /
    20Y…
    get_content
    )。读取失败 → 停止操作;绝不盲目编辑/发布。
  • 0-U → 步骤8c(必须先展示完整内容主体 + 编辑指令提示),通过步骤7对话框结束。0-P → 步骤9b,发布确认后结束会话(无步骤10——无会话上下文)。两者均不执行步骤1–5。

Step 0-D: DELETE (hard stop)

步骤0-D:删除(终止流程)

Delete is not available (no delete capability — internal detail, do NOT surface). Print exactly and only this message, nothing else:
text
Deleting content isn't supported here. To delete this content, open it in Salesforce CMS and use the Delete option there.
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.
删除操作不可用(无删除功能——内部细节,请勿透露)。仅打印以下消息,无其他内容:
text
此处不支持删除内容。要删除此内容,请在Salesforce CMS中打开它并使用删除选项。
前后不得添加任何内容——无开场白、解释、规则重述、工具/服务器名称或元叙述;用户只能看到这条纯文本消息。结束会话。绝不提供
unpublish_content
、SOQL或CLI作为替代方案——CMS UI是唯一可行的途径。

Step 1: Understand Intent

步骤1:理解意图

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.
静默步骤——此处绝不询问任何问题。 内部提取信息后直接进入步骤2。不得出现“让我确认一下…”的会话轮次,不得调用
ask_user_tool
,不得提供内容类型菜单——即使是模糊的提示(“为Q4发布会生成新内容”)也包含步骤2所需的全部信息。如果打算在步骤1中提出问题(确认、内容类型菜单、“是否有指定类型?”、“需要多少条?”),这属于错误操作——请直接进入步骤2。解析消息以获取:
  • 内容领域(文章、博客、新闻、常见问题等)——按推断原样保留;未指定领域也可。
  • 数量——明确提及的数量 → 使用该数字;“multiple”/“several”/“a few”/“some” → Agent选择4–5条;无数量指示 → 单条。
  • 内容类型引用——逐字捕获任何看起来像内容类型名称的标记(精确FQN、单下划线近似值、纯开发者名称、自然语言名称)。请勿在此处分类——步骤2会分配分类。
不得剥离或改写消息——原始消息是步骤4主题提示的创作方向,也是步骤2a传递给同类工具的
intent
原文。
多类型检查门——步骤1唯一允许提出的问题。 如果提示涉及**≥2种不同的内容类型**(每种对应自己的
ContentTypeBundle
,例如
grooming packages
service area coverage
),必须在步骤2之前询问用户选择其中一种(每次运行仅处理一种类型;两种类型会破坏委托约定)。通过
ask_user_tool
发送步骤1多类型提示(答案为用户提及的不同领域 +
Cancel
),仅将选中的领域作为
intent
继续处理。这是“绝不询问”规则的唯一例外——仅在涉及≥2种不同类型时触发,绝不针对目标/模式/数量触发。同一类型的多个主题(“5篇博客文章”)不会触发此检查门(属于批量操作)。规则和示例请参考
references/content-type-classification.md
§ 多类型检查门。

Step 2: Resolve the Content Type

步骤2:解析内容类型

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.
将步骤1捕获的内容类型引用分类为四类之一——完整检测规则、示例、路由请参考
references/content-type-classification.md
。摘要:
  • 分类1 — 精确FQN。 匹配正则表达式
    ^[a-zA-Z_][a-zA-Z0-9_]*__[A-Za-z][A-Za-z0-9_]*$
    (例如
    c__BlogPost
    )。捕获
    contentTypeFqn
    ,进入步骤3。静默处理。
  • 分类2 — 可自动修正的近似值。 已知命名空间和名称之间为单下划线(例如
    c_news
    c__news
    )。自动修正,在聊天中告知用户(无需调用
    ask_user_tool
    ),进入步骤3。
  • 分类3 — 低置信度类FQN。 纯名称(例如
    BlogPost
    →推荐
    c__BlogPost
    )或未知命名空间的单下划线形式。发送步骤2的FQN修正提示,根据答案路由。
  • 无效FQN检查门。 标记为FQN(包含
    __
    )但格式错误,且不属于分类2的近似值(例如
    c__
    __Foo
    c__Blog Post
    c__123
    ) → 请勿作为自由文本委托;发送FQN修正提示(“让我提供一个不同的FQN”/“取消”),使用新字符串重新执行步骤2。
  • 分类4 — 自然语言或无标记(例如
    blog post
    )。委托处理 → 步骤2a。
快速路径约束(分类1/2/3): 捕获FQN后,请勿在组织中验证、委托、扫描
contentTypes/
、调度
metadata-grounding
、检索或读取
schema.json
。错误的FQN会在步骤5中确定性地触发
INVALID_TYPE
错误。在委托路径中,同类工具负责扫描、关联、选择问题、创建新类型+部署、构建FQN、检索和协调。

2a–2d. Delegate to the sibling (Bucket 4 only)

2a–2d. 委托给同类工具(仅分类4)

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.
完整协议请参考
references/delegation-protocol.md
简而言之:2a 首先解析工作区(步骤3 →
contentSpaceOrFolderId
),打印提示
正在为您的请求解析内容类型…
,通过
mcp__skill_bridge__load_skill("experience-cms-content-type-generate")
调用(请勿使用内置
Skill
——会返回
Unknown skill
),传入
{ intent: "<用户消息原文>", suppressCreateContentPrompt: true, <scope> }
<scope>
=
spaceId
0Zu
folderId
9Pu
,二选一,绝不能是
baseType
);委托前无需询问。2b —— 在同类工具运行期间,此技能处于暂停状态(在获得最终结果之前不得调用步骤4及以后的操作;交错调用会破坏其状态机)。接收
{ status, fqn, message }
(忽略任何
schema
),严格根据
status
路由:
status
此技能的操作
success
(存在
fqn
逐字打印同类工具返回的
message
(包含类型+部署信息);若为空,则打印
正在使用内容类型\
<fqn>`。`然后进入步骤2c。
not_deployed
(存在
fqn
停止操作。 逐字打印
message
。不得继续执行步骤3——
create_cms_content
针对本地仅有的bundle会触发
INVALID_TYPE
错误。
cancelled
静默停止。 打印
会话已结束。
并退出。不得重新调用同类工具。
error
停止操作。 逐字打印
message
(包含原因+恢复提示)。不得重试或寻找替代方案。
load failed
(桥接器返回
Unknown skill
/错误——同类工具从未运行)
停止操作,参考
references/delegation-protocol.md
§ 2b(终止性错误,无 fallback 方案——不得本地扫描、关联或调用工作区)。先通过
search_skills
load_skill
重试一次。
2c(仅
success
状态)——验证
fqn
是否匹配FQN正则表达式;缺失/格式错误 → 展示重新运行消息 +
ask_user_tool
(“使用明确的FQN重试”/“取消”);然后捕获
contentTypeFqn
,进入步骤3。2d —— 绝不调用
metadata-grounding
sf project retrieve
、重新展示/选择或从文件夹名称构建FQN(这些均由同类工具负责);出现五种偏离信号 → 终止流程并执行
load failed
对应的操作;绝不将
not_deployed
降级为
success
。对于手动指定的空间,2a调用是第二层确认——无效/不存在 → 终止流程,通过无效ID模板重新询问。

Step 3: Resolve the Workspace — Question 1

步骤3:解析工作区——问题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 + validation →
references/workspace-resolution.md
.
In short:
  • Discovery (silent): scan
    uiBundles/
    under each
    sfdx-project.json
    package path (fallback: recursive), read each
    <name>.uibundle-meta.xml
    <masterLabel>
    { developerName, masterLabel }
    . Zero → "no local UIBundles" variant. Never invent a workspace, run SOQL, or read
    ui-bundle.json
    .
  • Ask (single question): dispatch the "Step 3 — Workspace resolution" template from
    assets/questions.md
    via
    ask_user_tool
    (never plain text); copy
    question
    +
    answers
    VERBATIM, reword/rename/drop nothing. No-UIBundle variant is fixed copy —
    question
    :
    "Which content space or folder should I create the content in? Provide the ID (Content Space IDs start with 
    0Zu
    ; Folder IDs start with 
    9Pu
    )."
    ,
    answers
    :
    ["Cancel"]
    .
    UIBundle-found, manual-ID, and invalid-ID variants →
    assets/questions.md
    .
  • UIBundle pick
    get_or_create_cms_workspace_and_web_app_channel
    (developerName, masterLabel); returned
    spaceId
    =
    contentSpaceOrFolderId
    ; record
    workspaceMethod=uibundle
    +
    channelId
    ; persist
    channelId
    to
    uiBundles/<developerName>/public/content-metadata.json
    (merge). Tool failure → retry prompt.
  • Manual ID → record
    workspaceMethod=manual
    (no
    channelId
    → Step 10 render hidden); manual-ID prompt with "Go back". Validate (prefix+length necessary NOT sufficient): L1
    0Zu
    spaceId
    /
    9Pu
    folderId
    , 15/18 alphanumeric. L2 on FIRST call touching the space (delegation:
    get_content_types_for_workspace
    ; fast-path:
    create_cms_content
    ) — invalid/not-found → STOP, surface verbatim, re-ask via invalid-ID template. No org picker.
步骤3的执行时机取决于步骤2如何解析类型: 快速路径(分类1/2/3)→ 在步骤2之后执行。委托路径(分类4)→ 提前执行,在步骤2a中调度同类工具之前首先执行,以便
contentSpaceOrFolderId
限定同类工具的发现范围;同类工具返回后不得重新执行或询问。两种情况的解析步骤相同。
静默扫描本地项目中的UIBundle目录,然后通过
ask_user_tool
提出一个包含所有选项的问题。完整发现+路由+验证请参考
references/workspace-resolution.md
简而言之:
  • 发现(静默): 扫描
    sfdx-project.json
    包路径下的
    uiBundles/
    ( fallback:递归扫描),读取每个
    <name>.uibundle-meta.xml
    中的
    <masterLabel>
    { developerName, masterLabel }
    。无结果 → “无本地UIBundles”变体。绝不凭空创建工作区、运行SOQL或读取
    ui-bundle.json
  • 询问(单个问题): 通过
    ask_user_tool
    发送
    assets/questions.md
    中的“步骤3 — 工作区解析”模板(绝不使用纯文本);逐字复制
    question
    +
    answers
    ,不得改写/重命名/删除任何内容。无UIBundle变体为固定内容——
    question
    "我应该在哪个内容空间或文件夹中创建内容?请提供ID(内容空间ID以
    0Zu
    开头;文件夹ID以
    9Pu
    开头)。"
    answers
    ["Cancel"]
    找到UIBundle、手动输入ID和无效ID的变体请参考
    assets/questions.md
  • 选择UIBundle → 调用
    get_or_create_cms_workspace_and_web_app_channel
    (developerName, masterLabel);返回的
    spaceId
    =
    contentSpaceOrFolderId
    ;记录
    workspaceMethod=uibundle
    +
    channelId
    ;将
    channelId
    持久化到
    uiBundles/<developerName>/public/content-metadata.json
    (合并)。工具调用失败 → 重新提示。
  • 手动输入ID → 记录
    workspaceMethod=manual
    (无
    channelId
    → 步骤10的渲染操作隐藏);手动输入ID提示包含“返回”选项。验证(前缀+长度为必要非充分条件): L1
    0Zu
    spaceId
    /
    9Pu
    folderId
    ,长度为15/18位字母数字。L2在首次访问空间的调用中验证(委托路径:
    get_content_types_for_workspace
    ;快速路径:
    create_cms_content
    )——无效/不存在 → 停止操作,逐字展示错误,通过无效ID模板重新询问。无组织选择器。

Step 4: Build the Create-Content Payload

步骤4:创建内容请求体

HARD ENTRY GATE —
contentTypeFqn
MUST come from Step 2
(Bucket 1/2/3 fast-path capture OR
status: success
sibling outcome). Not run Step 2 (and delegated on Bucket 4)? STOP, back to Step 2. Never invent, guess, or default a type — picking
sfdc_cms__news
or any base/standard type without Step 2 is a regression.
No FQN → Bucket 4 → delegate FIRST. Front-loading the create tool via ToolSearch before Step 2 is the same bug.
Goal passes as
prompt
; server generates + validates the body. Agent only shapes the payload and generates a title. Inputs:
contentType
= Step 2
contentTypeFqn
;
contentSpaceOrFolderId
= Step 3;
prompt
=
[USER GOAL]
(message verbatim for single, or Step 4.B.2-approved topic prompt for bulk). Title stays agent-side — concise, on-topic, customer-facing, reflecting
[USER GOAL]
.
  • Single (quantity = 1):
    assets/payloads/create-content-single.json
    . Required:
    contentType
    ,
    contentSpaceOrFolderId
    ,
    title
    ,
    prompt
    (verbatim). Optional (
    urlName
    ,
    contentKey
    ,
    externalId
    ,
    apiName
    ) only when the user named them. Never include
    contentBody
    — mutually exclusive with
    prompt
    .
  • Bulk (quantity > 1): generate N distinct topic prompts, present for approval (two-part: markdown list +
    ask_user_tool
    ), then build N independent 1-element payloads (shared
    contentType
    /
    contentSpaceOrFolderId
    ; per-item
    title
    +
    prompt
    ). Never combine into one
    inputs
    array — one call per item.
    Flow →
    references/bulk-batching.md
    .
Full schema →
references/content-write-tool.md
; payload walkthrough →
examples/create-content-call.md
.
严格入口检查 —
contentTypeFqn
必须来自步骤2
(分类1/2/3快速路径捕获或
status: success
的同类工具结果)。未执行步骤2(且分类4未委托)?停止操作,返回步骤2。绝不能凭空创建、猜测或默认类型——未经过步骤2就选择
sfdc_cms__news
或任何基础/标准类型属于回归错误
。无FQN → 分类4 → 首先委托。在步骤2之前通过ToolSearch提前调用创建工具属于同一类错误。
目标作为
prompt
传递;服务器生成并验证内容主体。Agent仅负责构造请求体并生成标题。输入参数:
contentType
= 步骤2的
contentTypeFqn
contentSpaceOrFolderId
= 步骤3的结果;
prompt
=
[用户目标]
(单条操作为消息原文,批量操作为步骤4.B.2确认的主题提示)。标题保留在Agent端——简洁、贴合主题、面向客户,反映
[用户目标]
  • 单条操作(数量=1): 使用
    assets/payloads/create-content-single.json
    。必填参数:
    contentType
    contentSpaceOrFolderId
    title
    prompt
    (原文)。可选参数(
    urlName
    contentKey
    externalId
    apiName
    )仅在用户指定时包含。绝不能包含
    contentBody
    ——与
    prompt
    互斥。
  • 批量操作(数量>1): 生成N个不同的主题提示,展示供用户确认(分为两部分:markdown列表 +
    ask_user_tool
    ),然后构建N个独立的单条请求体(共享
    contentType
    /
    contentSpaceOrFolderId
    ;每个条目包含独立的
    title
    +
    prompt
    )。绝不能合并为一个
    inputs
    数组——每个条目单独调用一次。
    流程请参考
    references/bulk-batching.md
完整架构请参考
references/content-write-tool.md
;请求体示例请参考
examples/create-content-call.md

Step 5: Execute the Create Call

步骤5:执行创建调用

Dispatch
create_cms_content
with the Step 4 payload; the server generates + validates and returns the record. Complex types can be slower.
使用步骤4的请求体调度
create_cms_content
;服务器生成并验证内容,然后返回记录。复杂类型可能耗时更长。

Bulk Content

批量内容

5a. Pre-dispatch confirmation (blanket approval) — one confirmation for all items (prevents per-call prompts). Print chat
Ready to create all **<N>** content items in your org. Proceed?
, dispatch the Step 5a approval prompt.
Yes, create all
→ 5b;
Cancel
→ end session.
5b. Dispatch N parallel single-item calls per
references/bulk-batching.md
: exactly N
create_cms_content
calls, each a 1-element
inputs
array, all fanned out in one turn. Partial failure → register successes, surface failures (topic + error), dispatch retry prompt (retry re-dispatches failed items as fresh parallel calls). Total failure → apply "Bulk total-failure retry guards" in
references/error-recovery.md
first (bulk total-failure branch only).
5a. 调度前确认(全局确认)——对所有条目进行一次确认(避免逐条提示)。在聊天中打印
准备在您的组织中创建全部**<N>**条内容项。是否继续?
,发送步骤5a的确认提示。
是,创建全部
→ 5b;
取消
→ 结束会话。
5b. 并行调度N次单条调用,参考
references/bulk-batching.md
:恰好调用N次
create_cms_content
,每次调用的
inputs
数组包含一个条目,所有调用在一个会话轮次中并行发出。部分失败 → 记录成功条目,展示失败条目(主题+错误),发送重试提示(重试时重新调度失败条目为新的并行调用)。全部失败 → 首先应用
references/error-recovery.md
中的“批量全部失败重试防护”(仅适用于批量全部失败分支)。

Step 6: Display Content Body and Summary

步骤6:展示内容主体和摘要

On success, print the summary + content-body tables from
assets/display-formats.md
(real markdown, every field; same for create/edit). NEVER collapse to one-line
title · status · id
— summary table MUST carry Content Key + Managed Content ID (omit only fields the response lacks). On failure, use
references/error-recovery.md
; surface the error verbatim, ask via
ask_user_tool
:
Retry / Refine goal and retry / Cancel
EXCEPT type-class-unsupported (
sfdc_cms__media
/ image / video), a hard stop (Principle 15): print ONLY this fixed copy verbatim (no preamble/rewording), then end turn:
Content generation isn't supported for content type \
<fqn>` (type class: `<class>`). This skill can't author that type class. To create or edit this content, use the Salesforce CMS UI directly.` Server owns validation.
成功时,打印
assets/display-formats.md
中的摘要+内容主体表格(真实markdown,包含所有字段;创建/编辑操作均使用相同格式)。绝不能简化为单行
标题 · 状态 · ID
——摘要表格必须包含Content Key + Managed Content ID(仅省略响应中不存在的字段)。失败时,参考
references/error-recovery.md
;逐字展示错误,通过
ask_user_tool
询问:
重试 / 细化目标并重试 / 取消
——除类型类不支持
sfdc_cms__media
/ 图片 / 视频)外,此类错误为终止性错误(原则15):仅打印以下固定内容(无开场白/改写),然后结束会话:
内容类型\
<fqn>`(类型类:`<class>`)不支持内容生成。此技能无法创作该类型类的内容。要创建或编辑此内容,请直接使用Salesforce CMS UI。`验证由服务器负责。

Step 7: Post-Action Loop

步骤7:操作后循环

After displaying the content body (create or edit), dispatch the Step 7 prompt from
assets/questions.md
(single or bulk variant by quantity). Route:
  • Edit content
    → Step 8
  • Publish content
    /
    Publish all
    → Step 9 with all variant IDs
  • Publish subset
    → ask which items by number via the publish-subset template in
    assets/questions.md
    , then Step 9 with selected variant IDs
  • End session
    → print one line:
    Session ended. Content saved as draft.
    and exit.
展示内容主体(创建或编辑)后,发送
assets/questions.md
中的步骤7提示(根据数量选择单条或批量变体)。路由:
  • 编辑内容
    → 步骤8
  • 发布内容
    /
    发布全部
    → 步骤9,传入所有variant ID
  • 发布部分内容
    → 通过
    assets/questions.md
    中的发布部分内容模板询问要发布的条目编号,然后步骤9传入选中的variant ID
  • 结束会话
    → 打印一行:
    会话已结束。内容已保存为草稿。
    并退出。

Steps 8, 9, 10: Edit / Publish / Post-Publish

步骤8、9、10:编辑/发布/发布后操作

Full procedural detail →
references/edit-publish-workflow.md
.
All three MCP-only — no SOQL, no CLI (read via
content-readonly
, write via
content-write
). Load-bearing summary:
  • Step 8 — Edit (
    update_cms_content_variant
    ). 8a scope (single, or Step 8a prompt for bulk) → 8b edit-instructions prompt (verbatim, applies to all selected) → 8c payload (
    variantId
    from item's latest response OR the Step 0-U ID;
    prompt
    verbatim; re-emit
    title
    ONLY on rename) → 8d dispatch (bulk = N parallel) → 8e back to Step 6, display full updated body, every field (NOT a diff table; re-fetch via
    get_content_variant
    if the response lacks it), then Step 7. Failures →
    Retry / Refine edit instruction and retry / Cancel
    ; bulk total-failure → error-recovery guards.
  • Step 9 — Publish (
    publish_content
    via
    variantIds
    ). 9a scope (all / subset / default all) → 9b dispatch (in-session IDs, or the Step 0-P validated ID — direct-entry ends the turn after confirmation, no Step 10) → 9c on success flip each published item's registry
    publishStatus
    draft→
    published
    (hard — Step 10 filters on it), print the
    assets/display-formats.md
    publish confirmation VERBATIM (
    Content published successfully.
    + Title/Managed Content ID/Variant ID) — NOT reworded
    Content is live
    /deployment-id prose
    , then Step 10. Partial/total-failure → error-recovery guards + retry prompt.
  • Step 10 — Post-Publish. Dispatch the Step 10 prompt; options depend on
    workspaceMethod
    (
    uibundle
    includes render,
    manual
    hides it). In-session publish ALWAYS dispatches this for BOTH methods — skipping to
    Session ended.
    is a regression.
    Create more content
    → restart FULL flow at Step 1 (silent — no "what next?" ask, wait for user's next message) → Step 2 → Step 3; do NOT reuse this run's workspace.
    Render…
    → hand off to
    experience-cms-content-render
    with
    channelId
    ,
    contentKeys
    (ONLY
    publishStatus=published
    ),
    contentTypeFqn
    ,
    uiBundleDeveloperName
    ,
    uiBundleMasterLabel
    ; zero published → print the "no published items" line + re-dispatch.
    End session
    Session ended.
完整流程细节请参考
references/edit-publish-workflow.md
这三个步骤仅使用MCP——禁止使用SOQL、CLI(通过
content-readonly
读取,通过
content-write
写入)。核心摘要:
  • 步骤8 — 编辑
    update_cms_content_variant
    )。8a确定范围(单条,或步骤8a提示选择批量条目) → 8b编辑指令提示(原文,适用于所有选中条目) → 8c请求体(
    variantId
    来自条目的最新响应或步骤0-U的ID;
    prompt
    为原文;仅在重命名时重新传入
    title
    ) → 8d调度(批量操作为N次并行调用) → 8e返回步骤6,展示完整的更新后内容主体,包含所有字段(绝不使用差异表格;若响应中缺少字段,通过
    get_content_variant
    重新获取),然后进入步骤7。失败 →
    重试 / 细化编辑指令并重试 / 取消
    ;批量全部失败 → 应用错误恢复防护。
  • 步骤9 — 发布(通过
    variantIds
    调用
    publish_content
    )。9a确定范围(全部/部分/默认全部) → 9b调度(会话内ID,或步骤0-P验证的ID——直接入口在确认后结束会话,无步骤10) → 9c成功后将每个已发布条目的注册表
    publishStatus
    从draft改为
    published
    (严格执行——步骤10会根据此字段过滤),逐字打印
    assets/display-formats.md
    中的发布确认信息**(
    内容发布成功。
    + 标题/Managed Content ID/Variant ID)——绝不能改写为
    内容已上线
    或包含部署ID的表述**,然后进入步骤10。部分/全部失败 → 应用错误恢复防护 + 重试提示。
  • 步骤10 — 发布后操作。发送步骤10提示;选项取决于
    workspaceMethod
    uibundle
    包含渲染操作,
    manual
    隐藏渲染操作)。会话内发布无论使用哪种方法都必须发送此提示——直接跳转到
    会话已结束。
    属于回归错误。
    创建更多内容
    → 从步骤1重新开始完整流程(静默——无需询问“接下来做什么?”,等待用户的下一条消息) → 步骤2 → 步骤3;不得重用本次运行的工作区。
    渲染…
    → 将控制权交给
    experience-cms-content-render
    ,传入
    channelId
    contentKeys
    (仅包含
    publishStatus=published
    的条目)、
    contentTypeFqn
    uiBundleDeveloperName
    uiBundleMasterLabel
    ;无已发布条目 → 打印“无已发布内容”并重新发送提示。
    结束会话
    会话已结束。

Error Handling

错误处理

references/error-recovery.md
— full error-signal → response mapping:
create_cms_content
/
update_cms_content_variant
/
publish_content
server-side failures, bulk partial failures, sibling terminal states, out-of-scope requests.
请参考
references/error-recovery.md
——完整的错误信号→响应映射:
create_cms_content
/
update_cms_content_variant
/
publish_content
服务器端失败、批量部分失败、同类工具终止状态、超出范围的请求。

Cross-Skill Integration

跨技能集成

  • Discover / define a ContentTypeBundle (Step 2 delegation path only, not fast-path) →
    experience-cms-content-type-generate
    (payload +
    status
    routing in Step 2a–2d).
  • Render published content to a UIBundle (Step 10) →
    experience-cms-content-render
    (handoff params +
    workspaceMethod=uibundle
    gate in Step 10).
  • 发现/定义ContentTypeBundle(仅步骤2委托路径,非快速路径)→
    experience-cms-content-type-generate
    (步骤2a–2d中的请求体+
    status
    路由)。
  • 将已发布内容渲染到UIBundle(步骤10)→
    experience-cms-content-render
    (步骤10中的移交参数+
    workspaceMethod=uibundle
    检查门)。

Key Principles

核心原则

Full text of all 15 →
references/principles.md
(canonical index; each is ALSO enforced inline in its Step body above): (1) workflow in order, (2) dispatch is the work, (3) server-side generation only, (4) user goal verbatim, (5) sibling owns type on delegation, (6) workspace from user/UIBundle — never infer/SOQL, (7) cancel terminates, (8) consistent display, (9) session registry + stable variant ID, (10) post-action loop, (11) bulk = one call per item parallel, (12) publish defaults to all, (13) route intent FIRST + identifier gate, (14) no-drift STOP, (15) type-class-unsupported hard stop. Identifiers →
references/identifier-resolution.md
.
全部15条原则的完整文本请参考
references/principles.md
(权威索引;每条原则也在上述步骤中强制执行):(1) 按顺序执行工作流,(2) 调度即为操作,(3) 仅服务器端生成,(4) 用户目标原文传递,(5) 委托时由同类工具负责类型处理,(6) 工作区来自用户/UIBundle——绝不推断/SOQL,(7) 取消即终止,(8) 展示格式一致,(9) 会话注册表+稳定variant ID,(10) 操作后循环,(11) 批量操作为并行单条调用,(12) 发布默认全部,(13) 首先路由意图+标识符检查,(14) 无偏离终止,(15) 类型类不支持即终止。标识符相关规则请参考
references/identifier-resolution.md