@salesforce/afv-skills 1.46.0 → 1.48.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 (317) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-observe/SKILL.md +32 -4
  3. package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
  4. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
  5. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
  6. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
  7. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
  8. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
  9. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
  10. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
  11. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
  12. package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
  13. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
  14. package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
  15. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
  16. package/skills/dx-devops-project-manage/SKILL.md +197 -0
  17. package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
  18. package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
  19. package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
  20. package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
  21. package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
  22. package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
  23. package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
  24. package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
  25. package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
  26. package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
  27. package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
  28. package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
  29. package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
  30. package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
  31. package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
  32. package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
  33. package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
  34. package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
  35. package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
  36. package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
  37. package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
  38. package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
  39. package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
  40. package/skills/education-cloud-domain-configure/SKILL.md +234 -0
  41. package/skills/education-cloud-domain-configure/references/dependent-features.md +198 -0
  42. package/skills/education-cloud-domain-configure/references/domain-features/academic-operations.md +386 -0
  43. package/skills/education-cloud-domain-configure/references/domain-features/alumni-relations.md +155 -0
  44. package/skills/education-cloud-domain-configure/references/domain-features/cross-domain-dependencies.md +18 -0
  45. package/skills/education-cloud-domain-configure/references/domain-features/industriessettings-toggle-reference.md +43 -0
  46. package/skills/education-cloud-domain-configure/references/domain-features/mentoring.md +198 -0
  47. package/skills/education-cloud-domain-configure/references/domain-features/recruitment-admissions.md +315 -0
  48. package/skills/education-cloud-domain-configure/references/domain-features/student-management.md +155 -0
  49. package/skills/education-cloud-domain-configure/references/domain-features/student-success.md +249 -0
  50. package/skills/education-cloud-domain-configure/references/domain-features.md +27 -0
  51. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +23 -0
  52. package/skills/education-cloud-domain-configure/references/toggle-write-path.md +67 -0
  53. package/skills/education-cloud-domain-configure/scripts/check_license_provisioned.py +62 -0
  54. package/skills/education-cloud-domain-configure/scripts/check_org_edition.py +44 -0
  55. package/skills/education-cloud-domain-configure/scripts/check_permission_assigned.py +39 -0
  56. package/skills/education-cloud-multi-campus-configure/SKILL.md +7 -0
  57. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +1 -2
  58. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
  59. package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
  60. package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
  61. package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
  62. package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
  63. package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
  64. package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
  65. package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
  66. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
  67. package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
  68. package/skills/experience-cms-brand-apply/SKILL.md +5 -5
  69. package/skills/experience-cms-brand-create/SKILL.md +2 -2
  70. package/skills/experience-cms-content-generate/SKILL.md +1 -0
  71. package/skills/experience-cms-content-render/SKILL.md +173 -0
  72. package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
  73. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
  74. package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
  75. package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
  76. package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
  77. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
  78. package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
  79. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
  80. package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
  81. package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
  82. package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
  83. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
  84. package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
  85. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
  86. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
  87. package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
  88. package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
  89. package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
  90. package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
  91. package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
  92. package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
  93. package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
  94. package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
  95. package/skills/experience-cms-content-render/references/package-api.md +106 -0
  96. package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
  97. package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
  98. package/skills/experience-cms-content-render/references/verify.md +49 -0
  99. package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
  100. package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
  101. package/skills/experience-search-coordinate/SKILL.md +198 -0
  102. package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
  103. package/skills/experience-search-coordinate/references/content-route.md +313 -0
  104. package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
  105. package/skills/experience-search-coordinate/references/media-route.md +172 -0
  106. package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
  107. package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
  108. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
  109. package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
  110. package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
  111. package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
  112. package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
  113. package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
  114. package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
  115. package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
  116. package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
  117. package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
  118. package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
  119. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
  120. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
  121. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
  122. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
  123. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
  124. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
  125. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
  126. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
  127. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
  128. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
  129. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
  130. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
  131. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
  132. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
  133. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
  134. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
  135. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
  136. package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
  137. package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
  138. package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
  139. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
  140. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
  141. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
  142. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
  143. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
  144. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
  145. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
  146. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
  147. package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
  148. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
  149. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
  150. package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
  151. package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
  152. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
  153. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
  154. package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
  155. package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
  156. package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
  157. package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
  158. package/skills/life-sciences-territory-configure/SKILL.md +217 -0
  159. package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
  160. package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
  161. package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
  162. package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
  163. package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
  164. package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
  165. package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
  166. package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
  167. package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
  168. package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
  169. package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
  170. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
  171. package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
  172. package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
  173. package/skills/service-agentforce-channel-configure/SKILL.md +33 -28
  174. package/skills/service-agentforce-human-escalation-configure/SKILL.md +205 -0
  175. package/skills/service-agentforce-human-escalation-configure/assets/escalation-thresholds.instructions.md +37 -0
  176. package/skills/service-agentforce-human-escalation-configure/assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml +173 -0
  177. package/skills/service-agentforce-human-escalation-configure/assets/package.xml +8 -0
  178. package/skills/service-agentforce-human-escalation-configure/assets/sfdx-project.json +5 -0
  179. package/skills/service-agentforce-human-escalation-configure/references/classifier-contracts.md +103 -0
  180. package/skills/service-agentforce-human-escalation-configure/references/escalation-mechanism.md +63 -0
  181. package/skills/service-agentforce-human-escalation-configure/references/failure-policy.md +44 -0
  182. package/skills/service-agentforce-human-escalation-configure/references/nga-escalation.md +57 -0
  183. package/skills/service-agentforce-human-escalation-configure/references/runtime-verification.md +72 -0
  184. package/skills/service-agentforce-human-escalation-configure/scripts/classify-agent-active.mjs +49 -0
  185. package/skills/service-agentforce-human-escalation-configure/scripts/classify-nga-escalation.mjs +166 -0
  186. package/skills/service-agentforce-human-escalation-configure/scripts/extract-outbound-route.mjs +67 -0
  187. package/skills/service-agentforce-human-escalation-configure/scripts/patch-escalation-surfaces.mjs +131 -0
  188. package/skills/service-agentforce-human-escalation-configure/scripts/tests/__init__.py +0 -0
  189. package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +249 -0
  190. package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +899 -0
  191. package/skills/service-agentforce-human-escalation-configure/scripts/verify-and-configure.sh +705 -0
  192. package/skills/service-agentforce-human-escalation-configure/scripts/verify-escalation-config.mjs +89 -0
  193. package/skills/service-de-channel-routing-configure/SKILL.md +13 -5
  194. package/skills/service-de-channel-routing-configure/scripts/tests/test_skill_contract.py +25 -0
  195. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +23 -10
  196. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -48
  197. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +6 -2
  198. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
  199. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
  200. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
  201. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
  202. package/skills/service-omni-agent-users-create/SKILL.md +96 -0
  203. package/skills/service-omni-agent-users-create/assets/create-users.apex.template +80 -0
  204. package/skills/service-omni-agent-users-create/references/apex-patterns.md +135 -0
  205. package/skills/service-omni-agent-users-create/references/apex-template-notes.md +40 -0
  206. package/skills/service-omni-agent-users-create/scripts/detect-and-create.sh +206 -0
  207. package/skills/service-omni-agent-users-create/scripts/detect-existing.sh +122 -0
  208. package/skills/service-omni-agent-users-create/scripts/run-create.sh +298 -0
  209. package/skills/service-omni-agent-users-create/scripts/tests/test_user_create_security.py +171 -0
  210. package/skills/service-omni-agent-work-sharing-configure/SKILL.md +78 -0
  211. package/skills/service-omni-agent-work-sharing-configure/references/api-notes.md +31 -0
  212. package/skills/service-omni-agent-work-sharing-configure/scripts/configure-and-report.sh +186 -0
  213. package/skills/service-omni-agent-work-sharing-configure/scripts/tests/_bootstrap.py +120 -0
  214. package/skills/service-omni-agent-work-sharing-configure/scripts/tests/test_agent_work_sharing_contracts.py +93 -0
  215. package/skills/service-omni-base-settings-configure/SKILL.md +77 -0
  216. package/skills/service-omni-base-settings-configure/assets/force-app/main/default/settings/OmniChannel.settings-meta.xml +8 -0
  217. package/skills/service-omni-base-settings-configure/assets/package.xml +8 -0
  218. package/skills/service-omni-base-settings-configure/assets/sfdx-project.json +12 -0
  219. package/skills/service-omni-base-settings-configure/references/api-notes.md +121 -0
  220. package/skills/service-omni-base-settings-configure/scripts/configure-and-report.sh +164 -0
  221. package/skills/service-omni-base-settings-configure/scripts/detect-existing.sh +69 -0
  222. package/skills/service-omni-channel-setup-coordinate/SKILL.md +168 -0
  223. package/skills/service-omni-channel-setup-coordinate/examples/output-templates.md +161 -0
  224. package/skills/service-omni-channel-setup-coordinate/references/gap-catalog.md +99 -0
  225. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +1542 -0
  226. package/skills/service-omni-channel-setup-coordinate/scripts/tests/__init__.py +0 -0
  227. package/skills/service-omni-channel-setup-coordinate/scripts/tests/_bootstrap.py +223 -0
  228. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +804 -0
  229. package/skills/service-omni-command-center-analyze/SKILL.md +84 -0
  230. package/skills/service-omni-command-center-analyze/references/api-notes.md +54 -0
  231. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +198 -0
  232. package/skills/service-omni-command-center-analyze/scripts/tests/_bootstrap.py +115 -0
  233. package/skills/service-omni-command-center-analyze/scripts/tests/test_command_center_analyze_contracts.py +165 -0
  234. package/skills/service-omni-permission-set-assign/SKILL.md +88 -0
  235. package/skills/service-omni-permission-set-assign/assets/package.xml +8 -0
  236. package/skills/service-omni-permission-set-assign/references/api-notes.md +143 -0
  237. package/skills/service-omni-permission-set-assign/scripts/verify-and-assign.sh +397 -0
  238. package/skills/service-omni-presence-status-deploy/SKILL.md +87 -0
  239. package/skills/service-omni-presence-status-deploy/assets/package.xml +12 -0
  240. package/skills/service-omni-presence-status-deploy/references/api-notes.md +115 -0
  241. package/skills/service-omni-presence-status-deploy/scripts/deploy-and-report.sh +422 -0
  242. package/skills/service-omni-presence-user-config-deploy/SKILL.md +80 -0
  243. package/skills/service-omni-presence-user-config-deploy/references/api-notes.md +60 -0
  244. package/skills/service-omni-presence-user-config-deploy/scripts/deploy-and-report.sh +261 -0
  245. package/skills/service-omni-presence-user-config-deploy/scripts/tests/_bootstrap.py +106 -0
  246. package/skills/service-omni-presence-user-config-deploy/scripts/tests/test_presence_user_config_contracts.py +142 -0
  247. package/skills/service-omni-queue-deploy/SKILL.md +91 -0
  248. package/skills/service-omni-queue-deploy/references/api-notes.md +140 -0
  249. package/skills/service-omni-queue-deploy/scripts/verify-and-align.sh +470 -0
  250. package/skills/service-omni-queue-members-assign/SKILL.md +93 -0
  251. package/skills/service-omni-queue-members-assign/references/api-notes.md +144 -0
  252. package/skills/service-omni-queue-members-assign/scripts/tests/_bootstrap.py +67 -0
  253. package/skills/service-omni-queue-members-assign/scripts/tests/test_queue_members_contracts.py +73 -0
  254. package/skills/service-omni-queue-members-assign/scripts/verify-and-bind.sh +362 -0
  255. package/skills/service-omni-queue-routing-config-deploy/SKILL.md +101 -0
  256. package/skills/service-omni-queue-routing-config-deploy/references/api-notes.md +127 -0
  257. package/skills/service-omni-queue-routing-config-deploy/scripts/tests/_bootstrap.py +90 -0
  258. package/skills/service-omni-queue-routing-config-deploy/scripts/tests/test_queue_routing_config_contracts.py +70 -0
  259. package/skills/service-omni-queue-routing-config-deploy/scripts/upsert-and-report.sh +538 -0
  260. package/skills/service-omni-routing-flow-deploy/SKILL.md +111 -0
  261. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.SkillsBased.flow-meta.xml +94 -0
  262. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.flow-meta.xml +88 -0
  263. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Cases.flow-meta.xml +144 -0
  264. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.SkillsBased.flow-meta.xml +94 -0
  265. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.flow-meta.xml +88 -0
  266. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCalls.flow-meta.xml +144 -0
  267. package/skills/service-omni-routing-flow-deploy/assets/package.xml +11 -0
  268. package/skills/service-omni-routing-flow-deploy/assets/sfdx-project.json +11 -0
  269. package/skills/service-omni-routing-flow-deploy/references/api-notes.md +265 -0
  270. package/skills/service-omni-routing-flow-deploy/scripts/deploy-and-report.sh +684 -0
  271. package/skills/service-omni-service-channel-configure/SKILL.md +83 -0
  272. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Cases.serviceChannel-meta.xml +9 -0
  273. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Incidents.serviceChannel-meta.xml +9 -0
  274. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/MessagingSessions.serviceChannel-meta.xml +9 -0
  275. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/VoiceCalls.serviceChannel-meta.xml +9 -0
  276. package/skills/service-omni-service-channel-configure/assets/package.xml +11 -0
  277. package/skills/service-omni-service-channel-configure/assets/sfdx-project.json +12 -0
  278. package/skills/service-omni-service-channel-configure/references/api-notes.md +84 -0
  279. package/skills/service-omni-service-channel-configure/scripts/deploy-and-report.sh +383 -0
  280. package/skills/service-omni-sidebar-configure/SKILL.md +77 -0
  281. package/skills/service-omni-sidebar-configure/references/api-notes.md +51 -0
  282. package/skills/service-omni-sidebar-configure/scripts/enable-and-report.sh +315 -0
  283. package/skills/service-omni-sidebar-configure/scripts/tests/_bootstrap.py +142 -0
  284. package/skills/service-omni-sidebar-configure/scripts/tests/test_sidebar_contracts.py +139 -0
  285. package/skills/service-omni-skills-based-routing-configure/SKILL.md +81 -0
  286. package/skills/service-omni-skills-based-routing-configure/references/api-notes.md +50 -0
  287. package/skills/service-omni-skills-based-routing-configure/scripts/configure-and-report.sh +270 -0
  288. package/skills/service-omni-skills-based-routing-configure/scripts/tests/_bootstrap.py +120 -0
  289. package/skills/service-omni-skills-based-routing-configure/scripts/tests/test_sbr_contracts.py +129 -0
  290. package/skills/service-omni-supervisor-config-deploy/SKILL.md +97 -0
  291. package/skills/service-omni-supervisor-config-deploy/assets/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml +9 -0
  292. package/skills/service-omni-supervisor-config-deploy/assets/package.xml +8 -0
  293. package/skills/service-omni-supervisor-config-deploy/assets/sfdx-project.json +12 -0
  294. package/skills/service-omni-supervisor-config-deploy/references/api-notes.md +205 -0
  295. package/skills/service-omni-supervisor-config-deploy/scripts/deploy-and-report.sh +586 -0
  296. package/skills/service-omni-supervisor-config-deploy/scripts/tests/_bootstrap.py +153 -0
  297. package/skills/service-omni-supervisor-config-deploy/scripts/tests/test_supervisor_config_contracts.py +116 -0
  298. package/skills/service-omni-supervisor-permset-assign/SKILL.md +88 -0
  299. package/skills/service-omni-supervisor-permset-assign/references/api-notes.md +48 -0
  300. package/skills/service-omni-supervisor-permset-assign/scripts/verify-and-assign.sh +316 -0
  301. package/skills/service-omni-supervisor-surface-deploy/SKILL.md +85 -0
  302. package/skills/service-omni-supervisor-surface-deploy/references/api-notes.md +47 -0
  303. package/skills/service-omni-supervisor-surface-deploy/scripts/deploy-and-report.sh +216 -0
  304. package/skills/service-omni-supervisor-surface-deploy/scripts/tests/_bootstrap.py +95 -0
  305. package/skills/service-omni-supervisor-surface-deploy/scripts/tests/test_supervisor_surface_contracts.py +154 -0
  306. package/skills/service-omni-supervisor-users-create/SKILL.md +92 -0
  307. package/skills/service-omni-supervisor-users-create/assets/create-supervisors.apex.template +72 -0
  308. package/skills/service-omni-supervisor-users-create/references/apex-patterns.md +73 -0
  309. package/skills/service-omni-supervisor-users-create/references/apex-template-notes.md +41 -0
  310. package/skills/service-omni-supervisor-users-create/scripts/detect-and-create.sh +197 -0
  311. package/skills/service-omni-supervisor-users-create/scripts/detect-existing.sh +112 -0
  312. package/skills/service-omni-supervisor-users-create/scripts/run-create.sh +296 -0
  313. package/skills/service-omni-work-skill-routing-configure/SKILL.md +80 -0
  314. package/skills/service-omni-work-skill-routing-configure/references/api-notes.md +67 -0
  315. package/skills/service-omni-work-skill-routing-configure/scripts/configure-and-report.sh +262 -0
  316. package/skills/service-omni-work-skill-routing-configure/scripts/tests/_bootstrap.py +121 -0
  317. package/skills/service-omni-work-skill-routing-configure/scripts/tests/test_work_skill_routing_contracts.py +161 -0
