@salesforce/afv-skills 1.55.0 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-generate/SKILL.md +8 -0
  3. package/skills/agentforce-generate/references/actions-reference.md +2 -2
  4. package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
  5. package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
  6. package/skills/agentforce-observe/SKILL.md +13 -9
  7. package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
  8. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
  9. package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
  10. package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
  11. package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
  12. package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
  13. package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
  14. package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
  15. package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
  16. package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
  17. package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
  18. package/skills/commerce-b2b-open-code-components-integrate/SKILL.md +1 -1
  19. package/skills/commerce-b2b-open-code-components-replace/SKILL.md +16 -16
  20. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
  21. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
  22. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
  23. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
  24. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
  25. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
  26. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
  27. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
  28. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
  29. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
  30. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
  31. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
  32. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
  33. package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
  34. package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
  35. package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
  36. package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
  37. package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
  38. package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
  39. package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
  40. package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
  41. package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
  42. package/skills/dx-devops-project-manage/SKILL.md +1 -1
  43. package/skills/dx-org-analyze/SKILL.md +0 -1
  44. package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
  45. package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
  46. package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
  47. package/skills/dx-org-manage/SKILL.md +6 -50
  48. package/skills/dx-org-manage/examples/README.md +10 -16
  49. package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
  50. package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
  51. package/skills/dx-org-shape-manage/SKILL.md +4 -3
  52. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
  53. package/skills/experience-accessibility-validate/SKILL.md +8 -5
  54. package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
  55. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
  56. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
  57. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
  58. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
  59. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
  60. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
  61. package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
  62. package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
  63. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
  64. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
  65. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
  66. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
  67. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
  68. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
  69. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
  70. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
  71. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
  72. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
  73. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
  74. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
  75. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
  76. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
  77. package/skills/experience-cms-content-generate/SKILL.md +1 -1
  78. package/skills/experience-cms-content-render/SKILL.md +3 -3
  79. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +35 -7
  80. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +13 -4
  81. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +30 -8
  82. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +14 -4
  83. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +11 -1
  84. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +1 -1
  85. package/skills/experience-cms-content-render/assets/shared/mediaLabels.ts +62 -0
  86. package/skills/experience-cms-content-render/references/init-scaffold.md +13 -6
  87. package/skills/experience-content-media-stock-image-search/SKILL.md +0 -1
  88. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
  89. package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
  90. package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
  91. package/skills/experience-lwc-design-generate/SKILL.md +1 -1
  92. package/skills/experience-lwc-legacy-migrate/SKILL.md +212 -0
  93. package/skills/experience-lwc-legacy-migrate/assets/lo20-host-page-template.html +192 -0
  94. package/skills/experience-lwc-legacy-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
  95. package/skills/experience-lwc-legacy-migrate/references/lightning-out-2-system-reference.md +495 -0
  96. package/skills/experience-lwc-legacy-migrate/references/lightning-out-beta-to-2-migration.md +824 -0
  97. package/skills/experience-lwc-legacy-migrate/scripts/convert-lo-names.py +94 -0
  98. package/skills/experience-lwc-legacy-migrate/scripts/validate-lo20-page.py +133 -0
  99. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
  100. package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
  101. package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
  102. package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
  103. package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
  104. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
  105. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
  106. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
  107. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
  108. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
  109. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
  110. package/skills/experience-ui-bundle-project-generate/SKILL.md +1 -1
  111. package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
  112. package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
  113. package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
  114. package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
  115. package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
  116. package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
  117. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
  118. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
  119. package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
  120. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
  121. package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
  122. package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
  123. package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
  124. package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
  125. package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
  126. package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
  127. package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
  128. package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
  129. package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
  130. package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
  131. package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
  132. package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
  133. package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
  134. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
  135. package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
  136. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
  137. package/skills/integration-connectivity-connected-app-configure/SKILL.md +5 -5
  138. package/skills/integration-connectivity-generate/SKILL.md +10 -10
  139. package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +2 -2
  140. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
  141. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
  142. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
  143. package/skills/mobile-apps-create/SKILL.md +1 -1
  144. package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
  145. package/skills/platform-apex-test-generate/SKILL.md +1 -1
  146. package/skills/platform-apex-test-run/SKILL.md +1 -1
  147. package/skills/platform-custom-field-generate/SKILL.md +1 -1
  148. package/skills/platform-custom-lightning-type-generate/SKILL.md +1 -1
  149. package/skills/platform-custom-metadata-type-generate/SKILL.md +1 -1
  150. package/skills/platform-custom-object-generate/SKILL.md +1 -1
  151. package/skills/platform-custom-report-type-generate/SKILL.md +1 -1
  152. package/skills/platform-custom-setting-generate/SKILL.md +1 -1
  153. package/skills/platform-data-and-tooling-api-context-get/SKILL.md +1 -1
  154. package/skills/platform-data-manage/SKILL.md +10 -10
  155. package/skills/platform-flexipage-generate/SKILL.md +1 -1
  156. package/skills/platform-lightning-app-coordinate/SKILL.md +1 -1
  157. package/skills/platform-metadata-api-context-get/SKILL.md +1 -1
  158. package/skills/platform-metadata-retrieve/SKILL.md +1 -1
  159. package/skills/platform-permission-set-generate/SKILL.md +1 -1
  160. package/skills/platform-report-generate/SKILL.md +1 -1
  161. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +4 -4
  162. package/skills/platform-sandbox-configure/SKILL.md +108 -133
  163. package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
  164. package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
  165. package/skills/platform-sharing-owd-configure/SKILL.md +1 -1
  166. package/skills/platform-sharing-rules-generate/SKILL.md +1 -1
  167. package/skills/platform-soql-query/SKILL.md +1 -1
  168. package/skills/platform-value-set-generate/SKILL.md +1 -1
  169. package/skills/platform-widget-generate/SKILL.md +26 -18
  170. package/skills/platform-widget-generate/examples/formulas.json +191 -0
  171. package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
  172. package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
  173. package/skills/sales-call-scoring-configure/SKILL.md +318 -0
  174. package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
  175. package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
  176. package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
  177. package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
  178. package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
  179. package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
  180. package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
  181. package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
  182. package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
  183. package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
  184. package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
  185. package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
  186. package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
  187. package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
  188. package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
  189. package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
  190. package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
  191. package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
  192. package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
  193. package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
  194. package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
  195. package/skills/service-agentforce-human-escalation-configure/SKILL.md +4 -0
  196. package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +26 -6
  197. package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +5 -4
  198. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
  199. package/skills/service-de-channel-activate/SKILL.md +6 -5
  200. package/skills/service-de-channel-create/SKILL.md +3 -3
  201. package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
  202. package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
  203. package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
  204. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
  205. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
  206. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
  207. package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
  208. package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
  209. package/skills/service-de-waba-integrate/SKILL.md +2 -1
  210. package/skills/service-digital-engagement-deployment-configure/SKILL.md +2 -0
  211. package/skills/service-digital-engagement-deployment-configure/scripts/check-api-version.sh +29 -0
  212. package/skills/service-email-to-case-configure/SKILL.md +1 -1
  213. package/skills/service-helpagent-coordinate/SKILL.md +3 -2
  214. package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
  215. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
  216. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
  217. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
  218. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
  219. package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
  220. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
  221. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
  222. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
  223. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
  224. package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
  225. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
  226. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
  227. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
  228. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
  229. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
  230. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
  231. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
  232. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
  233. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
  234. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
  235. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
  236. package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
  237. package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
  238. package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
  239. package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
  240. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
  241. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
  242. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
  243. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
  244. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
  245. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
  246. package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
  247. package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
  248. package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
  249. package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
  250. package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
  251. package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
  252. package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
  253. package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
  254. package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
  255. package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
  256. package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
  257. package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
  258. package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
  259. package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
  260. package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
  261. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
  262. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
  263. package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
  264. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  265. package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
  266. package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
  267. package/skills/dx-org-manage/references/cli_flags.md +0 -67
  268. package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
  269. package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
  270. package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
  271. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
  272. package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
  273. /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
  274. /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
