@salesforce/afv-skills 1.55.0 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-generate/SKILL.md +8 -0
  3. package/skills/agentforce-generate/references/actions-reference.md +2 -2
  4. package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
  5. package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
  6. package/skills/agentforce-observe/SKILL.md +13 -9
  7. package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
  8. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
  9. package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
  10. package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
  11. package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
  12. package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
  13. package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
  14. package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
  15. package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
  16. package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
  17. package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
  18. package/skills/commerce-b2b-open-code-components-integrate/SKILL.md +1 -1
  19. package/skills/commerce-b2b-open-code-components-replace/SKILL.md +16 -16
  20. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
  21. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
  22. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
  23. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
  24. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
  25. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
  26. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
  27. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
  28. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
  29. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
  30. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
  31. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
  32. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
  33. package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
  34. package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
  35. package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
  36. package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
  37. package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
  38. package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
  39. package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
  40. package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
  41. package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
  42. package/skills/dx-devops-project-manage/SKILL.md +1 -1
  43. package/skills/dx-org-analyze/SKILL.md +0 -1
  44. package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
  45. package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
  46. package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
  47. package/skills/dx-org-manage/SKILL.md +6 -50
  48. package/skills/dx-org-manage/examples/README.md +10 -16
  49. package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
  50. package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
  51. package/skills/dx-org-shape-manage/SKILL.md +4 -3
  52. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
  53. package/skills/experience-accessibility-validate/SKILL.md +8 -5
  54. package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
  55. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
  56. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
  57. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
  58. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
  59. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
  60. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
  61. package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
  62. package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
  63. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
  64. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
  65. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
  66. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
  67. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
  68. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
  69. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
  70. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
  71. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
  72. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
  73. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
  74. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
  75. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
  76. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
  77. package/skills/experience-cms-content-generate/SKILL.md +1 -1
  78. package/skills/experience-cms-content-render/SKILL.md +3 -3
  79. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +35 -7
  80. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +13 -4
  81. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +30 -8
  82. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +14 -4
  83. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +11 -1
  84. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +1 -1
  85. package/skills/experience-cms-content-render/assets/shared/mediaLabels.ts +62 -0
  86. package/skills/experience-cms-content-render/references/init-scaffold.md +13 -6
  87. package/skills/experience-content-media-stock-image-search/SKILL.md +0 -1
  88. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
  89. package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
  90. package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
  91. package/skills/experience-lwc-design-generate/SKILL.md +1 -1
  92. package/skills/experience-lwc-legacy-migrate/SKILL.md +212 -0
  93. package/skills/experience-lwc-legacy-migrate/assets/lo20-host-page-template.html +192 -0
  94. package/skills/experience-lwc-legacy-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
  95. package/skills/experience-lwc-legacy-migrate/references/lightning-out-2-system-reference.md +495 -0
  96. package/skills/experience-lwc-legacy-migrate/references/lightning-out-beta-to-2-migration.md +824 -0
  97. package/skills/experience-lwc-legacy-migrate/scripts/convert-lo-names.py +94 -0
  98. package/skills/experience-lwc-legacy-migrate/scripts/validate-lo20-page.py +133 -0
  99. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
  100. package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
  101. package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
  102. package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
  103. package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
  104. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
  105. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
  106. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
  107. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
  108. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
  109. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
  110. package/skills/experience-ui-bundle-project-generate/SKILL.md +1 -1
  111. package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
  112. package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
  113. package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
  114. package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
  115. package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
  116. package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
  117. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
  118. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
  119. package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
  120. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
  121. package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
  122. package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
  123. package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
  124. package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
  125. package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
  126. package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
  127. package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
  128. package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
  129. package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
  130. package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
  131. package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
  132. package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
  133. package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
  134. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
  135. package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
  136. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
  137. package/skills/integration-connectivity-connected-app-configure/SKILL.md +5 -5
  138. package/skills/integration-connectivity-generate/SKILL.md +10 -10
  139. package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +2 -2
  140. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
  141. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
  142. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
  143. package/skills/mobile-apps-create/SKILL.md +1 -1
  144. package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
  145. package/skills/platform-apex-test-generate/SKILL.md +1 -1
  146. package/skills/platform-apex-test-run/SKILL.md +1 -1
  147. package/skills/platform-custom-field-generate/SKILL.md +1 -1
  148. package/skills/platform-custom-lightning-type-generate/SKILL.md +1 -1
  149. package/skills/platform-custom-metadata-type-generate/SKILL.md +1 -1
  150. package/skills/platform-custom-object-generate/SKILL.md +1 -1
  151. package/skills/platform-custom-report-type-generate/SKILL.md +1 -1
  152. package/skills/platform-custom-setting-generate/SKILL.md +1 -1
  153. package/skills/platform-data-and-tooling-api-context-get/SKILL.md +1 -1
  154. package/skills/platform-data-manage/SKILL.md +10 -10
  155. package/skills/platform-flexipage-generate/SKILL.md +1 -1
  156. package/skills/platform-lightning-app-coordinate/SKILL.md +1 -1
  157. package/skills/platform-metadata-api-context-get/SKILL.md +1 -1
  158. package/skills/platform-metadata-retrieve/SKILL.md +1 -1
  159. package/skills/platform-permission-set-generate/SKILL.md +1 -1
  160. package/skills/platform-report-generate/SKILL.md +1 -1
  161. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +4 -4
  162. package/skills/platform-sandbox-configure/SKILL.md +108 -133
  163. package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
  164. package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
  165. package/skills/platform-sharing-owd-configure/SKILL.md +1 -1
  166. package/skills/platform-sharing-rules-generate/SKILL.md +1 -1
  167. package/skills/platform-soql-query/SKILL.md +1 -1
  168. package/skills/platform-value-set-generate/SKILL.md +1 -1
  169. package/skills/platform-widget-generate/SKILL.md +26 -18
  170. package/skills/platform-widget-generate/examples/formulas.json +191 -0
  171. package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
  172. package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
  173. package/skills/sales-call-scoring-configure/SKILL.md +318 -0
  174. package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
  175. package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
  176. package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
  177. package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
  178. package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
  179. package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
  180. package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
  181. package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
  182. package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
  183. package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
  184. package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
  185. package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
  186. package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
  187. package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
  188. package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
  189. package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
  190. package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
  191. package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
  192. package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
  193. package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
  194. package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
  195. package/skills/service-agentforce-human-escalation-configure/SKILL.md +4 -0
  196. package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +26 -6
  197. package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +5 -4
  198. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
  199. package/skills/service-de-channel-activate/SKILL.md +6 -5
  200. package/skills/service-de-channel-create/SKILL.md +3 -3
  201. package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
  202. package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
  203. package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
  204. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
  205. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
  206. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
  207. package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
  208. package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
  209. package/skills/service-de-waba-integrate/SKILL.md +2 -1
  210. package/skills/service-digital-engagement-deployment-configure/SKILL.md +2 -0
  211. package/skills/service-digital-engagement-deployment-configure/scripts/check-api-version.sh +29 -0
  212. package/skills/service-email-to-case-configure/SKILL.md +1 -1
  213. package/skills/service-helpagent-coordinate/SKILL.md +3 -2
  214. package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
  215. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
  216. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
  217. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
  218. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
  219. package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
  220. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
  221. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
  222. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
  223. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
  224. package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
  225. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
  226. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
  227. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
  228. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
  229. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
  230. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
  231. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
  232. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
  233. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
  234. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
  235. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
  236. package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
  237. package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
  238. package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
  239. package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
  240. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
  241. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
  242. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
  243. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
  244. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
  245. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
  246. package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
  247. package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
  248. package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
  249. package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
  250. package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
  251. package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
  252. package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
  253. package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
  254. package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
  255. package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
  256. package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
  257. package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
  258. package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
  259. package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
  260. package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
  261. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
  262. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
  263. package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
  264. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  265. package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
  266. package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
  267. package/skills/dx-org-manage/references/cli_flags.md +0 -67
  268. package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
  269. package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
  270. package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
  271. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
  272. package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
  273. /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
  274. /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+