@@ -0,0 +1,122 @@
1
+ # Init scaffold — runtime tree, verbatim copy, foundation sets
2
+
3
+ Detail for the **Init** mode and **Init vs Embed detection** (SKILL.md → *Modes*,
4
+ *Init vs Embed detection*). SKILL.md holds the decision rules; this file holds the
5
+ file tree, the Read→Write copy mechanics, and the per-framework foundation sets used
6
+ for detection.
7
+
8
+ ## Runtime tree (framework-scoped under `src/cms/`)
9
+
10
+ Init writes the shared runtime once, plus the detected framework's pair:
11
+
12
+ ```text
13
+ src/cms/
14
+ shared/ ← framework-agnostic, always written
15
+ cmsCore.types.ts ← CmsExternalRef, CmsRef, AnyCmsRef, CmsFieldType; re-exports CmsImageField
16
+ externalRefs.ts ← ref catalog + CMS_CHANNEL_ID_FALLBACK (marker-blocked)
17
+ react/ ← written ONLY when framework=react
18
+ useCmsItem.ts ← item hook: cache + inflight dedup (StrictMode-safe)
19
+ heuristicRenderer.tsx ← schema-less renderer: field-pick + value-shape dispatch + sanitizer plug + resolveImageSrc (the ONE RichText injection site)
20
+ angular/ ← written ONLY when framework=angular
21
+ cms-item.service.ts ← item service: shared cache + inflight dedup
22
+ cms-content.component.ts ← schema-less renderer (the ONE RichText injection site)
23
+ ```
24
+
25
+ Per-type generated code lands under the framework's `types/` dir, created on the
26
+ first Embed; each renderer imports its sibling by direct path, so there is no barrel
27
+ to maintain. Detail pages land under `src/pages/<type>/`. The skill never creates
28
+ tests, CSS files, router files, or app entry; `main.tsx`/`App.tsx` / Angular
29
+ bootstrap must pre-exist.
30
+
31
+ The toolkit's `content-metadata.json` catalog (`<appRoot>/public/content-metadata.json`)
32
+ is written **on demand at the first `CmsRef` embed that needs a channel** — NOT at Init,
33
+ and NOT for foreign-ref-only apps (Rule 1; shape + policy in `references/package-api.md`).
34
+ It is a pipeline-regenerated data seam (the deploy pipeline overwrites it per target org),
35
+ so it is **explicitly NOT part of the foundation detection sets below** — otherwise every
36
+ pre-existing app that already carries a catalog would mis-classify as drift.
37
+
38
+ ## Emit runtime files VERBATIM — Read→Write, don't retype
39
+
40
+ The foundation files are pure copies: never reconstruct API behaviour from memory
41
+ (the templates encode the StrictMode hook, the sanitizer seam, and the correct
42
+ package call sites). Only `cmsContentType.ts` and the renderer templates carry
43
+ `{{…}}` substitution — those are handled in Embed, not here.
44
+
45
+ For each file in the set, **`Read` the template by its skill-relative path and
46
+ `Write` it unchanged to the destination**. The harness loads `assets/` alongside
47
+ SKILL.md, so no CWD, absolute path, or shell command is involved. **Skip any
48
+ destination that already exists — never overwrite**, so this is safe for Init *and*
49
+ the drift-complete branch. If a `Read` fails because the asset is not loadable in
50
+ this harness, FALL BACK to the byte-by-byte VERBATIM copy for that file.
51
+
52
+ | `Read` (skill-relative) | `Write` (under `<appRoot>/`) |
53
+ |-------------------------|------------------------------|
54
+ | `assets/shared/cmsCore.types.ts` | `src/cms/shared/cmsCore.types.ts` |
55
+ | `assets/shared/externalRefs.ts` | `src/cms/shared/externalRefs.ts` |
56
+ | `assets/react/useCmsItem.ts` *(react)* | `src/cms/react/useCmsItem.ts` |
57
+ | `assets/react/heuristicRenderer.tsx` *(react)* | `src/cms/react/heuristicRenderer.tsx` |
58
+ | `assets/angular/cms-item.service.ts` *(angular)* | `src/cms/angular/cms-item.service.ts` |
59
+ | `assets/angular/cms-content.component.ts` *(angular)* | `src/cms/angular/cms-content.component.ts` |
60
+
61
+ Copy the shared pair always, plus the detected framework's pair. This NEVER touches
62
+ the `{{…}}`-substituted templates (`cmsContentType.ts`, the per-type renderers,
63
+ detail pages).
64
+
65
+ No dev proxy is scaffolded: the CMS delivery backend serves CORS headers, so the
66
+ browser fetches the CDN directly in dev and `vite.config.ts` stays the standard
67
+ React config. (The former dev-proxy rule was removed; SKILL.md → *Codegen
68
+ guardrails*.)
69
+
70
+ ## Media renderer — VERBATIM, emitted on the first media embed
71
+
72
+ Standalone media (`sfdc_cms__{image,audio,video,document}`) is a predefined type: it
73
+ renders through one shared, verbatim `MediaRenderer` per framework, not a generated
74
+ per-type renderer. On the FIRST media embed, `Read`→`Write` the framework's media
75
+ renderer (skip if it already exists — never overwrite):
76
+
77
+ | `Read` (skill-relative) | `Write` (under `<appRoot>/`) |
78
+ |-------------------------|------------------------------|
79
+ | `assets/react/MediaRenderer.tsx` *(react)* | `src/cms/react/MediaRenderer.tsx` |
80
+ | `assets/angular/MediaRenderer.component.ts` *(angular)* | `src/cms/angular/MediaRenderer.component.ts` |
81
+
82
+ The media types (`CmsMediaBody`, `CmsMediaField`, `CmsMediaType`) ship inside the
83
+ always-written `shared/cmsCore.types.ts`, so a media embed onto an existing runtime
84
+ needs only the one renderer file plus the ref entry — provided the runtime's
85
+ `cmsCore.types.ts` carries the media exports (a pre-media scaffold that lacks them is
86
+ Init drift on that file; HALT, don't silently patch). On the `contentKey` path URL
87
+ resolution is entirely toolkit-owned (`resolveCmsImageUrl` / `resolveMediaUrl`); no
88
+ local prefix helper ships. On the foreign `url` path the renderer uses `ref.url`
89
+ directly — no resolver, no fetch (Rule 1/Rule 2).
90
+
91
+ **The media renderer is NOT in the foundation sets below.** Init/Embed detection is
92
+ unchanged: a runtime scaffolded before media existed is still a complete `embed`
93
+ runtime, and the media renderer is written lazily on the first media embed exactly
94
+ like a per-type `<type>.ts`. Do not add `MediaRenderer.*` to the detection sets, or
95
+ every pre-media app would mis-classify as drift.
96
+
97
+ ## Foundation sets (used by Init vs Embed detection)
98
+
99
+ Check every path for existence against the target uiBundle root (the dir with
100
+ `src/`), then classify by how many are present — not a single canary:
101
+
102
+ - **React foundation set:** `src/cms/shared/cmsCore.types.ts`,
103
+ `src/cms/shared/externalRefs.ts`, `src/cms/react/heuristicRenderer.tsx`,
104
+ `src/cms/react/useCmsItem.ts`.
105
+ - **Angular foundation set:** `src/cms/shared/cmsCore.types.ts`,
106
+ `src/cms/shared/externalRefs.ts`, `src/cms/angular/cms-content.component.ts`,
107
+ `src/cms/angular/cms-item.service.ts`.
108
+
109
+ The app root is inside a uiBundle, not the SFDX project root, so foundation files
110
+ resolve to `force-app/main/default/uiBundles/<bundleName>/src/cms/…`. Run the check
111
+ against the target bundle when known; otherwise scan each subdir of
112
+ `force-app/main/default/uiBundles/` and pick the scaffolded one, asking the user
113
+ with options if multiple qualify (`references/interaction-model.md` →
114
+ *Candidate uiBundle*).
115
+
116
+ ### Drift-complete branch
117
+
118
+ On a **drift** classification, when the user answers **Yes, write the missing
119
+ files**: write ONLY the missing files VERBATIM from `assets/…` via the Read→Write
120
+ copy set above (it skips destinations that already exist), then re-check. Never
121
+ touch or "refresh" the present ones; never silently complete, overwrite, or reset a
122
+ present file.
@@ -0,0 +1,173 @@
1
+ # Interaction model — ask with options, and where the session ends
2
+
3
+ This skill is **interactive**. At every decision the prompt leaves open, ASK the
4
+ user with an **option-select** question (the `AskUserQuestion` tool) instead of
5
+ free-text: one decision per question, a short header, 2–4 labeled options, and
6
+ wait for the answer. Never guess past an unanswered required decision — it HALTs.
7
+
8
+ Two answers are **terminal**: they END the session with no scaffolding. They are called out below and in `SKILL.md` (*HALT behaviour*) and `references/failure-modes.md`.
9
+
10
+ ## Bypass mode (non-interactive / automation)
11
+
12
+ When the prompt explicitly asks to bypass the interaction model — e.g. "bypass the
13
+ interaction model", "non-interactive", "don't ask", "proceed/yes to all prompts",
14
+ "auto-proceed" — do **not** call `AskUserQuestion` at all. Treat every would-be
15
+ question as answered with the **affirmative / recommended** intent ("proceed/yes")
16
+ and continue. This is for automation/eval where nothing can reply to a prompt.
17
+
18
+ Per-decision defaults in bypass mode (the Recommended option, or the obvious value):
19
+
20
+ | Decision | Bypass default |
21
+ |----------|----------------|
22
+ | Framework — ambiguous | The framework the prompt names; if truly none, HALT (no safe default). |
23
+ | Run Init? | **Yes, scaffold it** (proceed — the affirmative). |
24
+ | Complete a partial runtime? (drift) | **Yes, write the missing files.** |
25
+ | Content type — unnamed | The type the prompt states or most strongly implies. |
26
+ | Media alt text — foreign `url` image/document, none from hand-off | Register with `altText: ''` (image → decorative) / no `title` (document → "Download"). Bypass ships the a11y fallback rather than HALT — this is not a safe-default-less stop. |
27
+ | Channel ID — unresolved for a contentKey | **No safe default — HALT.** Bypass never invents a channel; write only a catalog/prompt-provided one, else HALT (like unnamed in-place placement). |
28
+ | Channel conflict — prompt channel differs from catalog | **Keep the catalog channel** (the Recommended option): leave `public/content-metadata.json` unchanged, do NOT overwrite it with the prompt channel. The catalog is primary. |
29
+ | Render target | **Dedicated detail page/route.** |
30
+ | Group render target | **A detail page for each item.** |
31
+ | Candidate uiBundle | The single scaffoldable/named bundle. |
32
+
33
+ Bypass changes ONLY the answer source (recommended option instead of a user reply)
34
+ — it makes NO pipeline-logic change. It does **not** suppress stops that are not
35
+ questions: a genuine **zero-content** search result still ends the session (there is
36
+ nothing to render), and any true HALT with no safe default still stops — e.g. an
37
+ **in-place** render with no placement named anywhere in the prompt (bypass defaults
38
+ to a detail page, so this only bites if the prompt forces in-place without a target),
39
+ a candidate-bundle choice that can't be resolved to one bundle, or a **`CmsRef` whose
40
+ channel is unresolvable** (no catalog, no prompt-provided channelId) — bypass never
41
+ invents a channel, so this HALTs.
42
+
43
+ ## How to ask
44
+
45
+ - **One decision per question.** Short `header` chip (≤12 chars); 2–4 options.
46
+ - **Recommended option FIRST**, its label suffixed " (Recommended)".
47
+ - Each option carries a one-line description of what happens if chosen.
48
+ - **Free-text only for open answers** — a component/region name, a URL, a slug.
49
+ There the option list is a fallback; let the user type the value ("Other").
50
+ - After a **terminal** option (declined Init, zero search results), END the turn.
51
+ Do not scaffold, do not proceed, do not re-ask in a loop.
52
+
53
+ ## Decision points
54
+
55
+ ### Framework — ambiguous
56
+ Both `react` and `@angular/core` are dependencies (unknown/neither → HALT, not a
57
+ supported app; do not ask).
58
+ - Question: "Which framework should I target for the CMS renderer?"
59
+ - Header: `Framework`
60
+ - Options: **React** — use the `assets/react/*` templates · **Angular** — use the
61
+ `assets/angular/*` templates.
62
+
63
+ ### Run Init? — runtime not scaffolded · ⛔ TERMINAL on "No"
64
+ All foundation files are missing (see *Init vs Embed detection*).
65
+ - Question: "The CMS runtime isn't scaffolded in this uiBundle yet. Scaffold it now (Init)?"
66
+ - Header: `Init`
67
+ - Options:
68
+ - **Yes, scaffold it (Recommended)** — run `npm i` for the toolkit and write the
69
+ foundation runtime once, then continue to Embed.
70
+ - **No — stop here; the skill will HALT and the session will end** — nothing is
71
+ installed or written; the skill cannot Embed without the runtime.
72
+ - On **No**: state that Init was declined, so the skill HALTS and the **session
73
+ ends**. Do NOT scaffold, install, or partially write anything. End the turn.
74
+
75
+ ### Complete a partial runtime? — drift
76
+ Some foundation files present, some missing (never Embed onto a partial runtime).
77
+ - Question: "The CMS runtime is partially scaffolded (present: {present}; missing:
78
+ {missing}). Complete the {N} missing foundation file(s) from the templates?"
79
+ - Header: `Drift`
80
+ - Options:
81
+ - **Yes, write the missing files (Recommended)** — write ONLY the {N} missing
82
+ files verbatim from `assets/…`; never touch the present ones. Then re-check.
83
+ - **No — stop** — leave the tree as-is and HALT; the user restores or removes the
84
+ partial set.
85
+
86
+ ### Content type — unnamed item
87
+ The item's `fqn` is unknown (URL pasted, `contentKey` given, or search returned an empty `fqn`). Ask ONCE.
88
+ - Question: "What content type is this item?"
89
+ - Header: `Type`
90
+ - Options: **News** (`sfdc_cms__news`) · **Blog** · **Announcement** · plus let the
91
+ user type another type name (open answer) when it isn't one of these.
92
+
93
+ ### Media alt text — foreign `url` image/document, none from the hand-off
94
+ Only for a **foreign `url` media ref** of type `image` or `document` when the search
95
+ hand-off supplied no `altText`/`title` (the direct-URL path has no fetched body to read
96
+ them from — SKILL.md step 3). `audio`/`video` never ask (controls + optional aria-label).
97
+ Ask ONCE, open answer.
98
+ - Question: "What alt text describes '{title}'? (Leave blank if it's decorative.)" — for a
99
+ document instead: "What label should the download link for '{title}' show?"
100
+ - Header: `Alt text`
101
+ - Open answer — the user types the alt text / link label; the skill sets it as `altText`
102
+ (image) or `title` (document) on the `CmsExternalRef`. Blank is a valid answer for an
103
+ image (decorative → `alt=''`, WCAG 1.1.1). In **bypass** mode do NOT HALT: register with
104
+ the a11y fallback (`altText: ''` / no `title`) and continue.
105
+
106
+ ### Channel ID — unresolved for a contentKey
107
+ A `CmsRef` (contentKey) needs a channel and none was found in `public/content-metadata.json`
108
+ or provided with the prompt (channel resolution, SKILL.md step 3). Ask ONCE, open answer.
109
+ - Question: "Which channel serves '{title}'? Paste the channelId (e.g. `0apSG0000000…`)."
110
+ - Header: `Channel`
111
+ - Open answer — the user pastes the channelId; the skill writes it to
112
+ `public/content-metadata.json`. No safe default: no answer → HALT (never invent or
113
+ placeholder a channel). In **bypass** mode there is NO auto-fill — an unresolved
114
+ channel HALTs like an unnamed in-place placement.
115
+
116
+ ### Channel conflict — prompt channel differs from the catalog
117
+ A `channelId` came with the prompt/identity, but `public/content-metadata.json` already
118
+ holds a DIFFERENT non-empty `channelId` (channel resolution, SKILL.md step 3). One
119
+ channel serves EVERY contentKey ref in the app, so overwriting repoints them all — never
120
+ silently. Ask ONCE; both concrete channels are known, so this is option-select, not open.
121
+ - Question: "'{title}' names channel `{promptChannel}`, but the catalog already uses
122
+ `{catalogChannel}`. Which channel is correct?"
123
+ - Header: `Channel`
124
+ - Options:
125
+ - **Keep the catalog channel `{catalogChannel}` (Recommended)** — leave
126
+ `public/content-metadata.json` UNCHANGED (no write); register the ref and proceed. The
127
+ catalog is primary and cross-org-safe, and any other refs already resolve through it.
128
+ - **Use the prompt channel `{promptChannel}`** — overwrite ONLY the `channelId` in
129
+ `public/content-metadata.json` (preserve the existing `contents` array); then register
130
+ the ref and proceed. This repoints EVERY contentKey ref in the app to `{promptChannel}`.
131
+ - Overwrite the catalog channel only on the explicit **Use the prompt channel** answer.
132
+ Same channel, or an empty/absent catalog, is NO conflict — use/write per *Channel ID*.
133
+
134
+ ### Render target — neither placement nor page stated
135
+ Only when the prompt names no route AND no in-place placement (step 4).
136
+ - Question: "How should I render '{title}'?"
137
+ - Header: `Render as`
138
+ - Options:
139
+ - **Dedicated detail page/route** — generate a page under `src/pages/<type>/` and
140
+ add its route.
141
+ - **In place in an existing view** — embed the renderer at a location you name.
142
+ - On **In place**, follow up for the location (open answer): "Where should '{title}'
143
+ render? Name a component, page, or region." An unanswered location HALTs — never
144
+ guess a placement.
145
+
146
+ ### Group render target — N items, same type
147
+ Only when neither a list/grid nor per-page layout is stated (step 4, *Groups*).
148
+ - Question: "Render the {N} items as separate detail pages, or together on one page?"
149
+ - Header: `Group as`
150
+ - Options:
151
+ - **A detail page for each item (Recommended)** — loop the Detail Page branch, one
152
+ page + slug per item.
153
+ - **One list/grid on a single page** — generate the list wrapper, place one node.
154
+
155
+ ### Candidate uiBundle — more than one qualifies
156
+ Multiple bundles under `force-app/main/default/uiBundles/` look scaffolded/targetable and the prompt didn't name one.
157
+ - Question: "Which uiBundle should I render into?"
158
+ - Header: `Bundle`
159
+ - Options: one per candidate bundle name (label = bundle dir); if >4, list the most
160
+ likely and allow an open answer.
161
+
162
+ ## Terminal stops (session ends — no scaffolding)
163
+
164
+ | Stop | When | What to say and do |
165
+ |------|------|--------------------|
166
+ | **Init declined** | User picks "No" at the *Run Init?* question | State Init was declined → the skill HALTS and the session ends. Write nothing; end the turn. |
167
+ | **Zero search content** | experience-search-coordinate returns ZERO content for the phrase (search succeeded, found nothing) | The item isn't authored in this uiBundle space yet. STOP the session and tell the user to generate the content there first — author + publish it (e.g. via `experience-cms-content-generate` / `experience-cms-content-type-generate`) — then re-run this skill. Do NOT guess an identity or scaffold. |
168
+
169
+ **Zero content vs. search failure** — distinct. ZERO content (nothing exists yet)
170
+ ends the session with an *author-the-content-first* instruction. A **cancelled,
171
+ errored, or unavailable** search is a recoverable HALT: ask the user to paste the
172
+ item's public delivery URL (`unauthenticatedUrl`) OR its `contentKey` (plus
173
+ `channelId` / content type), and resume once they do — see `SKILL.md` step 1.
@@ -0,0 +1,106 @@
1
+ # Toolkit package API + delivery response contract
2
+
3
+ Ground truth for reading CMS content. Transport, envelope-unwrap, catalog remap, channel resolution, image-URL resolution, and entity-decoding all live in the npm package **`@salesforce/ui-bundle-template-feature-cms-toolkit`**.
4
+ Generated code CALLS this API — never re-implement HTTP, unwrap, or URL building, and never reconstruct an endpoint or response from memory.
5
+
6
+ ## Public API surface (the single import target)
7
+
8
+ ```ts
9
+ import {
10
+ getCmsContentByUrl, // (url, options?) → Promise<TBody> public CDN, unauthenticated; THROWS
11
+ getCmsContentByKey, // (contentKey, options?) → Promise<TBody> one item, authenticated Connect; THROWS
12
+ getCmsContentByKeys, // (keys[], options?) → Promise<CmsBulkResult<TBody>[]> many, authenticated, ONE round-trip; BEST-EFFORT (per-key error, never throws except on abort). See references/bulk-loading.md
13
+ resolveCmsImageUrl, // (field, options?) → string | undefined image field → loadable src (SYNC); pass no options — resolves relative urls itself
14
+ resolveMediaUrl, // (url, options?) → string | undefined media url string → loadable src (SYNC); pass no options
15
+ getCmsInstanceOrigin, // () → string | undefined instance origin (SYNC); no longer needed by generated code
16
+ decodeRichHtmlEntities, // (encoded) → string decode RichText before injection (SYNC)
17
+ resolveEffectiveContentKey, // (key, catalogUrl?) → Promise<string> source→target key remap
18
+ getCmsDefaultChannelId, // (catalogUrl?) → Promise<string|undefined> catalog default channel (fail-open)
19
+ // errors (stable for instanceof):
20
+ CmsDeliveryError, CmsDeliveryNotFoundError, ConnectApiError, CmsNotFoundError,
21
+ } from '@salesforce/ui-bundle-template-feature-cms-toolkit';
22
+
23
+ import type {
24
+ CmsContentBody, CmsReadOptions, CmsBulkResult, CmsContentCatalog, CmsImageField, CmsImageOptions,
25
+ } from '@salesforce/ui-bundle-template-feature-cms-toolkit';
26
+ ```
27
+
28
+ Every read takes a required positional subject (url / key / keys) plus ONE optional `CmsReadOptions = { signal?: AbortSignal; channelId?: string }` (`channelId` is for authenticated reads only and overrides the catalog default).
29
+ New params arrive as new OPTIONAL fields — no call site ever breaks.
30
+
31
+ Both `byUrl` and `byKey` return the already-UNWRAPPED `contentBody` typed as `TBody` — there is no envelope handling in skill code.
32
+ `byKey` also remaps source→target and resolves the channel first.
33
+
34
+ ## Delivery response contract (what `TBody` describes)
35
+
36
+ Both transports return the SAME managed content item DIRECTLY (NOT wrapped in
37
+ `{ items }`, `data`, or `result`). Real `news` payload, pre-unwrap:
38
+
39
+ ```jsonc
40
+ {
41
+ "contentBody": { // ← per-type renderable fields (this is <Type>Body)
42
+ "body": "A powerful earthquake…", // RichText/Text → primitive (Rule 5)
43
+ "excerpt": "A devastating earthquake…",
44
+ "bannerImage": { "source": { "type": "url", "ref": "https://cdn.…/x.svg" } } // Image → object
45
+ },
46
+ "contentKey": "MCVIWPYY…",
47
+ "title": "News Content on Venezuela Earthquake", // ← ENVELOPE-level, NOT in contentBody
48
+ "contentType": { "fullyQualifiedName": "sfdc_cms__news" }
49
+ }
50
+ ```
51
+
52
+ - **`contentBody` IS the per-type body**, and its keys VARY BY TYPE — derive
53
+ `<Type>Body` from the schema / a real payload (`references/schema-sync.md`), never
54
+ hard-code. `getCmsContentByUrl<TBody>` / `getCmsContentByKey<TBody>` return it.
55
+ - **`title` is ENVELOPE-level** (root, not in `contentBody`). The toolkit LIFTS it
56
+ into the body when the body lacks one, so `body.title` works — keep room in
57
+ `<Type>Body`'s index signature; do NOT emit `title` as a schema field.
58
+ - A root `channelSummary` block may appear — ignore it.
59
+
60
+ ## Image field — `CmsImageField` + `resolveCmsImageUrl`
61
+
62
+ Images are OBJECTS, not primitives — never use one as a `src` directly; pass it to `resolveCmsImageUrl(field)`.
63
+ Pass NO options object — the resolver resolves a relative Connect-API url on its own. It is SYNCHRONOUS — resolve inline, there is no async image component. Three cases the resolver handles:
64
+
65
+ - **CMS image** (`source.type === "imageReference"`) — has a ROOT-RELATIVE top-level
66
+ `url`; the resolver returns it resolved to a loadable src (a relative Connect-API
67
+ url now works as-is — no instance-origin prefix needed).
68
+ - **Foreign image** (`source.type === "url"`) — no top-level `url`; the absolute URL
69
+ is the STRING `source.ref`, returned as-is.
70
+ - **Fallback** — `imageReference` with no top-level `url`. Rare; the common payload
71
+ inlines the media `url`.
72
+
73
+ Standalone media (audio/video/document) on a **`contentKey` ref** uses the sibling
74
+ `resolveMediaUrl(url)`, given the body `sfdc_cms:media.url` string directly (same
75
+ no-options, relative-safe contract). A **foreign `url` media ref** skips this entirely —
76
+ its `unauthenticatedUrl` is the asset itself and is set directly as the element
77
+ `src`/`href`, with no fetch and no resolver (Rule 1/Rule 2). The resolvers apply only
78
+ when a body was fetched.
79
+
80
+ The field also carries an optional `altText` string — bind it to the `<img alt>`
81
+ (`resolveImageAlt`), falling back to `''` (decorative, WCAG 1.1.1) when absent.
82
+ `resolveCmsImageUrl` returns only the `src`, so read `altText` off the field object.
83
+
84
+ ## RichText & scalars
85
+
86
+ RichText arrives entity-encoded (`"&lt;div&gt;…"`) — decode with
87
+ `decodeRichHtmlEntities` before injecting, through ONE path per framework (Rule 4,
88
+ `references/heuristic-render-rules.md`). Scalar `contentBody` fields are primitives,
89
+ never `{ value }` (Rule 5, `references/schema-sync.md`). Symptoms if either is
90
+ violated: `references/failure-modes.md`.
91
+
92
+ ## `content-metadata.json` — the catalog the skill writes (Rule 1)
93
+
94
+ The `byKey` path loads a public `content-metadata.json` to supply a default `channelId` and remap each baked-in `sourceContentKey` → the org's `targetContentKey`.
95
+ Loaded once, memoized, and **FAIL-OPEN**: missing / unreachable / malformed → treated as `{}` (no channel, keys used verbatim). Served from the uiBundle base at `${BASE_URL}content-metadata.json` (override with `VITE_CONTENT_CATALOG_URL`); with Vite the web root is `public/`, so the file lives at `<appRoot>/public/content-metadata.json`.
96
+
97
+ **The skill writes it — catalog-primary channel resolution.** When a `CmsRef` needs a channel and the catalog is absent, the skill creates `public/content-metadata.json` with the resolved `channelId` and an **empty `contents: []`**:
98
+
99
+ ```jsonc
100
+ { "channelId": "0apSG0000000ExampleChannel", "contents": [] }
101
+ ```
102
+
103
+ Only `channelId` (string) and `contents` (`{ sourceContentKey, targetContentKey }` pairs; entries missing either key are skipped) are read — the empty `contents` is safe because per-entry remap fails open to the baked-in `contentKey`. Write it **on demand at the first `CmsRef` embed** that needs a channel, not at Init; idempotent (present channel → never overwrite; absent → create; present-but-empty → fill).
104
+
105
+ Write **only a known channel** (catalog / prompt / user) — a placeholder with a fake `channelId` breaks every `byKey` read, because fail-open triggers on a MISSING file, not a present-but-wrong one; a present-but-wrong catalog is worse than none. It is a **regenerable data seam, not source of truth**: the deploy pipeline always regenerates it against the target org (filling real `contents`), which is why the catalog is cross-org-safe where a baked-in `CMS_CHANNEL_ID_FALLBACK` source constant is not. Precedence when reading: explicit option > `CMS_CHANNEL_ID_FALLBACK` (see `externalRefs.ts`, a cautioned opt-in override) > catalog `channelId` > the toolkit throws.
106
+ Failure modes: `references/failure-modes.md`.
@@ -0,0 +1,114 @@
1
+ # Schema Sync
2
+
3
+ Every Embed fetches the content type's shape and emits typed TS. The per-type body
4
+ module is FRAMEWORK-AGNOSTIC (identical for React and Angular); the renderer is
5
+ framework-specific. Files under `src/cms/react/` or `src/cms/angular/`:
6
+
7
+ - `<framework>/types/<type>.ts` — **above-marker** region (user-editable: layouts,
8
+ slots, className presets) + **below-marker** region (generated: `<Type>Body`
9
+ interface and `<type>FieldTypes` map). Imports `CmsFieldType`/`CmsImageField` from
10
+ `../../shared/cmsCore.types`.
11
+ - The renderer — no user region, regenerated in full. React
12
+ `react/types/<Type>Renderer.tsx`, Angular `angular/types/<Type>Renderer.component.ts`.
13
+
14
+ ## OOTB `sfdc_cms__news` — predefined, do NOT fetch
15
+
16
+ The metadata fetch cannot resolve OOTB Salesforce content types, so `sfdc_cms__news`
17
+ has a FIXED schema — skip retrieval and emit exactly these fields:
18
+
19
+ | field | lightningType | `<Type>Body` TS | `CmsFieldType` |
20
+ |-------|---------------|-----------------|----------------|
21
+ | `bannerImage` | Image | `CmsImageField` | `'image'` |
22
+ | `body` | RichText | `string` | `'richText'` |
23
+ | `excerpt` | Text | `string` | `'text'` |
24
+
25
+ No `sf project retrieve` / MCP / SOQL for news. Other OOTB types are not predefined —
26
+ treat them as custom and fetch below.
27
+
28
+ ## Schema retrieval (custom types)
29
+
30
+ Retrieve the ContentTypeBundle from the org (bare DeveloperName — no `c__` /
31
+ `sfdc_cms__` prefix; relative `--output-dir` inside the project):
32
+
33
+ ```bash
34
+ sf project retrieve start --metadata ContentTypeBundle:<DeveloperName> \
35
+ --target-org <targetOrg> --output-dir retrieved-content-types --json
36
+ ```
37
+
38
+ Resolve `<targetOrg>` via `sf config get target-org --json`; unset → HALT, ask the
39
+ user to `sf config set target-org=<alias>`. Read (with the `Read` tool, not `cat`)
40
+ `retrieved-content-types/contentTypes/<DeveloperName>/schema.json`; valid iff
41
+ `lightning:type === "lightning__objectType"` and `properties` is a non-empty object.
42
+
43
+ Map each `properties` entry to `{ name, lightningType (PascalCase: Text, RichText,
44
+ Image, …), required, localizable }`, then to the lowerCamel `CmsFieldType` literal
45
+ per the table below. Do NOT use Tooling/REST `/sobjects/` or Connect CMS —
46
+ ContentTypeBundle is Metadata-API only. Type not found → verify DeveloperName
47
+ (case-sensitive, no prefix); auth/session error → `sf org login web`. Retrieval
48
+ fails → emit the below-marker block with a `TODO` listing fields to fill manually.
49
+
50
+ ## Markers
51
+
52
+ ```ts
53
+ // <experience-cms-content-render:above-begin>
54
+ // … user-editable …
55
+ // <experience-cms-content-render:above-end>
56
+ // <experience-cms-content-render:below-begin>
57
+ // … generated …
58
+ // <experience-cms-content-render:below-end>
59
+ ```
60
+
61
+ Line-comments only; never inside strings/JSX. Skill greps for exact begin/end
62
+ pairs and requires both.
63
+
64
+ ## Regeneration algorithm
65
+
66
+ 1. Read `<framework>/types/<type>.ts`; locate the four markers.
67
+ 2. Any marker missing / duplicated / out of order → **HALT** with file+line and the
68
+ expected marker. NEVER auto-heal — marker damage means a hand-edit the skill
69
+ can't safely merge.
70
+ 3. Extract the above region byte-for-byte.
71
+ 4. Regenerate the below region from the schema: `<Type>Body` (one prop per field) +
72
+ `<type>FieldTypes` (field → lowerCamel `CmsFieldType` literal).
73
+ 5. Reassemble `[preamble][above as-read][below as-generated]`; write only if
74
+ changed, else report "no drift".
75
+
76
+ ## Field shapes — primitives, not wrappers (Rule 5)
77
+
78
+ Delivery returns SCALAR fields as PLAIN primitives, not `{ value }` wrappers. Map
79
+ `lightningType` → TS type accordingly:
80
+
81
+ | lightningType | `<Type>Body` TS type | `CmsFieldType` literal | Delivery shape |
82
+ |-------------------|----------------------|------------------------|------------------------------------|
83
+ | Text | `string` | `'text'` | `"title": "Berries"` |
84
+ | RichText | `string` | `'richText'` | `"body": "&lt;div&gt;…"` (encoded) |
85
+ | Url | `string` | `'url'` | `"link": "https://…"` |
86
+ | Date | `string` | `'date'` | ISO string |
87
+ | DateTime | `string` | `'dateTime'` | ISO string |
88
+ | Number | `number` | `'number'` | `12` |
89
+ | Boolean | `boolean` | `'boolean'` | `true` |
90
+ | Image | `CmsImageField` | `'image'` | `{ url, altText, source }` — OBJECT |
91
+ | Reference | see RenderField | `'reference'` | `{ ref: { contentKey } }` |
92
+
93
+ `<type>FieldTypes` values are the **lowerCamel literals** in column 3, NOT the
94
+ PascalCase `lightningType` token — copying `'Text'`/`'RichText'` verbatim is a type
95
+ error against the `CmsFieldType` union in `cmsCore.types.ts`.
96
+
97
+ Only Image (and refs) are objects — NEVER emit `{ value: string }` for a scalar
98
+ (that bug made RichText render as nothing: `body.body.value` was `undefined`). The
99
+ renderer reads `body.<field>` directly, no `.value` unwrap. When the schema alone is
100
+ ambiguous, **confirm each field's shape against a real payload** (`unauthenticatedUrl`).
101
+
102
+ ## Drift → below-region effect
103
+
104
+ New field → added; removed field → dropped (referencing code fails typecheck,
105
+ intentional); type changed → prop+entry change; rename → remove+add (user
106
+ reconciles); required flip → optional marker flips. Above region unaffected.
107
+
108
+ ## No barrel
109
+
110
+ No per-type `index.ts`. Consumers import each renderer by its direct path — React
111
+ `import { NewsRenderer } from '../types/NewsRenderer'`, Angular
112
+ `import { NewsRendererComponent } from '../types/NewsRenderer.component'` — so
113
+ adding a type writes only `<type>.ts` + the renderer, and removing one is a plain
114
+ file delete (referencing imports then fail typecheck, intentional).
@@ -0,0 +1,65 @@
1
+ # Styling Scopes
2
+
3
+ The skill NEVER scaffolds a CSS file, a design system, or CSS variables. Two things
4
+ carry presentation, and only these two:
5
+
6
+ 1. **Stable class hooks** the render always emits (below) — selector anchors for the
7
+ app's own stylesheet.
8
+ 2. **Presentation applied ON TOP of the render**, per the user's prompt, at the
9
+ render target the skill writes (the detail page's `<main>`, or the wrapper it
10
+ inserts for an in-place embed). Applied inline (a `style={{…}}` object or an
11
+ added `className` the app already defines) — never by emitting a `.css` file.
12
+
13
+ ## Default reading layout
14
+
15
+ When the user asks to render / embed / create a detail page and gives NO explicit
16
+ styling direction, apply this baseline on the render target:
17
+
18
+ - **Centered single column**, `max-width` ~`700px`, `margin: 0 auto`.
19
+ - **Large, readable typography** (body ~`1.125rem`, `line-height` ~`1.6–1.7`).
20
+ - **Ample whitespace** (generous padding around the column, spacing between fields).
21
+
22
+ This is a starting look, not a mandate — the prompt overrides it. "Make it full-bleed",
23
+ "use a 2-column card", "tighter spacing", "match our brand font" all replace the
24
+ relevant part. If the user names their own class or stylesheet, prefer wiring that
25
+ over inline values.
26
+
27
+ ## Detail page vs. in-place embed — style them differently
28
+
29
+ - **Detail page** owns its `<main>` route → style generously (the full reading
30
+ layout above: centered column, hero image, article spacing). Low clash risk.
31
+ - **In-place embed** is dropped into the app's own component → stay conservative.
32
+ Apply typography/whitespace that inherits context; do NOT impose fixed widths,
33
+ centering, or layout that fights the host. When unsure for an embed, lean on the
34
+ class hook and let the app's stylesheet own layout.
35
+
36
+ ## Classes emitted (always, regardless of styling)
37
+
38
+ | Scope | Class | Source |
39
+ |-------|-------|--------|
40
+ | Per-type card | `cms-<type>-card` | `{{type}}Layouts.card.className` |
41
+ | Per-type detail | `cms-<type>-detail` | `{{type}}Layouts.detail.className` |
42
+ | Detail page wrapper | `cms-detail-page cms-<type>-detail-page` | React `assets/react/DetailPage.tsx` / Angular `assets/angular/DetailPage.component.ts` |
43
+
44
+ Same class hooks in both frameworks: React emits them on the renderer's
45
+ `<article>` / detail-page `<main>`; Angular's `<cms-content>` article and the
46
+ `{{PageName}}Component` `<main>` emit the identical strings. Inner tags (`<h1>`,
47
+ `<img>`, …) carry no class — reach them via descendant selectors
48
+ (`.cms-news-card > img { … }`) or style the container.
49
+
50
+ ## Precedence & override
51
+
52
+ `className` prop on the embed beats the layout preset's className (React
53
+ `className="…"`, Angular `[className]="…"`). Override presets in the above-marker
54
+ region of `src/cms/<framework>/types/<type>.ts` (regeneration preserves it):
55
+
56
+ ```ts
57
+ export const newsLayouts = {
58
+ card: { fields: ['title', 'bannerImage', 'excerpt'] as const, className: 'my-news-tile' },
59
+ detail: { fields: undefined, className: 'my-news-hero' },
60
+ } as const;
61
+ ```
62
+
63
+ React custom slot components (`components={{ Image: MyImg }}`) own their own
64
+ className; the wrapper `<article>` keeps the type-scoped class so ancestor
65
+ selectors work. Angular has no slot props — style via the class hooks.
@@ -0,0 +1,49 @@
1
+ # Verify — bounded typecheck + fix policy
2
+
3
+ Detail for Embed pipeline step 5 (SKILL.md → *Embed pipeline* → *5. Verify*).
4
+ SKILL.md holds the one-pass rule; this file holds the full fix policy and the report
5
+ checklist.
6
+
7
+ ## Typecheck ONLY the files this skill wrote or edited — bounded, never a loop
8
+
9
+ Run `npx tsc --noEmit` ONCE (React/Vite) or `npx tsc --noEmit -p tsconfig.json` ONCE
10
+ (Angular). Then read ONLY the diagnostics whose file path the skill touched this run:
11
+ foundation files, `<framework>/types/<type>.ts` + renderer, `externalRefs.ts`, the
12
+ render target, detail pages. Every diagnostic in a file the skill did NOT touch is
13
+ pre-existing; ignore it, do not fix it, do not open it.
14
+
15
+ If no TypeScript is configured (no `tsc`/`tsconfig`), skip and note it.
16
+
17
+ ## Fix policy — at most ONE fix pass, then stop
18
+
19
+ - Diagnostic in a file the skill **generated** this run (`<type>.ts` below-marker
20
+ `<Type>Body`, a ref entry, an import specifier, an unused symbol, a `.value`
21
+ unwrap) → fix it, then re-run tsc **once** to confirm. One pass, one re-run, no
22
+ more.
23
+ - Diagnostic in a **verbatim foundation file** (`useCmsItem.ts`,
24
+ `heuristicRenderer.tsx`, `cms-item.service.ts`, `cms-content.component.ts`,
25
+ `cmsCore.types.ts`, …) → **do NOT edit or rewrite it.** These are copied
26
+ byte-for-byte and correct by construction; a diagnostic here is almost always the
27
+ toolkit not resolvable yet (install / tsconfig-paths / JSX config), NOT a code
28
+ defect. Report it as an environment/install note ("toolkit unresolved — confirm
29
+ `npm i` ran and tsconfig resolves `@salesforce/…`"); if certain it is a genuine
30
+ template bug, REPORT it, never patch in place.
31
+ - Do NOT run `lint`, `build`, `ng build`, or the dev server; do NOT re-derive the
32
+ toolkit contract from `references/*` to "fix" a template. If errors remain after
33
+ the single fix pass, report them verbatim and stop.
34
+
35
+ ## Report
36
+
37
+ Report: files written/modified (paths + inserted line ranges); the `npm install` if
38
+ run; the typecheck result (clean / fixed N in generated files / skipped) plus any
39
+ environment or pre-existing notes; ref name + identity; renderer type; chosen render
40
+ target; and any HALTs. The skill does NOT run lint, a build, or the dev server.
41
+
42
+ **Media on an authenticated channel — temporary-limitation note.** When this run
43
+ scaffolds media (`sfdc_cms__{image,audio,video,document}`) whose ref is a `CmsRef`
44
+ (a `contentKey`, read via authenticated Connect / a uiBundle channel), add a note to
45
+ the report: *rendering that media inside an internal app is not supported yet — this
46
+ is a temporary platform limitation planned for a future release; media served from a
47
+ public delivery URL (a `CmsExternalRef`) renders today.* Scaffold normally and do not
48
+ HALT — the note is informational only. Media registered as a `CmsExternalRef` (public
49
+ URL) needs no note.