@@ -2,7 +2,7 @@
2
2
  name: platform-widget-generate
3
3
  description: "Use this skill to author a complete HXL WidgetBundle (UEM body + schema.json + -meta.xml). TRIGGER when: user asks for a widget, mosaic, fragment, card, or rich UI surface for any subject, domain, feature, or entity noun; the prompt names only an entity or data shape without invoking Lightning Types, CLTs, or Apex-backed types. DO NOT TRIGGER when: the prompt explicitly says 'Lightning Type', 'CLT', 'Custom Lightning Type', 'Apex-backed type', or references '@apexClassType/...' (use platform-lightning-type-widget-coordinate); authoring a custom-LWC renderer for a Custom Lightning Type (use platform-custom-lightning-type-generate); or editing only an LWC component."
4
4
  metadata:
5
- version: "1.3"
5
+ version: "1.4"
6
6
  domains: ["Platform", "Agentforce"]
7
7
  minApiVersion: "68.0"
8
8
  relatedSkills:
@@ -93,6 +93,7 @@ The first child of `tile/widget.children` SHOULD be a single `tile/column`. All
93
93
 
94
94
  - Bind a block property to runtime data with `{!$attrs.<attrName>}`. `<attrName>` MUST match a property name in `schema.json`.
95
95
  - Inside a `forEach`, reference the loop variable instead — e.g. `"text": "{!$item.name}"`. See `references/widget-meta-directives.md`.
96
+ - A binding may be a **formula expression** instead of a bare field reference. See `references/widget-formulas.md` for the full supported-function list, syntax, and gotchas.
96
97
 
97
98
  ---
98
99
 
@@ -180,15 +181,19 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
180
181
  |---|---|
181
182
  | Single object (no iteration) | `<skill-root>/examples/single-object.json` |
182
183
  | Any list iteration (root-level array, nested list, or list embedded in a single-object widget) | `<skill-root>/examples/list-with-foreach.json` |
183
- | Conditional rendering (`if` bound to a boolean) | `<skill-root>/examples/conditional.json` |
184
+ | Conditional rendering (`if` bound to a boolean or formula) | `<skill-root>/examples/conditional.json` |
185
+ | Computed values, text/number transforms, or `if` driven by a formula (not a bare boolean field) | `<skill-root>/examples/formulas.json` |
184
186
 
185
187
  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.**
186
188
 
189
+ **Before writing any formula**, read `references/widget-formulas.md` in full — it is the authoritative list of supported operators and functions; do not improvise a function name or operator that isn't documented there.
190
+
187
191
  Then:
188
192
  - Map each widget-spec property to a block property; preserve spec order.
