@salesforce/afv-skills 1.37.0 → 1.38.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 (247) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-generate/README.md +20 -3
  3. package/skills/agentforce-generate/SKILL.md +253 -440
  4. package/skills/agentforce-generate/assets/agent-spec-template.md +6 -2
  5. package/skills/agentforce-generate/assets/agents/order-service.agent +16 -12
  6. package/skills/agentforce-generate/assets/agents/production-faq.agent +4 -4
  7. package/skills/agentforce-generate/assets/agents/router-first.agent +5 -5
  8. package/skills/agentforce-generate/assets/agents/template-single-subagent.agent +4 -4
  9. package/skills/agentforce-generate/assets/agents/verification-gate.agent +8 -6
  10. package/skills/agentforce-generate/assets/agents/voice-knowledge-grounded.agent +9 -9
  11. package/skills/agentforce-generate/assets/agents/voice-service-agent.agent +7 -7
  12. package/skills/agentforce-generate/assets/patterns/README.md +3 -3
  13. package/skills/agentforce-generate/assets/patterns/action-callbacks.agent +5 -5
  14. package/skills/agentforce-generate/assets/patterns/advanced-input-bindings.agent +6 -8
  15. package/skills/agentforce-generate/assets/patterns/bidirectional-routing.agent +11 -13
  16. package/skills/agentforce-generate/assets/patterns/critical-input-collection.agent +11 -16
  17. package/skills/agentforce-generate/assets/patterns/lifecycle-events.agent +2 -3
  18. package/skills/agentforce-generate/assets/patterns/llm-controlled-actions.agent +6 -7
  19. package/skills/agentforce-generate/assets/patterns/open-gate-routing.agent +3 -3
  20. package/skills/agentforce-generate/assets/patterns/prompt-template-action.agent +14 -19
  21. package/skills/agentforce-generate/assets/patterns/system-instruction-overrides.agent +11 -20
  22. package/skills/agentforce-generate/references/actions-reference.md +2 -2
  23. package/skills/agentforce-generate/references/agent-audit-and-repair.md +135 -0
  24. package/skills/agentforce-generate/references/agent-audit-candidate-verification.md +160 -0
  25. package/skills/agentforce-generate/references/agent-audit-diagnostic-catalog.md +156 -0
  26. package/skills/agentforce-generate/references/agent-audit-diagnostics-actions-state.md +176 -0
  27. package/skills/agentforce-generate/references/agent-audit-diagnostics-architecture-evaluation.md +68 -0
  28. package/skills/agentforce-generate/references/agent-audit-diagnostics-instructions-routing.md +283 -0
  29. package/skills/agentforce-generate/references/agent-audit-evaluation-loop.md +191 -0
  30. package/skills/agentforce-generate/references/agent-audit-repair-report.md +143 -0
  31. package/skills/agentforce-generate/references/agent-audit-scope-path-review.md +180 -0
  32. package/skills/agentforce-generate/references/agent-design-and-spec-creation.md +105 -59
  33. package/skills/agentforce-generate/references/agent-script-core-language.md +144 -61
  34. package/skills/agentforce-generate/references/agent-subagent-map-diagrams.md +33 -23
  35. package/skills/agentforce-generate/references/agent-validation-and-debugging.md +37 -11
  36. package/skills/agentforce-generate/references/agentscript-toolchain.md +112 -0
  37. package/skills/agentforce-generate/references/architecture-patterns.md +81 -18
  38. package/skills/agentforce-generate/references/common-control-flow-pitfalls.md +255 -0
  39. package/skills/agentforce-generate/references/control-flow-actions-sequencing.md +198 -0
  40. package/skills/agentforce-generate/references/control-flow-lifecycle-side-effects.md +87 -0
  41. package/skills/agentforce-generate/references/examples.md +22 -22
  42. package/skills/agentforce-generate/references/instruction-resolution.md +123 -83
  43. package/skills/agentforce-generate/references/known-issues.md +1 -2
  44. package/skills/agentforce-generate/references/optimization-pattern-1-data-flow.md +4 -0
  45. package/skills/agentforce-generate/references/optimization-pattern-2-deterministic-logic.md +33 -0
  46. package/skills/agentforce-generate/references/optimization-pattern-3-reference-syntax.md +32 -3
  47. package/skills/agentforce-generate/references/optimization-pattern-4-escalation.md +2 -2
  48. package/skills/agentforce-generate/references/patterns-by-requirement.md +3 -1
  49. package/skills/agentforce-generate/references/posture-and-determinism.md +103 -22
  50. package/skills/agentforce-generate/references/reference-map.md +19 -3
  51. package/skills/agentforce-generate/references/scoring-rubric.md +1 -1
  52. package/skills/agentforce-generate/references/voice-latency-heuristics.md +4 -0
  53. package/skills/agentforce-generate/references/voice-modality-reference.md +4 -4
  54. package/skills/agentforce-generate/references/zen-of-agentscript.md +139 -23
  55. package/skills/agentforce-generate/scripts/agentscript-sdk-loader.mjs +133 -0
  56. package/skills/agentforce-generate/scripts/index-agent.mjs +141 -0
  57. package/skills/agentforce-generate/scripts/setup-agentscript-sdk.mjs +337 -0
  58. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +1 -1
  59. package/skills/automation-sandbox-post-copy-configure/SKILL.md +433 -0
  60. package/skills/automation-sandbox-post-copy-configure/assets/api_request_templates.json +89 -0
  61. package/skills/automation-sandbox-post-copy-configure/examples/sample_config_input.json +40 -0
  62. package/skills/automation-sandbox-post-copy-configure/examples/sample_execution_summary.md +79 -0
  63. package/skills/automation-sandbox-post-copy-configure/references/api_endpoints.md +273 -0
  64. package/skills/automation-sandbox-post-copy-configure/references/authentication.md +94 -0
  65. package/skills/automation-sandbox-post-copy-configure/references/execution_phasing.md +93 -0
  66. package/skills/automation-sandbox-post-copy-configure/references/rules_gotchas.md +35 -0
  67. package/skills/automation-sandbox-post-copy-configure/scripts/classify-patch-result.mjs +88 -0
  68. package/skills/automation-sandbox-post-copy-configure/scripts/map-metadata-key.mjs +98 -0
  69. package/skills/automation-sandbox-post-copy-configure/scripts/plan-phases.mjs +98 -0
  70. package/skills/automation-sandbox-post-copy-configure/scripts/resolve-target-org.mjs +56 -0
  71. package/skills/design-systems-slds-validate/SKILL.md +14 -13
  72. package/skills/dx-code-analyzer-custom-rule-create/examples/xpath-examples.md +1 -1
  73. package/skills/dx-code-analyzer-custom-rule-create/references/xpath-patterns-security.md +1 -1
  74. package/skills/dx-org-devhub-configure/SKILL.md +268 -0
  75. package/skills/dx-org-devhub-configure/examples/status-output.md +39 -0
  76. package/skills/dx-org-devhub-configure/scripts/devhub.sh +650 -0
  77. package/skills/dx-org-devhub-configure/scripts/test-devhub.sh +116 -0
  78. package/skills/dx-org-manage/SKILL.md +135 -42
  79. package/skills/dx-org-manage/assets/derive-alias.sh +95 -0
  80. package/skills/dx-org-manage/assets/scratch-def.seed.json +6 -0
  81. package/skills/dx-org-manage/examples/README.md +1 -1
  82. package/skills/dx-org-manage/examples/scratch-orgs/delete_output.json +8 -0
  83. package/skills/dx-org-manage/examples/scratch-orgs/display_output.json +23 -0
  84. package/skills/dx-org-manage/examples/scratch-orgs/list_output.json +58 -0
  85. package/skills/dx-org-manage/examples/scratch-orgs/resume_output.json +38 -0
  86. package/skills/dx-org-manage/examples/scratch-orgs/success_definition_file.json +1 -1
  87. package/skills/dx-org-manage/examples/scratch-orgs/success_edition.json +1 -1
  88. package/skills/dx-org-manage/examples/scratch-orgs/success_shape.json +41 -0
  89. package/skills/dx-org-manage/examples/scratch-orgs/success_snapshot.json +1 -1
  90. package/skills/dx-org-manage/examples/snapshots/error_output.json +3 -3
  91. package/skills/dx-org-manage/references/creating-scratch-org.md +2 -2
  92. package/skills/dx-org-manage/references/creating-snapshot.md +1 -2
  93. package/skills/dx-org-manage/references/definition_file_options.md +24 -0
  94. package/skills/dx-org-manage/references/edition_types.md +10 -8
  95. package/skills/dx-org-manage/references/opening-org.md +11 -12
  96. package/skills/dx-org-manage/references/scratch-org-create.md +303 -0
  97. package/skills/dx-org-manage/references/scratch-org-operations.md +135 -0
  98. package/skills/experience-aura-lwc-migrate/SKILL.md +120 -0
  99. package/skills/experience-aura-lwc-migrate/references/aura-api-expert.md +170 -0
  100. package/skills/experience-aura-lwc-migrate/references/aura-data-expert.md +172 -0
  101. package/skills/experience-aura-lwc-migrate/references/aura-migration-guidelines.md +299 -0
  102. package/skills/experience-aura-lwc-migrate/references/aura-prd-framework.md +79 -0
  103. package/skills/experience-aura-lwc-migrate/references/aura-redundant-code-expert.md +24 -0
  104. package/skills/experience-aura-lwc-migrate/references/aura-reference-expert.md +140 -0
  105. package/skills/experience-aura-lwc-migrate/references/aura-resolver-expert.md +115 -0
  106. package/skills/experience-aura-lwc-migrate/references/aura-slots-expert.md +67 -0
  107. package/skills/experience-aura-lwc-migrate/references/aura-style-expert.md +62 -0
  108. package/skills/experience-aura-lwc-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
  109. package/skills/experience-aura-lwc-migrate/references/aura-values-expert.md +67 -0
  110. package/skills/experience-content-media-search/SKILL.md +17 -12
  111. package/skills/experience-content-media-stock-image-search/SKILL.md +192 -0
  112. package/skills/experience-content-media-stock-image-search/scripts/download-stock-image.py +102 -0
  113. package/skills/experience-lds-best-practices-apply/SKILL.md +245 -0
  114. package/skills/experience-lds-best-practices-apply/references/adapter-apis.md +1640 -0
  115. package/skills/experience-lds-best-practices-apply/references/lds-data-consistency.md +126 -0
  116. package/skills/experience-lds-best-practices-apply/references/lds-expert.md +429 -0
  117. package/skills/experience-lds-best-practices-apply/references/lds-referential-integrity.md +322 -0
  118. package/skills/experience-lds-best-practices-apply/references/wire-adapter-types.md +1511 -0
  119. package/skills/experience-lds-graphql-generate/SKILL.md +222 -0
  120. package/skills/experience-lds-graphql-generate/references/generation-guide.md +236 -0
  121. package/skills/experience-lds-graphql-generate/references/generation-mutation.md +277 -0
  122. package/skills/experience-lds-graphql-generate/references/generation-query.md +237 -0
  123. package/skills/experience-lds-graphql-generate/scripts/fetch-lds-graphql-schema.sh +230 -0
  124. package/skills/experience-lds-graphql-generate/scripts/test-lds-graphql-query.sh +128 -0
  125. package/skills/experience-lwc-accessibility-validate/SKILL.md +112 -0
  126. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +88 -0
  127. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +52 -0
  128. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +106 -0
  129. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +78 -0
  130. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +26 -0
  131. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +66 -0
  132. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +70 -0
  133. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +115 -0
  134. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +47 -0
  135. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +39 -0
  136. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +50 -0
  137. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +54 -0
  138. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +49 -0
  139. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +77 -0
  140. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +45 -0
  141. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +55 -0
  142. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +51 -0
  143. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +84 -0
  144. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +50 -0
  145. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +64 -0
  146. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +105 -0
  147. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +99 -0
  148. package/skills/experience-lwc-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +97 -0
  149. package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-1-1-non-text-content.md +83 -0
  150. package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-1-use-of-color.md +62 -0
  151. package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-10-resize-reflow.md +18 -0
  152. package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-11-non-text-contrast.md +43 -0
  153. package/skills/experience-lwc-accessibility-validate/references/vision/sc-1-4-3-contrast.md +25 -0
  154. package/skills/experience-lwc-accessibility-validate/scripts/contrast-ratio.py +153 -0
  155. package/skills/experience-lwc-design-generate/SKILL.md +261 -0
  156. package/skills/experience-lwc-design-generate/references/figma-to-prd-blueprint.md +66 -0
  157. package/skills/experience-lwc-design-generate/references/prd-analysis-template.md +17 -0
  158. package/skills/experience-lwc-design-generate/scripts/check-component-name.sh +75 -0
  159. package/skills/experience-lwc-design-generate/scripts/detect-project-tools.sh +97 -0
  160. package/skills/experience-lwc-runtime-observe/SKILL.md +244 -0
  161. package/skills/experience-lwc-runtime-observe/examples/component-preview-and-dom.md +41 -0
  162. package/skills/experience-lwc-runtime-observe/scripts/extract-dom.sh +79 -0
  163. package/skills/experience-lwc-runtime-observe/scripts/open-frontdoor.sh +46 -0
  164. package/skills/experience-lwc-runtime-observe/scripts/verify-toolchain.sh +48 -0
  165. package/skills/experience-lwc-security-validate/SKILL.md +151 -0
  166. package/skills/experience-lwc-security-validate/examples/review-report.md +6 -0
  167. package/skills/experience-lwc-security-validate/examples/score-report.sarif.json +32 -0
  168. package/skills/experience-lwc-security-validate/references/lws-security-expert.md +986 -0
  169. package/skills/experience-lwc-security-validate/references/security-analysis.md +611 -0
  170. package/skills/experience-lwc-security-validate/scripts/check-lwc-import.sh +166 -0
  171. package/skills/experience-lwc-security-validate/scripts/validate-sarif.sh +131 -0
  172. package/skills/experience-ui-bundle-2gp-deploy/SKILL.md +454 -0
  173. package/skills/experience-ui-bundle-2gp-deploy/assets/CustomApplication.app-meta.xml +12 -0
  174. package/skills/experience-ui-bundle-2gp-deploy/assets/PermissionSet.permissionset-meta.xml +9 -0
  175. package/skills/experience-ui-bundle-2gp-deploy/scripts/find-bundle-package-dir.sh +53 -0
  176. package/skills/experience-ui-bundle-agentforce-client-generate/SKILL.md +104 -26
  177. package/skills/experience-ui-bundle-agentforce-client-generate/references/constraints.md +35 -24
  178. package/skills/experience-ui-bundle-agentforce-client-generate/references/examples.md +92 -1
  179. package/skills/experience-ui-bundle-agentforce-client-generate/references/style-tokens.md +2 -0
  180. package/skills/experience-ui-bundle-agentforce-client-generate/references/troubleshooting.md +14 -1
  181. package/skills/experience-ui-bundle-agentforce-client-generate/scripts/detect-framework.sh +67 -0
  182. package/skills/experience-ui-bundle-deploy/SKILL.md +83 -14
  183. package/skills/experience-ui-bundle-deploy/assets/Communities.settings-meta.xml +19 -0
  184. package/skills/experience-ui-bundle-deploy/assets/org-setup.config.template.json +5 -0
  185. package/skills/experience-ui-bundle-deploy/assets/social-login-auth-providers.apex +158 -0
  186. package/skills/experience-ui-bundle-deploy/references/config-scaffold.md +13 -1
  187. package/skills/experience-ui-bundle-deploy/references/social-login.md +179 -0
  188. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +14 -0
  189. package/skills/experience-ui-bundle-mfa-configure/SKILL.md +6 -5
  190. package/skills/experience-ui-bundle-mfa-configure/references/social-login.md +15 -7
  191. package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +41 -5
  192. package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +10 -22
  193. package/skills/experience-ui-bundle-salesforce-data-access/references/graphql-hand-authoring.md +4 -19
  194. package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +5 -0
  195. package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +33 -150
  196. package/skills/mobile-platform-native-capabilities-integrate/references/nfc.md +35 -0
  197. package/skills/platform-apex-generate/SKILL.md +8 -7
  198. package/skills/platform-apex-test-generate/SKILL.md +3 -1
  199. package/skills/platform-apex-test-run/SKILL.md +9 -8
  200. package/skills/platform-lightning-type-widget-coordinate/SKILL.md +1 -1
  201. package/skills/platform-lightning-type-widget-coordinate/examples/existing-lightning-type-with-widget-prompt.md +1 -1
  202. package/skills/platform-lightning-type-widget-coordinate/examples/new-lightning-type-with-widget-prompt.md +1 -1
  203. package/skills/platform-lightning-type-widget-coordinate/references/validation-gates.md +3 -3
  204. package/skills/platform-mcp-tool-widget-coordinate/SKILL.md +43 -67
  205. package/skills/platform-mcp-tool-widget-coordinate/examples/action-name-source-prompt.md +1 -2
  206. package/skills/platform-mcp-tool-widget-coordinate/examples/apex-invocable-source-prompt.md +2 -3
  207. package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-list-source-prompt.md +163 -0
  208. package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-single-source-prompt.md +198 -0
  209. package/skills/platform-mcp-tool-widget-coordinate/examples/pasted-tool-output-prompt.md +0 -1
  210. package/skills/platform-mcp-tool-widget-coordinate/references/build-plan-format.md +17 -11
  211. package/skills/platform-mcp-tool-widget-coordinate/references/mcp-tool-output-discovery.md +48 -15
  212. package/skills/platform-mcp-tool-widget-coordinate/references/two-clt-modeling.md +73 -10
  213. package/skills/platform-mcp-tool-widget-coordinate/references/validation-gates.md +48 -8
  214. package/skills/platform-policy-rule-generate/SKILL.md +22 -12
  215. package/skills/platform-policy-rule-generate/references/deploy-errors.md +1 -1
  216. package/skills/platform-policy-rule-generate/references/policy-schema-full.md +8 -29
  217. package/skills/platform-policy-rule-generate/references/templates-advanced.md +1 -1
  218. package/skills/platform-sharing-owd-configure/SKILL.md +20 -8
  219. package/skills/platform-sharing-owd-configure/references/access_levels.md +14 -1
  220. package/skills/platform-sharing-rules-generate/SKILL.md +67 -35
  221. package/skills/platform-sharing-rules-generate/examples/create-cases.md +16 -17
  222. package/skills/platform-sharing-rules-generate/examples/delete-cases.md +34 -79
  223. package/skills/platform-sharing-rules-generate/examples/edit-cases.md +13 -26
  224. package/skills/platform-sharing-rules-generate/scripts/count-remaining-rules.sh +33 -0
  225. package/skills/platform-widget-generate/SKILL.md +3 -5
  226. package/skills/platform-widget-generate/examples/conditional.json +18 -13
  227. package/skills/platform-widget-generate/examples/list-with-foreach.json +2 -2
  228. package/skills/platform-widget-generate/examples/single-object.json +2 -2
  229. package/skills/platform-widget-generate/references/schema-from-lightning-type.md +27 -6
  230. package/skills/platform-widget-generate/references/widget-bundle-layout.md +4 -3
  231. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +287 -0
  232. package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +260 -0
  233. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +252 -0
  234. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/references/mcp-invocation.md +204 -0
  235. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +259 -0
  236. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +188 -0
  237. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +197 -0
  238. package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +77 -0
  239. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +316 -0
  240. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/references/mcp-invocation.md +221 -0
  241. package/skills/service-itsm-incident-priority-configure/SKILL.md +168 -0
  242. package/skills/service-itsm-incident-priority-configure/examples/matrix-operations.md +200 -0
  243. package/skills/service-itsm-incident-priority-configure/examples/render-matrix.md +54 -0
  244. package/skills/service-itsm-incident-priority-configure/examples/seed-full-matrix.md +52 -0
  245. package/skills/service-itsm-incident-priority-configure/references/sf-cli-invocation.md +264 -0
  246. package/skills/platform-mcp-tool-widget-coordinate/examples/nested-object-source-prompt.md +0 -191
  247. package/skills/platform-policy-rule-generate/references/fixtures-index.md +0 -29
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  name: experience-ui-bundle-deploy
3
- description: "MUST activate when the project contains a uiBundles/*/src/ directory and the task involves deploying, pushing to an org, or post-deploy org setup. Use this skill to deploy a UI bundle app to a Salesforce org and run the full ordered setup: org authentication, pre-deploy build, metadata deploy, permission-set assignment, role assignment, Experience Cloud self-registration, seed-data import, and GraphQL schema fetch plus codegen. Activate when a uiBundles/ project also has files like *.network-meta.xml, org-setup.config.json, a data-plan.json in the data/ dir, or sfdx-project.json and the user mentions deploying, pushing, org setup, or post-deploy tasks. DO NOT TRIGGER when: creating a new UI bundle project from scratch (use experience-ui-bundle-project-generate); styling or editing pages in an existing app without deploying (use experience-ui-bundle-frontend-generate); adding a specific feature such as auth, search, or file upload without deploying (use the matching experience-ui-bundle-*-generate skill)."
3
+ description: "MUST activate when the project has a uiBundles/*/src/ directory and the task involves deploying to an org or post-deploy org setup. Deploys a UI bundle app and runs ordered setup: org auth, build, metadata deploy, permission-set and role assignment, Experience Cloud self-registration, social login / SSO / IDP linking (Auth Providers + SAML SSO configs on a React site), seed-data import, and GraphQL schema fetch + codegen. Trigger signals: *.network-meta.xml, org-setup.config.json (with a socialLogin block), data-plan.json, sfdx-project.json, or mentions of deploy, org setup, or social login / SSO / IDP linking on an Experience site. DO NOT TRIGGER when: creating a new UI bundle project (use experience-ui-bundle-project-generate); styling pages without deploying (use experience-ui-bundle-frontend-generate); adding a feature such as auth, search, or file upload without deploying (use the matching experience-ui-bundle-*-generate skill); configuring MFA permission sets (use experience-ui-bundle-mfa-configure)."
4
4
  metadata:
