@salesforce/afv-skills 1.55.0 → 1.56.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 (220) 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/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
  19. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
  20. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
  21. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
  22. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
  23. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
  24. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
  25. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
  26. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
  27. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
  28. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
  29. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
  30. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
  31. package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
  32. package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
  33. package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
  34. package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
  35. package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
  36. package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
  37. package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
  38. package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
  39. package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
  40. package/skills/dx-org-analyze/SKILL.md +0 -1
  41. package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
  42. package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
  43. package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
  44. package/skills/dx-org-manage/SKILL.md +6 -50
  45. package/skills/dx-org-manage/examples/README.md +10 -16
  46. package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
  47. package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
  48. package/skills/dx-org-shape-manage/SKILL.md +4 -3
  49. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
  50. package/skills/experience-accessibility-validate/SKILL.md +8 -5
  51. package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
  52. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
  53. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
  54. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
  55. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
  56. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
  57. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
  58. package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
  59. package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
  60. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
  61. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
  62. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
  63. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
  64. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
  65. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
  66. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
  67. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
  68. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
  69. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
  70. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
  71. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
  72. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
  73. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
  74. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
  75. package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
  76. package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
  77. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
  78. package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
  79. package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
  80. package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
  81. package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
  82. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
  83. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
  84. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
  85. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
  86. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
  87. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
  88. package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
  89. package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
  90. package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
  91. package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
  92. package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
  93. package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
  94. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
  95. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
  96. package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
  97. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
  98. package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
  99. package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
  100. package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
  101. package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
  102. package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
  103. package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
  104. package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
  105. package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
  106. package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
  107. package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
  108. package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
  109. package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
  110. package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
  111. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
  112. package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
  113. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
  114. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
  115. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
  116. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
  117. package/skills/mobile-apps-create/SKILL.md +1 -1
  118. package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
  119. package/skills/platform-sandbox-configure/SKILL.md +108 -133
  120. package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
  121. package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
  122. package/skills/platform-widget-generate/SKILL.md +26 -18
  123. package/skills/platform-widget-generate/examples/formulas.json +191 -0
  124. package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
  125. package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
  126. package/skills/sales-call-scoring-configure/SKILL.md +318 -0
  127. package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
  128. package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
  129. package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
  130. package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
  131. package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
  132. package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
  133. package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
  134. package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
  135. package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
  136. package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
  137. package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
  138. package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
  139. package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
  140. package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
  141. package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
  142. package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
  143. package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
  144. package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
  145. package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
  146. package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
  147. package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
  148. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
  149. package/skills/service-de-channel-activate/SKILL.md +6 -5
  150. package/skills/service-de-channel-create/SKILL.md +3 -3
  151. package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
  152. package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
  153. package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
  154. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
  155. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
  156. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
  157. package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
  158. package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
  159. package/skills/service-helpagent-coordinate/SKILL.md +3 -2
  160. package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
  161. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
  162. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
  163. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
  164. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
  165. package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
  166. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
  167. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
  168. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
  169. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
  170. package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
  171. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
  172. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
  173. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
  174. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
  175. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
  176. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
  177. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
  178. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
  179. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
  180. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
  181. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
  182. package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
  183. package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
  184. package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
  185. package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
  186. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
  187. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
  188. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
  189. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
  190. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
  191. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
  192. package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
  193. package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
  194. package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
  195. package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
  196. package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
  197. package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
  198. package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
  199. package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
  200. package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
  201. package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
  202. package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
  203. package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
  204. package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
  205. package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
  206. package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
  207. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
  208. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
  209. package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
  210. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  211. package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
  212. package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
  213. package/skills/dx-org-manage/references/cli_flags.md +0 -67
  214. package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
  215. package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
  216. package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
  217. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
  218. package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
  219. /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
  220. /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
@@ -24,7 +24,7 @@ PERM_CATEGORIES = [
24
24
  ("Einstein/AI", ["einstein", "ai", "predict", "ml", "copilot", "agent"]),
25
25
  ("Service", ["service", "case", "knowledge", "chat", "messaging", "omni", "entitlement"]),
26
26
  ("Data", ["data", "record", "report", "dashboard", "analytics", "tableau"]),
27
- ("Trialforce", ["trial", "trialforce", "tso", "tmo", "signup", "template", "edition"]),
27
+ ("Trialforce", ["trialforce", "tso", "tmo", "signup", "template"]),
28
28
  ("Sales", ["sales", "opportunity", "lead", "forecast", "quote", "contract"]),
29
29
  ("Work/HR", ["work", "hr", "employee", "shift", "wellness"]),
30
30
  ]
