platform-widget-generate

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Generating a Widget Bundle

生成Widget Bundle

Author a complete WidgetBundle: a UEM tree (
tile/widget
), a JSON Schema describing the widget's input contract, and the
.uiwidget-meta.xml
that registers the bundle.
编写完整的WidgetBundle:包含UEM树(
tile/widget
)、描述widget输入契约的JSON Schema,以及用于注册bundle的
.uiwidget-meta.xml
文件。

When to Use This Skill

何时使用此技能

Use when the user asks for a widget, mosaic, fragment, or card-style rich UI surface. Do not use this skill for custom-LWC renderers or for
renderer.json
files inside a Custom Lightning Type bundle — those belong to
platform-custom-lightning-type-generate
.
当用户请求widget、mosaic、fragment或卡片式富UI界面时使用。请勿将此技能用于自定义LWC渲染器,或Custom Lightning Type bundle内的
renderer.json
文件——这些场景应使用
platform-custom-lightning-type-generate

Inputs

输入参数

  • widgetName
    (required) —
    camelCase
    identifier; becomes the directory name under
    uiWidgets/
    .
  • A shape — what data the widget renders. The widget cannot be generated without it. The shape arrives one of two ways, in priority order:
    1. lightningTypeSchema
      { path, apexClassFqn }
      for an existing Apex-backed Lightning Type. The FQN takes one of two forms: outer-class (
      <namespace>__<ClassName>
      ) where the outer class is the payload, or inner-class (
      <namespace>__<ClassName>$<InnerClass>
      ) where the named inner class is the payload. Passed in by the
      platform-lightning-type-widget-coordinate
      orchestrator. When present, derive per
      references/schema-from-lightning-type.md
      .
    2. Extracted from the user's prompt — when no
      lightningTypeSchema
      is passed, infer the shape directly from what the user wrote: a pasted JSON payload, an enumerated field list ("id as string, total as number"), or descriptive prose. The output is the same ordered list of
      { name, type, required }
      either way.
If neither source yields a shape, STOP and ask the user before proceeding.
  • widgetName
    (必填)——驼峰式(
    camelCase
    )标识符;将作为
    uiWidgets/
    目录下的子目录名称。
  • 数据结构——widget要渲染的数据。没有数据结构则无法生成widget。数据结构通过以下两种方式提供,优先级如下:
    1. lightningTypeSchema
      ——现有Apex-backed Lightning Type的
      { path, apexClassFqn }
      。FQN有两种形式:外部类(
      <namespace>__<ClassName>
      ,其中外部类为负载),或内部类(
      <namespace>__<ClassName>$<InnerClass>
      ,其中指定的内部类为负载)。由
      platform-lightning-type-widget-coordinate
      编排器传入。若存在,请根据
      references/schema-from-lightning-type.md
      推导。
    2. 从用户提示中提取——当未传入
      lightningTypeSchema
      时,直接从用户的描述中推断数据结构:粘贴的JSON负载、枚举字段列表(如"id为字符串,total为数字")或描述性文本。无论哪种方式,输出均为有序的
      { name, type, required }
      列表。
若两种来源均无法得到数据结构,请停止操作并询问用户。

Output

输出结果

Three files in
<pkgDir>/uiWidgets/<widgetName>/
:
FileContent
<widgetName>.json
Widget envelope —
{ "type": "lightning__agentforceWidget", "contentBody": { "widgetBody": { UEM tree rooted at tile/widget } } }
schema.json
JSON Schema — root has
type: "object"
+
properties.attributes
wrapper carrying
lightning:type: "lightning__objectType"
and the field
properties
<widgetName>.uiwidget-meta.xml
<UiWidgetBundle>
element with
<masterLabel>
,
<description>
, and
<widgetType>JSON</widgetType>
See
references/widget-bundle-layout.md
for the
<pkgDir>
resolution procedure and the exact
<widgetName>.uiwidget-meta.xml
shape.

<pkgDir>/uiWidgets/<widgetName>/
目录下生成三个文件:
文件内容
<widgetName>.json
Widget信封——
{ "type": "lightning__agentforceWidget", "contentBody": { "widgetBody": { 以tile/widget为根节点的UEM树 } } }
schema.json
JSON 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