5
- version: "1.1"
5
+ version: "1.2"
6
6
  relatedSkills:
7
7
  - "experience-ui-bundle-frontend-generate"
8
+ - "experience-ui-bundle-mfa-configure"
8
9
  - "experience-ui-bundle-project-generate"
9
10
  cliTools:
10
11
  - tool: ["jq"]
@@ -43,10 +44,11 @@ Read these from the project; **ask the user** only for what's missing:
43
44
  source dir from `sfdx-project.json` (`packageDirectories[0].path` + `/main/default`).
44
45
  It exits non-zero if the project file is missing or malformed. Never hardcode
45
46
  `force-app/main/default`.
46
- - **`org-setup.config.json`** (optional) — drives permset assignment, role, and
47
- self-registration. Absent keys mean "skip that step". **Exception:** if the
48
- file is missing but `permissionsets/` has permsets to assign, don't silently
49
- skip — scaffold the config or gather equivalent inputs (see step 4).
47
+ - **`org-setup.config.json`** (optional) — drives permset assignment, role,
48
+ self-registration, and social login. Absent keys mean "skip that step".
49
+ **Exception:** if the file is missing but `permissionsets/` has permsets to
50
+ assign, don't silently skip — scaffold the config or gather equivalent inputs
51
+ (see step 4).
50
52
  - **`data-plan.json`** (optional, in the project's `data/` dir) — presence enables the data step.
51
53
 
52
54
  ## Step 1 — Org authentication (always)
@@ -168,6 +170,67 @@ running.** Sequence (full detail in `references/self-registration.md`):
168
170
  `assets/network-selfreg.apex` (idempotent; both are query-then-create; run 4a
169
171
  and 4b as two separate `sf apex run` invocations).
170
172
 
173
+ ## Step 6b — Enable social login (config-gated)
174
+
175
+ Run only when `org-setup.config.json` has a `socialLogin` block. If the block is
176
+ absent, `loadSocialLoginConfig` returns null and the step is hidden — no-op
177
+ cleanly and say so. This step is **non-destructive and idempotent** (it only adds
178
+ missing links/members), so — unlike self-registration and data import — it does
179
+ **not** require asking first.
180
+
181
+ This links the site's configured **Auth Providers** (OAuth) and **SAML SSO
182
+ configs** to the site so the built-in Social Login component renders their
183
+ buttons on the React login page. On React (Site Container) sites the SSO admin UI
184
+ is hidden, so the linking is done programmatically via `AuthConfig` /
185
+ `AuthConfigProviders` records — you cannot do it by clicking through Setup. Full
186
+ detail, sub-steps, and port-provenance: `references/social-login.md`.
187
+
188
+ Config shape (see `references/config-scaffold.md` for the full schema):
189
+
190
+ ```json
191
+ { "socialLogin": {
192
+ "communityMemberProfile": "Customer Community User",
193
+ "authProviderNames": ["Google", "My_SAML_Provider"],
194
+ "communityUserPermset": "myapp_Guest_User_Api_Access"
195
+ } }
196
+ ```
197
+
198
+ Sequence (mirrors reference `org-setup.mjs` `main()` social-login step, which runs
199
+ **after** self-registration and **before** the data/GraphQL steps):
200
+
201
+ Apply the `assets/` templates **verbatim** (like the self-reg/data steps) — full
202
+ runnable commands for each sub-step are in `references/social-login.md`:
203
+
204
+ 1. **Derive the site** — run `scripts/derive-site-name.sh` (single
205
+ `*.network-meta.xml`; stop if zero/ambiguous). Social login needs the site to
206
+ resolve its `AuthConfig`.
207
+ 2. **Enable "Allow standard external profiles"** — deploy
208
+ `assets/Communities.settings-meta.xml` via Metadata API (from a throwaway
209
+ minimal project; see the reference). Required so the SSO registration handler
210
+ can create users on standard community profiles; without it auth providers fail
211
+ user insert with `FIELD_INTEGRITY_EXCEPTION`. A "already active" warning is a
212
+ non-fatal skip.
213
+ 3. **Link Auth Providers to the site `AuthConfig`** — run
214
+ `assets/social-login-auth-providers.apex` verbatim (substitute `<siteName>`,
215
+ `<ProviderNamesList>`, `<ApiVersion>`) to create the missing
216
+ `AuthConfigProviders` junctions, then read its `|DEBUG|` lines (table in the
217
+ reference). All-or-nothing: if any configured `authProviderNames` entry has no
218
+ matching `AuthProvider` (OAuth) or `SamlSsoConfig` (SAML) record, it emits
219
+ `MISSING_PROVIDERS` and links nothing — create/fix them in Setup first.
220
+ Already-linked providers are skipped (idempotent).
221
+ 4. **Add the community member profile to `NetworkMemberGroup`** — resolve the
222
+ Network + Profile Ids and create the membership if absent (`sf data` commands in
223
+ the reference). Without it, SSO-registered users hit `NO_ACCESS: User was not
224
+ authorized for the community`.
225
+ 5. **(Optional) Assign `communityUserPermset` to community users** — only when
226
+ configured. Grants `ApiEnabled` so `getCurrentUser()` (`/chatter/users/me`)
227
+ works for SSO-created users.
228
+
229
+ > **IMPORTANT:** A `socialLogin` block present but skipped is a silent-failure
230
+ > trap — the app deploys fine, but no social-login buttons ever appear on the
231
+ > login page and there is no error explaining why. Do not silently skip: run the
232
+ > step when the block is present, or state clearly that it was absent.
233
+
171
234
  ## Step 7 — Data import (presence-driven) — ask first
172
235
 
173
236
  Run `scripts/find-data-plan.sh` first. If it exits non-zero, **skip this step** —
@@ -211,9 +274,10 @@ that changes objects, fields, or permissions.
211
274
 
212
275
  ## Done
213
276
 
214
- Setup ends here — the 8 steps above are the complete sequence. Local dev preview
215
- (`npm run dev:preview`) is a separate developer action, not part of setup; if the
216
- user asks to preview the site, see `references/dev-preview.md`.
277
+ Setup ends here — the steps above (including the config-gated 6b social login)
278
+ are the complete sequence. Local dev preview (`npm run dev:preview`) is a separate
279
+ developer action, not part of setup; if the user asks to preview the site, see
280
+ `references/dev-preview.md`.
217
281
 
218
282
  ## Critical rules
219
283
 
@@ -222,14 +286,18 @@ user asks to preview the site, see `references/dev-preview.md`.
222
286
  - Assign permissions **before** schema fetch — the caller may lack FLS otherwise.
223
287
  - Re-run schema fetch + codegen **after every** metadata deploy that changes
224
288
  objects, fields, or permissions.
225
- - Never silently skip permission assignment, self-registration, or data import —
226
- either the convention file is present (run it, asking first for the destructive
227
- ones) or it's absent (skip cleanly and say so).
289
+ - Never silently skip permission assignment, self-registration, social login, or
290
+ data import — either the convention file/config block is present (run it, asking
291
+ first for the destructive ones) or it's absent (skip cleanly and say so). A
292
+ present-but-skipped `socialLogin` block means no login buttons appear with no
293
+ error to explain it.
228
294
  - Discover the source path from `sfdx-project.json`; never hardcode
229
295
  `force-app/main/default`.
230
296
  - Apply the `assets/` Apex and XML templates **verbatim** — they encode
231
- duplicate-rule bypass, `allOrNone=false` deletes, idempotency, and SOQL-safety
232
- that are easy to get wrong by hand.
297
+ duplicate-rule bypass, `allOrNone=false` deletes, idempotency, SOQL-safety, and
298
+ (for social login) the all-or-nothing provider pre-check and the
299
+ DML-not-allowed-on-`AuthConfigProviders` REST-callout insert — all easy to get
300
+ wrong by hand.
233
301
 
234
302
  ## Interaction order (summary)
235
303
 
@@ -239,5 +307,6 @@ user asks to preview the site, see `references/dev-preview.md`.
239
307
  4. Assign permission sets (config-driven assignee)
240
308
  5. Assign role (if configured)
241
309
  6. Enable self-registration (if configured — ask first)
310
+ 6b. Enable social login (if `socialLogin` configured — idempotent, no ask needed)
242
311
  7. Import data (if data plan exists — ask first)
243
312
  8. Fetch GraphQL schema + codegen + final build
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ Enables the "Allow using standard external profiles for self-registration,
4
+ user creation, and login" org setting (field enableOotbProfExtUserOpsEnable).
5
+
6
+ Ported VERBATIM from reference org-setup.mjs enableExternalProfiles (lines
7
+ 581-586). Required so SSO registration handlers can create users on standard
8
+ community profiles (e.g. "Customer Community User"); without it, auth providers
9
+ fail user insert with FIELD_INTEGRITY_EXCEPTION.
10
+
11
+ This is sub-step 1 of SKILL.md step 6b. Deploy this file via Metadata API
12
+ (the REST/Tooling approaches fail on many org types). See
13
+ references/social-login.md for the exact deploy invocation and the throwaway
14
+ minimal-project layout it needs. If the deploy warns that the setting is
15
+ already active, treat it as a non-fatal skip.
16
+ -->
17
+ <CommunitiesSettings xmlns="http://soap.sforce.com/2006/04/metadata">
18
+ <enableOotbProfExtUserOpsEnable>true</enableOotbProfExtUserOpsEnable>
19
+ </CommunitiesSettings>
@@ -13,5 +13,10 @@
13
13
  "selfRegistration": {
14
14
  "selfRegProfile": "<Profile API name>",
15
15
  "accountName": "<display name>"
16
+ },
17
+ "socialLogin": {
18
+ "communityMemberProfile": "<Profile name, e.g. Customer Community User>",
19
+ "authProviderNames": ["<AuthProvider or SamlSsoConfig DeveloperName>"],
20
+ "communityUserPermset": "<PermissionSet API name (optional)>"
16
21
  }
17
22
  }
