# WidgetBundle Layout The widget skill writes three files into one directory under the project's package directory. --- ## Folder layout ```text /uiWidgets// .json # widget envelope + UEM body schema.json # JSON Schema .uiwidget-meta.xml # UiWidgetBundle registration ``` `` is `camelCase` and matches the directory name and both `.json` / `.uiwidget-meta.xml` filenames exactly. --- ## Resolving `` `` resolves to `/main/default` — the SFDX source-format default, where `` is the `default: true` entry in `sfdx-project.json` (or the first entry if none is marked default). --- ## `.json` — Widget envelope + UEM body The envelope has exactly two top-level keys — `type` and `contentBody`. The UEM tree lives at `contentBody.widgetBody`. Display metadata (label / description) lives in `.uiwidget-meta.xml`, not in the envelope. ```json { "type": "lightning__agentforceWidget", "contentBody": { "widgetBody": { "definition": "tile/widget", "children": [ /* every block — root and non-root — carries "definition", optional "attributes", optional "meta", optional "children". No "type" key on any node. */ ] } } } ``` Envelope keys: - `type` — always `"lightning__agentforceWidget"`. - `contentBody.widgetBody` — the root UEM node; this is `tile/widget`. It carries `definition` and `children` only — no `type` key on the root, no `type` key on any child. Tree composition (everything inside `widgetBody.children`) is owned by `SKILL.md` *Composition*. No node — root or non-root — carries a `type` key. --- ## `schema.json` — Input contract JSON Schema describing what data the widget accepts at runtime. Fields are wrapped one level deep under `properties.attributes`. **Required root keys:** - `title` (string) — display name - `type` (string) — must equal `"object"` - `properties.attributes` (object) — must carry `lightning:type: "lightning__objectType"` and a nested `properties` map whose leaves each carry `lightning:type` **Optional root keys:** - `description` (string) **Each leaf under `properties.attributes.properties` MUST have `lightning:type`.** Optional per-leaf: `title`, `description`. Example: ```json { "title": "Order Summary Widget", "description": "Displays an order's id, customer, and total.", "type": "object", "properties": { "attributes": { "lightning:type": "lightning__objectType", "properties": { "orderId": { "title": "Order ID", "description": "Stable identifier shown in the header.", "lightning:type": "lightning__textType" }, "customer": { "title": "Customer", "description": "Display name of the customer on the order.", "lightning:type": "lightning__textType" }, "total": { "title": "Total", "description": "Order total in the order's currency.", "lightning:type": "lightning__numberType" } } } } } ``` `{!$attrs.X}` in the body resolves to `properties.attributes.properties.X` in the schema. --- ## `.uiwidget-meta.xml` — Registration ```xml JSON ``` Elements: - `` — required. Human-readable label shown in the runtime UI. Prefer title-case (e.g. `Account Summary Card`) — not the `camelCase` ``. - `` — required. One-line description of what the widget renders. Populates the display metadata previously carried in the envelope. - `` — required. Only the `JSON` variant is supported. The `FUNCTION` variant is out of scope. --- ## Validation reminders - Every `{!$attrs.X}` in `.json` MUST resolve to a property under `schema.json` `properties.attributes.properties` (or to a `forItem` loop variable defined upstream). - `.uiwidget-meta.xml` MUST parse as well-formed XML, have root element ``, and carry non-empty ``, ``, and `JSON` elements. - The three files MUST be co-located in the same `/` directory under `uiWidgets/`.