3
+ # Fetch a competency's full record, or just a single field. Used by S8
4
+ # (improvement suggestions) to load current EvaluationInstructions into
5
+ # Claude's context before drafting an edit.
6
+ #
7
+ # Usage:
8
+ # ./get-competency.sh <org-alias> <name-or-id> # full record JSON
9
+ # ./get-competency.sh <org-alias> <name-or-id> --field <name> # raw field value
10
+
11
+ set -euo pipefail
12
+
13
+ export NO_COLOR=1
14
+ export FORCE_COLOR=0
15
+
16
+ ORG_ALIAS="${1:-}"
17
+ IDENT="${2:-}"
18
+ FIELD=""
19
+
20
+ if [[ -z "$ORG_ALIAS" || -z "$IDENT" ]]; then
21
+ echo "Usage: $0 <org-alias> <name-or-id> [--field <field>]"
22
+ exit 1
23
+ fi
24
+
25
+ if [[ "${3:-}" == "--field" ]]; then
26
+ FIELD="${4:-}"
27
+ if [[ -z "$FIELD" ]]; then
28
+ echo "Error: --field requires a field name"; exit 1
29
+ fi
30
+ fi
31
+
32
+ # ---------------------------------------------------------------------------
33
+ # Auth
34
+ # ---------------------------------------------------------------------------
35
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
36
+ # shellcheck source=shared/auth.sh
37
+ source "$SCRIPT_DIR/shared/auth.sh"
38
+ # shellcheck source=shared/soql.sh
39
+ source "$SCRIPT_DIR/shared/soql.sh"
40
+
41
+ resolve_org_auth "$ORG_ALIAS" || exit 1
42
+
43
+ TOOLING_BASE="services/data/v68.0/tooling"
44
+
45
+ # ---------------------------------------------------------------------------
46
+ # Resolve identifier → record
47
+ # ---------------------------------------------------------------------------
48
+ if [[ "$IDENT" =~ ^1nA[0-9a-zA-Z]{12,15}$ ]]; then
49
+ WHERE="Id='${IDENT}'"
50
+ else
51
+ SAFE=$(soql_escape "$IDENT")
52
+ WHERE="DeveloperName='${SAFE}' OR MasterLabel='${SAFE}'"
53
+ fi
54
+
55
+ QUERY_ENC=$(printf 'SELECT Id, DeveloperName, MasterLabel, Description, IsActive, EvaluationScope, EvaluationConditions, EvaluationInstructions, SourceCompetencyTemplate FROM EnablementCompetencyDef WHERE %s' "$WHERE" | jq -sRr @uri)
56
+ LOOKUP=$(sf api request rest "${TOOLING_BASE}/query/?q=${QUERY_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null) || true
57
+ RC=$(echo "$LOOKUP" | jq -r '.totalSize // 0')
58
+
59
+ if [[ "$RC" == "0" ]]; then echo "No competency matched: $IDENT" >&2; exit 1; fi
60
+ if [[ "$RC" != "1" ]]; then
61
+ echo "Multiple competencies matched '$IDENT':" >&2
62
+ echo "$LOOKUP" | jq -r '.records[] | " \(.Id) \(.MasterLabel)"' >&2
63
+ exit 1
64
+ fi
65
+
66
+ RECORD=$(echo "$LOOKUP" | jq '.records[0] | del(.attributes)')
67
+
68
+ if [[ -n "$FIELD" ]]; then
69
+ echo "$RECORD" | jq -r --arg f "$FIELD" 'if has($f) then .[$f] else "Field not found: \($f)" | halt_error(1) end'
70
+ else
71
+ echo "$RECORD"
72
+ fi
@@ -0,0 +1,78 @@
1
+ #!/bin/bash
2
+ # sales_call_scoring: story="custom-competency-crud" owner="W-CUSTOM-CRUD"
3
+ #
4
+ # Fetch a competency's full record, or just a single field. Used by S8
5
+ # (improvement suggestions) to load current EvaluationInstructions into
6
+ # Claude's context before drafting an edit.
7
+ #
8
+ # Companion of create-custom-competency.sh — parallel to get-competency.sh
9
+ # so the custom-CRUD story can extend it (e.g. --raw json without cleanup,
10
+ # --fields Field1,Field2 for multi-field cherry-pick) without touching the
11
+ # OOTB-owned read surface.
12
+ #
13
+ # Usage:
14
+ # ./get-custom-competency.sh <org-alias> <name-or-id> # full record JSON
15
+ # ./get-custom-competency.sh <org-alias> <name-or-id> --field <name> # raw field value
16
+
17
+ set -euo pipefail
18
+
19
+ export NO_COLOR=1
20
+ export FORCE_COLOR=0
21
+
22
+ ORG_ALIAS="${1:-}"
23
+ IDENT="${2:-}"
24
+ FIELD=""
25
+
26
+ if [[ -z "$ORG_ALIAS" || -z "$IDENT" ]]; then
27
+ echo "Usage: $0 <org-alias> <name-or-id> [--field <field>]"
28
+ exit 1
29
+ fi
30
+
31
+ if [[ "${3:-}" == "--field" ]]; then
32
+ FIELD="${4:-}"
33
+ if [[ -z "$FIELD" ]]; then
34
+ echo "Error: --field requires a field name"; exit 1
35
+ fi
36
+ fi
37
+
38
+ # ---------------------------------------------------------------------------
39
+ # Auth
40
+ # ---------------------------------------------------------------------------
41
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
42
+ # shellcheck source=shared/auth.sh
43
+ source "$SCRIPT_DIR/shared/auth.sh"
44
+ # shellcheck source=shared/soql.sh
45
+ source "$SCRIPT_DIR/shared/soql.sh"
46
+
47
+ resolve_org_auth "$ORG_ALIAS" || exit 1
48
+
49
+ TOOLING_BASE="services/data/v68.0/tooling"
50
+
51
+ # ---------------------------------------------------------------------------
52
+ # Resolve identifier → record
53
+ # ---------------------------------------------------------------------------
54
+ if [[ "$IDENT" =~ ^1nA[0-9a-zA-Z]{12,15}$ ]]; then
55
+ WHERE="Id='${IDENT}'"
56
+ else
57
+ SAFE=$(soql_escape "$IDENT")
58
+ WHERE="DeveloperName='${SAFE}' OR MasterLabel='${SAFE}'"
59
+ fi
60
+
61
+ QUERY_ENC=$(printf 'SELECT Id, DeveloperName, MasterLabel, Description, IsActive, EvaluationScope, EvaluationConditions, EvaluationInstructions, SourceCompetencyTemplate FROM EnablementCompetencyDef WHERE %s' "$WHERE" | jq -sRr @uri)
62
+ LOOKUP=$(sf api request rest "${TOOLING_BASE}/query/?q=${QUERY_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null || true)
63
+ RC=$(echo "$LOOKUP" | jq -r '.totalSize // 0' 2>/dev/null || echo "0")
64
+
65
+ if [[ "$RC" == "0" ]]; then echo "No competency matched: $IDENT" >&2; exit 1; fi
66
+ if [[ "$RC" != "1" ]]; then
67
+ echo "Multiple competencies matched '$IDENT':" >&2
68
+ echo "$LOOKUP" | jq -r '.records[] | " \(.Id) \(.MasterLabel)"' >&2
69
+ exit 1
70
+ fi
71
+
72
+ RECORD=$(echo "$LOOKUP" | jq '.records[0] | del(.attributes)')
73
+
74
+ if [[ -n "$FIELD" ]]; then
75
+ echo "$RECORD" | jq -r --arg f "$FIELD" 'if has($f) then .[$f] else "Field not found: \($f)" | halt_error(1) end'
76
+ else
77
+ echo "$RECORD"
78
+ fi
@@ -0,0 +1,223 @@
1
+ #!/bin/bash
2
+
3
+ # Install best-practice Coaching Competencies (Momentum reference prompts,
4
+ # 7 total) from PRD-canonical prompt bodies. Parallel to install-ootb-*
5
+ # but reads from assets/best-practice-competencies.json.
6
+ #
7
+ # The prompt bodies here are the full PURPOSE / KEY AREAS / positive-
8
+ # negative-indicators / EXAMPLE structure — NOT the terse OOTB defaults.
9
+ # When installed, each record's EvaluationInstructions is the best-practice
10
+ # prompt, so Codey scores calls against the richer reference criteria.
11
+ #
12
+ # Idempotent: skips any competency whose SourceCompetencyTemplate already
13
+ # exists on the org.
14
+ #
15
+ # Usage:
16
+ # ./install-best-practice-competencies.sh <org-alias>
17
+ # ./install-best-practice-competencies.sh <org-alias> --dry-run
18
+ # ./install-best-practice-competencies.sh <org-alias> --only "Discovery Excellence,Product Knowledge"
19
+
20
+ set -euo pipefail
21
+
22
+ export NO_COLOR=1
23
+ export FORCE_COLOR=0
24
+
25
+ ORG_ALIAS="${1:-}"
26
+ DRY_RUN=""
27
+ ONLY_LIST=""
28
+
29
+ # Parse args after alias
30
+ shift || true
31
+ while [[ $# -gt 0 ]]; do
32
+ case "$1" in
33
+ --dry-run) DRY_RUN="--dry-run"; shift ;;
34
+ --only) ONLY_LIST="${2:-}"; shift 2 ;;
35
+ *) echo "Error: Unknown arg: $1"; exit 1 ;;
36
+ esac
37
+ done
38
+
39
+ if [[ -z "$ORG_ALIAS" ]]; then
40
+ echo "Error: Missing org alias"
41
+ echo "Usage: $0 <org-alias> [--dry-run] [--only 'Name1,Name2,...']"
42
+ exit 1
43
+ fi
44
+
45
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
46
+ ASSETS_FILE="$SCRIPT_DIR/../assets/best-practice-competencies.json"
47
+
48
+ if [[ ! -f "$ASSETS_FILE" ]]; then
49
+ echo "Cannot find $ASSETS_FILE"
50
+ exit 1
51
+ fi
52
+
53
+ echo "Installing Best-Practice Coaching Competencies on org: $ORG_ALIAS"
54
+ if [[ "$DRY_RUN" == "--dry-run" ]]; then
55
+ echo " (DRY RUN — will not create records)"
56
+ fi
57
+ if [[ -n "$ONLY_LIST" ]]; then
58
+ echo " Subset: $ONLY_LIST"
59
+ fi
60
+ echo ""
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # Auth
64
+ # ---------------------------------------------------------------------------
65
+ # shellcheck source=shared/auth.sh
66
+ source "$SCRIPT_DIR/shared/auth.sh"
67
+
68
+ resolve_org_auth "$ORG_ALIAS" || exit 1
69
+
70
+ TOOLING_BASE="services/data/v68.0/tooling"
71
+
72
+ # shellcheck source=shared/cap.sh
73
+ source "$SCRIPT_DIR/shared/cap.sh"
74
+
75
+ # Detect cap state once up-front. New installs land inactive (with a clear
76
+ # warning) rather than being refused — the admin activates later.
77
+ CAP_HIT="false"
78
+ INITIAL_ACTIVE_COUNT=$(query_active_count "$ORG_ALIAS")
79
+ if [[ "$INITIAL_ACTIVE_COUNT" -ge "$MAX_ACTIVE_COMPETENCIES" ]]; then
80
+ print_cap_report "$ORG_ALIAS" "installing best-practice Coaching Competencies"
81
+ echo " Any new records created by this run will land INACTIVE. Activate them" >&2
82
+ echo " once you free a slot with toggle-custom-competency.sh." >&2
83
+ echo "" >&2
84
+ CAP_HIT="true"
85
+ fi
86
+
87
+ # ---------------------------------------------------------------------------
88
+ # Build the working list (all 7 or --only subset)
89
+ # ---------------------------------------------------------------------------
90
+ if [[ -n "$ONLY_LIST" ]]; then
91
+ # Comma-separated MasterLabels → jq array filter
92
+ ONLY_ARR=$(echo "$ONLY_LIST" | jq -Rc 'split(",") | map(gsub("^\\s+|\\s+$"; ""))')
93
+ WORKING=$(jq --argjson only "$ONLY_ARR" \
94
+ '.competencies | map(select(.MasterLabel as $ml | $only | index($ml)))' \
95
+ "$ASSETS_FILE")
96
+ # Validate: warn on any --only entry that didn't match.
97
+ # Iterate via NUL separator so labels with spaces survive intact.
98
+ while IFS= read -r -d '' req; do
99
+ HIT=$(echo "$WORKING" | jq --arg r "$req" '[.[] | select(.MasterLabel == $r)] | length')
100
+ if [[ "$HIT" == "0" ]]; then
101
+ echo "Warning: --only entry not found in asset file: '$req'"
102
+ fi
103
+ done < <(echo "$ONLY_ARR" | jq -jr '.[] + "\u0000"')
104
+ else
105
+ WORKING=$(jq '.competencies' "$ASSETS_FILE")
106
+ fi
107
+
108
+ COUNT=$(echo "$WORKING" | jq 'length')
109
+ if [[ "$COUNT" == "0" ]]; then
110
+ echo "No competencies matched — nothing to install"
111
+ exit 1
112
+ fi
113
+
114
+ echo "Working set: $COUNT competencies"
115
+ echo ""
116
+
117
+ # ---------------------------------------------------------------------------
118
+ # Iterate
119
+ # ---------------------------------------------------------------------------
120
+ CREATED=0
121
+ SKIPPED=0
122
+ FAILED=0
123
+
124
+ for i in $(seq 0 $((COUNT - 1))); do
125
+ MASTER_LABEL=$(echo "$WORKING" | jq -r ".[$i].MasterLabel")
126
+ DEV_NAME_BASE=$(echo "$WORKING" | jq -r ".[$i].DeveloperNameBase")
127
+ TEMPLATE=$(echo "$WORKING" | jq -r ".[$i].SourceCompetencyTemplate // \"\"")
128
+ DESCRIPTION=$(echo "$WORKING" | jq -r ".[$i].Description // \"\"")
129
+ INSTRUCTIONS=$(echo "$WORKING" | jq -r ".[$i].EvaluationInstructions")
130
+ SCOPE=$(echo "$WORKING" | jq -r ".[$i].EvaluationScope // \"AllCalls\"")
131
+
132
+ # Char-cap enforcement (server rejects with a generic error; we surface up front)
133
+ INSTR_LEN=${#INSTRUCTIONS}
134
+ if [[ "$INSTR_LEN" -gt 16000 ]]; then
135
+ echo " Error: $MASTER_LABEL — EvaluationInstructions is $INSTR_LEN chars (max 16000), skipping"
136
+ FAILED=$((FAILED + 1))
137
+ continue
138
+ fi
139
+
140
+ # Idempotency check by SourceCompetencyTemplate. Best-practice templates
141
+ # like BUSINESS_PROBLEM_DIAGNOSIS live in the same enum space as OOTB
142
+ # (DISCOVERY_QUESTIONING etc), so this correctly prevents dup installs
143
+ # across both installer scripts.
144
+ if [[ -n "$TEMPLATE" ]]; then
145
+ ALREADY_INSTALLED=$( (sf api request rest \
146
+ "${TOOLING_BASE}/query/?q=SELECT+Id+FROM+EnablementCompetencyDef+WHERE+SourceCompetencyTemplate='${TEMPLATE}'" \
147
+ --target-org "$ORG_ALIAS" 2>/dev/null || true) | jq -r '.totalSize // 0' 2>/dev/null)
148
+ ALREADY_INSTALLED="${ALREADY_INSTALLED:-0}"
149
+
150
+ if [[ "$ALREADY_INSTALLED" != "0" ]]; then
151
+ # No Template enum leak — rule #5.
152
+ echo " $MASTER_LABEL — already installed, skipping"
153
+ SKIPPED=$((SKIPPED + 1))
154
+ continue
155
+ fi
156
+ fi
157
+
158
+ # 8-active cap handled up-front by CAP_HIT: if we're at the cap, land the
159
+ # record as inactive so the admin can activate it later. Prevents mid-batch
160
+ # server rejections and keeps the installer non-blocking.
161
+
162
+ SUFFIX=$(hexdump -n 3 -e '"%06x"' /dev/urandom)
163
+ DEV_NAME="${DEV_NAME_BASE}_${SUFFIX}"
164
+
165
+ IS_ACTIVE_JSON=$([[ "$CAP_HIT" == "true" ]] && echo "false" || echo "true")
166
+ PAYLOAD=$(jq -n \
167
+ --arg mn "$MASTER_LABEL" \
168
+ --arg dn "$DEV_NAME" \
169
+ --arg tp "$TEMPLATE" \
170
+ --arg de "$DESCRIPTION" \
171
+ --arg ei "$INSTRUCTIONS" \
172
+ --arg sc "$SCOPE" \
173
+ --argjson ia "$IS_ACTIVE_JSON" \
174
+ '{
175
+ MasterLabel: $mn,
176
+ DeveloperName: $dn,
177
+ Description: $de,
178
+ EvaluationInstructions: $ei,
179
+ EvaluationScope: $sc,
180
+ IsActive: $ia
181
+ } + (if $tp == "" then {} else {SourceCompetencyTemplate: $tp} end)')
182
+
183
+ if [[ "$DRY_RUN" == "--dry-run" ]]; then
184
+ # No DeveloperName / char-count leak — rule #5.
185
+ echo " $MASTER_LABEL — would create"
186
+ CREATED=$((CREATED + 1))
187
+ continue
188
+ fi
189
+
190
+ RESP=$(sf api request rest "${TOOLING_BASE}/sobjects/EnablementCompetencyDef" \
191
+ --target-org "$ORG_ALIAS" \
192
+ --method POST \
193
+ --header 'Content-Type: application/json' \
194
+ --body "$PAYLOAD" \
195
+ 2>/dev/null) || true
196
+
197
+ if echo "$RESP" | jq -e '.success == true' >/dev/null 2>&1; then
198
+ # No record Id / char-count leak — rule #5.
199
+ if [[ "$CAP_HIT" == "true" ]]; then
200
+ echo " $MASTER_LABEL — created inactive (8-active cap), activate later"
201
+ else
202
+ echo " $MASTER_LABEL — created"
203
+ fi
204
+ CREATED=$((CREATED + 1))
205
+ else
206
+ echo " Error: $MASTER_LABEL — create failed:"
207
+ echo " $(echo "$RESP" | jq -c '.' 2>/dev/null || echo "$RESP")"
208
+ FAILED=$((FAILED + 1))
209
+ fi
210
+ done
211
+
212
+ echo ""
213
+ if [[ "$CAP_HIT" == "true" && "$CREATED" -gt 0 ]]; then
214
+ echo "Summary: $CREATED created INACTIVE (8-active cap), $SKIPPED already-installed, $FAILED failed"
215
+ echo " Deactivate a currently-active competency, then activate these with:"
216
+ echo " ./skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh $ORG_ALIAS <Id-or-name> activate"
217
+ else
218
+ echo "Summary: $CREATED created, $SKIPPED already-installed, $FAILED failed"
219
+ fi
220
+
221
+ if [[ "$FAILED" -gt 0 ]]; then
222
+ exit 1
223
+ fi
@@ -0,0 +1,237 @@
1
+ #!/bin/bash
2
+
3
+ # Install the 6 OOTB Coaching Competencies from PRD-canonical prompt bodies.
4
+ # Creates EnablementCompetencyDef records via Tooling API (per its entity XML,
5
+ # EnablementCompetencyDef has perApiAccess sobjectFamily="TOOLING" with
6
+ # isApiInsertable=true, so this is the sanctioned CRUD surface).
7
+ #
8
+ # Idempotent: skips any competency whose DeveloperName already exists.
9
+ #
10
+ # Usage: ./install-ootb-competencies.sh <org-alias> [--dry-run]
11
+ # ./install-ootb-competencies.sh --list
12
+
13
+ set -euo pipefail
14
+
15
+ export NO_COLOR=1
16
+ export FORCE_COLOR=0
17
+
18
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
19
+ ASSETS_FILE="$SCRIPT_DIR/../assets/ootb-competencies.json"
20
+
21
+ if [[ ! -f "$ASSETS_FILE" ]]; then
22
+ echo "Cannot find $ASSETS_FILE"
23
+ exit 1
24
+ fi
25
+
26
+ # --list is read-only and org-agnostic — it just renders the asset file so
27
+ # Claude can show the admin what the OOTB set contains *before* they choose
28
+ # between OOTB and custom. No auth needed, no state touched.
29
+ if [[ "${1:-}" == "--list" ]]; then
30
+ echo "| Competency | What it evaluates |"
31
+ echo "|---|---|"
32
+ jq -r '.competencies[] | "| " + .MasterLabel + " | " + .Description + " |"' "$ASSETS_FILE"
33
+ exit 0
34
+ fi
35
+
36
+ ORG_ALIAS="${1:-}"
37
+ DRY_RUN="${2:-}"
38
+
39
+ if [[ -z "$ORG_ALIAS" ]]; then
40
+ echo "Error: Missing org alias"
41
+ echo "Usage: $0 <org-alias> [--dry-run]"
42
+ echo " $0 --list"
43
+ exit 1
44
+ fi
45
+
46
+ echo "Installing OOTB Coaching Competencies on org: $ORG_ALIAS"
47
+ if [[ "$DRY_RUN" == "--dry-run" ]]; then
48
+ echo " (DRY RUN — will not create records)"
49
+ fi
50
+ echo ""
51
+
52
+ # ---------------------------------------------------------------------------
53
+ # Auth
54
+ # ---------------------------------------------------------------------------
55
+ # shellcheck source=shared/auth.sh
56
+ source "$SCRIPT_DIR/shared/auth.sh"
57
+
58
+ # Needs the raw ACCESS_TOKEN (not just resolve_org_auth) because the
59
+ # Tooling API precheck below can fall back to a SOAP Metadata sessionId
60
+ # call — same documented exception as enable-call-scoring.sh.
61
+ resolve_org_auth_with_token "$ORG_ALIAS" || exit 1
62
+
63
+ TOOLING_BASE="services/data/v68.0/tooling"
64
+
65
+ # shellcheck source=shared/soap.sh
66
+ source "$SCRIPT_DIR/shared/soap.sh"
67
+
68
+ # enableECICallScoring exposes at v68+ only.
69
+ SOAP_ENDPOINT="${INSTANCE_URL}/services/Soap/m/68.0"
70
+ readonly CURL_TIMEOUT=30
71
+
72
+ # ---------------------------------------------------------------------------
73
+ # Precondition: Call Coaching must be enabled before writing competencies.
74
+ # EnablementCompetencyDef inserts aren't rejected server-side when Call
75
+ # Coaching is off, so without this check the script would silently create
76
+ # orphaned records the admin can't see or use until enable-call-scoring.sh
77
+ # runs. Fail fast with a pointer instead.
78
+ #
79
+ # The Tooling API SOQL query below can throw a hard server-side exception
80
+ # (observed: UNKNOWN_EXCEPTION) on some orgs/pods, independent of the
81
+ # actual pref value — reproduced 3x over ~95s against callscoring-dev while
82
+ # SOAP readMetadata concurrently confirmed enableECICallScoring=true. The
83
+ # original code treated any query failure the same as a clean "false" read
84
+ # (via `// false`), so a transient/org-specific API exception silently
85
+ # collapsed into "Call Coaching is not enabled" even when it demonstrably
86
+ # was. Distinguish "query succeeded and says false" (trust it) from "query
87
+ # itself errored" (fall back to the same SOAP read enable-call-scoring.sh
88
+ # treats as source of truth) rather than conflating the two.
89
+ # ---------------------------------------------------------------------------
90
+ CALL_SCORING_RAW=$(sf data query --target-org "$ORG_ALIAS" --use-tooling-api \
91
+ --query "SELECT IsEciCallScoringEnabled FROM ConversationalIntelligenceSettings" \
92
+ --json 2>/dev/null) || true
93
+ CALL_SCORING_JSON=$(echo "$CALL_SCORING_RAW" | awk '/^{/,EOF')
94
+ QUERY_STATUS=$(echo "$CALL_SCORING_JSON" | jq -r '.status // empty' 2>/dev/null)
95
+
96
+ if [[ "$QUERY_STATUS" == "0" ]]; then
97
+ CALL_SCORING_ENABLED=$(echo "$CALL_SCORING_JSON" | jq -r '.result.records[0].IsEciCallScoringEnabled // false' 2>/dev/null || echo "false")
98
+ else
99
+ SOAP_RAW=$(soap_call "readMetadata" "<?xml version='1.0' encoding='utf-8'?>
100
+ <soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
101
+ <soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
102
+ <soapenv:Body><met:readMetadata><met:type>ConversationalIntelligenceSettings</met:type><met:fullNames>ConversationalIntelligence</met:fullNames></met:readMetadata></soapenv:Body>
103
+ </soapenv:Envelope>")
104
+ SOAP_CLASS=$(classify_field "$SOAP_RAW" "enableECICallScoring")
105
+ CALL_SCORING_ENABLED=$(normalize_class "$SOAP_CLASS")
106
+
107
+ if [[ -z "$CALL_SCORING_ENABLED" ]]; then
108
+ echo "Could not determine whether Call Coaching is enabled — $(describe_failure "$SOAP_CLASS")."
109
+ exit 1
110
+ fi
111
+ fi
112
+
113
+ if [[ "$CALL_SCORING_ENABLED" != "true" ]]; then
114
+ echo "Call Coaching is not enabled on this org — refusing to install competencies."
115
+ echo " Run enable-call-scoring.sh first: $SCRIPT_DIR/enable-call-scoring.sh \"$ORG_ALIAS\""
116
+ exit 1
117
+ fi
118
+
119
+ # shellcheck source=shared/cap.sh
120
+ source "$SCRIPT_DIR/shared/cap.sh"
121
+
122
+ # Detect cap state once up-front. New installs land inactive (with a clear
123
+ # warning) rather than being refused — the admin can activate later.
124
+ CAP_HIT="false"
125
+ INITIAL_ACTIVE_COUNT=$(query_active_count "$ORG_ALIAS")
126
+ if [[ "$INITIAL_ACTIVE_COUNT" -ge "$MAX_ACTIVE_COMPETENCIES" ]]; then
127
+ print_cap_report "$ORG_ALIAS" "installing OOTB Coaching Competencies"
128
+ echo " Any new records created by this run will land INACTIVE. Activate them" >&2
129
+ echo " once you free a slot with toggle-custom-competency.sh." >&2
130
+ echo "" >&2
131
+ CAP_HIT="true"
132
+ fi
133
+
134
+ # ---------------------------------------------------------------------------
135
+ # Idempotency: fetch existing DeveloperNames
136
+ # ---------------------------------------------------------------------------
137
+ EXISTING_RAW=$(sf api request rest "${TOOLING_BASE}/query/?q=SELECT+DeveloperName+FROM+EnablementCompetencyDef" \
138
+ --target-org "$ORG_ALIAS" 2>/dev/null) || true
139
+ EXISTING=$(echo "$EXISTING_RAW" | jq -r '.records[]?.DeveloperName // empty' 2>/dev/null || echo "")
140
+
141
+ # ---------------------------------------------------------------------------
142
+ # Iterate competencies
143
+ # ---------------------------------------------------------------------------
144
+ COUNT=$(jq '.competencies | length' "$ASSETS_FILE")
145
+ CREATED=0
146
+ SKIPPED=0
147
+ FAILED=0
148
+
149
+ for i in $(seq 0 $((COUNT - 1))); do
150
+ MASTER_LABEL=$(jq -r ".competencies[$i].MasterLabel" "$ASSETS_FILE")
151
+ DEV_NAME_BASE=$(jq -r ".competencies[$i].DeveloperNameBase" "$ASSETS_FILE")
152
+ TEMPLATE=$(jq -r ".competencies[$i].SourceCompetencyTemplate" "$ASSETS_FILE")
153
+ DESCRIPTION=$(jq -r ".competencies[$i].Description" "$ASSETS_FILE")
154
+ INSTRUCTIONS=$(jq -r ".competencies[$i].EvaluationInstructions" "$ASSETS_FILE")
155
+ SCOPE=$(jq -r ".competencies[$i].EvaluationScope" "$ASSETS_FILE")
156
+
157
+ # Idempotency check by SourceCompetencyTemplate (canonical OOTB template key).
158
+ # Skips if any record with the same template already exists (regardless of
159
+ # DeveloperName suffix); safer than by-name since names can be renamed.
160
+ ALREADY_INSTALLED=$( (sf api request rest \
161
+ "${TOOLING_BASE}/query/?q=SELECT+Id+FROM+EnablementCompetencyDef+WHERE+SourceCompetencyTemplate='${TEMPLATE}'" \
162
+ --target-org "$ORG_ALIAS" 2>/dev/null || true) | jq -r '.totalSize // 0' 2>/dev/null)
163
+ ALREADY_INSTALLED="${ALREADY_INSTALLED:-0}"
164
+
165
+ if [[ "$ALREADY_INSTALLED" != "0" ]]; then
166
+ # No Template enum leak here — rule #5. Idempotency detail lives in --verbose diagnostics only.
167
+ echo " $MASTER_LABEL — already installed, skipping"
168
+ SKIPPED=$((SKIPPED + 1))
169
+ continue
170
+ fi
171
+
172
+ # DeveloperName must be unique. Append a short random suffix to match the
173
+ # naming convention used by the Setup wizard LWC (CCH_<Sanitized>_<hex>).
174
+ SUFFIX=$(hexdump -n 3 -e '"%06x"' /dev/urandom)
175
+ DEV_NAME="${DEV_NAME_BASE}_${SUFFIX}"
176
+
177
+ IS_ACTIVE_JSON=$([[ "$CAP_HIT" == "true" ]] && echo "false" || echo "true")
178
+ PAYLOAD=$(jq -n \
179
+ --arg mn "$MASTER_LABEL" \
180
+ --arg dn "$DEV_NAME" \
181
+ --arg tp "$TEMPLATE" \
182
+ --arg de "$DESCRIPTION" \
183
+ --arg ei "$INSTRUCTIONS" \
184
+ --arg sc "$SCOPE" \
185
+ --argjson ia "$IS_ACTIVE_JSON" \
186
+ '{
187
+ MasterLabel: $mn,
188
+ DeveloperName: $dn,
189
+ SourceCompetencyTemplate: $tp,
190
+ Description: $de,
191
+ EvaluationInstructions: $ei,
192
+ EvaluationScope: $sc,
193
+ IsActive: $ia
194
+ }')
195
+
196
+ if [[ "$DRY_RUN" == "--dry-run" ]]; then
197
+ # No DeveloperName leak here — rule #5.
198
+ echo " $MASTER_LABEL — would create"
199
+ CREATED=$((CREATED + 1))
200
+ continue
201
+ fi
202
+
203
+ RESP=$(sf api request rest "${TOOLING_BASE}/sobjects/EnablementCompetencyDef" \
204
+ --target-org "$ORG_ALIAS" \
205
+ --method POST \
206
+ --header 'Content-Type: application/json' \
207
+ --body "$PAYLOAD" \
208
+ 2>/dev/null) || true
209
+
210
+ if echo "$RESP" | jq -e '.success == true' >/dev/null 2>&1; then
211
+ # No record Id leak on the primary line — rule #5. Calling agent that
212
+ # needs the Id can re-query via list-competencies.sh --verbose or --json.
213
+ if [[ "$CAP_HIT" == "true" ]]; then
214
+ echo " $MASTER_LABEL — created inactive (8-active cap), activate later"
215
+ else
216
+ echo " $MASTER_LABEL — created"
217
+ fi
218
+ CREATED=$((CREATED + 1))
219
+ else
220
+ echo " Error: $MASTER_LABEL — create failed:"
221
+ echo " $(echo "$RESP" | jq -c '.' 2>/dev/null || echo "$RESP")"
222
+ FAILED=$((FAILED + 1))
223
+ fi
224
+ done
225
+
226
+ echo ""
227
+ if [[ "$CAP_HIT" == "true" && "$CREATED" -gt 0 ]]; then
228
+ echo "Summary: $CREATED created INACTIVE (8-active cap), $SKIPPED already-installed, $FAILED failed"
229
+ echo " Deactivate a currently-active competency, then activate these with:"
230
+ echo " ./skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh $ORG_ALIAS <Id-or-name> activate"
231
+ else
232
+ echo "Summary: $CREATED created, $SKIPPED already-installed, $FAILED failed"
233
+ fi
234
+
235
+ if [[ "$FAILED" -gt 0 ]]; then
236
+ exit 1
237
+ fi