189
193
  - **Decide root iteration:** single object → properties directly under root `tile/column`. Collection → wrap repeating block in `forEach`/`forItem`. See `references/widget-meta-directives.md`.
190
194
  - Bind values with `{!$attrs.X}` (or `{!$item.X}` inside `forEach`).
191
- - For conditional blocks, add `"if"` on `meta` — only when the schema has a matching `lightning__booleanType` property.
195
+ - For conditional blocks, add `"if"` on `meta` — either a bare `lightning__booleanType` property, or a formula expression that evaluates to boolean. See `references/widget-formulas.md`.
196
+ - **When the widget spec calls for a computed value** (a total, a derived label, a formatted string) rather than a raw field, express it as a formula inside `{!...}` per `references/widget-formulas.md` — do not invent a new schema property to hold a value that can be computed from existing ones.
192
197
 
193
198
  6. **Author `schema.json`.** Build the JSON Schema from the widget spec. Fields live one level deep under an `attributes` wrapper:
194
199
 
@@ -235,7 +240,8 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
235
240
  - **`schema-parses`** — `<pkgDir>/uiWidgets/<widgetName>/schema.json` parses as JSON.
236
241
  - **`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`.
237
242
  - **`schema-leaf-types`** — every leaf under `properties.attributes.properties` carries a `lightning:type`. Singular nested inner-class fields carry `lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`); the nested shape is not redeclared. `List<InnerClass>` fields carry `lightning:type: "lightning__listType"` with `items.lightning:type` set to the inner Apex class reference (`@apexClassType/<namespace>__<OuterClass>$<InnerClass>`), not a redeclared field map — see `references/schema-from-lightning-type.md`. **When the list has no Apex-backed type** (schema inferred from the prompt), `items.lightning:type: "lightning__objectType"` MUST carry an inline nested `properties` map for every item field the body binds via `{!$item.X}`.
238
- - **`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.
243
+ - **`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. This applies to `$attrs`/`$item` references **inside formula expressions** too.
244
+ - **`formulas-supported`** — every function name used inside a `{!...}` expression appears in the *Supported functions* list in `references/widget-formulas.md`.
239
245
  - **`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.
240
246
  - **`metaxml-wellformed`** — `<widgetName>.uiwidget-meta.xml` parses as well-formed XML.
241
247
  - **`metaxml-elements`** — `<widgetName>.uiwidget-meta.xml` has root `<UiWidgetBundle>` and contains `<masterLabel>` (non-empty), `<description>` (non-empty), and `<widgetType>JSON</widgetType>`.
@@ -259,24 +265,26 @@ Widgets express *intent*, not pixels. Each surface provides a default look and f
259
265
 
260
266
  ## Gotchas
261
267
 
262
- | Issue | Resolution |
263
- |---|---|
264
- | `getUiComponentSchemas` returns a partial-failure entry | Pick a different block from `discoverUiComponents`; do not silently continue without a schema |
265
- | 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 |
268
+ | Issue | Resolution |
269
+ |---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
270
+ | `getUiComponentSchemas` returns a partial-failure entry | Pick a different block from `discoverUiComponents`; do not silently continue without a schema |
271
+ | 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 |
266
272
  | 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/...` |
267
- | `if` bound to a non-boolean | Use `if` only when the schema has a `lightning__booleanType` property |
268
- | `tile/button` renders but does nothing when clicked | No `actions.click` entry was set — an action-less button renders disabled by design. Add one (see *Actions* above) |
269
- | Using `action/sendMessage` for pure navigation, or `action/openLink` when the agent should respond | `action/openLink` is synchronous and does not consume a turn; `action/sendMessage` is asynchronous and earns a fresh turn. Pick the one matching the intended UX |
273
+ | `if` bound directly to a raw string or number relies on truthiness and is unreliable | Bind to a `lightning__booleanType` property, or use a formula comparison that evaluates to boolean |
274
+ | `tile/button` renders but does nothing when clicked | No `actions.click` entry was set — an action-less button renders disabled by design. Add one (see *Actions* above) |
275
+ | Using `action/sendMessage` for pure navigation, or `action/openLink` when the agent should respond | `action/openLink` is synchronous and does not consume a turn; `action/sendMessage` is asynchronous and earns a fresh turn. Pick the one matching the intended UX |
270
276
 
271
277
  ---
272
278
 
273
279
  ## Reference File Index
274
280
 
