mcpField
P
platform-widget-generate

platform-widget-generate

github.com/forcedotcom设计与 UI1.1k3.3k 次安装1 天前更新
代码仓库

关于 platform-widget-generate

用于根据组件名称和数据结构构建 Salesforce WidgetBundle 的技能。它生成 UEM 布局、JSON Schema 和注册元数据,并通过组织操作发现 UI 区块及其架构。

主要功能

  1. 01创建 UEM 组件树
  2. 02生成组件 JSON Schema
  3. 03编写 .uiwidget-meta.xml 注册文件
  4. 04发现可用 UI 组件
  5. 05获取所选区块的架构
  6. 06绑定数据并配置操作

适用场景

  1. 01构建卡片式富 UI 组件
  2. 02呈现对象或列表中的字段
  3. 03添加条件或计算内容

MCP 相关

通过 H360 MCP dispatch 工具调用 Salesforce 可调用操作,以发现 UI 组件并获取其架构;文档还说明了 sf API 请求作为备用方式。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill platform-widget-generate

安装后在 Claude Code 中输入/platform-widget-generate确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples/
conditional.json
formulas.json
list-with-foreach.json
localized-labels.json
single-object.json
references/
schema-from-lightning-type.md
widget-actions.md
widget-bundle-layout.md
widget-bundle-validation.md
widget-formulas.md
widget-gotchas.md
widget-labels.md
widget-meta-directives.md
widget-styling.md

详细介绍

生成 WidgetBundle

编写一个完整的 WidgetBundle:UEM 树(tile/widget)、描述该 widget 输入约定的 JSON Schema,以及用于注册此 bundle 的 .uiwidget-meta.xml。

适用场景

当用户要求创建 widget、mosaic、fragment 或卡片式富 UI 表面时使用。自定义 LWC 渲染器或 Custom Lightning Type bundle 中的 renderer.json 文件不适用此技能;这些应使用 platform-custom-lightning-type-generate。

输入

  • widgetName(必填)——camelCase 标识符;将成为 uiWidgets/ 下的目录名。
  • shape——widget 要渲染的数据。没有 shape 就无法生成 widget。shape 按以下优先顺序通过两种方式之一提供:
    1. lightningTypeSchema——现有 Apex 支持的 Lightning Type 的 { path, apexClassFqn }。FQN 有两种形式:外部类(<namespace>__<ClassName>),其中外部类是 payload;或内部类(<namespace>__<ClassName>$<InnerClass>),其中指定的内部类是 payload。由 platform-lightning-type-widget-coordinate 编排器传入。若存在,请按 references/schema-from-lightning-type.md 推导。
    2. 从用户提示词中提取——未传入 lightningTypeSchema 时,直接根据用户提供的内容推断 shape:粘贴的 JSON payload、列出的字段(如“id 为字符串,total 为数字”)或描述性文字。无论通过哪种方式,输出都是相同的有序 { name, type, required } 列表。

如果两种来源都无法提供 shape,请停止并先询问用户。

输出

在 <pkgDir>/uiWidgets/<widgetName>/ 中创建三个文件:

文件内容
<widgetName>.jsonWidget envelope——{ "type": "lightning__agentforceWidget", "contentBody": { "widgetBody": { UEM tree rooted at tile/widget } } }
schema.jsonJSON Schema——根节点包含 type: "object" 和 properties.attributes 包装结构,其中包含 lightning:type: "lightning__objectType" 及字段 properties
<widgetName>.uiwidget-meta.xml<UiWidgetBundle> 元素,包含 <masterLabel>、<description> 和 <widgetType>JSON</widgetType>

<pkgDir> 的解析步骤以及 <widgetName>.uiwidget-meta.xml> 的确切结构,请参见 references/widget-bundle-layout.md。


组合结构

Widget 主体是一个 UEM 树,块嵌套在 contentBody.widgetBody 下。根节点为 tile/widget。所有节点——根节点和非根节点——结构相同:没有 type 键;仅包含 definition、可选的 attributes、可选的 meta 和可选的 children。块结构:

interface Block {
  definition: string  // {namespace}/{blockName} — root is "tile/widget"
  attributes?: Record<string, any>
  meta?: { // see references/widget-meta-directives.md
    forEach?: string
    forItem?: string
    if?: string
  }
  children?: Block[]
}

tile/widget.children 的第一个子节点应为一个 tile/column。为使不同表面上的垂直结构保持可预测,widget 内容通常都放在这个首个子节点中。