Composition

结构组成

A widget body is a UEM tree of blocks nested under
contentBody.widgetBody
. The root node is
tile/widget
. Every node — root and non-root — has the same shape: no
type
key; just
definition
, optional
attributes
, optional
meta
, and optional
children
. Block shape:
ts
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[]
}
The first child of
tile/widget.children
SHOULD be a single
tile/column
(or a single
tile/card
). All widget content typically goes inside that first child for predictable vertical structure across surfaces.

Widget主体是嵌套在
contentBody.widgetBody
下的UEM块树,根节点为
tile/widget
。所有节点(根节点和非根节点)结构相同:无
type
键;仅包含
definition
、可选的
attributes
、可选的
meta
和可选的
children
。块结构如下:
ts
interface Block {
  definition: string  // {namespace}/{blockName} — 根节点为"tile/widget"
  attributes?: Record<string, any>
  meta?: { // 请参阅references/widget-meta-directives.md
    forEach?: string
    forItem?: string
    if?: string
  }
  children?: Block[]
}
tile/widget.children
的第一个子节点应为单个
tile/column
(或单个
tile/card
)。为了在不同界面中保持一致的垂直结构,所有widget内容通常都放在这个第一个子节点内。

Available Metadata Actions

可用元数据操作

discoverUiComponents

discoverUiComponents

Purpose: Discover the palette of blocks available for composition.
Required parameters:
actionName: "discoverUiComponents"
,
metadataType: "FRAGMENT"
,
parameters.pageType: "FRAGMENT"
. Optional:
searchQuery
to filter by name/description.
Returns: list of
{ definition, description, label, attributes? }
.
用途: 发现可用于组合的块组件库。
必填参数:
actionName: "discoverUiComponents"
metadataType: "FRAGMENT"
parameters.pageType: "FRAGMENT"
。可选参数:
searchQuery
,用于按名称/描述过滤。
返回值:
{ definition, description, label, attributes? }
列表。

getUiComponentSchemas

getUiComponentSchemas

Purpose: Fetch JSON schemas (property types, required vs optional, validation) for selected blocks.
Required parameters:
actionName: "getUiComponentSchemas"
,
metadataType: "FRAGMENT"
,
parameters.pageType: "FRAGMENT"
,
parameters.componentDefinitions: ["namespace/definition", ...]
. Optional:
includeKnowledge
(default
true
).
Returns:
componentSchemas[]
— success entries carry the JSON schema, failure entries carry an error message. Partial failures are supported.
Never pass
tile/widget
to
getUiComponentSchemas
— it is a fixed wrapper, not a queryable component.

用途: 获取所选块的JSON Schema(属性类型、必填/可选、验证规则)。
必填参数:
actionName: "getUiComponentSchemas"
metadataType: "FRAGMENT"
parameters.pageType: "FRAGMENT"
parameters.componentDefinitions: ["namespace/definition", ...]
。可选参数:
includeKnowledge
(默认值
true
)。
返回值:
componentSchemas[]
——成功条目包含JSON Schema,失败条目包含错误信息。支持部分失败。
请勿将
tile/widget
传入
getUiComponentSchemas
——它是固定的包装器,并非可查询的组件。

Attribute Binding

属性绑定

  • Bind a block property to runtime data with
    {!$attrs.<attrName>}
    .
    <attrName>
    MUST match a property name in
    schema.json
    .
  • Inside a
    forEach
    , reference the loop variable instead — e.g.
    "text": "{!$item.name}"
    . See
    references/widget-meta-directives.md
    .

  • 使用
    {!$attrs.<attrName>}
    将块属性绑定到运行时数据。
    <attrName>
    必须与
    schema.json
    中的属性名称匹配。
  • forEach
    循环内,请改用循环变量引用——例如
    "text": "{!$item.name}"
    。请参阅
    references/widget-meta-directives.md

Layout Best Practices

布局最佳实践