275
- | File | When to read |
276
- |---|---|
277
- | `references/widget-meta-directives.md` | For `forEach` / `forItem` (iteration) and `if` (conditional rendering), including nested loops |
278
- | `references/schema-from-lightning-type.md` | When `lightningTypeSchema` is provided; how to derive the widget `schema.json` from an Apex-backed Lightning Type |
279
- | `references/widget-bundle-layout.md` | Folder layout, `-meta.xml` shape, `<pkgDir>` resolution rules |
280
- | `examples/single-object.json` | Single-object pattern (root binding via `{!$attrs.X}`, no iteration) |
281
+ | File | When to read |
282
+ |---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
283
+ | `references/widget-meta-directives.md` | For `forEach` / `forItem` (iteration) and `if` (conditional rendering), including nested loops |
284
+ | `references/schema-from-lightning-type.md` | When `lightningTypeSchema` is provided; how to derive the widget `schema.json` from an Apex-backed Lightning Type |
285
+ | `references/widget-bundle-layout.md` | Folder layout, `-meta.xml` shape, `<pkgDir>` resolution rules |
286
+ | `references/widget-formulas.md` | Supported formula functions and operators |
287
+ | `examples/single-object.json` | Single-object pattern (root binding via `{!$attrs.X}`, no iteration) |
281
288
  | `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) |
282
- | `examples/conditional.json` | Conditional pattern (`if` on `meta`, including `if` + `forEach` together) |
289
+ | `examples/conditional.json` | Conditional pattern (`if` on `meta`, including `if` + `forEach` together) |
290
+ | `examples/formulas.json` | Formula usage — text/arithmetic/date transforms, `IF`/`AND`/`NOT` driving both a `tile/text` and `meta.if` |
@@ -0,0 +1,191 @@
1
+ {
2
+ "type": "lightning__agentforceWidget",
3
+ "contentBody": {
4
+ "widgetBody": {
5
+ "definition": "tile/widget",
6
+ "children": [
7
+ {
8
+ "definition": "tile/column",
9
+ "attributes": { "gap": "md" },
10
+ "children": [
11
+
12
+ {
13
+ "definition": "tile/column",
14
+ "attributes": { "gap": "xs" },
15
+ "children": [
16
+ { "definition": "tile/text", "attributes": { "text": "1. Arithmetic operators", "variant": "h3" } },
17
+ { "definition": "tile/text", "attributes": { "text": "Base: ${!$attrs.price}" } },
18
+ { "definition": "tile/text", "attributes": { "text": "Discount: -${!$attrs.price * $attrs.discountPercentage / 100}" } },
19
+ { "definition": "tile/text", "attributes": { "text": "Tax: ${!$attrs.price * $attrs.taxRate}" } },
20
+ { "definition": "tile/text", "attributes": { "text": "Total: ${!$attrs.price * (1 + $attrs.taxRate) - ($attrs.price * $attrs.discountPercentage / 100)}", "variant": "h4", "color": "primary" } },
21
+ { "definition": "tile/text", "attributes": { "text": "Division: {!$attrs.price / $attrs.durationInMin} | Exponent: {!2 ^ 8}" } }
22
+ ]
23
+ },
24
+
25
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
26
+
27
+ {
28
+ "definition": "tile/column",
29
+ "attributes": { "gap": "xs" },
30
+ "children": [
31
+ { "definition": "tile/text", "attributes": { "text": "2. Comparison operators", "variant": "h3" } },
32
+ { "definition": "tile/text", "attributes": { "text": "Equal: {!IF($attrs.status = 'boarding', 'yes', 'no')} | Not equal: {!IF($attrs.status <> 'boarding', 'yes', 'no')}" } },
33
+ { "definition": "tile/text", "attributes": { "text": "Greater than: {!IF($attrs.price > 1000, 'yes', 'no')} | Less than: {!IF($attrs.price < 1000, 'yes', 'no')}" } },
34
+ { "definition": "tile/text", "attributes": { "text": ">= : {!IF($attrs.price >= 1250, 'yes', 'no')} | <= : {!IF($attrs.price <= 1250, 'yes', 'no')}" } }
35
+ ]
36
+ },
37
+
38
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
39
+
40
+ {
41
+ "definition": "tile/column",
42
+ "attributes": { "gap": "xs" },
43
+ "children": [
44
+ { "definition": "tile/text", "attributes": { "text": "3. Logical functions — IF / CASE / AND / OR / NOT", "variant": "h3" } },
45
+ { "definition": "tile/text", "attributes": { "text": "IF: {!IF($attrs.price > 1000, 'PREMIUM', 'standard')}" } },
46
+ { "definition": "tile/text", "attributes": { "text": "IF nested: {!IF($attrs.status = 'boarding', 'Now boarding!', IF($attrs.status = 'delayed', 'Delayed', 'Scheduled'))}" } },
47
+ { "definition": "tile/text", "attributes": { "text": "CASE: {!CASE($attrs.status, 'boarding', 'Now boarding', 'delayed', 'Please wait', 'cancelled', 'Refunded', 'On schedule')}" } },
48
+ { "definition": "tile/text", "attributes": { "text": "AND: {!IF(AND($attrs.isPriority, $attrs.price > 500), 'yes', 'no')}" } },
49
+ { "definition": "tile/text", "attributes": { "text": "OR: {!IF(OR($attrs.isPriority, $attrs.price > 5000), 'yes', 'no')}" } },
50
+ { "definition": "tile/text", "attributes": { "text": "NOT: {!IF(NOT($attrs.isPetAllowed), 'no pets', 'pets ok')}" } },
51
+ {
52
+ "definition": "tile/badge",
53
+ "attributes": {
54
+ "label": "{!IF($attrs.status = 'boarding', 'Boarding', IF($attrs.status = 'delayed', 'Delayed', 'Scheduled'))}",
55
+ "variant": "{!IF($attrs.status = 'boarding', 'info', IF($attrs.status = 'delayed', 'warning', 'secondary'))}"
56
+ }
57
+ }
58
+ ]
59
+ },
60
+
61
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
62
+
63
+ {
64
+ "definition": "tile/column",
65
+ "attributes": { "gap": "xs" },
66
+ "children": [
67
+ { "definition": "tile/text", "attributes": { "text": "4. Text functions", "variant": "h3" } },
68
+ { "definition": "tile/text", "attributes": { "text": "UPPER: {!UPPER($attrs.airline)} | LOWER: {!LOWER($attrs.airline)}" } },
69
+ { "definition": "tile/text", "attributes": { "text": "LEFT/RIGHT/MID: {!LEFT($attrs.airline, 3)} | {!RIGHT($attrs.airline, 4)} | {!MID($attrs.airline, 1, 3)}" } },
70
+ { "definition": "tile/text", "attributes": { "text": "LEN / TRIM / REVERSE: {!LEN($attrs.airline)} | [{!TRIM($attrs.notes)}] | {!REVERSE($attrs.flightId)}" } },
71
+ { "definition": "tile/text", "attributes": { "text": "SUBSTITUTE / FIND: {!SUBSTITUTE($attrs.airline, 'Indigo', 'IndiGo')} | {!FIND('IX', $attrs.flightId)}" } },
72
+ { "definition": "tile/text", "attributes": { "text": "LPAD / RPAD: [{!LPAD($attrs.flightId, 12, '.')}] | [{!RPAD($attrs.flightId, 12, '.')}]" } },
73
+ { "definition": "tile/text", "attributes": { "text": "TEXT / VALUE: {!TEXT($attrs.price)} | {!VALUE('42.5')}" } },
74
+ { "definition": "tile/text", "attributes": { "text": "CONTAINS / BEGINS: {!IF(CONTAINS($attrs.airline, 'Indi'), 'yes', 'no')} | {!IF(BEGINS($attrs.flightId, 'IX'), 'yes', 'no')}" } },
75
+ { "definition": "tile/text", "attributes": { "text": "Concat: {!$attrs.airline & ' — ' & $attrs.flightId}", "variant": "h4" } }
76
+ ]
77
+ },
78
+
79
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
80
+
81
+ {
82
+ "definition": "tile/column",
83
+ "attributes": { "gap": "xs" },
84
+ "children": [
85
+ { "definition": "tile/text", "attributes": { "text": "5. Math functions", "variant": "h3" } },
86
+ { "definition": "tile/text", "attributes": { "text": "MOD/MAX/MIN: {!MOD($attrs.price, 100)} | {!MAX($attrs.price, 2000)} | {!MIN($attrs.price, 2000)}" } },
87
+ { "definition": "tile/text", "attributes": { "text": "ROUND/ABS/SQRT: {!ROUND($attrs.discountPercentage, 1)} | {!ABS(-42.5)} | {!SQRT($attrs.durationInMin)}" } },
88
+ { "definition": "tile/text", "attributes": { "text": "CEILING/FLOOR: {!CEILING(4.2)} | {!FLOOR(4.8)}" } },
89
+ { "definition": "tile/text", "attributes": { "text": "MCEILING/MFLOOR: {!MCEILING(-4.2)} | {!MFLOOR(-4.8)}" } },
90
+ { "definition": "tile/text", "attributes": { "text": "LOG/EXP/LN: {!LOG(1000)} | {!EXP(1)} | {!LN(2.718281828)}" } }
91
+ ]
92
+ },
93
+
94
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
95
+
96
+ {
97
+ "definition": "tile/column",
98
+ "attributes": { "gap": "xs" },
99
+ "children": [
100
+ { "definition": "tile/text", "attributes": { "text": "6. Date & time functions", "variant": "h3" } },
101
+ { "definition": "tile/text", "attributes": { "text": "departureDate: {!$attrs.departureDate}" } },
102
+ { "definition": "tile/text", "attributes": { "text": "DAY/MONTH/YEAR: {!DAY(DATEVALUE($attrs.departureDate))} | {!MONTH(DATEVALUE($attrs.departureDate))} | {!YEAR(DATEVALUE($attrs.departureDate))}" } },
103
+ { "definition": "tile/text", "attributes": { "text": "WEEKDAY: {!WEEKDAY(DATEVALUE($attrs.departureDate))}" } },
104
+ { "definition": "tile/text", "attributes": { "text": "ADDMONTHS+3: {!ADDMONTHS(DATEVALUE($attrs.departureDate), 3)}" } },
105
+ { "definition": "tile/text", "attributes": { "text": "TODAY/NOW/TIMENOW: {!TODAY()} | {!NOW()} | {!TIMENOW()}" } },
106
+ { "definition": "tile/text", "attributes": { "text": "DATE(2026,12,31): {!DATE(2026,12,31)}" } },
107
+ { "definition": "tile/text", "attributes": { "text": "HOUR/MINUTE/SECOND/MILLISECOND from NOW: {!HOUR(NOW())} · {!MINUTE(NOW())} · {!SECOND(NOW())} · {!MILLISECOND(NOW())}" } }
108
+ ]
109
+ },
110
+
111
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
112
+
113
+ {
114
+ "definition": "tile/column",
115
+ "attributes": { "gap": "xs" },
116
+ "children": [
117
+ { "definition": "tile/text", "attributes": { "text": "7. Validation & encoding functions", "variant": "h3" } },
118
+ { "definition": "tile/text", "attributes": { "text": "ISNULL/ISBLANK: {!IF(ISNULL($attrs.notes), 'null', 'has-value')} | {!IF(ISBLANK($attrs.notes), 'blank', 'has-value')}" } },
119
+ { "definition": "tile/text", "attributes": { "text": "NULLVALUE/BLANKVALUE: {!NULLVALUE($attrs.notes, 'n/a')} | {!BLANKVALUE($attrs.notes, 'empty')}" } },
120
+ { "definition": "tile/text", "attributes": { "text": "HTMLENCODE: {!HTMLENCODE($attrs.airline & ' <b>tag</b>')}" } },
121
+ { "definition": "tile/text", "attributes": { "text": "JSENCODE: {!JSENCODE($attrs.airline & \"'quote\")}" } }
122
+ ]
123
+ },
124
+
125
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
126
+
127
+ {
128
+ "definition": "tile/column",
129
+ "attributes": { "gap": "xs" },
130
+ "children": [
131
+ { "definition": "tile/text", "attributes": { "text": "8. Pattern matching — ISNUMBER, REGEX", "variant": "h3" } },
132
+ { "definition": "tile/text", "attributes": { "text": "ISNUMBER '42.5': {!IF(ISNUMBER('42.5'), 'numeric', 'not-numeric')}" } },
133
+ { "definition": "tile/text", "attributes": { "text": "ISNUMBER 'abc': {!IF(ISNUMBER('abc'), 'numeric', 'not-numeric')}" } },
134
+ { "definition": "tile/text", "attributes": { "text": "REGEX flightId ^[A-Z]{2} [0-9]+$: {!IF(REGEX($attrs.flightId, '^[A-Z]{2} [0-9]+$'), 'match', 'no-match')}" } },
135
+ { "definition": "tile/text", "attributes": { "text": "REGEX airline ^[A-Za-z ]+$: {!IF(REGEX($attrs.airline, '^[A-Za-z ]+$'), 'match', 'no-match')}" } }
136
+ ]
137
+ },
138
+
139
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
140
+
141
+ {
142
+ "definition": "tile/column",
143
+ "meta": { "if": "{!AND($attrs.isPriority, $attrs.price > 500)}" },
144
+ "children": [
145
+ {
146
+ "definition": "tile/row",
147
+ "attributes": { "gap": "sm", "align": "center" },
148
+ "children": [
149
+ { "definition": "tile/icon", "attributes": { "name": "lightning", "color": "warning" } },
150
+ { "definition": "tile/text", "attributes": { "text": "9. Formula-driven meta.if: priority fare over $500 — expedited handling" } }
151
+ ]
152
+ }
153
+ ]
154
+ },
155
+
156
+ { "definition": "tile/spacer", "attributes": { "size": "sm" } },
157
+
158
+ {
159
+ "definition": "tile/column",
160
+ "meta": { "forEach": "{!$attrs.flights}", "forItem": "$flight" },
161
+ "attributes": { "gap": "xs" },
162
+ "children": [
163
+ { "definition": "tile/text", "attributes": { "text": "10. forEach + per-row formula", "variant": "h3" } },
164
+ {
165
+ "definition": "tile/row",
166
+ "attributes": { "justify": "between", "align": "center" },
167
+ "children": [
168
+ {
169
+ "definition": "tile/column",
170
+ "attributes": { "gap": "xs" },
171
+ "children": [
172
+ { "definition": "tile/text", "attributes": { "text": "{!$flight.airline} — {!$flight.flightId}", "variant": "h4" } },
173
+ { "definition": "tile/text", "attributes": { "text": "Total with tax: ${!$flight.price * (1 + $flight.taxRate)}", "color": "muted" } }
174
+ ]
175
+ },
176
+ {
177
+ "definition": "tile/badge",
178
+ "meta": { "if": "{!$flight.price > 1000}" },
179
+ "attributes": { "label": "PREMIUM", "variant": "primary" }
180
+ }
181
+ ]
182
+ }
183
+ ]
184
+ }
185
+
186
+ ]
187
+ }
188
+ ]
189
+ }
190
+ }
191
+ }
@@ -0,0 +1,123 @@
1
+ # Widget Formula Expressions
2
+
3
+ A formula expression can appear anywhere a `{!...}` binding is written — `attributes` values, string interpolation, and `meta.if`. Read this file when a widget needs formulas.
4
+
5
+ ---
6
+
7
+ ## Syntax
8
+
9
+ Every formula expression is wrapped in `{!...}`, similar to a plain binding:
10
+
11
+ ```text
12
+ {!FUNCTION($attrs.fieldName)}
13
+ ```
14
+
15
+ - **Field references inside a formula** use the same `$attrs.<path>` convention as plain bindings.
16
+ - Inside a `forEach`, use the loop variable instead of `$attrs` — e.g. `{!UPPER($item.property)}`. Formulas inside `forEach` evaluate once per iteration against the current loop item — not the whole array.
17
+ - Functions and operators are case-sensitive UPPERCASE.
18
+ - A formula can nest functions and mix functions with operators: `{!TEXT(ROUND($attrs.property, 2))}`, `{!LEFT($attrs.property, 5) & "..."}`.
19
+ - A formula-bearing attribute is still bound to schema properties the same way as a plain binding — every `$attrs.X` / `$item.X` referenced inside a formula must resolve to a real schema property or loop variable, per the `bindings-resolve` self-validation check.
20
+
21
+ ---
22
+
23
+ ## Supported functions and operators, by category
24
+
25
+ Only the operators/functions listed here are confirmed supported — do not invent variants.
26
+
27
+ ### 1. Arithmetic operators
28
+
29
+ | Operator | Meaning | Example |
30
+ |---|---|-------------------------------------|
31
+ | `+` | Add | `$attrs.operand1 + $attrs.operand2` |
32
+ | `-` | Subtract | `$attrs.operand1 - $attrs.operand2` |
33
+ | `*` | Multiply | `$attrs.operand1 * $attrs.operand2` |
34
+ | `/` | Divide | `$attrs.operand1 / $attrs.operand2` |
35
+ | `^` | Exponent | `$attrs.operand1 ^ $attrs.operand2` |
36
+
37
+ Standard precedence applies (`^` > `*`/`/` > `+`/`-`); parenthesize to be explicit, especially when combining multiple arithmetic operators.
38
+
39
+ ### 2. Comparison operators
40
+
41
+ Return `true`/`false`; commonly used inside `IF()` or `meta.if`.
42
+
43
+ | Operator | Meaning | Example |
44
+ |---|---|----------------------------------------|
45
+ | `=` | Equal | `$attrs.property = 'constantValue'` |
46
+ | `<>` | Not equal | `$attrs.property <> 'constantValue'` |
47
+ | `>` / `<` | Greater / less than | `$attrs.property > 1000` |
48
+ | `>=` / `<=` | Greater-or-equal / less-or-equal | `$attrs.property1 >= $attrs.property2` |
49
+
50
+ ### 3. Logical functions
51
+
52
+ | Function | Description | Example |
53
+ |---|---|------------------------------------------------------------------------------------------------------|
54
+ | `IF(cond, then, else)` | Conditional value; nests for multi-branch logic | `IF($attrs.property > value, 'result1', 'result2')` |
55
+ | `CASE(expr, val1, res1, val2, res2, ..., default)` | Multi-way match, cleaner than nested `IF` for 3+ branches | `CASE($attrs.property, 'value1', 'result1', 'value2', 'result2', 'value3', 'result3', 'defaultResult')` |
56
+ | `AND(...)` | All conditions true | `AND($attrs.property1, $attrs.property2 > value)` |
57
+ | `OR(...)` | Any condition true | `OR($attrs.property1, $attrs.property2 > value)` |
58
+ | `NOT(val)` | Negate a boolean | `NOT($attrs.property)` |
59
+ | `ISNULL(val)` | True if the value is null | `IF(ISNULL($attrs.property), 'null', 'has-value')` |
60
+ | `ISBLANK(val)` | True if null or empty string | `IF(ISBLANK($attrs.property), 'blank', 'has-value')` |
61
+
62
+ ### 4. Text functions
63
+
64
+ | Function | Description | Example |
65
+ |---|---|-----------------------------------------------------|
66
+ | `UPPER(str)` / `LOWER(str)` | Case conversion | `UPPER($attrs.property)` |
67
+ | `LEFT(str, n)` / `RIGHT(str, n)` | First/last `n` characters | `LEFT($attrs.property, 3)` |
68
+ | `MID(str, start, len)` | Substring, **1-based** start index (first character is position 1, not 0) | `MID($attrs.property, 1, 3)` |
69
+ | `LEN(val)` | Length of a string | `LEN($attrs.property)` |
70
+ | `TRIM(str)` | Strip leading/trailing whitespace | `TRIM($attrs.property)` |
71
+ | `REVERSE(str)` | Reverse a string | `REVERSE($attrs.property)` |
72
+ | `SUBSTITUTE(str, old, new)` | Replace all occurrences | `SUBSTITUTE($attrs.property, 'string1', 'string2')` |
73
+ | `FIND(search, str)` | 1-based index of `search` in `str`, or falsy if absent | `FIND('string', $attrs.property)` |
74
+ | `LPAD(str, len, pad)` / `RPAD(str, len, pad)` | Pad to a fixed width | `LPAD($attrs.property, 12, '.')` |
75
+ | `TEXT(val)` | Coerce a non-string value to text (commonly paired with `ROUND`) | `TEXT(ROUND($attrs.property, 2))` |
76
+ | `VALUE(str)` | Parse text to a number (inverse of `TEXT`) | `VALUE($attrs.property)` |
77
+ | `CONTAINS(str, sub)` | String contains substring — boolean, pair with `IF` | `CONTAINS($attrs.property, 'string')` |
78
+ | `BEGINS(str, prefix)` | String starts with — boolean, pair with `IF` | `BEGINS($attrs.property, 'string')` |
79
+ | `&` (operator) | Concatenate strings | `$attrs.property1 & ' — ' & $attrs.property2` |
80
+
81
+ ### 5. Math functions
82
+
83
+ | Function | Description | Example |
84
+ |---|---|------------------------------------------------|
85
+ | `MOD(num, div)` | Remainder | `MOD($attrs.fieldName, 100)` |
86
+ | `MAX(...)` / `MIN(...)` | Largest/smallest of the arguments | `MAX($attrs.fieldName, 2000)` |
87
+ | `ROUND(num, digits)` | Round to `digits` decimal places | `ROUND($attrs.fieldName, 1)` |
88
+ | `ABS(num)` | Absolute value | `ABS($attrs.fieldName)` |
89
+ | `SQRT(num)` | Square root | `SQRT($attrs.fieldName)` |
90
+ | `CEILING(num)` / `FLOOR(num)` | Round away from / toward zero on the *magnitude* | `CEILING($attrs.fieldName)`|
91
+ | `MCEILING(num)` / `MFLOOR(num)` | Round toward +∞ / −∞ ("mathematical" ceiling/floor) — matters for negative numbers | `MCEILING($attrs.fieldName)`, `MFLOOR($attrs.fieldName)`|
92
+ | `LOG(num)` / `EXP(num)` / `LN(num)` | Base-10 log, e^x, natural log | `LOG($attrs.fieldName)` |
93
+
94
+ ### 6. Date & time functions
95
+
96
+ | Function | Description | Example |
97
+ |---|---|-------------------------------------------------|
98
+ | `DATEVALUE(str)` / `DATETIMEVALUE(str)` / `TIMEVALUE(str)` | Parse a date/datetime/time string into a value | `DATEVALUE($attrs.fieldName)` |
99
+ | `DAY(date)` / `MONTH(date)` / `YEAR(date)` | Extract date components | `DAY(DATEVALUE($attrs.fieldName))` |
100
+ | `WEEKDAY(date)` | Day of week, `1`=Sunday … `7`=Saturday | `WEEKDAY(DATEVALUE($attrs.fieldName))` |
101
+ | `ADDMONTHS(date, n)` | Add `n` whole months to a date | `ADDMONTHS(DATEVALUE($attrs.fieldName), 3)` |
102
+ | `TODAY()` / `NOW()` / `TIMENOW()` | Current server date / datetime / time — no arguments | `TODAY()` |
103
+ | `DATE(year, month, day)` | Construct a date literal | `DATE(2026, 12, 31)` |
104
+ | `HOUR(dt)` / `MINUTE(dt)` / `SECOND(dt)` / `MILLISECOND(dt)` | Extract time components from a datetime | `HOUR(NOW())` |
105
+
106
+ A raw date/datetime **string** attribute (e.g. an ISO string from `$attrs`) must be parsed with `DATEVALUE`/`DATETIMEVALUE`/`TIMEVALUE` before date-math or extractor functions can operate on it.
107
+
108
+ ### 7. Validation & encoding functions
109
+
110
+ | Function | Description | Example |
111
+ |---|---|----------------------------------------------|
112
+ | `NULLVALUE(val, fallback)` | `fallback` only when `val` is null | `NULLVALUE($attrs.fieldName, 'fallback')` |
113
+ | `BLANKVALUE(val, fallback)` | `fallback` when `val` is null or an empty string | `BLANKVALUE($attrs.fieldName, 'fallback')` |
114
+ | `HTMLENCODE(str)` | Escape for literal HTML display — use on any text binding that must render literally rather than as markup | `HTMLENCODE($attrs.fieldName & ' <b>tag</b>')` |
115
+ | `JSENCODE(str)` | Escape for safe embedding in a JS-string context | `JSENCODE($attrs.fieldName & "'quote")` |
116
+
117
+ ### 8. Pattern matching functions
118
+
119
+ | Function | Description | Example |
120
+ |---|---|---|
121
+ | `ISNUMBER(val)` | True if the value parses as a number | `ISNUMBER($attrs.fieldName)` |
122
+ | `REGEX(str, pattern)` | True if `str` matches the regex `pattern` (standard regex string) | `REGEX($attrs.fieldName, '^[A-Z]{2} [0-9]+$')` |
123
+
@@ -1,4 +1,4 @@
1
- # Widget Meta Directives Reference
1
+ # Widget Meta Directives
2
2
 
3
3
  The `meta` object on a UEM block carries runtime directives for iteration (`forEach` / `forItem`) and conditional rendering (`if`). Read this file when a widget needs either.
4
4
 
@@ -79,8 +79,8 @@ The inner `forEach` references an array on the outer loop variable and uses a di
79
79
  ### Rules
80
80
 
81
81
  - Place `if` on the `meta` object of the block.
82
- - Use `if` only when the schema has a `lightning__booleanType` property suited to the condition. Bind directly to that property (or to a loop variable holding such a value). If no suitable boolean exists in the schema, do not use `if` — render the block unconditionally instead.
83
- - Do not lean on the truthiness of strings (`""` vs `"value"`), numbers (`0` vs `1`), or nullable fields — that may render today but is not guaranteed across surfaces. Comparisons, arithmetic, and string operations are not supported.
82
+ - `if` accepts either a bare `lightning__booleanType` property (or a loop variable holding one) OR a **formula expression** that evaluates to a boolean — comparisons (`{!$attrs.fieldName > 1000}`) and logical functions (`{!AND($attrs.fieldName1, $attrs.fieldName2 > 500)}`) are both valid. See `references/widget-formulas.md` for the full formula syntax and supported-function list.
83
+ - Do not lean on the truthiness of a raw string (`""` vs `"value"`) or number (`0` vs `1`) bound directly — that relies on implicit coercion and is unreliable. Bind to a real boolean property, or use an explicit formula comparison instead.
84
84
  - `if` may coexist with `forEach` on the same `meta`. `if` is evaluated first — if `false`, the loop is skipped entirely.
85
85
 
86
86
  ### Example — top-level boolean
@@ -126,5 +126,5 @@ The inner `forEach` references an array on the outer loop variable and uses a di
126
126
 
127
127
  | Issue | Resolution |
128
128
  |---|---|
129
- | `if` bound to a non-boolean (string or number) does not behave as expected | Use `if` only when the schema has a `lightning__booleanType` property; otherwise render the block unconditionally |
129
+ | `if` bound directly to a raw string or number relies on truthiness and is unreliable | Bind to a `lightning__booleanType` property, or use a formula comparison that evaluates to boolean — see `references/widget-formulas.md` |
130
130
  | Nested loops share the same `forItem` name | Pick distinct names (e.g. `$item` outer, `$line` inner) — there is no validation error on collision |