可用的可调用操作

两者都是目标 org 上的标准可调用操作。

调用约定

使用可用的任一机制调用每个操作:H360 MCP dispatch 工具(向端点路径发送 POST 请求并附带请求正文),或 sf api request rest。使用 v{version} = 此技能的 minApiVersion。切勿使用 curl,也不要提取 org 的访问令牌。

sf api request rest '/services/data/v{version}/actions/standard/<actionName>' --method POST --body '<request body>' --target-org <org>
响应处理

每个响应都是包含一个 envelope 的数组(dispatch 会将其嵌套在 body 下)。请按顺序检查以下三层失败情况:

层信号处理方式
传输 / 身份验证dispatch 的 status_code 不是 200,或 CLI 以非零状态退出呈现错误
操作[0].isSuccess 为 false,或 [0].errors 非空呈现 errors[].message
单条结果(仅 getUiComponentSchemas)任意 componentSchemas[].success 为 false,即使 [0].isSuccess 为 true将该块视为不可用

成功时,读取 [0].outputValues。

discoverUiComponents

用途: 发现可用于组合的区块。

端点: POST /services/data/v{version}/actions/standard/discoverUiComponents

请求正文: {"inputs":[{"pageType":"FRAGMENT"}]}

返回: outputValues.componentDefinitions[]——{ definition, description, label } 列表。

getUiComponentSchemas

用途: 获取所选区块的架构(属性类型、必填项与可选项、验证规则)。

端点: POST /services/data/v{version}/actions/standard/getUiComponentSchemas

请求正文: {"inputs":[{"pageType":"FRAGMENT","componentDefinitions":["namespace/definition", ...]}]}

返回: outputValues.componentSchemas[]——{ definition, success, schema } 列表(schema 是 YAML 字符串)。支持部分失败。

切勿将 tile/widget 传给 getUiComponentSchemas——它是固定包装器,不是可查询的组件。


属性绑定

  • 使用 {!$attrs.<attrName>} 将区块属性绑定到运行时数据。<attrName> 必须与 schema.json 中的属性名称一致。
  • 在 forEach 中,应改为引用循环变量,例如 "text": "{!$item.name}"。参见 references/widget-meta-directives.md。
  • 绑定可以是公式表达式,而不只是裸字段引用。支持的函数列表、语法和注意事项,请参见 references/widget-formulas.md。
  • **本地化:**仅当用户要求本地化或翻译文本(或提及 Custom Labels / $Label)时,才将静态的用户可见字符串写为 Custom Label 引用——{!$Label.c.<LabelName>}。参见 references/widget-labels.md。

操作

tile/button 支持 actions 属性,可在事件发生时分派操作节点。支持两种操作定义:

操作时机必填属性效果
action/openLink同步url(字符串)。target 可选(_blank|_self,默认为 _blank)打开 URL
action/sendMessage异步content(字符串)向 Agent 发回一条新的用户消息,并开启新一轮交互

完整的 sendMessage 和 openLink 按钮 JSON,请参见 references/widget-actions.md。

没有 actions 属性的 tile/button 会呈现为禁用状态——按钮用于触发操作,因此要让按钮可交互,务必为其附加 click 操作。


布局最佳实践

这些约定涵盖组件的结构——区块如何分组和堆叠。

基元用途使用场景
tile/column垂直堆叠子项根包装器,以及任何需要堆叠区块的分组
tile/row水平排列子项两个或更多需要位于同一行的区块
tile/spacer区块之间的留白内容组之间需要额外间距时
  • **嵌套:**优先使用扁平布局。只有当子组的视觉方向确实发生变化时,才在 tile/row 中嵌套 tile/column(反之亦然)。
  • **权威区块列表:**上表列出了常见布局基元。务必检查 discoverUiComponents 的输出,确认区块存在;切勿仅凭此表假定某个区块名称有效。

样式最佳实践

使用语义化样式(变体,而非具体颜色或像素),每组使用一个主按钮,每个小组件使用一个 h1,且仅使用 Lucide 图标。指定变体、尺寸或图标前,请阅读 references/widget-styling.md。