These conventions cover widget structure — how blocks are grouped and stacked.
PrimitivePurposeWhen to use
tile/column
Vertical stack of childrenRoot wrapper, and any group of blocks that should stack
tile/row
Horizontal stack of childrenTwo or more blocks that belong on the same line
tile/card
Visually-boxed groupA bounded section that should read as one unit
tile/spacer
Whitespace between blocksWhen extra space is needed between content groups
  • Sectioning: Separate major content groups with a fresh
    tile/card
    -bounded section. Do not nest cards inside cards.
  • Nesting: Prefer flat layouts. Only nest a
    tile/column
    inside a
    tile/row
    (or vice versa) when the visual orientation actually changes for that subgroup.
  • Authoritative palette: the table above lists typical layout primitives. Always confirm a block exists by inspecting
    discoverUiComponents
    output — do not assume a block name from this table without seeing it in the discovery response.

这些约定涵盖widget的结构——块如何分组和堆叠。
基础组件用途使用场景
tile/column
垂直堆叠子组件根包装器,以及所有需要垂直堆叠的块组
tile/row
水平堆叠子组件两个或多个需要放在同一行的块
tile/card
带视觉边框的组需要作为一个整体呈现的有界区域
tile/spacer
块之间的空白区域内容组之间需要额外空间时
  • 分区: 使用新的
    tile/card
    边界区域分隔主要内容组。请勿在卡片内嵌套卡片。
  • 嵌套: 优先使用扁平化布局。仅当子组的视觉方向确实需要改变时,才在
    tile/row
    内嵌套
    tile/column
    (反之亦然)。
  • 权威组件库: 上表列出了典型的布局基础组件。请始终通过查看
    discoverUiComponents
    的输出确认块是否存在——不要仅凭此表中的块名称假设其存在,必须在发现响应中看到该名称。

Styling Best Practices

样式最佳实践

Widgets express intent, not pixels. Each surface provides a default look and feel; brand/theme overrides apply automatically.
  • Style semantically. Use
    variant
    ,
    size
    , and other enum-typed attributes (
    primary
    ,
    destructive
    ,
    success
    ,
    warning
    ). Do not pin literal colors or pixel values.
  • One primary action per visible group. At most one
    tile/button
    with
    variant: primary
    . Use
    secondary
    ,
    outline
    , or
    ghost
    for additional actions.
  • One
    h1
    per widget.
    Use
    h2
    /
    h3
    for sub-section headings,
    body
    for prose,
    caption
    for helper text.
  • Use semantic state variants on state-bearing blocks (
    tile/alert
    ,
    tile/badge
    ,
    tile/callout
    ,
    tile/chip
    ).
  • Accept schema defaults for
    gap
    ,
    padding
    ,
    size
    unless there is a specific reason to override.
  • Don't pin
    width
    ,
    height
    ,
    maxWidth
    unless a content constraint requires it. For long text, use
    truncate: true
    .
  • Use the Lucide icon set. Pass the Lucide name (
    "check"
    ,
    "alert-circle"
    ); other icon libraries are not supported.

Widget传递的是意图,而非像素细节。每个界面都提供默认的外观和风格;品牌/主题覆盖会自动应用。
  • 语义化样式。 使用
    variant
    size
    和其他枚举类型属性(如
    primary
    destructive
    success
    warning
    )。不要硬编码具体颜色或像素值。
  • 每个可见组最多一个主操作。 最多保留一个
    variant: primary
    tile/button
    。其他操作使用
    secondary
    outline
    ghost
    变体。
  • 每个widget最多一个
    h1
    标题。
    子区域标题使用
    h2
    /
    h3
    ,正文使用
    body
    ,辅助文本使用
    caption
  • 在承载状态的块上使用语义化状态变体(如
    tile/alert
    tile/badge
    tile/callout
    tile/chip
    )。
  • 接受
    gap
    padding
    size
    的Schema默认值
    ,除非有特定理由需要覆盖。
  • 不要硬编码
    width
    height
    maxWidth
    ,除非内容约束要求。对于长文本,请使用
    truncate: true
  • 使用Lucide图标集。 传入Lucide图标名称(如
    "check"
    "alert-circle"
    );不支持其他图标库。

Workflow

