Skip to content

Commit 5d33d63

Browse files
feat: @W-22259678@ changes with clt ref to mosaic rendition guidance (#190)
* changes with clt ref to mosaic rendition * updated widget rendition guidance * removed new line characters from description. * added back version metadata
1 parent 597ec01 commit 5d33d63

2 files changed

Lines changed: 137 additions & 2 deletions

File tree

skills/generating-custom-lightning-type/SKILL.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: generating-custom-lightning-type
3-
description: "Use this skill when users need to create Custom Lightning Types (CLTs) for Einstein Agent actions or structured input/output schemas. Trigger when users mention CLT, Custom Lightning Types, JSON schemas for agents, type definitions, lightning__objectType, or editor/renderer configurations. This is complex - always use this skill for CLT work."
3+
description: "Use this skill when users need to create Custom Lightning Types (CLTs) for Einstein Agent actions or structured input/output schemas. Trigger when users mention CLT, Custom Lightning Types, Custom Lightning Types (CLTs) with widget/mosaic/fragment rendition/renderer, JSON schemas for agents, type definitions, lightning__objectType, or editor/renderer configurations. When widget renditions are requested, you MUST first read the widget-rendition.md reference file in this skill's references/ directory and follow its complete workflow. This is complex - always use this skill for CLT work."
44
metadata:
55
version: "1.0"
66
---
@@ -12,6 +12,7 @@ Use this skill when you need to:
1212
- Generate JSON Schema-based type definitions for Lightning Platform
1313
- Configure CLTs for Einstein Agent actions
1414
- Set up editor and renderer configurations for custom UI
15+
- Create CLTs with widget/mosaic/fragment rendition
1516
- Troubleshoot deployment errors related to Custom Lightning Types
1617

1718
## Specification
@@ -26,6 +27,7 @@ Custom Lightning Types (CLTs) are JSON Schema-based type definitions used by the
2627
- **Choose standard Lightning types** when the structure is simple and can be expressed with properties and supported primitive `lightning:type` identifiers.
2728
- **Choose Apex class types** (`@apexClassType/...`) when the structure already exists server-side and you want the Apex class to define the shape.
2829
- **Include editor/renderer config** only when you need custom UI behavior (custom LWC input/output components). Otherwise, omit.
30+
- **Widget rendition**: After `schema.json` is drafted, you **must read references/widget-rendition.md and follow the "Widget renderer pattern"** section below for complete guidance. Do NOT attempt widget generation without reading the reference file first.
2931

3032
## Critical Rules (Read First)
3133
- **Root object schemas MUST include**:
@@ -127,7 +129,7 @@ When strict validation is enabled (`unevaluatedProperties: false`), keep each pr
127129
- **Avoid known-invalid patterns**:
128130
- Do not use `es_property_editors/inputList`.
129131
- Do not use `itemSchema` attributes.
130-
4. **(Optional) Draft `renderer.json`** (only if custom UI is required)
132+
4. **(Optional) Draft `renderer.json`** (only if custom UI or mosaic rendition is required)
131133
- **Supported shape:** Top-level `renderer` object with `renderer.componentOverrides` and `renderer.layout`.
132134
- Top-level `renderer` object.
133135
- Use `renderer.componentOverrides` for component overrides.
@@ -138,6 +140,15 @@ When strict validation is enabled (`unevaluatedProperties: false`), keep each pr
138140
- Use `{!$attrs.<name>}` in attribute mappings when binding schema data to custom renderer component attributes.
139141
- **CRITICAL**: Attribute mappings like `{!$attrs.propertyName}` must reference properties that **actually exist** in your type schema. Referencing non-existent properties will fail validation.
140142
- **Type matching**: Attribute values must match the expected type for the component. For example, if a component expects a string attribute, passing an integer will fail validation.
143+
- **Widget renderer pattern** (for widget rendition):
144+
- **When to use:** Use this when users request "mosaic", "widget", "fragment", or "cross-platform rendering" for their CLT.
145+
- **Structure:** `renderer.componentOverrides["$"] = { "type": "mosaic", "definition": "tile/mosaic", "children": [ /* UEM tree of blocks and regions */ ] }`
146+
- **REQUIRED workflow:**
147+
- **STOP**: Do NOT attempt to create the widget renderer yourself.
148+
- **MANDATORY FIRST STEP**: You MUST fetch the reference file `references/widget-rendition.md` located in this skill's directory before proceeding.
149+
- Follow the complete workflow documented in `widget-rendition.md` using the generated CLT schema as the grounding schema.
150+
- The `widget-rendition.md` reference contains the full widget generation workflow: discovering UEM blocks via discoverUiComponents, calling getUiComponentSchemas, building the UEM tree, and writing renderer.json.
151+
- **Do not** attempt to generate widget rendition without first fetching the `widget-rendition.md` reference file.
141152
- **Property-level override pattern**:
142153
- `renderer.componentOverrides["<propertyName>"] = { "definition": "es_property_editors/outputText" | "es_property_editors/outputNumber" | "es_property_editors/outputImage" | ... }`. **Valid renderer components** (examples): `es_property_editors/outputText`, `es_property_editors/outputNumber`, `es_property_editors/outputImage`. Avoid input-style components in the renderer.
143154
- **Layout pattern for renderer**:
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Widget Generation Guide
2+
3+
## 📋 Overview
4+
Widgets are reusable pieces of UI similar to templates, with placeholders for actual data values. The purpose of this file is to assist developers in creating mosaic renditions for CLTs.
5+
6+
## 🎯 Purpose
7+
Widgets render data in a structured and unified way across various Salesforce experiences like Slack, Mobile, LEX etc.
8+
9+
## Schema Grounding
10+
Widget generation is **always schema-grounded** using a CLT's schema. The schema describes the data shape the widget should render. Extract property names, types, required vs optional, and nesting from the schema; then follow the full **Workflow** below, using this extracted structure to guide every step. Do not add or remove properties relative to the schema.
11+
12+
## ⚙️ Composition
13+
A widget is a UEM (Unified Experience Model) tree of blocks and regions. The widget you return must follow the Typescript interfaces below:
14+
15+
```ts
16+
interface BlockType {
17+
type: 'block'
18+
definition: string // {namespace}/{blockName}
19+
attributes?: Record<string, any>
20+
children?: (BlockType | RegionType)[]
21+
}
22+
23+
interface RegionType {
24+
type: 'region'
25+
name: string
26+
children: BlockType[]
27+
}
28+
```
29+
---
30+
31+
## 🔧 Available Metadata Actions
32+
33+
### When to Use Each Action
34+
35+
#### discoverUiComponents
36+
37+
**Purpose:** Discover the palette of available blocks that can be used in widget composition.
38+
39+
**Use for:** Finding available blocks before building your widget structure.
40+
41+
**Input Parameters:**
42+
- `actionName` (**required***): "discoverUiComponents"
43+
- `metadataType` (**required**): "FRAGMENT"
44+
- `parameters` (**required**): JSON object with the below fields
45+
- `pageType` (**required**): "FRAGMENT"
46+
- `pageContext` (optional): JSON object - not required for FRAGMENT type
47+
- `searchQuery` (optional): String to filter components by name or description
48+
49+
**Returns:** List of components with:
50+
- `definition`: Fully qualified name (e.g., "namespace/definiton")
51+
- `description`: Component description
52+
- `label`: Human-readable label
53+
- `attributes`: Optional attribute metadata
54+
55+
#### getUiComponentSchemas
56+
57+
**Purpose:** Get detailed JSON schemas for component configuration, including property types, required vs optional fields, and validation rules.
58+
59+
**Use for:** You know which components you want but need to understand their properties before adding them to your widget.
60+
61+
**Input Parameters:**
62+
- `actionName` (**required***): "getUiComponentSchemas"
63+
- `metadataType` (**required**): "FRAGMENT"
64+
- `parameters` (**required**): JSON object with the below fields
65+
- `pageType` (**required**): "FRAGMENT"
66+
- `componentDefinitions` (**required**): List of fully qualified names (e.g., ["namespace/definition"])
67+
- **CRITICAL**: NEVER include "tile/mosaic" in this list. "tile/mosaic" is a container component used in renderer.json structure and **should not** be passed to getUiComponentSchemas
68+
- `pageContext` (optional): JSON object - not required for FRAGMENT type
69+
- `includeKnowledge` (optional): Boolean, defaults to true - includes additional component-specific guidance
70+
71+
**Returns:**
72+
- `componentSchemas`: List of results (supports partial failures)
73+
- **Success entries**: Contains JSON schema with property definitions, types, constraints
74+
- **Failure entries**: Contains error message explaining why schema couldn't be retrieved
75+
- `$defs`: Schema definitions and references (if schema transformation applied)
76+
77+
**Key Feature:** Supports partial failures - if some components can't be found, you still get schemas for the successful ones.
78+
79+
---
80+
81+
## Attribute binding using placeholder syntax
82+
83+
- **Where to use:** When block properties must display or pass runtime data from the grounding schema, use the **Placeholder Syntax** below so that the runtime binds values into the widget. Check each block's schema (from `getUiComponentSchemas`) for the correct property name (e.g. `value`, `text`, `label`).
84+
- **Placeholder Syntax:** Use `{!$attrs.<attrName>}` as the placeholder for each block property that should receive data.
85+
`<attrName>` **must** match the property name from the grounding schema so that the runtime can resolve its value.
86+
Example: for a schema property `title`, set the block property to `{!$attrs.title}`.
87+
- **List / iterative data:** Only the children (list items) hold bound values; the parent list block does not. For each item inside a list (e.g. `tile/listItem`), use `{!$attrs.<listAttrName>.item}` so the runtime binds the current item. `<listAttrName>` MUST match the schema property name of the list. Example: for `icons`, use `"{!$attrs.icons.item}"` on the list item.
88+
89+
---
90+
91+
## 💡Workflow
92+
93+
1. **Schema Parsing**
94+
- Parse the schema and extract: property names, types, required vs optional, and nested structure. Use this as the **widget spec**.
95+
96+
2. **Discover Available Blocks** (**REQUIRED** - do NOT skip)
97+
- Use **discoverUiComponents metadata action** above to explore what blocks are available.
98+
- Use property types from the **widget spec** to inform `searchQuery` (e.g. text → "text", number → "number").
99+
100+
3. **Select Components**
101+
- Choose blocks that can represent each property in the **widget spec** from the results of step 2.
102+
103+
4. **Get Component Schemas** (**REQUIRED** - do NOT skip)
104+
- Use **getUiComponentSchemas metadata action** with the selected block definitions from step 3 and review block properties' metadata.
105+
106+
5. **Build Widget**
107+
- Construct the UEM tree. Map each property in the **widget spec** to block properties and preserve order of the **widget spec**.
108+
- For block properties that must show or pass runtime data, use the placeholder syntax (see **Attribute binding using placeholder syntax** above).
109+
- Use block properties from the schemas retrieved in step 4.
110+
111+
6. **Write output to CLT Bundle**
112+
- Always write to `lightningTypes/<TypeName>/lightningDesktopGenAi/renderer.json` (or the correct target subfolder for the product surface, e.g. `experienceBuilder/`, `lightningMobileGenAi/`, `enhancedWebChat/` when applicable).
113+
Check **required root override pattern** below -
114+
`renderer.componentOverrides["$"] = { "type": "mosaic", "definition": "tile/mosaic", "children": [ ... ] — array of UEM nodes - contains the widget UEM generated using the **Workflow** steps 1-5 above }`
115+
116+
---
117+
118+
## ⚠️ Important Notes
119+
120+
- **widget spec** includes both required and optional attributes - review carefully to ensure valid configuration.
121+
- When using **`execute_metadata_action`** tool, always supply **`parameters`** with the required fields above; missing `parameters` or required keys causes hard failures, not partial results.
122+
- Block definitions always follow the `{namespace}/{blockName}` convention.
123+
- Use the same definition format returned by `discoverUiComponents` when calling `getUiComponentSchemas`
124+
- Placeholder syntax for non-list properties is `{!$attrs.<attrName>}` and for list properties is `{!$attrs.<listAttrName>.item}`.

0 commit comments

Comments
 (0)