关于 platform-flexipage-generate
为 Salesforce 开发者生成和编辑 Lightning 页面 FlexiPage 元数据,适用于 RecordPage、AppPage 和 HomePage。新页面从 CLI 模板开始,并通过组件发现、属性推断和部署验证来构建。
主要功能
- 01通过 CLI 模板初始化页面
- 02生成 RecordPage、AppPage 和 HomePage
- 03发现页面组件并推断属性
- 04验证 XML 标识符与区域
- 05使用 dry-run 检查部署
适用场景
- 01创建对象记录页
- 02向现有 FlexiPage 添加组件
- 03检查 FlexiPage 部署错误
- 04更新页面元数据 XML
MCP 相关
通过 MCP 的 `execute_metadata_action` 调用组件发现和组件模式获取操作,用于未能在本地找到的组件及其属性推断。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-flexipage-generate安装后在 Claude Code 中输入/platform-flexipage-generate确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/cli_commands.mdflexipage_fieldSection.mdflexipage_richText.mdidentifiers_and_regions.mdmcp_action_examples.mdrecord_flexipage_dynamicHighlights.mdxml_rules.mdscripts/resolve-component-instructions.shscan-lwc-components.sh详细介绍
何时使用此技能
在需要以下操作时使用此技能:
- 创建 Lightning 页面(RecordPage、AppPage、HomePage)
- 生成 FlexiPage 元数据 XML
- 向现有 FlexiPage 添加组件
- 排查 FlexiPage 部署错误
- 了解 FlexiPage 结构和组件配置
- 使用页面布局或自定义 Lightning 页面
- 编辑或更新任何
*.flexipage-meta.xml文件
规范
概述
重要:创建新的 FlexiPage 时,必须始终从 CLI 模板命令开始。 切勿从头创建 FlexiPage XML——CLI 会提供有效的结构、正确的区域和正确的组件配置,避免部署错误。
使用 CLI 引导来发现和配置组件,从而生成 Lightning 页面(RecordPage、AppPage、HomePage)。
快速入门工作流
步骤 1:使用 CLI 引导
新建页面的强制步骤:此步骤不可跳过。 创建新的 FlexiPage 时,始终使用 CLI 模板命令。CLI 会生成有效的 XML 结构、正确的区域和正确的元数据,避免常见部署错误。仅在编辑现有 FlexiPage 文件时才跳过此步骤。
<packageDirectory> = sfdx-project.json 中的 path 值 → packageDirectories[0](例如 force-app)。运行命令前,请先从项目文件中读取该值。
sf template generate flexipage \
--name <PageName> \
--template <RecordPage|AppPage|HomePage> \
--sobject <SObject> \
--primary-field <Field1> \
--secondary-fields <Field2,Field3> \
--detail-fields <Field4,Field5,Field6,Field7> \
--output-dir <packageDirectory>/main/default/flexipages
重要: 如果 sf template generate flexipage 命令失败,请停止。
- 安装 templates 插件:
sf plugins install templates - 重试
sf template generate flexipage命令 - 验证 FlexiPage XML 文件是否已创建
在模板命令成功之前,请勿继续执行步骤 2。生成的 XML 是整个工作流的必需内容。
模板专属要求
RecordPage:
- 需要
--sobject(例如 Account、Custom_Object__c) - 需要字段参数:
--primary-field:最重要的标识字段(例如 Name)--secondary-fields:记录摘要(建议 4–6 个,最多 12 个)--detail-fields:完整记录详情,包括必填字段(例如 Name)
AppPage:
- 无其他要求
HomePage:
- 无其他要求
字段选择规则
- 验证字段是否存在:指定命令中的字段前,使用 MCP 工具或 describe 命令发现对象的可用字段
- 优先使用复合字段:如果有
Name,请使用它(而非FirstName/LastName);如果有BillingAddress,请使用它(而非BillingStreet/BillingCity/BillingState);MailingAddress等字段也同理 - 在 detail-fields 中包含必填字段:始终将对象的必填字段(如
Name)包含在--detail-fields参数中,即使它们也用于--primary-field或--secondary-fields
生成内容
- 结构正确的有效 FlexiPage XML
- 预配置的区域和基础组件
- 正确的字段引用和 facet 结构
- 可直接部署或进一步增强
步骤 2:部署基础页面
运行试运行部署,以验证页面和依赖项(使用 sfdx-project.json 中的默认包目录):
sf project deploy start --dry-run -d "<packageDirectory>/main/default" --test-level NoTestRun --wait 10 --json
重要: 继续之前,请修复所有部署错误。页面必须通过验证。
步骤 3:动态添加组件(如有请求)
基础页面成功部署后,如果用户需要其他组件,请遵循下方的动态添加组件工作流。所有组件都必须通过发现和推断流程添加——切勿仅凭记忆编写组件 XML。
XML 核心规则
请阅读 references/xml_rules.md,了解所有 XML 编码规则、字段引用格式、区域/分面类型、fieldInstance 结构、唯一标识符要求以及常见部署错误的解决方法。
关键规则(快速提醒):
- 在
<value>标签中对 HTML 进行编码:依次编码&、<、>、"、' - 字段引用:
Record.{FieldApiName}(绝不能使用Object.Field) - 文件中的每个
<identifier>和区域<name>都必须唯一 - 同一分面中的多个组件 → 合并到同一个区域,并使用多个
<itemInstances>
标识符、区域和容器
请阅读 references/identifiers_and_regions.md,了解标识符生成算法、分面命名模式(命名型与 UUID)、区域选择规则以及容器组件的分面结构。
特定组件提示
dynamicHighlights(RecordPage 页眉)
位置: 仅限 header 区域。完整结构请参见 references/record_flexipage_dynamicHighlights.md。
CLI 会根据 --primary-field 和 --secondary-fields 自动生成 Facet。
fieldSection
用途: 以列的形式显示字段。三层嵌套:区域 → 列 Facet → 字段 Facet。
完整结构和 XML 示例请参见 references/flexipage_fieldSection.md。
关键: columns 属性值是 Facet 名称,而不是数字。
richText
编码规则和 XML 结构请参见 references/flexipage_richText.md。
标识符:flexipage_richText 或 flexipage_richText_{N}
必需的元数据结构
<FlexiPage xmlns="http://soap.sforce.com/2006/04/metadata">
<flexiPageRegions>
</flexiPageRegions>
<masterLabel>Page Label</masterLabel>
<template>
<name>flexipage:recordHomeTemplateDesktop</name>
</template>
<type>RecordPage</type>
<sobjectType>Object__c</sobjectType>
</FlexiPage>
页面类型:
RecordPage- 需要<sobjectType>AppPage- 不需要 sobjectTypeHomePage- 不需要 sobjectType
验证清单
结构(新页面)
- 使用 CLI 进行引导 — 绝不要从头创建 FlexiPage XML
标识符和区域
- 整个文件中的所有
<identifier>值均唯一 - 整个文件中的所有区域/分面
<name>值均唯一 - 同一分面中的多个组件合并到同一个区域,并使用多个
<itemInstances>
字段实例
- 所有字段引用均使用
Record.{Field}格式 - 每个 fieldInstance 都有包含
uiBehavior的fieldInstanceProperties - 每个 fieldInstance 都放在各自的
<itemInstances>包装元素中
类型和编码
- 模板区域使用
<type>Region</type>;组件分面使用<type>Facet</type> - 含 HTML/XML 的属性值均经过实体编码
- 不包含不必要的
<mode>标签(仅在组件模式要求时使用) - 页面名称不带
__c后缀 - 每个 Facet 仅由一个组件属性引用
快速参考:CLI 命令
请阅读 references/cli_commands.md,查看完整的 CLI 示例(RecordPage、AppPage、HomePage)和可用选项。
动态添加组件
强制工作流: 向 FlexiPage 添加任何组件都必须遵循此工作流。不要凭记忆编写组件 XML,也不要跳过发现步骤。此要求适用于标准 OOTB 组件、自定义 LWC 组件以及任何其他组件类型。
概述
当用户请求添加组件时(例如,“添加一个联系人相关列表和一份报告”),请遵循以下流程:
1. Parse Intent → identify ALL requested components
2. Discover ALL → batch components through 3-tier discovery
3. Infer Properties → run 3-step inference for EACH discovered component
4. Generate XML → produce valid XML for all components together
5. Validate → check identifiers, regions, property completeness
关键规则: 首先批量发现所有组件(一次扫描、一次 MCP 调用),然后再推断每个组件的属性。不要逐个组件调用发现步骤,也不要交替进行发现和推断。
第 1 步:解析用户意图
从用户的表述中提取每个组件请求。示例:
- “创建一个包含报告和相关联系人的 Account 页面” → 2 个组件:报告、相关列表
- “添加活动、chatter 和一个 Cases 的 DRL” → 3 个组件:活动、chatter、动态相关列表
步骤 2:三层组件发现
完成所有组件的每一层后,再进入下一层——不要按组件逐个执行第 1 层→第 2 层→第 3 层:
| 层级 | 来源 | 时机 | 调用次数 |
|---|---|---|---|
| 1 | 本地工作区扫描 | 始终首先执行——扫描所有组件 | 0(仅本地) |
| 2 | discoverUiComponents MCP 操作 | 对第 1 层之后仍未解决的所有组件执行一次调用 | 1 |
| 3 | 生成新的 LWC 包 | 仅适用于第 2 层之后仍未解决且用户已确认的组件 | 0 |
对所有组件完成第 1 层后,仅收集尚未解决的组件,并在一次 MCP 调用中将它们传递给第 2 层。只有第 2 层之后仍未解决的组件才会进入第 3 层。
详情请参阅下方的 本地工作区扫描器 和 MCP 操作集成 部分。
步骤 3:属性推断(每个组件)
对于每个发现的组件,使用以下三步策略推断属性:
- 获取架构或读取源代码 — 对于第 2 层(组织)组件,调用
getUiComponentSchemas;对于第 1 层(本地)组件,从源代码中提取@api属性 - 应用组件说明 — 如果存在
references/<name>.md,请读取并遵循其中的推断规则 - 解决剩余问题 — 智能默认值 → LLM 推断 → 向用户提问(最后手段)
完整详情请参阅下方的 混合属性推断策略。
步骤 4:生成 XML
你不能做的事:
- 修改 XML 文件中的顶层结构
- 添加任何未通过三层组件发现解析出的记忆组件
- 进行任何增强
写入任何 XML 之前,请先阅读 references/xml_rules.md。 遵循其中定义的所有元素命名和结构规则。
为所有已解决的组件生成 <itemInstances> XML:
- 每个属性都使用
<componentInstanceProperties>(而非<properties>) - 在整个集合中分配唯一标识符(参见 references/identifiers_and_regions.md)
- 插入到相应区域(header、main、sidebar 或 facets)
- 遵循组件说明文件或架构中定义的 XML 结构
步骤 5:验证
检查完整的 FlexiPage,确认以下内容:
- 标识符唯一(整个文件中没有重复项)
- 区域有效(组件位于正确的区域)
- 属性完整(所有必需属性均已填写)
- XML 编码正确(HTML 值已进行实体编码)
- 元素名称正确(参见 references/xml_rules.md §6)
使用试运行进行部署(使用 sfdx-project.json 中的默认包目录):
sf project deploy start --dry-run -d "<packageDirectory>/main/default" --test-level NoTestRun --wait 10 --json
MCP 操作集成
完整的输入/输出示例和参数表请阅读 references/mcp_action_examples.md。
通过 execute_metadata_action 执行两个 MCP 操作:
| 操作 | 用途 | 时机 |
|---|---|---|
DISCOVER_UI_COMPONENTS | 查找页面类型对应的组件 | 第 2 层发现——对所有尚未解决的组件执行一次调用 |
GET_UI_COMPONENT_SCHEMAS | 获取属性架构 | 属性推断第 1 步(仅适用于第 2 层的组织组件) |
关键约定:
- 组件定义格式:MCP 调用中使用
namespace/blockName(正斜杠),XML 中使用namespace:blockName(冒号) - RECORD_PAGE 必须提供包含
entityName的pageContext getUiComponentSchemas支持部分失败——检查每个组件的success布尔值
本地工作区扫描器
在进行任何 MCP 调用之前,扫描本地 SFDX 项目以查找自定义 LWC 组件(第 1 层发现)。
算法
针对每个组件查询运行扫描器(本地扫描——不进行网络调用):
scripts/scan-lwc-components.sh "<query>" [packageDirectory]
该脚本会扫描 <packageDirectory>/**/lwc/*/,对 camelCase 组件名称进行分词,根据用户意图关键词评分,并返回包含匹配项及其置信度层级的 JSON 数组:
- 高置信度(≥70%): 自动选择,并向用户确认
- 中置信度(40-69%): 提供按排名排列的列表供用户选择
- 低置信度(<40%): 跳过,继续进行第 2 层
在将任何组件移至第 2 层之前,先对所有组件运行第 1 层。从第 1 层收集所有尚未解决的组件,然后在一次 MCP 调用中将它们传递给第 2 层。
消歧
对于中等置信度匹配(40-69%)或多个高置信度匹配:
- 阅读每个候选项的
.js-meta.xml,查看<description>和<targetConfigs> - 向用户展示按排名排序的列表,包含组件名称和描述
- 用户选择,或回复“这些都不是”(→ 继续到第 2 层)
何时跳过
以下情况跳过本地扫描:
- 用户明确提到组织级组件(“使用标准报表组件”)
- 用户意图明确对应已知标准组件(DRL、richText 等)
- 工作区中不存在
<packageDirectory>目录
混合属性推断策略
对于发现的每个组件,按顺序使用以下 3 步策略填充其属性:
第 1 步:获取最新架构(有条件)
仅当组件不存在于本地计算机上时(即第 2 层发现的组织组件),才调用 getUiComponentSchemas。对于本地组件(第 1 层),应直接从源代码中提取 @api 属性。
调用时机:
- 第 2 层(组织发现):始终调用——架构是属性信息的唯一来源
- 第 1 层(本地):跳过——从组件的
.js源文件中读取@api属性 - 第 3 层(生成):跳过——刚刚创建了源代码,因此属性已知
第 2 步:应用组件说明(如果存在)
运行 scripts/resolve-component-instructions.sh <namespace:component>——如果说明文件存在,则返回其路径;否则返回空字符串。
示例:
record_flexipage:dynamicHighlights→references/record_flexipage_dynamicHighlights.mdflexipage:fieldSection→references/flexipage_fieldSection.mdc:expenseTracker→ (空——没有文件)
如果返回了文件:阅读并遵循其中的推断规则、XML 模式和默认值。 如果为空:直接跳到第 3 步。
说明文件会扩充架构——它们提供如何根据用户意图推导值的指导。架构中未被说明文件涵盖的属性,则在第 3 步中解析。
第 3 步:解析剩余属性
对于尚未解析的属性,按以下优先顺序处理:
3a. 智能默认值启发式规则:
| 属性模式 | 默认值 |
|---|---|
recordId | {!recordId} |
objectApiName / sObjectName | 页面 <sobjectType> 的值 |
show* / visible* / display* | true |
hide* / hidden* / disabled* | false |
| 无前缀的布尔值 | false |
架构指定 "default" | 使用架构默认值 |
3b. LLM 推断:
结合组件架构、用户意图和页面上下文推断合理值。例如:用户说“显示顶级商机的报表”→ 推断 reportName 应引用商机报表。
3c. 询问用户(最后手段): 仅当关键必填属性无法推断时才询问用户。如果用户说“跳过”,则完全省略该组件。
按层级区分的行为
| 层级 | 额外步骤 | 架构调用 | 说明 |
|---|---|---|---|
| 第 1 层(本地) | 从源代码中提取 @api 属性 | 否(使用源代码) | 如果存在 |
| 第 2 层(组织) | — | 是 | 如果存在 |
| 第 3 层(生成) | 从刚生成的源代码中提取 @api | 否(刚创建) | 否 |
新建 LWC(第 3 层)
如果在本地(第 1 层)或组织中(第 2 层)都没有找到组件,则提出生成新的 LWC。
触发条件
- 第 1 层和第 2 层均未找到,或用户拒绝了所有候选项
- 用户未明确表示“跳过”或“不要创建”
确认
创建前务必确认,并说明组件名称。如果用户拒绝:跳过该组件,继续处理其他组件。
生成后
创建 LWC 包后:
- 立即将其视为第 1 层本地组件
- 从生成的源代码中提取
@api属性 - 为
recordId和objectApiName应用智能默认值 - 使用
c:{componentName}作为 componentName,生成 FlexiPage XML
命名约定
- 根据用户意图推导名称:“客户健康评分” →
customerHealthScore - 使用 camelCase,JS 类名中不使用连字符或下划线
- 文件夹名称与类名一致(首字母小写):
customerHealthScore/
参考文件索引
| 文件 | 何时阅读 |
|---|---|
references/xml_rules.md | 编写或编辑任何 FlexiPage XML 之前 — 编码、字段引用、标识符、部署错误 |
references/identifiers_and_regions.md | 添加组件时 — 标识符算法、Facet 命名、区域选择、容器模式 |
references/cli_commands.md | 初始化新页面时 — RecordPage、AppPage、HomePage 的完整 CLI 示例 |
references/mcp_action_examples.md | 调用 MCP 操作时 — discoverUiComponents 和 getUiComponentSchemas 的完整输入/输出 JSON |
references/flexipage_fieldSection.md | 添加带列的 Field Section 时 |
references/record_flexipage_dynamicHighlights.md | 添加 Dynamic Highlights 面板时 |
references/flexipage_richText.md | 添加 Rich Text 组件时 |
scripts/scan-lwc-components.sh | Tier 1 本地工作区扫描 — 将 LWC 组件名称分词,并根据用户查询进行评分 |
scripts/resolve-component-instructions.sh | 属性推断第 2 步 — 将组件定义解析为指令文件路径 |
添加新的组件模式: 按照现有文件的结构创建 references/<namespace>_<componentName>.md。该技能会在属性推断的第 2 步自动检查此文件。
动态组件验证规则
为动态添加的组件生成 XML 后,部署前请验证以下所有内容:
标识符唯一性
- 提取整个 FlexiPage 文件中的所有
<identifier>值 - 确认没有重复项
- 如有冲突:自动递增后缀(
_2、_3等)
区域有效性
- 将组件放置在其类型对应的正确区域:
record_flexipage:dynamicHighlights→ 仅限headerflexipage:fieldSection→main或选项卡 Facetflexipage:richText→ 任意区域
属性完整性
- 架构中标记为必需的所有属性均已赋值
- 所有值均符合预期类型(String、Boolean、valueList、Integer)
<value>标签中不得包含原始 HTML(必须进行实体编码)
结构完整性
- 组件属性引用的每个 Facet 都以
<flexiPageRegions>块的形式存在 - 不存在孤立的 Facet(每个 Facet 恰好由一个组件引用)
- 同一区域中的多个组件使用一个
<flexiPageRegions>块,其中包含多个<itemInstances>
跨组件一致性
- 对于添加多个组件的情况:所有新增组件的标识符均不重复
- Facet UUID 在不同组件之间不冲突
- 需要单例放置的组件(dynamicHighlights、recordDetailPanelMobile)不得重复