工作流程

  1. Resolve the widget spec — an ordered list of
    { name, type, required }
    . Source depends on which input was provided (see Inputs):
    • If
      lightningTypeSchema
      was passed by the orchestrator → derive per
      references/schema-from-lightning-type.md
      .
    • Otherwise → infer the list directly from the user prompt (pasted JSON payload, enumerated field list, or descriptive prose).
  2. Discover blocks (REQUIRED — do NOT skip). Call the
    discoverUiComponents
    metadata action via
    execute_metadata_action
    . Use property types from the widget spec to seed
    searchQuery
    (text →
    "text"
    , number →
    "number"
    ). If
    discoverUiComponents
    returns
    success: false
    , an error, or an empty list, STOP and surface the error verbatim — do not improvise block names from memory, prior runs, or training data. Re-run discover with a different
    searchQuery
    only if the failure is search-query-specific.
  3. Select blocks. Choose one block per widget-spec property, plus structural primitives from Layout Best Practices.
  4. Get block schemas (REQUIRED — do NOT skip). Call the
    getUiComponentSchemas
    metadata action via
    execute_metadata_action
    for the selected blocks. Review property metadata. If
    componentSchemas
    returns all-failure or empty, STOP and surface the error — do not improvise from existing widgets in the project.
  5. Build the UEM tree (example reads REQUIRED — do NOT skip). First, identify which patterns match the widget spec and read each matching example file from this skill's own
    examples/
    directory (
    <skill-root>/examples/
    ):
    Pattern in the specExample to read
    Single object (no iteration)
    <skill-root>/examples/single-object.json
    Any list iteration (root-level array, nested list, or list embedded in a single-object widget)
    <skill-root>/examples/list-with-foreach.json
    Conditional rendering (
    if
    bound to a boolean)
    <skill-root>/examples/conditional.json
    A spec may match multiple patterns (e.g. a list of items where some items render conditionally reads both
    list-with-foreach.json
    and
    conditional.json
    ). Read every matching example, and only those — do not skip the read because the pattern feels familiar.
    Then:
    • Map each widget-spec property to a block property; preserve spec order.
    • Decide root iteration: single object → properties directly under root
      tile/column
      . Collection → wrap repeating block in
      forEach
      /
      forItem
      . See
      references/widget-meta-directives.md
      .
    • Bind values with
      {!$attrs.X}
      (or
      {!$item.X}
      inside
      forEach
      ).
    • For conditional blocks, add
      "if"
      on
      meta
      — only when the schema has a matching
      lightning__booleanType
      property.
  6. Author
    schema.json
    .
    Build the JSON Schema from the widget spec. Fields live one level deep under an
    attributes
    wrapper:
    json
    {
      "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 | ...>"
            }
          }
        }
      }
    }
    Required root keys:
    title
    ,
    type: "object"
    ,
    properties.attributes
    (with
    lightning:type: "lightning__objectType"
    and a nested
    properties
    map). See
    references/schema-from-lightning-type.md
    for full primitive type guidance.
  7. Author
    <widgetName>.uiwidget-meta.xml
    .
    See
    references/widget-bundle-layout.md
    for the exact shape.
  8. Resolve
    <pkgDir>
    and write the bundle.
    Follow the procedure in
    references/widget-bundle-layout.md
    (
    ## Resolving <pkgDir>
    ). A widget bundle is a three-file set — all three files must be written in the same step; a bundle with fewer than three files is incomplete and will not deploy.
    text
    <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
    Each file has a distinct role:
    • <widgetName>.json
      — the widget envelope with the
      tile/widget
      UEM tree. This is the primary artifact;
      schema.json
      is its companion contract, not a substitute.
    • schema.json
      — the JSON Schema for the attributes referenced by
      {!$attrs.X}
      bindings in the envelope.
    • <widgetName>.uiwidget-meta.xml
      — the
      UiWidgetBundle
      element that registers the bundle for source tracking and deployment.
    Write all three before proceeding to self-validation.
  9. Self-validate. Before reporting, confirm each check below and report each result individually (
    pass
    or
    fail (<reason>)
    ). Do not summarize as a single "all passed" line — list every check so a reviewer can spot a silent skip.
    • schema-parses
      <pkgDir>/uiWidgets/<widgetName>/schema.json
      parses as JSON.
    • schema-root-keys
      — root has
      title
      (string),
      type: "object"
      , and
      properties.attributes
      (object) — where
      properties.attributes
      carries
      lightning:type: "lightning__objectType"
      and a nested
      properties
      map. No
      unevaluatedProperties: false
      .
    • schema-leaf-types
      — every leaf under
      properties.attributes.properties
      carries a
      lightning:type
      . Singular nested inner-class fields appear as
      lightning__objectType
      ; the nested shape is not redeclared.
    • bindings-resolve
      — every
      {!$attrs.X}
      (or
      {!$attrs.<outerField>.<innerField>}
      for nested objects) in
      <widgetName>.json
      resolves to a property under
      schema.json
      properties.attributes.properties
      , and every
      {!$item.X}
      resolves to a
      forItem
      loop variable defined upstream.
    • body-envelope
      <widgetName>.json
      root has
      type: "lightning__agentforceWidget"
      and a
      contentBody
      object whose
      widgetBody
      carries the UEM tree rooted at
      tile/widget
      . No node in the tree — root or non-root — carries a
      type
      key.
    • metaxml-wellformed
      <widgetName>.uiwidget-meta.xml
      parses as well-formed XML.
    • metaxml-elements
      <widgetName>.uiwidget-meta.xml
      has root
      <UiWidgetBundle>
      and contains
      <masterLabel>
      (non-empty),
      <description>
      (non-empty), and
      <widgetType>JSON</widgetType>
      .
    • files-present
      — all three files exist at the resolved
      <pkgDir>/uiWidgets/<widgetName>/
      path.

  1. 解析widget规格——生成有序的
    { name, type, required }
    列表。来源取决于提供的输入(请参阅输入参数):
    • 如果编排器传入了
      lightningTypeSchema
      → 根据
      references/schema-from-lightning-type.md
      推导。
    • 否则 → 直接从用户提示中推断列表(粘贴的JSON负载、枚举字段列表或描述性文本)。
  2. 发现块组件(必填——请勿跳过)。 通过
    execute_metadata_action
    调用
    discoverUiComponents
    元数据操作。使用widget规格中的属性类型作为
    searchQuery
    的种子(文本类型→
    "text"
    ,数字类型→
    "number"
    )。如果
    discoverUiComponents
    返回
    success: false
    、错误或空列表,请停止操作并直接显示错误信息——不要凭记忆、之前的运行记录或训练数据随意编造块名称。仅当失败是由搜索查询引起时,才使用不同的
    searchQuery
    重新运行发现操作。
  3. 选择块组件。 为widget规格中的每个属性选择一个块组件,再加上布局最佳实践中的结构基础组件。
  4. 获取块组件Schema(必填——请勿跳过)。 通过
    execute_metadata_action
    为所选块组件调用
    getUiComponentSchemas
    元数据操作。查看属性元数据。如果
    componentSchemas
    返回全失败或空列表,请停止操作并显示错误信息——不要从项目中现有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
    一个规格可能匹配多个模式(例如,包含条件渲染项的列表需要同时读取
    list-with-foreach.json
    conditional.json
    )。请阅读所有匹配的示例,且仅读取这些示例——不要因为觉得模式熟悉而跳过读取步骤。
    然后:
    • 将每个widget规格属性映射到块属性;保留规格中的顺序。
    • 决定根迭代方式: 单个对象→属性直接放在根
      tile/column
      下。集合→将重复块包装在
      forEach
      /
      forItem
      中。请参阅
      references/widget-meta-directives.md
    • 使用
      {!$attrs.X}
      (或在
      forEach
      内使用
      {!$item.X}
      )绑定值。
    • 对于条件块,在
      meta
      中添加
      "if"
      ——仅当Schema中存在匹配的
      lightning__booleanType
      属性时才添加。
  6. 编写
    schema.json
    根据widget规格构建JSON Schema。字段位于
    attributes
    包装器下的一级目录中:
    json
    {
      "title": "<Widget显示名称>",
      "description": "<关于此widget展示内容的一行描述>",
      "type": "object",
      "properties": {
        "attributes": {
          "lightning:type": "lightning__objectType",
          "properties": {
            "<propertyName>": {
              "title": "<标签>",
              "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不完整,无法部署。
    text
    <pkgDir>/uiWidgets/<widgetName>/<widgetName>.json               # Widget信封——UEM树(核心产物)
    <pkgDir>/uiWidgets/<widgetName>/schema.json                     # 信封的属性契约
    <pkgDir>/uiWidgets/<widgetName>/<widgetName>.uiwidget-meta.xml  # UiWidgetBundle注册文件
    每个文件都有明确的作用:
    • <widgetName>.json
      ——包含
      tile/widget
      UEM树的Widget信封。这是核心产物;
      schema.json
      是其配套契约,而非替代品。
    • schema.json
      ——信封中
      {!$attrs.X}
      绑定引用的属性对应的JSON Schema。
    • <widgetName>.uiwidget-meta.xml
      ——用于注册bundle以进行源跟踪和部署的
      UiWidgetBundle
      元素。
    在进行自验证之前,请写入所有三个文件。
  9. 自验证。 在提交结果之前,请确认以下每项检查,并单独报告结果(
    pass
    fail (<原因>)
    )。请勿总结为单一的“全部通过”——列出每项检查,以便审核者发现遗漏的步骤。
    • schema-parses
      ——
      <pkgDir>/uiWidgets/<widgetName>/schema.json
      可解析为JSON。
    • schema-root-keys
      ——根节点包含
      title
      (字符串)、
      type: "object"
      properties.attributes
      (对象)——其中
      properties.attributes
      包含
      lightning:type: "lightning__objectType"
      和嵌套的
      properties
      映射。无
      unevaluatedProperties: false
    • schema-leaf-types
      ——
      properties.attributes.properties
      下的每个叶子节点都包含
      lightning:type
      。单个嵌套内部类字段显示为
      lightning__objectType
      ;不重新声明嵌套结构。
    • bindings-resolve
      ——
      <widgetName>.json
      中的每个
      {!$attrs.X}
      (或嵌套对象的
      {!$attrs.<outerField>.<innerField>}
      )都能解析到
      schema.json
      properties.attributes.properties
      下的属性,且每个
      {!$item.X}
      都能解析到上游定义的
      forItem
      循环变量。
    • body-envelope
      ——
      <widgetName>.json
      根节点包含
      type: "lightning__agentforceWidget"
      contentBody
      对象,其中
      widgetBody
      包含以
      tile/widget
      为根的UEM树。树中的所有节点(根节点和非根节点)均不包含
      type
      键。
    • metaxml-wellformed
      ——
      <widgetName>.uiwidget-meta.xml
      可解析为格式良好的XML。
    • metaxml-elements
      ——
      <widgetName>.uiwidget-meta.xml
      的根节点为
      <UiWidgetBundle>
      ,且包含非空的
      <masterLabel>
      、非空的
      <description>
      <widgetType>JSON</widgetType>
    • files-present
      ——所有三个文件都存在于解析后的
      <pkgDir>/uiWidgets/<widgetName>/
      路径下。

Rules / Constraints

规则/约束

ConstraintRationale
Block definitions follow
{namespace}/{blockName}
and must match
discoverUiComponents
output
Runtime resolves blocks by exact definition string
Never pass
tile/widget
to
getUiComponentSchemas
It is a fixed wrapper, not a queryable component
Always supply
parameters
(with required keys) when calling
execute_metadata_action
Missing parameters cause hard failure, not partial result
Every
{!$attrs.X}
in the body resolves to a property in the widget
schema.json
No invented fields
No
$(…)
, backticks,
<(…)
, brace expansion
{a,b,c}
, or
eval
/
exec
in any Bash tool call
Vibes' safe-shell filter forces manual approval on these patterns even in Bypass mode. Emit separate commands (
mkdir -p a && mkdir -p b
) or print each value with its own command and reason about the output — do not capture into a shell variable

约束理由
块定义遵循
{namespace}/{blockName}
格式,且必须与
discoverUiComponents
的输出匹配
运行时通过精确的定义字符串解析块组件
请勿将
tile/widget
传入
getUiComponentSchemas
它是固定的包装器,并非可查询的组件
调用
execute_metadata_action
时始终提供
parameters
(包含必填键)
参数缺失会导致彻底失败,而非部分结果
主体中的每个
{!$attrs.X}
都能解析到widget
schema.json
中的属性
禁止使用虚构字段
在任何Bash工具调用中,禁止使用
$(…)
, 反引号,
<(…)
, 大括号扩展
{a,b,c}
eval
/
exec
Vibes的安全shell过滤器即使在绕过模式下,也会对这些模式强制要求手动审批。请发出单独的命令(如
mkdir -p a && mkdir -p b
),或使用单独的命令打印每个值并分析输出——不要捕获到shell变量中

Gotchas

常见问题

IssueResolution
getUiComponentSchemas
returns a partial-failure entry
Pick a different block from
discoverUiComponents
; do not silently continue without a schema
Body references
{!$attrs.foo}
but
foo
is not under
schema.json
properties.attributes.properties
Add
foo
to
schema.json
properties.attributes.properties
OR remove the body reference
Output written outside
<pkgDir>/uiWidgets/<widgetName>/
<pkgDir>
=
<packageDirectories[].path>/main/default
(see
references/widget-bundle-layout.md
). Dropping the
main/default/
segment is the common cause of widgets landing at
force-app/uiWidgets/...
instead of
force-app/main/default/uiWidgets/...
if
bound to a non-boolean
Use
if
only when the schema has a
lightning__booleanType
property

问题解决方案
getUiComponentSchemas
返回部分失败条目
discoverUiComponents
中选择其他块组件;不要在没有Schema的情况下继续操作
主体引用了
{!$attrs.foo}
foo
不在
schema.json
properties.attributes.properties
foo
添加到
schema.json
properties.attributes.properties
中,或移除主体中的引用
输出写入到
<pkgDir>/uiWidgets/<widgetName>/
之外的路径
<pkgDir>
=
<packageDirectories[].path>/main/default
(请参阅
references/widget-bundle-layout.md
)。常见错误是遗漏
main/default/
段,导致widget被写入到
force-app/uiWidgets/...
而非
force-app/main/default/uiWidgets/...
if
绑定到非布尔值
仅当Schema中存在
lightning__booleanType
属性时才使用
if

Reference File Index

参考文件索引

FileWhen to read
references/widget-meta-directives.md
For
forEach
/
forItem
(iteration) and
if
(conditional rendering), including nested loops
references/schema-from-lightning-type.md
When
lightningTypeSchema
is provided; how to derive the widget
schema.json
from an Apex-backed Lightning Type
references/widget-bundle-layout.md
Folder layout,
-meta.xml
shape,
<pkgDir>
resolution rules
examples/single-object.json
Single-object pattern (root binding via
{!$attrs.X}
, no iteration)
examples/list-with-foreach.json
Any list-iteration case — root-level collections, nested lists, and lists embedded inside a single-object widget (e.g. iterating a
List<InnerClass>
inside an outer Apex payload)
examples/conditional.json
Conditional pattern (
if
on
meta
, including
if
+
forEach
together)
文件阅读场景
references/widget-meta-directives.md
涉及
forEach
/
forItem
(迭代)和
if
(条件渲染)时,包括嵌套循环
references/schema-from-lightning-type.md
当提供
lightningTypeSchema
时;如何从Apex-backed Lightning Type推导widget的
schema.json
references/widget-bundle-layout.md
文件夹布局、
-meta.xml
结构、
<pkgDir>
解析规则
examples/single-object.json
单个对象模式(通过
{!$attrs.X}
进行根绑定,无迭代)
examples/list-with-foreach.json
任何列表迭代场景——根级集合、嵌套列表,以及嵌入在单个对象widget中的列表(例如,迭代外部Apex负载中的
List<InnerClass>
examples/conditional.json
条件模式(
meta
中的
if
,包括
if
+
forEach
组合场景)