@@ -0,0 +1,158 @@
1
+ /*
2
+ * Anonymous Apex — link Auth Providers (OAuth + SAML) to a site's AuthConfig
3
+ * by creating AuthConfigProviders junction records (idempotent, all-or-nothing).
4
+ *
5
+ * Ported VERBATIM from reference org-setup.mjs enableAuthProvidersForSite
6
+ * (the generated `apex` template, lines 650-772). Apply this template as-is; do
7
+ * NOT invent your own AuthConfigProviders Apex — DML is not allowed on
8
+ * AuthConfigProviders, the linking must be an HTTP callout to the REST API, and
9
+ * the all-or-nothing failure check must run BEFORE any junction is created. These
10
+ * are easy to get wrong by hand.
11
+ *
12
+ * This is sub-step 2 of SKILL.md step 6b. It runs as a SINGLE `sf apex run`
13
+ * invocation. See references/social-login.md for how to read the |DEBUG| output
14
+ * lines this emits (AUTHCONFIG_FOUND / MISSING_PROVIDERS / INSERTED / etc.).
15
+ *
16
+ * Why programmatic: React (Site Container) sites hide the SSO admin UI, so
17
+ * providers cannot be linked via Setup -> Digital Experiences -> Login &
18
+ * Registration. AuthConfig.AuthOptionsAuthProvider auto-flips to true when the
19
+ * junctions are inserted — no separate update needed.
20
+ *
21
+ * PLACEHOLDERS — substitute before running:
22
+ * <siteName> = the derived site name (base name of the single
23
+ * networks/<siteName>.network-meta.xml). Used in the
24
+ * AuthConfig.Url LIKE match and the log header.
25
+ * <ProviderNamesList> = the socialLogin.authProviderNames values as a
26
+ * comma-separated Apex string-literal list, e.g.
27
+ * 'Google', 'My_SAML_Provider'. Each name MUST be
28
+ * validated against the SOQL-name whitelist first
29
+ * (reject any value containing ' \ or a control char —
30
+ * same guard the permset/self-reg paths use) and then
31
+ * single-quoted. This exact literal is used in BOTH the
32
+ * `DeveloperName IN (...)` clauses AND the requested-name
33
+ * loop below; keep them identical.
34
+ * <ApiVersion> = REST API version for the callout endpoint (e.g. 62.0).
35
+ */
36
+
37
+ // Enable Auth Providers (OAuth + SAML) for community "<siteName>"
38
+ Http http = new Http();
39
+ String baseUrl = Url.getOrgDomainUrl().toExternalForm();
40
+ String token = UserInfo.getSessionId();
41
+
42
+ // Step 1: Find the AuthConfig for this site
43
+ List<AuthConfig> authConfigs = [
44
+ SELECT Id, Url
45
+ FROM AuthConfig
46
+ WHERE Url LIKE '%<siteName>%'
47
+ LIMIT 1
48
+ ];
49
+ if (authConfigs.isEmpty()) {
50
+ System.debug('ERROR_NO_AUTHCONFIG');
51
+ return;
52
+ }
53
+ AuthConfig ac = authConfigs[0];
54
+ System.debug('AUTHCONFIG_FOUND:' + ac.Id + ':' + ac.Url);
55
+
56
+ // Step 2: Query AuthProvider records by DeveloperName (OAuth providers)
57
+ List<AuthProvider> oauthProviders = [
58
+ SELECT Id, DeveloperName, FriendlyName
59
+ FROM AuthProvider
60
+ WHERE DeveloperName IN (<ProviderNamesList>)
61
+ ];
62
+ System.debug('OAUTH_PROVIDERS_FOUND:' + oauthProviders.size());
63
+
64
+ // Step 3: Query SamlSsoConfig records by DeveloperName (SAML providers)
65
+ List<SamlSsoConfig> samlProviders = [
66
+ SELECT Id, DeveloperName
67
+ FROM SamlSsoConfig
68
+ WHERE DeveloperName IN (<ProviderNamesList>)
69
+ ];
70
+ System.debug('SAML_PROVIDERS_FOUND:' + samlProviders.size());
71
+
72
+ // Combine both into a unified list with (Id, DeveloperName, Type)
73
+ List<Map<String, String>> allProviders = new List<Map<String, String>>();
74
+ for (AuthProvider ap : oauthProviders) {
75
+ allProviders.add(new Map<String, String>{
76
+ 'Id' => ap.Id,
77
+ 'DeveloperName' => ap.DeveloperName,
78
+ 'Type' => 'OAuth'
79
+ });
80
+ }
81
+ for (SamlSsoConfig sp : samlProviders) {
82
+ allProviders.add(new Map<String, String>{
83
+ 'Id' => sp.Id,
84
+ 'DeveloperName' => sp.DeveloperName,
85
+ 'Type' => 'SAML'
86
+ });
87
+ }
88
+
89
+ if (allProviders.isEmpty()) {
90
+ System.debug('ERROR_NO_PROVIDERS');
91
+ return;
92
+ }
93
+ System.debug('TOTAL_PROVIDERS_FOUND:' + allProviders.size());
94
+
95
+ // Fail fast if any requested provider name did not resolve to an AuthProvider
96
+ // (OAuth) or SamlSsoConfig (SAML) record. The isEmpty() check above only catches
97
+ // the case where NONE resolve; comparing the found DeveloperNames against the
98
+ // requested list also catches the strict-subset case (e.g. ["Google","Typo"]
99
+ // links Google but must not silently drop "Typo"). This runs BEFORE any junction
100
+ // record is created, so linking is all-or-nothing. Case-insensitive because SOQL
101
+ // "DeveloperName IN (...)" matches case-insensitively, so a stored DeveloperName
102
+ // may differ in case from the configured value and must not read as "missing".
103
+ Set<String> foundProviderNames = new Set<String>();
104
+ for (AuthProvider ap : oauthProviders) {
105
+ foundProviderNames.add(ap.DeveloperName.toLowerCase());
106
+ }
107
+ for (SamlSsoConfig sp : samlProviders) {
108
+ foundProviderNames.add(sp.DeveloperName.toLowerCase());
109
+ }
110
+ List<String> missingProviderNames = new List<String>();
111
+ for (String requestedName : new List<String>{<ProviderNamesList>}) {
112
+ if (!foundProviderNames.contains(requestedName.toLowerCase())) {
113
+ missingProviderNames.add(requestedName);
114
+ }
115
+ }
116
+ if (!missingProviderNames.isEmpty()) {
117
+ System.debug('MISSING_PROVIDERS:' + String.join(missingProviderNames, ','));
118
+ return;
119
+ }
120
+
121
+ // Step 4: Check existing AuthConfigProviders to avoid duplicates
122
+ Set<Id> existingProviderIds = new Set<Id>();
123
+ for (AuthConfigProviders acp : [
124
+ SELECT AuthProviderId FROM AuthConfigProviders WHERE AuthConfigId = :ac.Id
125
+ ]) {
126
+ existingProviderIds.add(acp.AuthProviderId);
127
+ }
128
+
129
+ // Step 5: Create missing junction records via REST API
130
+ Integer inserted = 0;
131
+ for (Map<String, String> provider : allProviders) {
132
+ String providerId = provider.get('Id');
133
+ String providerName = provider.get('DeveloperName');
134
+ String providerType = provider.get('Type');
135
+
136
+ if (existingProviderIds.contains(providerId)) {
137
+ System.debug('ALREADY_LINKED:' + providerName + ':' + providerType);
138
+ continue;
139
+ }
140
+ HttpRequest req = new HttpRequest();
141
+ req.setEndpoint(baseUrl + '/services/data/v<ApiVersion>/sobjects/AuthConfigProviders');
142
+ req.setMethod('POST');
143
+ req.setHeader('Authorization', 'Bearer ' + token);
144
+ req.setHeader('Content-Type', 'application/json');
145
+ req.setBody('{"AuthConfigId":"' + ac.Id + '","AuthProviderId":"' + providerId + '"}');
146
+ HttpResponse res = http.send(req);
147
+ if (res.getStatusCode() == 201 || res.getStatusCode() == 200) {
148
+ System.debug('INSERTED:' + providerName + ':' + providerType);
149
+ inserted++;
150
+ } else {
151
+ System.debug('INSERT_FAILED:' + providerName + ':' + providerType + ':' + res.getStatusCode() + ':' + res.getBody());
152
+ }
153
+ }
154
+ if (inserted == 0 && existingProviderIds.size() >= allProviders.size()) {
155
+ System.debug('ALL_ALREADY_LINKED');
156
+ } else {
157
+ System.debug('TOTAL_INSERTED:' + inserted);
158
+ }
@@ -32,7 +32,10 @@ Every top-level key is optional; each object is strict (no extra keys).
32
32
  },