工作流

  1. 确定小组件规格——按顺序排列的 { name, type, required } 列表。来源取决于提供的输入(参见 输入):

    • 如果编排器传入了 lightningTypeSchema → 按 references/schema-from-lightning-type.md 推导。
    • 否则 → 直接根据用户提示推断列表(粘贴的 JSON 负载、枚举字段列表或描述性文字)。
  2. 发现区块(必需——不要跳过)。 调用 discoverUiComponents 可调用操作(参见 Available Invocable Actions),并根据返回的 label/description 值匹配 widget 规范中的属性类型。如果 isSuccess 为 false、errors 非空,或 componentDefinitions 为空,请停止并原样呈现错误——不要根据记忆、以往运行结果或训练数据臆造区块名称。

  3. 选择区块。 为 widget 规范中的每个属性选择一个区块,并从 Layout Best Practices 中选择结构基元。

  4. 获取区块架构(必需——不要跳过)。 调用 getUiComponentSchemas 可调用操作,获取所选区块的架构。检查属性元数据,包括每个属性的 default——省略任何值等于默认值的属性(参见 references/widget-styling.md)。如果 isSuccess 为 false、componentSchemas 为空,或任何条目的 success: false,请勿使用该区块——从步骤 2 的结果中重新选择其他区块;如果没有可用区块,请停止并呈现错误。切勿根据项目中已有的 widget 臆造。

  5. **构建 UEM 树(必须阅读示例——不要跳过)。**首先,确定哪些模式与 widget 规范匹配,并从此技能自己的 examples/ 目录(<skill-root>/examples/)中读取每个匹配的示例文件:

    规范中的模式要读取的示例
    单个对象(无迭代)<skill-root>/examples/single-object.json
    任意列表迭代(根级数组、嵌套列表,或嵌入单对象 widget 的列表)<skill-root>/examples/list-with-foreach.json
    条件渲染(if 绑定到布尔值或公式)<skill-root>/examples/conditional.json
    计算值、文本/数字转换、本地化格式的数字/货币/日期,或由公式驱动的 if(而非直接使用布尔字段)<skill-root>/examples/formulas.json
    用户要求使用本地化/翻译文本(Custom Labels)<skill-root>/examples/localized-labels.json

    规范可能匹配多种模式(例如,包含一些有条件渲染项的项目列表,需要同时读取 list-with-foreach.json 和 conditional.json)。读取每个匹配的示例,且只读取这些示例——即使模式看起来很熟悉,也不要跳过阅读。

    编写任何公式之前,请完整阅读 references/widget-formulas.md——这是受支持运算符和函数的权威列表;不要臆造其中未记载的函数名称或运算符。

    编写任何 $Label 引用之前,请完整阅读 references/widget-labels.md。

    然后:

    • 将 widget 规范中的每个属性映射到区块属性;保持规范中的顺序。
    • **确定根级迭代方式:**单个对象 → 属性直接放在根 tile/column 下。集合 → 使用 forEach/forItem 包裹重复区块。参见 references/widget-meta-directives.md。
    • 使用 {!$attrs.X}(或在 forEach 中使用 {!$item.X})绑定值。
    • 对于条件区块,在 meta 上添加 "if"——可以是直接的 lightning__booleanType 属性,也可以是计算结果为布尔值的公式表达式。参见 references/widget-formulas.md。
    • 当 widget 规范要求计算值(总计、派生标签、格式化字符串)而不是原始字段时,请按照 references/widget-formulas.md,使用 {!...} 中的公式表达该值——不要为了保存可通过现有属性计算出的值而臆造新的架构属性。
  6. 编写 schema.json。 根据 widget 规范构建 JSON Schema。字段位于 attributes 包装器下一层:

    {
      "title": "<Widget Display Name>",
      "description": "<one line about what the widget shows>",
      "type": "object",
      "properties": {
        "attributes": {
          "lightning:type": "lightning__objectType",
          "properties": {
            "<propertyName>": {
              "title": "<label>",
              "description": "<short description>",
              "lightning:type": "<lightning__textType | lightning__numberType | ...>"
            }
          }
        }
      }
    }
    

    必需的根键:title、type: "object"、properties.attributes(包含 lightning:type: "lightning__objectType" 和嵌套的 properties 映射)。关于基本类型的完整指导,请参见 references/schema-from-lightning-type.md。

  7. 编写 <widgetName>.uiwidget-meta.xml。 具体结构请参见 references/widget-bundle-layout.md。

  8. 解析 <pkgDir> 并写入 bundle。 按照 references/widget-bundle-layout.md 中的 ## Resolving <pkgDir> 流程操作。一个 widget bundle 是一组三个文件——必须在同一步写入全部三个文件;少于三个文件的 bundle 不完整,无法部署。

    <pkgDir>/uiWidgets/<widgetName>/<widgetName>.json               # widget envelope — UEM tree (primary artifact)
    <pkgDir>/uiWidgets/<widgetName>/schema.json                     # attribute contract for the envelope
    <pkgDir>/uiWidgets/<widgetName>/<widgetName>.uiwidget-meta.xml  # UiWidgetBundle registration
    

    每个文件都有不同的作用:

    • <widgetName>.json — 包含 tile/widget UEM 树的 widget 封装。它是主要产物;schema.json 是它的配套契约,不能替代它。
    • schema.json — 用于定义封装中 {!$attrs.X} 绑定所引用属性的 JSON Schema。
    • <widgetName>.uiwidget-meta.xml — 用于注册 bundle 以进行源代码跟踪和部署的 UiWidgetBundle 元素。

    在继续自检之前,先写入全部三个文件。

  9. 自检。 报告前,运行检查并逐项报告结果(pass 或 fail (<reason>))。不要用单独一行“全部通过”来概括——请列出每项检查,方便审核者发现被悄然跳过的检查。 运行 references/widget-bundle-validation.md 中的所有检查。

  10. 报告标签。 如果 widget 使用 $Label,请在回复末尾附上 references/widget-labels.md 中所述的标签报告。