@@ -32,8 +32,8 @@ PERM_CATEGORIES = [
32
32
  VALUE_CATEGORIES = [
33
33
  ("Identity", ["name", "edition", "org", "domain", "id", "type", "instance", "locale"]),
34
34
  ("Storage", ["storage", "file", "size", "space", "quota"]),
35
- ("Feature Limits", ["max", "limit", "count", "num", "enable"]),
36
- ("API", ["api", "call", "request", "bandwidth"]),
35
+ ("API", ["api", "request", "daily", "hourly", "concurrent", "streaming", "bulk"]),
36
+ ("Feature Limits", ["custom", "rule", "flow", "process", "workflow", "approval", "limit", "max"]),
37
37
  ]
38
38
 
39
39
 
@@ -84,23 +84,10 @@ def analyze_metadata(data):
84
84
  for mtype, items in sorted(components.items()):
85
85
  org_native = [c for c in items if not c.get("namespace")]
86
86
  namespaced = [c for c in items if c.get("namespace")]
87
- org_native_names = sorted(
88
- c.get("fullName") or c.get("name", "") for c in org_native
89
- )
90
- namespaced_by_ns = {}
91
- for c in namespaced:
92
- ns = c.get("namespace", "unknown")
93
- namespaced_by_ns.setdefault(ns, []).append(
94
- c.get("fullName") or c.get("name", "")
95
- )
96
- for ns in namespaced_by_ns:
97
- namespaced_by_ns[ns] = sorted(namespaced_by_ns[ns])
98
87
  by_type[mtype] = {
99
88
  "total": len(items),
100
89
  "org_native": len(org_native),
101
90
  "namespaced": len(namespaced),
102
- "org_native_names": org_native_names,
103
- "namespaced_by_ns": namespaced_by_ns,
104
91
  }
105
92
  total += len(org_native)
106
93
  namespaced_total += len(namespaced)
@@ -246,24 +233,6 @@ def render_markdown(data, meta, perms, vals, pkgs, lics, sys_perms, deep, label)
246
233
  lines.append(f"| **Total** | **{meta['total_org_native']}** | **{meta['total_namespaced']}** | **{meta['total_org_native'] + meta['total_namespaced']}** |")
247
234
  lines.append("")
248
235
 
249
- # Detailed metadata listing
250
- lines.append("---\n")
251
- lines.append("## Metadata Components by Type\n")
252
- for mtype, counts in sorted(meta["by_type"].items()):
253
- if counts["total"] == 0:
254
- continue
255
- lines.append(f"#### {mtype} ({counts['org_native']} org-native, {counts['namespaced']} namespaced)\n")
256
- if counts["org_native_names"]:
257
- lines.append(f"**Org-native ({counts['org_native']}):** " +
258
- ", ".join(f"`{n}`" for n in counts["org_native_names"]))
259
- lines.append("")
260
- if counts["namespaced_by_ns"]:
261
- for ns, names in sorted(counts["namespaced_by_ns"].items()):
262
- lines.append(f"**Namespaced — `{ns}` ({len(names)}):** " +
263
- ", ".join(f"`{n}`" for n in names))
264
- lines.append("")
265
- lines.append("")
266
-
267
236
  # Installed packages
268
237
  lines.append("---\n")
269
238
  lines.append("## Installed Packages\n")
@@ -314,12 +283,7 @@ def render_markdown(data, meta, perms, vals, pkgs, lics, sys_perms, deep, label)
314
283
  lines.append("| " + " | ".join(keys) + " |")
315
284
  lines.append("| " + " | ".join(["---"] * len(keys)) + " |")
316
285
  for item in info["items"]:
317
- vals_row = []
318
- for k in keys:
319
- v = item.get(k, "")
320
- if k in ("AllowedLicenses", "TotalLicenses") and v == -1:
321
- v = "-1 (unlimited)"
322
- vals_row.append(str(v))
286
+ vals_row = [str(item.get(k, "")) for k in keys]
323
287
  lines.append("| " + " | ".join(vals_row) + " |")
324
288
  else:
325
289
  for item in info["items"]:
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: dx-org-manage
3
- description: "INVOKE this skill to execute Salesforce org operations: create scratch orgs, list/display/resume/delete scratch orgs, create org snapshots, open orgs in browser. This skill EXECUTES operations immediately - it does NOT generate scripts or code files. ALWAYS invoke this skill (do not execute SF CLI commands directly) when user requests to: create a scratch org (from edition, definition file (.json), snapshot, or org shape), list/display/resume/delete scratch orgs, create an org snapshot, or open a Salesforce org. Trigger phrases include: 'create a snapshot', 'take a snapshot', 'create scratch org', 'new scratch org', 'spin up an org', 'create 5 scratch orgs', 'create org from snapshot', 'scratch-def.json', 'project-scratch-def.json', 'list scratch orgs', 'display org', 'delete scratch org', 'resume scratch org', 'open my Salesforce org', 'open org in browser'. Do NOT use for switching default org (use dx-org-switch) or deploying metadata (use platform-metadata-deploy)."
3
+ description: "Use to EXECUTE Salesforce org operations immediately via the sf CLI (this skill runs them, it does NOT generate scripts): create scratch orgs (from edition, definition file, snapshot, or org shape), list/display/resume/delete scratch orgs, open orgs in browser. Trigger: 'create scratch org', 'create org from snapshot', 'delete scratch org', 'open my org'. Do NOT use for switching the default org (use dx-org-switch), deploying metadata (use platform-metadata-deploy), or creating/checking/listing/deleting org snapshots (use dx-org-snapshot-manage)."
4
4
  metadata:
5
- version: "1.2"
5
+ version: "1.3"
6
6
  domains: ["Developer Experience"]
7
7
  minApiVersion: "60.0"
8
8
  relatedSkills:
@@ -19,7 +19,7 @@ metadata:
19
19
 
20
20
  **Tool constraint:** Use the Bash tool for all `sf` CLI commands. Always include `--json` for structured output. Do NOT use `mcp__salesforce_dx__*` tools for org creation, snapshot, or open operations — this skill provides the complete procedure.
21
21
 
22
- **Output artifacts for eval/testing:** ALWAYS write the command's JSON response to a file when an output directory is available. Do NOT ask the user what file to write — this skill defines the filenames. After executing the command: (1) if the user specified an output path (e.g. "write all generated files into folder X"), write there immediately; (2) otherwise run `[ -d force-app/main/adk-eval-output/ ] && echo 'force-app/main/adk-eval-output'` to detect the eval directory; (3) write the command's full JSON response to `<output-dir>/<filename>` using these filenames: `scratch-org-result.json` for org creation (for a batch of N orgs, `scratch-org-result-1.json` … `scratch-org-result-N.json`), `scratch-org-list-result.json` for list, `org-display-result.json` for display, `scratch-org-resume-result.json` for resume, `scratch-org-delete-result.json` for delete, or `snapshot-result.json` for snapshot creation. This is the generated output — write it without asking. (Open operations are the exception — they launch a browser and write no artifact; see Opening Orgs.)
22
+ **Output artifacts for eval/testing:** ALWAYS write the command's JSON response to a file when an output directory is available. Do NOT ask the user what file to write — this skill defines the filenames. After executing the command: (1) if the user specified an output path (e.g. "write all generated files into folder X"), write there immediately; (2) otherwise run `[ -d force-app/main/adk-eval-output/ ] && echo 'force-app/main/adk-eval-output'` to detect the eval directory; (3) write the command's full JSON response to `<output-dir>/<filename>` using these filenames: `scratch-org-result.json` for org creation (for a batch of N orgs, `scratch-org-result-1.json` … `scratch-org-result-N.json`), `scratch-org-list-result.json` for list, `org-display-result.json` for display, `scratch-org-resume-result.json` for resume, or `scratch-org-delete-result.json` for delete. This is the generated output — write it without asking. (Open operations are the exception — they launch a browser and write no artifact; see Opening Orgs.)
23
23
 
24
24
  ---
25
25
 
@@ -118,7 +118,7 @@ Write the extracted org-list entry (the resolved org record), NOT the raw creati
118
118
  - For the complete creation workflow (AUTO MODE, STATE A/B, batch, definition-file authoring) → load `references/scratch-org-create.md`; for list/display/resume/delete → load `references/scratch-org-operations.md`
119
119
  - For available features, settings, and definition file structure → load `references/definition_file_options.md`
120
120
  - For edition selection guidance and comparison → load `references/edition_types.md`
121
- - For snapshot workflow and post-creation usage → load `references/snapshot_usage.md`
121
+ - To create/check/list/delete the snapshot itself before referencing it here → use the `dx-org-snapshot-manage` skill
122
122
 
123
123
  ---
124
124
 
@@ -182,47 +182,6 @@ sf org delete scratch --target-org <alias> --no-prompt --json
182
182
 
183
183
  ---
184
184
 
185
- ## Creating Snapshots
186
-
187
- **REQUIRED steps — execute in order:**
188
-
189
- **Step 1. Get inputs:**
190
- - Source org: scratch org ID or alias (from user)
191
- - Snapshot name: unique name (from user)
192
- - Description: optional (from user)
193
-
194
- **Step 2. Determine Dev Hub:** resolve to a concrete value and pass it explicitly via `--target-dev-hub` in Step 3 (same order as scratch-org creation — never guess a name):
195
- 1. A Dev Hub the user named → use it verbatim.
196
- 2. Else the default: non-empty `result[0].value` from `sf config get target-dev-hub --json`.
197
- 3. Else the single authenticated Dev Hub — run **this exact all-bucket command** (do NOT hand-write a single-bucket filter, which misses hubs that land in `devHubs`/`nonScratchOrgs`):
198
- ```bash
199
- sf org list --json | jq -r '[.result.devHubs[]?, .result.nonScratchOrgs[]?, .result.other[]?, .result.sandboxes[]?, .result.scratchOrgs[]?] | map(select(.isDevHub == true).username) | unique | .[]'
200
- ```
201
- Exactly one → use it. Zero → **do NOT run the snapshot command at all**; advise `sf org login web --set-default-dev-hub` and stop. Two or more → ask the user which.
202
-
203
- Never fabricate a placeholder alias (e.g. `eval-target`, `my-dev-hub`) and never run the command with no `--target-dev-hub` flag — the CLI rejects a bad name with `NotADevHubError` and a missing default with `NoDefaultDevHubError`. If no hub resolves, that is a hard stop, not a value to guess.
204
-
205
- **Step 3. Execute:**
206
- ```bash
207
- sf org create snapshot --source-org <orgId-or-alias> --name <SnapshotName> --target-dev-hub <devHub> --json
208
- ```
209
-
210
- With description:
211
- ```bash
212
- sf org create snapshot --source-org <orgId-or-alias> --name <SnapshotName> --description "<desc>" --target-dev-hub <devHub> --json
213
- ```
214
-
215
- **Step 4. Report result:** Returns JSON with SnapshotId and Status. If an output directory is available (per the output artifacts rule above), write the JSON response to `<output-dir>/snapshot-result.json`.
216
-
217
- **Error handling:** surface the CLI's own error unchanged. For example:
218
- - "Snapshot name already exists" → use a different unique name
219
-
220
- **When you need more detail:**
221
- - For complete snapshot creation workflow and flag reference → load `references/creating-snapshot.md`
222
- - For CLI flag reference → load `references/cli_flags.md`
223
-
224
- ---
225
-
226
185
  ## Opening Orgs
227
186
 
228
187
  **REQUIRED steps — execute in order:**
@@ -264,11 +223,10 @@ Load these reference files for detailed guidance:
264
223
  | `references/scratch-org-operations.md` | Operating on existing orgs: list, display, resume, delete — plus shared lifecycle rules and troubleshooting |
265
224
  | `references/definition_file_options.md` | User needs to configure org features, settings, or advanced definition file options beyond basic org creation |
266
225
  | `references/edition_types.md` | User asks which edition to choose or needs to understand edition differences |
267
- | `references/snapshot_usage.md` | User wants to use snapshots in definition files or needs post-snapshot workflow guidance |
268
- | `references/cli_flags.md` | User needs complete snapshot CLI flag reference |
269
- | `references/creating-snapshot.md` | Troubleshooting snapshot creation failures or need detailed snapshot workflow |
270
226
  | `references/opening-org.md` | User needs to navigate to specific setup paths, open metadata files, or use advanced open flags |
271
227
 
228
+ To create/check/list/delete a snapshot itself (rather than just consuming one), use the `dx-org-snapshot-manage` skill.
229
+
272
230
  ## Example Files
273
231
 
274
232
  Example command outputs for testing and troubleshooting:
@@ -285,5 +243,3 @@ Example command outputs for testing and troubleshooting:
285
243
  | `examples/scratch-orgs/display_output.json` | `sf org display --json` output (wrapped, tokens redacted) |
286
244
  | `examples/scratch-orgs/resume_output.json` | `sf org resume scratch --json` output (completed org) |
287
245
  | `examples/scratch-orgs/delete_output.json` | `sf org delete scratch --json` output |
288
- | `examples/snapshots/success_output.json` | Successful snapshot creation |
289
- | `examples/snapshots/error_output.json` | Common snapshot error scenario (duplicate name) |
@@ -1,20 +1,21 @@
1
1
  # Examples Directory
2
2
 
3
- This directory contains example outputs for the three workflows supported by the `dx-org-manage` skill.
3
+ This directory contains example outputs for the workflows supported by the `dx-org-manage` skill.
4
+
5
+ Snapshot lifecycle examples (create/get/list/delete the snapshot itself) live in the `dx-org-snapshot-manage` skill's `examples/` directory — this skill only *consumes* an existing snapshot (see `success_snapshot.json` below).
4
6
 
5
7
  ## Structure
6
8
 
7
9
  ```text
8
10
  examples/
9
11
  ├── README.md # This file
10
- ├── scratch-orgs/ # Scratch org creation examples
11
- │ ├── success_definition_file.json
12
- │ ├── success_edition.json
13
- │ ├── error_no_devhub.json
14
- │ └── error_timeout.json
15
- └── snapshots/ # Snapshot creation examples
16
- ├── success_output.json
17
- └── error_output.json
12
+ └── scratch-orgs/ # Scratch org creation examples
13
+ ├── success_definition_file.json
14
+ ├── success_edition.json
15
+ ├── success_snapshot.json
16
+ ├── success_shape.json
17
+ ├── error_no_devhub.json
18
+ └── error_timeout.json
18
19
  ```
19
20
 
20
21
  ## scratch-orgs/
@@ -27,13 +28,6 @@ Examples of `sf org create scratch` command outputs for all four creation method
27
28
  - **error_no_devhub.json** - Error when Dev Hub not authenticated
28
29
  - **error_timeout.json** - Timeout error (exit code 69)
29
30
 
30
- ## snapshots/
31
-
32
- Examples of `sf org create snapshot` command outputs.
33
-
34
- - **success_output.json** - Successful snapshot creation
35
- - **error_output.json** - Common error scenario (duplicate snapshot name)
36
-
37
31
  ## Usage
38
32
 
39
33
  These examples help illustrate:
@@ -300,4 +300,4 @@ user-supplied name — the CLI auto-populates the org name.
300
300
  - `scratch-org-operations.md` — list, display, resume, delete
301
301
  - `definition_file_options.md` — features, settings, and definition-file schema
302
302
  - `edition_types.md` — edition selection and the CLI-flag-vs-definition-file format distinction
303
- - `snapshot_usage.md` — using snapshots in definition files and post-snapshot workflow
303
+ - `dx-org-snapshot-manage` skill — create/check/list/delete a snapshot before referencing it here; this file only covers consuming an existing, `Active` snapshot via `--snapshot`/the `snapshot` definition-file field
@@ -132,4 +132,4 @@ sf org delete scratch --target-org <alias> --no-prompt --json
132
132
  AUTO MODE, STATE A/B, batch create, and definition-file authoring
133
133
  - `definition_file_options.md` — features, settings, and definition-file schema
134
134
  - `edition_types.md` — edition selection and the CLI-flag-vs-definition-file format distinction
135
- - `snapshot_usage.md` — using snapshots in definition files and post-snapshot workflow
135
+ - `dx-org-snapshot-manage` skill — create/check/list/delete a snapshot before referencing it here; this file only covers consuming an existing, `Active` snapshot via `--snapshot`/the `snapshot` definition-file field
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: dx-org-shape-manage
3
- description: "ALWAYS USE THIS SKILL to create, list, or delete org shapes. An org shape is a captured baseline configuration (features, limits, edition, and Metadata API settings) of a source org, without its data or metadata. Use when the user asks to create/make/take an org shape, capture or replicate an org's configuration/edition/limits, list/show/view existing org shapes (including INACTIVE/superseded ones) or their IDs and status, or delete/remove org shapes for a source org. Requires a source org with Dev Hub and Org Shape for Scratch Orgs enabled. DO NOT TRIGGER for creating snapshots or scratch orgs (use dx-org-manage)."
3
+ description: "ALWAYS USE THIS SKILL to create, list, or delete org shapes. An org shape is a captured baseline configuration (features, limits, edition, and Metadata API settings) of a source org, without its data or metadata. Use when the user asks to create/make/take an org shape, capture or replicate an org's configuration/edition/limits, list/show/view existing org shapes (including INACTIVE/superseded ones) or their IDs and status, or delete/remove org shapes for a source org. Requires a source org with Dev Hub and Org Shape for Scratch Orgs enabled. DO NOT TRIGGER for creating/checking/listing/deleting snapshots (use dx-org-snapshot-manage) or for creating scratch orgs (use dx-org-manage)."
4
4
  metadata:
5
5
  version: "1.0"
6
6
  domains: ["Developer Experience"]
@@ -33,7 +33,7 @@ Coordinates the full lifecycle of Salesforce org shapes — **create**, **list**
33
33
  ## Scope
34
34
 
35
35
  - **In scope**: Creating (`sf org create shape`), listing (`sf org list shape`), listing including inactive shapes for a specific source org (SOQL against `ShapeRepresentation`), and deleting (`sf org delete shape`) org shapes
36
- - **Out of scope**: Creating snapshots, creating scratch orgs (use `dx-org-manage`)
36
+ - **Out of scope**: Creating/checking/listing/deleting snapshots (use `dx-org-snapshot-manage`), creating scratch orgs (use `dx-org-manage`)
37
37
 
38
38
  ---
39
39
 
@@ -136,7 +136,8 @@ See the example files referenced below for full response structures.
136
136
 
137
137
  | Need | Delegate to |
138
138
  |------|-------------|
139
- | Create a scratch org, or create/use a snapshot | `dx-org-manage` skill |
139
+ | Create a scratch org, or create/use a snapshot to make one | `dx-org-manage` skill |
140
+ | Create, check status of, list, or delete a snapshot itself | `dx-org-snapshot-manage` skill |
140
141
 
141
142
  ---
142
143
 
@@ -21,3 +21,4 @@ Lower-frequency gotchas and toggle-write failure classes, split out of `SKILL.md
21
21
  | **Failure class — settings type invisible to Tooling/EntityDefinition but still MDAPI-writable** (e.g. Omnistudio Metadata, `OmniStudioSettings`, `fullName: OmniStudio`) | Metadata PUT write succeeds, but no GET/verify path exists via Tooling API — UI-confirmed only; if you encounter one of these, note it as write-succeeds-zero-verify-path rather than assuming failure |
22
22
  | **Failure class — type-level UPDATE block** (e.g. Timeline `TimelineSettings`, Video Calls `VideoCallsSettings`) | PUT returns HTTP 400 `UNSUPPORTED_OPERATION: "MetadataCrud does not support UPDATE on type: X"` — block is on the whole type, no `fullName` variant fixes it; manual UI only |
23
23
  | **Pattern — org preference API, not `IndustriesSettings`** (confirmed on Einstein Generative AI, `EinsteinGPTCopilotEnabled`) | Some toggles are Setup-Connect org preferences, not `IndustriesSettings` metadata fields — no `type`/`fullName`/`xmlRep`. Shape: `GET /services/data/v68.0/setup/org/preferences/<PrefName>` → `{"isPreferenceEnabled": bool}`; `PATCH` same path with `{"desiredState": true}` → response echoes post-write state. If a metadata PUT returns `FIELD_INTEGRITY_EXCEPTION: invalid at this location` for a plausible-looking element name, the field may not be on `IndustriesSettings` at all — try this org-preference path next before assuming manual-UI-only |
24
+ | **Failure class — write-enabled `dispatch` MCP tool not connected/loaded** | Fall back to the `sf api request rest` CLI (via Bash) for the exact same READ/WRITE/cold-VERIFY calls before giving up to manual Setup UI — confirmed working in the same run where other datasets hit this identical MCP gap. Never report a toggle's state as "assumed default" or "pending admin confirmation" without trying this fallback first |
@@ -11,7 +11,7 @@ metadata:
11
11
  - "design-systems-slds-validate"
12
12
  - "experience-lwc-generate"
13
13
  ---
14
- <!-- adk-managed-skill -->
14
+ <!-- a11y-expert-managed-skill -->
15
15
 
16
16
  # Web Component Accessibility
17
17
 
@@ -47,16 +47,19 @@ Key Review Criteria:
47
47
  4. Component Library Usage
48
48
 
49
49
  - Assume that well-known component libraries (e.g., Salesforce Lightning, Material UI, Chakra UI) are accessible out of the box when correctly implemented. Unless they are used specifically in conflict with WCAG, library-provided components can be ignored for this review, as they are implemented in an accessible way beneath the abstraction.
50
+ - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, and similar components) provide accessible labeling, ARIA, and error handling through dedicated attributes such as `label` and `alternative-text`. A `label` remains programmatic even with `variant="label-hidden"`; do not require a sibling or wrapper `<label>` to target the component. Navigation, button-icon, and other self-labeling base components likewise expose supplied label text as their accessible name and treat their internal icon as decorative. Do not report a missing association merely because that implementation is hidden inside the component.
51
+ - The same self-labeling logic applies to **imported or custom control components in any framework** (React/JSX, Angular, Vue, Web Components), not only Lightning. A capitalized or imported component tag (`<Input>`, `<TextField>`, `<Button>`, `<Select>`, `<Checkbox>`, `<SearchField>`, and design-system wrappers from Material UI, Chakra, Radix, or an internal library) is **not** a bare HTML element — assume it renders its own accessible label, ARIA, and error handling beneath the abstraction (see the component-library grounding rule). When such a component is given a labeling prop — `label`, `aria-label`, `aria-labelledby`, `title`, or visible child text/`children` — treat it as already programmatically labeled and do **not** flag it for a missing `<label>`, a missing `for`/`id` association, or a missing accessible name. Only flag when **no** labeling prop or text is supplied, or the supplied value is clearly empty or nonsensical. Do not demand a native `<label for>` for a component whose internal control you cannot see.
52
+ - Resolve dynamic `id` / `htmlFor` / `for` expressions before judging a label association. When a `<label htmlFor={X}>` (or `for={X}`) and its control's `id={X}` are bound to the **same expression** — the same variable, prop, `useId()` value, or template literal (e.g. both `htmlFor` and `id` set to the same interpolation such as `${id}-email`) — treat the association as **matching**, even though the literal string cannot be resolved at review time. A dynamic `id`/`htmlFor` pair is a mismatch only when the two expressions are demonstrably different. Do **not** flag identical dynamic `id`/`htmlFor` expressions as unmatched or mismatched labels.
50
53
 
51
- **Focus**: Provide actionable feedback to ensure the component meets the necessary WCAG accessibility requirements, avoiding extraneous feedback unrelated to the prompt's scope. Identify issues in code only if there is an immediate fix. You MUST conduct the review, and subsequently suggest the code fix that solves this issue.
54
+ 5. Source Interpretation
52
55
 
56
+ - Resolve expressions according to the framework's binding semantics before judging them. Trace a dynamic value to every source available in that context. In React/JSX, an expression may reference local variables, props, hook results, or imported bindings; Vue, Svelte, and Astro expose their own template or script scopes. In an LWC template specifically, `{someValue}` resolves to a field, property, or getter on the component class (`.js` or `.ts`), including `@api` properties; module-level imported constants are not directly bindable. In Aura markup, follow the expression's value provider, such as `v.` or `c.`, to the corresponding component attribute or controller logic. Do not conclude that a value is undefined, empty, or missing until you have inspected the applicable source. In a diff, verify which side contains the corrected code rather than assuming that the change introduced the problem.
53
57
 
58
+ **Focus**: Provide actionable feedback to ensure the component meets the necessary WCAG accessibility requirements, avoiding extraneous feedback unrelated to the prompt's scope. Identify issues in code only if there is an immediate fix. You MUST conduct the review, and subsequently suggest the code fix that solves this issue.
54
59
 
55
60
  ## Success Criteria Reviewers
56
61
 
57
- Identify which Success Criteria apply to the code under review, then open the reference files relevant to that code. Each reference is a
58
- self-contained reviewer with analysis framework, examples, and remediation
59
- guidance.
62
+ Identify which Success Criteria apply to the code under review, then open the reference files relevant to that code. Each reference supplies criterion-specific analysis, examples, and remediation guidance; the review-wide rules above continue to apply.
60
63
 
61
64
  ### Perceivable
62
65
 
@@ -77,12 +77,9 @@ Rules to follow:
77
77
  - Flag missing or generic alt text on informative images
78
78
  - Flag overly descriptive alt text on clearly decorative images
79
79
  - Consider the context and purpose of each image
80
+ - **This reviewer covers `<img>` elements only.** Do **not** flag non-image content: an `aria-hidden="true"` `<span>`, icon-font glyph, emoji, or decorative `<svg>` is intentionally removed from the accessibility tree and is correctly handled — it is not an `<img>` missing alt text. A decorative `<span aria-hidden="true">` is correct, not a violation.
80
81
 
81
82
  - For each issue found, provide a separate, detailed report.
82
83
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
83
84
  - Assume that any imported functionality works as expected and was already analyzed.
84
85
  - Components do not supplement or provide global functionalities.
85
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
86
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
87
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
88
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
@@ -46,7 +46,3 @@ Rules to follow:
46
46
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
47
47
  - Assume that any imported functionality works as expected and was already analyzed.
48
48
  - Components do not supplement or provide global functionalities.
49
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
50
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
51
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
52
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
@@ -4,103 +4,38 @@ Information, structure, and relationships conveyed through presentation can be p
4
4
 
5
5
  ## SC: 1.3.1 (ii) - Tables Only
6
6
 
7
- Analyze the given files using the following framework:
7
+ For every `<table>` element in the source, apply the criteria below and produce one fix entry per violation. Other SC 1.3.1 concerns (lists, regions, form-labels, groups) are out of scope — they are owned by sibling reviewers.
8
8
 
9
- Review the provided HTML and JS files for accessibility violations per WCAG 2.2 SC 1.3.1 (ii), 'Tables'.
10
- (Only tables from this rule should be considered). For all tables on the components, ensure that any information conveyed through presentation is programmatically determinable in order to determine if they meet SC 1.3.1 (ii).
9
+ ### Structural criteria
11
10
 
12
- For each of these elements, check if any of the following conditions of WCAG 2.2 SC 1.3.1 (ii), 'Tables' are true:
11
+ For each `<table>`, verify:
13
12
 
14
- - The objective of this technique is to present tabular information in a way that preserves relationships within the information even when users cannot see the table or the presentation format is changed. Information is considered tabular when logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal). These relationships are represented in columns and rows, and the columns and rows must be recognizable in order for the logical relationships to be perceived.
15
- Check for the presence of tabular information.
16
- For each instance of the `<table>` element found, perform the following checks:
17
- - Verify the presence of table rows (`<tr>`): Ensure that each `<table>` element contains at least one `<tr>` element
18
- - Verify the presence of table data cells (`<td>`) within rows (`<tr>`): For each `<tr>` element within a `<table>`, confirm that it contains one or more `<td>` elements representing the data cells
19
- - Verify the presence of table header cells (`<th>`) when applicable: If the table includes headers, ensure that the header information is marked up using `<th>` elements, typically within the first `<tr>` element or within `<thead>` elements
20
- - Check that all data content within the table is enclosed within `<td>` cell elements and that header content (if present) is within `<th>` elements
21
- - For every `<table>` element identified, verify that it contains at least the following elements: `<tr>`, `<th>` (if headers are present, otherwise `<td>`), and `<td>`
22
- - Providing an accessible name for a table is considered a best practice that significantly enhances usability for all users, especially those relying on assistive technologies.The accessible name can be provided in various ways:
23
- - By either using a `aria-label` or `aria-labelledby` attributes or `<caption>` element in the table. Its a best practice and absence of accessible name is acceptable but not a violation.
24
- - The objective of this technique is to associate header cells with data cells in simple data tables using the `scope` attribute.
25
- - The `scope` attribute identifies whether the cell is a header for a row, column, or group of rows or columns
26
- - Valid `scope` values: `row`, `col`, `rowgroup`, `colgroup`
13
+ - Contains at least one `<tr>` element.
14
+ - Each `<tr>` contains one or more cells appropriate to its content: `<th>` for headers and `<td>` for data. A header-only row containing only `<th>` cells is valid.
15
+ - Header content (if present) is marked up with `<th>` (typically in the first `<tr>` or inside `<thead>`).
16
+ - All data content is inside `<td>` cells; all header content is inside `<th>` cells.
17
+ - The table is either a recognizable data table (`<tr>`, `<td>`, plus `<th>` when headers exist) or a layout table (no relationships across rows and columns).
27
18
 
28
- For simple data tables:
19
+ ### Header-association criteria
29
20
 
30
- - If headers are in the first row or column:
31
- - `th` elements without `scope` are sufficient
32
- - If headers are not in the first row or column:
33
- - Check that all `th` elements have a `scope` attribute
34
- - Verify `scope` values match the header's role (`row`/`col`/`rowgroup`/`colgroup`)
35
- Note: For complex tables (multiple levels of headers, headers spanning rows/columns), use id and headers attributes instead (see H43)
36
- - The objective of this technique is to associate each data cell (in a data table) with the appropriate headers.
37
- Check for layout tables and data tables:
38
- - For layout tables:
39
- - Determine if content has a relationship with other content in both its column and row
40
- - If "no", the table is a layout table
41
- - For data tables:
42
- - Check that any cell associated with multiple row/column headers contains a headers attribute listing all associated header IDs
43
- - For cells with id or headers attributes:
44
- - Verify each id in headers attribute matches a header element's id
45
- - Verify headers attribute contains all associated header IDs
46
- - Ensure all IDs are unique within the component
21
+ - **Simple data tables** with headers in the first row or column: `<th>` without `scope` is sufficient.
22
+ - **Simple data tables** with headers NOT in the first row or column: every `<th>` must carry a valid `scope` (`row` / `col` / `rowgroup` / `colgroup`) matching the header's role.
23
+ - **Irregular tables** with headers spanning rows or columns may use explicitly defined row or column groups with `scope="rowgroup"` or `scope="colgroup"`. Do not require `id` + `headers` solely because a table uses `rowspan`, `colspan`, or multiple header levels when groups and `scope` express the relationships.
24
+ - **Complex tables** whose data-cell relationships are too complex to identify using `<th>` alone or `<th>` with `scope` must provide programmatically determinable header-to-cell associations. Use `id` + `headers` attributes (see H43), or simplify the table so `<th>` and `scope` can express the relationships. Complex cases include tables whose headers repeat or change partway through the table or whose data cells are associated with three or more headers. When `id` + `headers` is used, verify that every `<th>` `id` is unique within the component and every id in a cell's `headers` attribute resolves to an actual `<th>`.
47
25
 
48
- In order to fix a violation for a given element, you must examine the given component code and apply the most logical fix available such that the element satisfies one of the following conditions of WCAG 2.2 SC 1.3.1 (ii), 'Tables':
26
+ ### Accessible-name criterion
49
27
 
50
- - The objective of this technique is to present tabular information in a way that preserves relationships within the information even when users cannot see the table or the presentation format is changed. Information is considered tabular when logical relationships among text, numbers, images, or other data exist in two dimensions (vertical and horizontal). These relationships are represented in columns and rows, and the columns and rows must be recognizable in order for the logical relationships to be perceived.
51
- Check for the presence of tabular information.
52
- For each instance of the `<table>` element found, perform the following checks:
53
- - Verify the presence of table rows (`<tr>`): Ensure that each `<table>` element contains at least one `<tr>` element
54
- - Verify the presence of table data cells (`<td>`) within rows (`<tr>`): For each `<tr>` element within a `<table>`, confirm that it contains one or more `<td>` elements representing the data cells
55
- - Verify the presence of table header cells (`<th>`) when applicable: If the table includes headers, ensure that the header information is marked up using `<th>` elements, typically within the first `<tr>` element or within `<thead>` elements
56
- - Check that all data content within the table is enclosed within `<td>` cell elements and that header content (if present) is within `<th>` elements
57
- - For every `<table>` element identified, verify that it contains at least the following elements: `<tr>`, `<th>` (if headers are present, otherwise `<td>`), and `<td>`
58
- - Providing an accessible name for a table is considered a best practice that significantly enhances usability for all users, especially those relying on assistive technologies.The accessible name can be provided in various ways:
59
- - By either using a `aria-label` or `aria-labelledby` attributes or `<caption>` element in the table. Its a best practice and absence of accessible name is acceptable but not a violation.
60
- - The objective of this technique is to associate header cells with data cells in simple data tables using the `scope` attribute.
61
- - The `scope` attribute identifies whether the cell is a header for a row, column, or group of rows or columns
62
- - Valid `scope` values: `row`, `col`, `rowgroup`, `colgroup`
28
+ Providing an accessible name (via `aria-label`, `aria-labelledby`, or `<caption>`) is a best practice but not a violation when absent. Do not produce a fix entry purely for a missing accessible name.
63
29
 
64
- For simple data tables:
30
+ ### Layout-table criterion
65
31
 
66
- - If headers are in the first row or column:
67
- - `th` elements without `scope` are sufficient
68
- - If headers are not in the first row or column:
69
- - Check that all `th` elements have a `scope` attribute
70
- - Verify `scope` values match the header's role (`row`/`col`/`rowgroup`/`colgroup`)
71
- Note: For complex tables (multiple levels of headers, headers spanning rows/columns), use id and headers attributes instead (see H43)
72
- - The objective of this technique is to associate each data cell (in a data table) with the appropriate headers.
73
- Check for layout tables and data tables:
74
- - For layout tables:
75
- - Determine if content has a relationship with other content in both its column and row
76
- - If "no", the table is a layout table
77
- - For data tables:
78
- - Check that any cell associated with multiple row/column headers contains a headers attribute listing all associated header IDs
79
- - For cells with id or headers attributes:
80
- - Verify each id in headers attribute matches a header element's id
81
- - Verify headers attribute contains all associated header IDs
82
- - Ensure all IDs are unique within the component
32
+ When a table's content has no row/column relationships, classify it as a layout table. Layout tables should not use `<th>` or `scope`; emit a fix entry if they do.
83
33
 
84
- Note: A complex table is one where:
34
+ ### Output contract
85
35
 
86
- - Headers span multiple rows or columns
87
- - Headers are not in the first row or column
88
- - Multiple levels of headers exist
89
- - Cells are associated with multiple headers
90
- - The table structure requires additional context to understand relationships between data
36
+ For each violation, produce one entry with: file + line number, which criterion above failed, and the corrected markup snippet. If every table satisfies the criteria, produce an empty list.
91
37
 
92
- If they do not meet this success criterion, then flag this as a violation.
93
-
94
- Rules to follow:
95
-
96
- - Find all violations of SC 1.3.1 (ii) 'Tables' in the provided HTML and JS files
97
- - Do not worry about violations of SC 1.3.1 that are not specific to tables (handled by other reviewers)
98
- - If no changes are needed, then produce an empty list
99
- - For each issue found, provide a separate, detailed report.
38
+ - For each issue found, provide a separate, detailed report.
100
39
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
101
40
  - Assume that any imported functionality works as expected and was already analyzed.
102
41
  - Components do not supplement or provide global functionalities.
103
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
104
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
105
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
106
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
@@ -61,6 +61,8 @@ Exceptions (No Label Required):
61
61
 
62
62
  If they do not meet this success criterion, then flag this as a violation.
63
63
 
64
+ Trace how the control's own accessible name is provided in the source before flagging a missing or unassociated label. Valid sources include a `<label>` that contains the control, a `<label for>` / `<label htmlFor>` whose value matches the control's `id`, an `aria-label`, an `aria-labelledby` target, or a self-labeling component prop on an imported/custom control such as `<Input>` or `<TextField>` (see the general rules). An adjacent `<label>` is not sufficient unless it contains the control or has a matching `for` / `htmlFor` association. A `<fieldset><legend>` or named `role="group"` / `role="radiogroup"` supplies group context but does **not** name each descendant control. A dynamic `for` / `htmlFor` and its control's `id` bound to the **same expression** are matched, even when the literal value cannot be resolved at review time (see the general rules). Only flag when none of the valid control-level naming mechanisms supplies the name.
65
+
64
66
  Rules to follow:
65
67
 
66
68
  - Find all violations of SC 1.3.1 (iii) 'Form Labels' in the provided HTML and JS files
@@ -72,7 +74,5 @@ Rules to follow:
72
74
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
73
75
  - Assume that any imported functionality works as expected and was already analyzed.
74
76
  - Components do not supplement or provide global functionalities.
75
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
76
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
77
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
78
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
77
+ - ARIA attribute spelling depends on the element type. Plain HTML elements use `aria-labelledby` and `aria-describedby`; `aria-labelled-by` or `aria-described-by` is invalid there. On an LWC component tag, however, the hyphen-split spelling can be the kebab-case binding for an `@api ariaLabelledBy` or `ariaDescribedBy` property. Do not report the component spelling as a broken association without evidence that the component fails to forward it.
78
+ - Attach label associations to the actual focusable control. A `for`, `htmlFor`, or ARIA relationship on a non-focusable wrapper around a composite editor does not label the internal control unless the wrapper forwards it. Recommend extending the control to accept or forward the association, or using its supported labeling prop.
@@ -20,7 +20,3 @@ Rules to follow:
20
20
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
21
21
  - Assume that any imported functionality works as expected and was already analyzed.
22
22
  - Components do not supplement or provide global functionalities.
23
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
24
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
25
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
26
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
@@ -52,6 +52,8 @@ For each selection list:
52
52
 
53
53
  - Check that links that are grouped and represent a section of page, are enclosed in a `nav` element or similar semantics.
54
54
 
55
+ Before flagging a group as unlabeled or improperly structured, resolve how the group is named. A `role="group"` / `role="radiogroup"` container with `aria-label` or `aria-labelledby` is a **valid and sufficient** grouping-and-naming technique (ARIA17) — it does **not** additionally require a `<fieldset>` / `<legend>`. Treat `<div role="group" aria-label={...}>` (including a dynamic `aria-label` / `aria-labelledby` expression such as `aria-label={section.title}`) as a properly labeled group; do **not** flag it for a missing `<legend>`, a missing `aria-label`, or a missing group name when an `aria-label` / `aria-labelledby` is present. Only flag a group that has **neither** a `fieldset` / `legend` **nor** a `role="group"` / `role="radiogroup"` carrying an accessible name.
56
+
55
57
  _Rules to follow_:
56
58
 
57
59
  - Require code to reinforce structure, relationships and information conveyed through presentation for groups of related elements, per this WCAG 2.2 SC 1.3.1 'Info and Relationships - Groups only' success criterion, in the provided HTML and JS files.
@@ -60,7 +62,3 @@ _Rules to follow_:
60
62
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
61
63
  - Assume that any imported functionality works as expected and was already analyzed.
62
64
  - Components do not supplement or provide global functionalities.
63
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
64
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
65
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
66
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.
@@ -64,7 +64,3 @@ Rules to follow:
64
64
  - Keep issues concise, avoid duplicated issues or unnecessary or non-applicable problems.
65
65
  - Assume that any imported functionality works as expected and was already analyzed.
66
66
  - Components do not supplement or provide global functionalities.
67
- - Lightning base components (`lightning-input`, `lightning-combobox`, `lightning-textarea`, `lightning-icon`, etc.) provide their own accessible labeling, ARIA, and error handling in shadow DOM via their dedicated attributes (`label`, `alternative-text`, field-level validation). When such a component is given a `label` attribute it is already programmatically labeled — even with `variant="label-hidden"`, which hides the label visually but keeps it for assistive technology. Do **not** flag a sibling/wrapper `<label>` or `<span>` for a missing `for`/`id` when the actual control is a self-labeling Lightning component, and do not treat a visible heading as if it were the control's only label. This also covers navigation and icon base components (`lightning-vertical-navigation-item`, `lightning-vertical-navigation-item-icon`, `lightning-button-icon`, etc.): when a `label` (or `alternative-text`) attribute is supplied, the base component renders it as the visible link/control text **and** exposes it as the accessible name, and any `icon-name` is decorative — do not emit a 4.1.2 "verify the label is associated with the icon" warning, even a hedged one. The presence of the `label` attribute is the association.
68
- - Resolve template bindings before judging them. A template expression like `{someValue}` refers to a property or getter on the component's controller (`.js`/`.ts`) — including `@api` properties and `get someValue()` getters — not to a module-level imported constant (which LWC templates cannot bind to). Check the controller for the binding's definition before concluding a value is undefined, empty, or missing. When reviewing a diff, verify which side is the corrected code; do not assume the change introduced the problem.
69
- - Prefer a real `<button>` for actions; for a link, `href="#"` with `event.preventDefault()` (the canonical SLDS pattern). Don't recommend `href="javascript:void(0)"` as a first-line remediation — it's a no-op-anchor anti-pattern. It is acceptable only as a last resort when moving `<a>` → `<button>` is genuinely impossible, and even then only when paired with the full set of attributes that make the anchor behave as an accessible button (`role="button"`, keyboard activation, etc.) — `void(0)` on its own is an incomplete fix. Don't flag existing `javascript:void(0)` as a violation.
70
- - ARIA attribute spelling depends on the element type. On a **plain HTML element** (`div`, `span`, `button`, `input`, `a`, `img`, `iframe`, …) the only valid spelling is the W3C form `aria-labelledby` / `aria-describedby`; the hyphen-split `aria-labelled-by` / `aria-described-by` there **is** a real bug — keep flagging it. But on an **LWC component tag** (`lightning-*` or a custom `ns-name` element), the hyphen-split form is the kebab-case binding of the component's `@api ariaLabelledBy` / `ariaDescribedBy` property (each capital letter maps to `-` + lowercase), and LWC reflects it to the spec-correct `aria-labelledby` in the rendered DOM. Do **not** flag `aria-labelled-by` on a component tag as a misspelling, and do not claim it "breaks the accessible name computation" — you cannot determine that from the attribute name alone, because both `aria-labelled-by` (via `@api` property kebab-casing) and `aria-labelledby` (via LWC's ARIA reflection) can wire to the same property depending on the component. Treat a hyphen-split ARIA attribute on a component tag as a valid binding, not a violation.