33
33
  "role": { "assignee": "currentUser", "roleName": "<UserRole name>" },
34
34
  "selfRegistration": { "selfRegProfile": "<Profile API name>",
35
- "accountName": "<display name>" }
35
+ "accountName": "<display name>" },
36
+ "socialLogin": { "communityMemberProfile": "<Profile name>",
37
+ "authProviderNames": ["<DeveloperName>", "..."],
38
+ "communityUserPermset": "<PermissionSet API name>" }
36
39
  }
37
40
  ```
38
41
 
@@ -48,6 +51,15 @@ Every top-level key is optional; each object is strict (no extra keys).
48
51
  `roleName` is a non-empty `UserRole` name.
49
52
  - **`selfRegistration`** has no license field — the required license is derived
50
53
  from `selfRegProfile` (see `references/license-checks.md`).
54
+ - **`socialLogin`** drives step 6b. `communityMemberProfile` (required) is the
55
+ profile added to `NetworkMemberGroup` so SSO-registered users can access the
56
+ site. `authProviderNames` (required, non-empty) are the **DeveloperNames** of
57
+ `AuthProvider` (OAuth) or `SamlSsoConfig` (SAML) records to link to the site's
58
+ `AuthConfig`. `communityUserPermset` (optional) is assigned to SSO-created
59
+ community users so `getCurrentUser()` works (needs `ApiEnabled`). Like
60
+ `selfRegistration`, there is **no `siteName`** — the site is derived from the
61
+ single `networks/<siteName>.network-meta.xml`. Full step detail:
62
+ `references/social-login.md`.
51
63
 
52
64
  ## Scaffolding flow (permset folder present, config missing)
53
65
 
@@ -0,0 +1,179 @@
1
+ # Social login — auth-provider linking, external profiles, community access
2
+
3
+ Detail for the **socialLogin** step (SKILL.md step 6b). Source of truth: reference
4
+ `org-setup.mjs` `loadSocialLoginConfig` (547-555), `enableExternalProfiles`
5
+ (569-617), `enableAuthProvidersForSite` (638-833), `addCommunityMemberProfile`
6
+ (847-917), `assignPermsetToCommunityUsers` (929-991), and the `main()` social-login
7
+ step (2124-2168). Config schema: `org-setup-config-schema.mjs` (65-81, strict).
8
+
9
+ Verbatim assets this step applies (do not hand-write — parity with the self-reg /
10
+ data steps): `assets/Communities.settings-meta.xml` (sub-step 1) and
11
+ `assets/social-login-auth-providers.apex` (sub-step 2). Sub-steps 3–4 are plain
12
+ `sf data query`/`create record` calls, given below.
13
+
14
+ Run this step **only** when `socialLogin` is configured in `org-setup.config.json`.
15
+ If the block is absent, `loadSocialLoginConfig` returns null and the step is hidden
16
+ — no-op cleanly. Unlike self-registration and data import, this step is
17
+ **non-destructive and idempotent**, so it does **not** require asking first.
18
+
19
+ ## Why this is programmatic (not a Setup click-path)
20
+
21
+ On React (Site Container) Experience sites the SSO admin UI is hidden, so auth
22
+ providers cannot be linked to the site by clicking through Setup → Login &
23
+ Registration. The linking is done by creating `AuthConfigProviders` junction
24
+ records that tie each `AuthProvider`/`SamlSsoConfig` to the site's `AuthConfig`.
25
+ DML is not allowed on `AuthConfigProviders`, so the linking is done via Anonymous
26
+ Apex issuing REST callouts — shipped verbatim as
27
+ `assets/social-login-auth-providers.apex` (ported from `enableAuthProvidersForSite`,
28
+ 638-833). `AuthConfig.AuthOptionsAuthProvider` auto-flips to true when the
29
+ junctions are inserted — no separate update needed.
30
+
31
+ Apply the `assets/` templates **verbatim**, exactly like the self-reg and data
32
+ steps — the Apex encodes the all-or-nothing pre-check, REST-callout insert
33
+ (DML-not-allowed workaround), and idempotency that are easy to get wrong by hand.
34
+ Do NOT invent your own social-login Apex.
35
+
36
+ Once linked, the site's built-in Social Login component (shipped in 264) renders a
37
+ button per configured provider on the React login page.
38
+
39
+ ## Config shape
40
+
41
+ ```json
42
+ { "socialLogin": {
43
+ "communityMemberProfile": "Customer Community User",
44
+ "authProviderNames": ["Google", "My_SAML_Provider"],
45
+ "communityUserPermset": "myapp_Guest_User_Api_Access"
46
+ } }
47
+ ```
48
+
49
+ - **`communityMemberProfile`** (required) — profile added to
50
+ `NetworkMemberGroup` so SSO-registered users can access the community. Also the
51
+ profile whose community users receive `communityUserPermset` (if set).
52
+ - **`authProviderNames`** (required, non-empty) — the **DeveloperNames** of
53
+ `AuthProvider` (OAuth) and/or `SamlSsoConfig` (SAML) records to link. These are
54
+ DeveloperNames, not friendly labels.
55
+ - **`communityUserPermset`** (optional) — permset assigned to SSO-created community
56
+ users so `getCurrentUser()` (`/chatter/users/me`, via `/sf/api/`) works; the
57
+ standard community profile lacks `ApiEnabled`. Typically the app's
58
+ `*_Guest_User_Api_Access` permset.
59
+
60
+ There is **no `siteName`** — the site is derived (below). All three string values
61
+ are validated against the SOQL-name whitelist before use in any query or generated
62
+ Apex (same guard the permset/self-reg paths use); a `'`, `\`, or control char is a
63
+ config error.
64
+
65
+ ## Site derivation (`deriveSiteName`, 418-441)
66
+
67
+ The site is the base name of the **single** `*.network-meta.xml` under
68
+ `<packageDir>/main/default/networks/`. Zero or more than one → STOP (ambiguous; the
69
+ reference throws rather than guessing). Social login needs the site to resolve its
70
+ `AuthConfig` (matched via `AuthConfig.Url LIKE '%<siteName>%'`).
71
+
72
+ ## Enablement sequence (mirrors `main()` 2124-2168)
73
+
74
+ Runs **after** self-registration (step 6) and **before** data import / GraphQL.
75
+ Every sub-step is idempotent — run its query first and skip work that already
76
+ exists. Substitute `<org>` with the target-org alias throughout. All three config
77
+ string values (`communityMemberProfile`, each `authProviderNames` entry,
78
+ `communityUserPermset`) MUST be validated against the SOQL-name whitelist before
79
+ use in any query/Apex below — reject any value containing `'`, `\`, or a control
80
+ char (same guard the permset/self-reg paths use); such a value is a config error.
81
+
82
+ ### 1. Enable "Allow standard external profiles" (`enableExternalProfiles`, 569-617)
83
+
84
+ An org setting required so SSO registration handlers can create users on standard
85
+ community profiles; without it, auth providers return `FIELD_INTEGRITY_EXCEPTION`
86
+ on user insert. It deploys via Metadata API (REST/Tooling approaches fail on many
87
+ org types), so the `CommunitiesSettings` file needs a minimal throwaway sfdx
88
+ project. Read `assets/Communities.settings-meta.xml` and stage it in a temp dir:
89
+
90
+ ```bash
91
+ TMP=$(mktemp -d)
92
+ mkdir -p "$TMP/force-app/main/default/settings"
93
+ printf '{"packageDirectories":[{"path":"force-app","default":true}],"sourceApiVersion":"68.0"}' > "$TMP/sfdx-project.json"
94
+ cp skills/experience-ui-bundle-deploy/assets/Communities.settings-meta.xml \
95
+ "$TMP/force-app/main/default/settings/Communities.settings-meta.xml"
96
+ sf project deploy start --target-org <org> --source-dir "$TMP/force-app" --json
97
+ rm -rf "$TMP"
98
+ ```
99
+
100
+ A deploy warning that the setting is already active is a **non-fatal skip** — the
101
+ setting may already be on. Continue to sub-step 2.
102
+
103
+ ### 2. Link Auth Providers to the site `AuthConfig` (`enableAuthProvidersForSite`, 638-833)
104
+
105
+ Apply `assets/social-login-auth-providers.apex` **verbatim** — do not hand-write
106
+ this. Substitute its placeholders: `<siteName>` (derived above), `<ProviderNamesList>`
107
+ (the whitelisted `authProviderNames` as a comma-separated single-quoted list, e.g.
108
+ `'Google', 'My_SAML_Provider'` — identical in both the `IN (...)` clauses and the
109
+ requested-name loop), and `<ApiVersion>` (e.g. `62.0`). Then run it as ONE call:
110
+
111
+ ```bash
112
+ sf apex run --target-org <org> --file assets/social-login-auth-providers.apex
113
+ ```
114
+
115
+ Read the `|DEBUG|` output lines (match `|DEBUG|` only — `sf apex run` echoes the
116
+ source, which would otherwise false-positive):
117
+
118
+ | `|DEBUG|` line | Meaning → action |
119
+ |----------------|------------------|
120
+ | `ERROR_NO_AUTHCONFIG` | No `AuthConfig` for the site → **fail**: "no AuthConfig found for site `<siteName>`". Publish/activate the site; confirm the derived name matches the org Network. |
121
+ | `ERROR_NO_PROVIDERS` | None of the names resolved → **fail**: none found for those names; create them in Setup first. |
122
+ | `MISSING_PROVIDERS:<names>` | Strict subset resolved → **fail**: "some configured auth providers were not found: `<names>`". Nothing was linked (all-or-nothing; the check runs before any insert). Create/fix them or fix the DeveloperName(s) and re-run. |
123
+ | `INSERT_FAILED:<name>:<type>:<code>:<body>` | A junction insert failed → **fail** after reporting each; `<code>`/`<body>` explain why. |
124
+ | `INSERTED:<name>:<type>` | Newly linked (report `+ <name>`). |
125
+ | `ALREADY_LINKED:<name>:<type>` / `ALL_ALREADY_LINKED` | Idempotent skip — already linked; report and continue. |
126
+ | `TOTAL_INSERTED:<n>` | Success — `<n>` providers newly linked. |
127
+
128
+ Matching is **case-insensitive** (SOQL `DeveloperName IN (...)` is), so a stored
129
+ name differing only in case is not "missing."
130
+
131
+ ### 3. Add the community member profile to `NetworkMemberGroup` (`addCommunityMemberProfile`, 847-917)
132
+
133
+ Without it, users created by the SSO registration handler hit `NO_ACCESS: User was
134
+ not authorized for the community`. Resolve the Network + Profile Ids, skip if the
135
+ membership already exists, else create it (idempotent):
136
+
137
+ ```bash
138
+ # Resolve Ids (<siteName> derived above; <communityMemberProfile> from config)
139
+ sf data query --target-org <org> --json \
140
+ --query "SELECT Id FROM Network WHERE Name = '<siteName>'" # -> <NetworkId>
141
+ sf data query --target-org <org> --json \
142
+ --query "SELECT Id FROM Profile WHERE Name = '<communityMemberProfile>'" # -> <ProfileId>
143
+ # Idempotency check — skip the create if this returns any record
144
+ sf data query --target-org <org> --json \
145
+ --query "SELECT Id FROM NetworkMemberGroup WHERE NetworkId = '<NetworkId>' AND ParentId = '<ProfileId>'"
146
+ # Create only if absent
147
+ sf data create record --target-org <org> --sobject NetworkMemberGroup \
148
+ --values "NetworkId='<NetworkId>' ParentId='<ProfileId>'" --json
149
+ ```
150
+
151
+ ### 4. (Optional) Assign `communityUserPermset` to community users (`assignPermsetToCommunityUsers`, 929-991)
152
+
153
+ Only when `communityUserPermset` is configured. Grants `ApiEnabled` so
154
+ `getCurrentUser()` (`/chatter/users/me` via `/sf/api/`) works for SSO-created
155
+ users. Find active community users on `communityMemberProfile` who lack the
156
+ permset, and assign it (idempotent; no users yet → skip, not fatal):
157
+
158
+ ```bash
159
+ # Resolve the permset Id
160
+ sf data query --target-org <org> --json \
161
+ --query "SELECT Id FROM PermissionSet WHERE Name = '<communityUserPermset>'" # -> <PermSetId>
162
+ # Find users on the profile who do NOT already have it
163
+ sf data query --target-org <org> --json \
164
+ --query "SELECT Id, Username FROM User WHERE Profile.Name = '<communityMemberProfile>' AND IsActive = true AND UserType IN ('CspLitePortal','CustomerSuccess','PowerCustomerSuccess') AND Id NOT IN (SELECT AssigneeId FROM PermissionSetAssignment WHERE PermissionSetId = '<PermSetId>')"
165
+ # For each returned user Id, assign (treat DUPLICATE_VALUE as an already-assigned skip)
166
+ sf data create record --target-org <org> --sobject PermissionSetAssignment \
167
+ --values "PermissionSetId='<PermSetId>' AssigneeId='<UserId>'" --json
168
+ ```
169
+
170
+ ## Gotchas
171
+
172
+ | Symptom | Cause | Fix |
173
+ |---------|-------|-----|
174
+ | No social-login buttons on the login page | `socialLogin` block absent or step skipped | Add the block and run step 6b; it links providers to the site `AuthConfig` |
175
+ | "some configured auth providers were not found: X" | A DeveloperName in `authProviderNames` has no `AuthProvider`/`SamlSsoConfig` record | Create it in Setup first, or fix the DeveloperName. Nothing is linked until all resolve |
176
+ | `no AuthConfig found for site "<name>"` | Site not published/active, or name mis-derived | Publish the site; confirm the single `*.network-meta.xml` base name matches the org's Network name |
177
+ | SSO user: `NO_ACCESS: User was not authorized for the community` | `communityMemberProfile` not in `NetworkMemberGroup` | Ensure sub-step 3 ran (profile added to member groups) |
178
+ | SSO user insert fails with `FIELD_INTEGRITY_EXCEPTION` | "Allow standard external profiles" org setting off | Ensure sub-step 1 ran (`enableExternalProfiles`) |
179
+ | `getCurrentUser()` / `/chatter/users/me` fails for SSO users | Community profile lacks `ApiEnabled` | Set `communityUserPermset` so sub-step 4 assigns API access |
@@ -5,6 +5,7 @@ metadata:
5
5
  version: "1.1"
6
6
  relatedSkills:
7
7
  - "experience-ui-bundle-app-coordinate"
8
+ - "experience-ui-bundle-features-generate"
8
9
  - "experience-ui-bundle-metadata-generate"
9
10
  - "experience-ui-bundle-salesforce-data-access"
10
11
  cliTools:
@@ -51,6 +52,19 @@ A request to rename/rebrand the app (e.g. "call it X everywhere a user would see
51
52
 
52
53
  ---
53
54
 
55
+ ## Pre-built Features (Check Before Hand-Building)
56
+
57
+ Some capabilities ship as pre-built, tested feature packages. The catalog **evolves and is not something you can know from memory** — never decide from the request wording alone whether a capability "is" or "isn't" a feature. Before hand-writing any non-trivial capability (anything beyond a plain page, component, or styling change) in this skill:
58
+
59
+ 1. **Consult the authoritative catalog.** Invoke `experience-ui-bundle-features-generate`, which runs `list` to show the *current* set of installable features. Do not rely on a hardcoded or remembered list — this skill deliberately names none, because any names it listed would go stale.
60
+ 2. **Detect whether a matching feature is already installed** in the bundle — inspect `package.json` dependencies and existing `src/` files. If present, use it as-is; do not reinstall or re-implement.
61
+ 3. **If a matching feature exists in the catalog but isn't installed**, let `experience-ui-bundle-features-generate` install the tested package. Do not build it from scratch here.
62
+ 4. **Only hand-build** a capability that has no matching catalog feature.
63
+
64
+ This gate is **idempotent**: when this skill runs as a phase of `experience-ui-bundle-app-coordinate` (which installs features earlier in its sequence), step 2 finds the feature already present and this collapses to a no-op. It only does real work when the skill was reached directly — the path that would otherwise skip feature detection.
65
+
66
+ ---
67
+
54
68
  ## Layout and Navigation
55
69
 
56
70
  `appLayout.tsx` is the source of truth for navigation and layout. Every page shares this shell.
@@ -2,21 +2,22 @@
2
2
  name: experience-ui-bundle-mfa-configure
3
3
  description: "Configure Multi-Factor Authentication (MFA) for Salesforce Experience Site users. TRIGGER when: user wants to enable MFA on a community, enforce two-factor authentication for portal users, add MFA to a React Experience Site / Web App, configure ForceTwoFactor permission, create MFA permission sets for external users, or troubleshoot MFA not appearing on login. Also triggers on: MFA community, two-factor portal, ForceTwoFactor permission set, MFA Experience Cloud, MFA React site, identity verification community, MFA experience site, ForceTwoFactor permissionset-meta.xml, MFA permissionset-meta.xml. DO NOT TRIGGER when: configuring org-wide MFA for internal users (that's Setup > Identity Verification), building custom login UI components (use experience-ui-bundle-frontend-generate), or generating generic permission sets without MFA context (use platform-permission-set-generate)."
4
4
  metadata:
5
- version: "1.0"
5
+ version: "1.1"
6
6
  minApiVersion: "47.0"
7
7
  cliTools:
8
- - tool: ["sf"]
9
- semver: ">=2.0.0"
10
8
  - tool: ["jq"]
11
9
  semver: ">=1.6"
10
+ - tool: ["sf"]
11
+ semver: ">=2.0.0"
12
12
  accessCheck:
13
13
  - type: "license"
14
14
  value: "Experience Cloud (Customer Community / Customer Community Login)"
15
15
  relatedSkills:
16
- - "platform-permission-set-generate"
17
16
  - "dx-org-permission-set-assign"
17
+ - "experience-ui-bundle-deploy"
18
18
  - "experience-ui-bundle-frontend-generate"
19
19
  - "platform-metadata-deploy"
20
+ - "platform-permission-set-generate"
20
21
  ---
21
22
 
22
23
  # Enabling MFA on Experience Sites
@@ -370,7 +371,7 @@ Files generated in the user's project:
370
371
  | User needs to deploy all project metadata | `platform-metadata-deploy` |
371
372
  | User wants to customize the login page UI | `experience-ui-bundle-frontend-generate` |
372
373
  | User needs to create a new generic permission set | `platform-permission-set-generate` |
373
- | User wants IDP/Social Login (different from MFA) | Supported on React sites — the built-in Social Login component renders configured Auth Providers on the login page automatically (shipped in 264). Configure Auth Providers in Setup; no custom code needed. See `references/social-login.md`. |
374
+ | User wants IDP/Social Login (different from MFA) | Supported on React sites — the built-in Social Login component renders linked Auth Providers on the login page automatically. Create the Auth Providers in Setup, then link them to the React site via the `experience-ui-bundle-deploy` social login step (`socialLogin` in `org-setup.config.json`) — the React SSO admin UI is hidden, so linking is programmatic, not a Setup click-path. See `references/social-login.md`. |
374
375
 
375
376
  ---
376
377
 
@@ -24,12 +24,20 @@ writing a component.
24
24
 
25
25
  ## How to enable
26
26
 
27
- 1. **Configure the Auth Provider(s)** in Setup → Identity → Auth. Providers
28
- (e.g. Google, Facebook, Salesforce, or a SAML/OpenID Connect provider).
29
- 2. **Add the provider(s) to the site's login configuration** so they are
30
- exposed to the community — Setup → Digital Experiences → *(site)* →
31
- Administration → Login & Registration.
32
- 3. **Publish** the site. The React login page renders a button per configured
27
+ 1. **Create the Auth Provider(s)** in Setup → Identity → Auth. Providers
28
+ (e.g. Google, Facebook, Salesforce, or a SAML/OpenID Connect provider). This
29
+ part is done in Setup as usual.
30
+ 2. **Link the provider(s) to the React site.** Do **not** use Setup → Digital
31
+ Experiences → Login & Registration for this — on React (Site Container) sites
32
+ that SSO admin UI is **hidden**, so the provider cannot be attached to the site
33
+ by clicking through Setup. The link is created programmatically by writing
34
+ `AuthConfigProviders` junction records against the site's `AuthConfig`. Use the
35
+ `experience-ui-bundle-deploy` skill's **social login step** (a `socialLogin`
36
+ block in `org-setup.config.json` with `communityMemberProfile` +
37
+ `authProviderNames`), which runs the shipped org-setup automation and also adds
38
+ the community profile to the site's `NetworkMemberGroup`. See that skill's
39
+ `references/social-login.md` for the mechanism and config.
40
+ 3. **Publish** the site. The React login page renders a button per linked
33
41
  provider automatically.
34
42
 
35
43
  ## How the redirect works (for troubleshooting)
@@ -56,7 +64,7 @@ writing a component.
56
64
 
57
65
  | Symptom | Cause | Fix |
58
66
  |---------|-------|-----|
59
- | No provider buttons on React login page | No Auth Providers configured, or not added to the site's Login & Registration settings | Configure Auth Providers and add them to the site, then re-publish |
67
+ | No provider buttons on React login page | No Auth Providers created, or created but not linked to the site's `AuthConfig` (React sites can't be linked via the Login & Registration UI — it's hidden) | Create the Auth Providers, then link them via the `experience-ui-bundle-deploy` social login step (`socialLogin` in `org-setup.config.json`), and re-publish |
60
68
  | Buttons appear but SSO fails to start | `startURL` points at `/` or `/login` | Set `startURL` to the site home path |
61
69
  | Redirect loop after SSO | `startURL` misconfigured | Point `startURL` at the site home path, not the login page |
62
70
  | Provider button missing an icon | Auth Provider icon not set | Set the icon on the Auth Provider definition |