规则 / 约束

约束原因
Block 定义遵循 {namespace}/{blockName} 格式,并且必须与 discoverUiComponents 的输出一致运行时会根据精确的定义字符串解析 block
绝不要将 tile/widget 传递给 getUiComponentSchemas它是固定封装,不是可查询的组件
仅在 references/ 和 examples/ 文件所指定的步骤中读取这些文件提前读取会浪费上下文,并且早于用于确定所需文件的发现结果
正文中的每个 {!$attrs.X} 都必须对应 widget schema.json 中的一个属性不得臆造字段
每个 tile/button 都必须包含一个使用 action/openLink 或 action/sendMessage 的 actions.click 条目这两种是 tile 唯一支持的操作定义;没有操作的按钮会呈现为禁用状态
任何 Bash 工具调用中都不得使用 $(…)、反引号、<(…)、花括号展开 {a,b,c} 或 eval/exec即使在 Bypass 模式下,Vibes 的安全 shell 过滤器也会要求对这些模式进行手动批准。请发出单独的命令(mkdir -p a && mkdir -p b),或用各自的命令打印每个值并根据输出进行判断——不要将值捕获到 shell 变量中

注意事项

已知故障模式及其修复方法(不完整的 schema、未解析的绑定、错误的输出路径、if 真值判断、失效的按钮、操作选择):参见 references/widget-gotchas.md。


参考文件索引

文件何时阅读
references/widget-meta-directives.md使用 forEach / forItem(迭代)和 if(条件渲染)时,包括嵌套循环
references/schema-from-lightning-type.md提供 lightningTypeSchema 时;如何从基于 Apex 的 Lightning Type 派生组件 schema.json
references/widget-bundle-layout.md文件夹布局、-meta.xml 结构、<pkgDir> 解析规则
references/widget-bundle-validation.md第 9 步——报告结果前要运行的检查
references/widget-formulas.md支持的公式函数和运算符,包括区域格式化函数(FORMATNUMBER、FORMATCURRENCY、FORMATDATE,等等)
references/widget-labels.md本地化——$Label 语法、命名和复用、允许的属性、与数据组合、创建标签以及标签报告
references/widget-actions.mdaction/sendMessage 和 action/openLink 的完整 tile/button JSON
references/widget-styling.md变体、大小、标题和图标规范
references/widget-gotchas.md已知故障模式及其修复方法
examples/single-object.json单对象模式(通过 {!$attrs.X} 进行根绑定,不迭代)
examples/list-with-foreach.json任意列表迭代场景——根级集合、嵌套列表,以及嵌入单对象组件中的列表(例如,迭代外层 Apex 负载中的 List<InnerClass>)
examples/conditional.json条件模式(对 meta 使用 if,包括同时使用 if 和 forEach)
examples/formulas.json公式用法——文本/算术/日期转换、区域格式化函数、使用 IF / AND / NOT 控制 tile/text 和 meta.if
examples/localized-labels.json本地化——标题、说明文字、徽章(由 IF 在标签之间选择)、按钮标签,以及与数据拼接的标签中的 $Label

评论

支持 Markdown