@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.
- package/package.json +1 -1
- package/skills/agentforce-generate/SKILL.md +8 -0
- package/skills/agentforce-generate/references/actions-reference.md +2 -2
- package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
- package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
- package/skills/agentforce-observe/SKILL.md +13 -9
- package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
- package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
- package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
- package/skills/commerce-b2b-open-code-components-integrate/SKILL.md +1 -1
- package/skills/commerce-b2b-open-code-components-replace/SKILL.md +16 -16
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
- package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
- package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
- package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
- package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
- package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
- package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
- package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
- package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
- package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
- package/skills/dx-devops-project-manage/SKILL.md +1 -1
- package/skills/dx-org-analyze/SKILL.md +0 -1
- package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
- package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
- package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
- package/skills/dx-org-manage/SKILL.md +6 -50
- package/skills/dx-org-manage/examples/README.md +10 -16
- package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
- package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
- package/skills/dx-org-shape-manage/SKILL.md +4 -3
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
- package/skills/experience-accessibility-validate/SKILL.md +8 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
- package/skills/experience-cms-content-generate/SKILL.md +1 -1
- package/skills/experience-cms-content-render/SKILL.md +3 -3
- package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +35 -7
- package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +13 -4
- package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +30 -8
- package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +14 -4
- package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +11 -1
- package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +1 -1
- package/skills/experience-cms-content-render/assets/shared/mediaLabels.ts +62 -0
- package/skills/experience-cms-content-render/references/init-scaffold.md +13 -6
- package/skills/experience-content-media-stock-image-search/SKILL.md +0 -1
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
- package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
- package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
- package/skills/experience-lwc-design-generate/SKILL.md +1 -1
- package/skills/experience-lwc-legacy-migrate/SKILL.md +212 -0
- package/skills/experience-lwc-legacy-migrate/assets/lo20-host-page-template.html +192 -0
- package/skills/experience-lwc-legacy-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
- package/skills/experience-lwc-legacy-migrate/references/lightning-out-2-system-reference.md +495 -0
- package/skills/experience-lwc-legacy-migrate/references/lightning-out-beta-to-2-migration.md +824 -0
- package/skills/experience-lwc-legacy-migrate/scripts/convert-lo-names.py +94 -0
- package/skills/experience-lwc-legacy-migrate/scripts/validate-lo20-page.py +133 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
- package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
- package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
- package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
- package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
- package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
- package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
- package/skills/experience-ui-bundle-project-generate/SKILL.md +1 -1
- package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
- package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
- package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
- package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
- package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
- package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
- package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
- package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
- package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
- package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
- package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
- package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
- package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
- package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
- package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
- package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
- package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
- package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
- package/skills/integration-connectivity-connected-app-configure/SKILL.md +5 -5
- package/skills/integration-connectivity-generate/SKILL.md +10 -10
- package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +2 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
- package/skills/mobile-apps-create/SKILL.md +1 -1
- package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
- package/skills/platform-apex-test-generate/SKILL.md +1 -1
- package/skills/platform-apex-test-run/SKILL.md +1 -1
- package/skills/platform-custom-field-generate/SKILL.md +1 -1
- package/skills/platform-custom-lightning-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-metadata-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-object-generate/SKILL.md +1 -1
- package/skills/platform-custom-report-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-setting-generate/SKILL.md +1 -1
- package/skills/platform-data-and-tooling-api-context-get/SKILL.md +1 -1
- package/skills/platform-data-manage/SKILL.md +10 -10
- package/skills/platform-flexipage-generate/SKILL.md +1 -1
- package/skills/platform-lightning-app-coordinate/SKILL.md +1 -1
- package/skills/platform-metadata-api-context-get/SKILL.md +1 -1
- package/skills/platform-metadata-retrieve/SKILL.md +1 -1
- package/skills/platform-permission-set-generate/SKILL.md +1 -1
- package/skills/platform-report-generate/SKILL.md +1 -1
- package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +4 -4
- package/skills/platform-sandbox-configure/SKILL.md +108 -133
- package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
- package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
- package/skills/platform-sharing-owd-configure/SKILL.md +1 -1
- package/skills/platform-sharing-rules-generate/SKILL.md +1 -1
- package/skills/platform-soql-query/SKILL.md +1 -1
- package/skills/platform-value-set-generate/SKILL.md +1 -1
- package/skills/platform-widget-generate/SKILL.md +26 -18
- package/skills/platform-widget-generate/examples/formulas.json +191 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
- package/skills/sales-call-scoring-configure/SKILL.md +318 -0
- package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
- package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
- package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
- package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
- package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
- package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
- package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
- package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
- package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
- package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
- package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
- package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
- package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
- package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +4 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +26 -6
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +5 -4
- package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
- package/skills/service-de-channel-activate/SKILL.md +6 -5
- package/skills/service-de-channel-create/SKILL.md +3 -3
- package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
- package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
- package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
- package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
- package/skills/service-de-waba-integrate/SKILL.md +2 -1
- package/skills/service-digital-engagement-deployment-configure/SKILL.md +2 -0
- package/skills/service-digital-engagement-deployment-configure/scripts/check-api-version.sh +29 -0
- package/skills/service-email-to-case-configure/SKILL.md +1 -1
- package/skills/service-helpagent-coordinate/SKILL.md +3 -2
- package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
- package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
- package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
- package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
- package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
- package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
- package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
- package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
- package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
- package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
- package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
- package/skills/dx-org-manage/references/cli_flags.md +0 -67
- package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
- package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
- package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
- /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
- /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Competency CRUD workflow — Full Spec
|
|
2
|
+
|
|
3
|
+
Consult this reference whenever the admin's ask touches competency records (list, install, create, edit, activate/deactivate, verify, delete).
|
|
4
|
+
|
|
5
|
+
Once Phase 5 of `enable-call-scoring.sh` confirms the feature is enabled (or Phase 1 detects State 3/4), Claude runs the `Next:` script from `enable-call-scoring.sh` directly, in the same turn. Records are managed via Tooling API on `EnablementCompetencyDef` (setup entity, keyPrefix `1nA`, module `conversation-udd`). Cap: **8 simultaneously active** per org (`CoachingCompetenciesFeature.MAX_ACTIVE_COMPETENCIES`).
|
|
6
|
+
|
|
7
|
+
All scripts share `shared/auth.sh` / `resolve_org_auth` (same fail-fast messages, token-reuse across chained invocations). Tooling API writes go through `sf api request rest` where practical; a subset (custom-CRUD variants, best-practice installer) drops to raw `curl` for finer request shape.
|
|
8
|
+
|
|
9
|
+
**Two parallel families:** generic scripts (`{create,edit,toggle,get}-competency.sh`) work on any competency; custom-CRUD variants (`*-custom-competency.sh`) harden the write path with SpecificCallsOnly filter JSON and richer validation. Prefer the custom variants when the admin's intent is unambiguously custom (S5-created); fall back to generic on OOTB or unknown-provenance records.
|
|
10
|
+
|
|
11
|
+
## Table of contents
|
|
12
|
+
|
|
13
|
+
- [S3 · List](#s3--list--list-competenciessh-alias---verbose--json)
|
|
14
|
+
- [S4 · Install OOTB set](#s4--install-ootb-set--install-ootb-competenciessh-alias---dry-run)
|
|
15
|
+
- [S4b · Install best-practice set](#s4b--install-best-practice-set--install-best-practice-competenciessh-alias---dry-run---only-name1name2)
|
|
16
|
+
- [S5 · Create custom (conversational)](#s5--create-custom-conversational--create-custom-competencysh-alias-payloadjson)
|
|
17
|
+
- [S6 · Edit](#s6--edit--edit-competencysh-alias-name-or-id--or-edit-custom-competencysh-alias-name-or-id-)
|
|
18
|
+
- [S7 · Activate/deactivate](#s7--activatedeactivate--toggle-competencysh-alias-name-or-id-activatedeactivate-or-toggle-custom-competencysh-alias-name-or-id-activatedeactivate)
|
|
19
|
+
- [S8 · Fetch a record](#s8--fetch-a-record--get-competencysh-alias-name-or-id---field-name-or-get-custom-competencysh-alias-name-or-id---field-name)
|
|
20
|
+
- [S9 · Verify](#s9--verify--verify-ootb-competenciessh-alias-name-)
|
|
21
|
+
- [S10 · Delete](#s10--delete--no-dedicated-script-yet-use-sf-cli-directly)
|
|
22
|
+
- [Execution sequence — by admin intent × org state](#execution-sequence--by-admin-intent--org-state)
|
|
23
|
+
- [Chaining checkpoints](#chaining-checkpoints-claude-must-respect)
|
|
24
|
+
|
|
25
|
+
## S3 · List — `list-competencies.sh <alias> [--verbose|--json]`
|
|
26
|
+
|
|
27
|
+
Enumerates current competencies. Shows `Active / 8 (max)` count.
|
|
28
|
+
|
|
29
|
+
**Output modes** (per admin-comms rule #5 — admin-safe by default):
|
|
30
|
+
|
|
31
|
+
- **Default** — `MasterLabel` + `IsActive` icon + `EvaluationScope` + `Description`. **No** record Ids, DeveloperNames, or Template enum keys. Safe to forward directly to the admin.
|
|
32
|
+
- **`--verbose`** — Default fields PLUS `DeveloperName`, `SourceCompetencyTemplate` enum, and `Id`. Use only when the admin explicitly asks to debug or share with support.
|
|
33
|
+
- **`--json`** — Raw record JSON for the calling agent to parse. Never forward this to the admin directly.
|
|
34
|
+
|
|
35
|
+
## S4 · Install OOTB set — `install-ootb-competencies.sh <alias> [--dry-run]`
|
|
36
|
+
|
|
37
|
+
Creates the 6 PRD-canonical competencies (Active Listening Skills, Relationship Building, Discovery Questioning, Objection Handling, Value Proposition Focus, Closing Urgency) with prompt bodies taken verbatim from `assets/ootb-competencies.json`. Idempotent: matches by `SourceCompetencyTemplate` and skips already-installed rows.
|
|
38
|
+
|
|
39
|
+
**`--list` mode** (`install-ootb-competencies.sh --list`) — no org alias, no auth, no write. Renders the 6 competencies (name + what each evaluates) as a markdown table straight from the asset file. This is what backs rule #13's OOTB-vs-custom question: show this table to the admin *before* they decide between the OOTB set and building custom competencies, not after installing.
|
|
40
|
+
|
|
41
|
+
Checks `IsEciCallScoringEnabled` on `ConversationalIntelligenceSettings` before writing — refuses with a pointer to `enable-call-scoring.sh` if Call Coaching isn't enabled yet, rather than creating competency records the admin can't see or use until it is.
|
|
42
|
+
|
|
43
|
+
Output is admin-safe by default — no DeveloperName suffixes, Template enum keys, or record Ids leak into per-row lines. When the org is already at the 8-active cap, records land inactive with an "activate later" hint.
|
|
44
|
+
|
|
45
|
+
**Always follow with S9** on first-time setup — see the S9 carve-out for why the verify table is the one place entity-level detail is surfaced to the admin by design.
|
|
46
|
+
|
|
47
|
+
## S4b · Install best-practice set — `install-best-practice-competencies.sh <alias> [--dry-run] [--only "Name1,Name2,..."]`
|
|
48
|
+
|
|
49
|
+
Creates the 7 Momentum best-practice reference prompts from `assets/best-practice-competencies.json` (Business Problem Diagnosis, Change Management Navigation, Discovery Excellence, Executive Vision Alignment, Multi-Stakeholder Orchestration, Product Knowledge, Enterprise Value Articulation). Parallel to S4 but with richer PRD/PURPOSE-structured prompt bodies.
|
|
50
|
+
|
|
51
|
+
Same idempotency (by `SourceCompetencyTemplate`) and cap-fallback behavior as S4. Use `--only "Name1,Name2"` to install a subset by `MasterLabel`.
|
|
52
|
+
|
|
53
|
+
## S5 · Create custom (conversational) — `create-custom-competency.sh <alias> <payload.json>`
|
|
54
|
+
|
|
55
|
+
The bash primitive expects a JSON payload with at minimum `MasterLabel` and `EvaluationInstructions`; optional `Description`, `EvaluationScope` (`AllCalls` | `SpecificCallsOnly`), `EvaluationConditions` (FilterCriteria JSON, required when scope is `SpecificCallsOnly`), `IsActive` (default `true`), `SourceCompetencyTemplate` (leave empty for custom).
|
|
56
|
+
|
|
57
|
+
**Claude's conversational role — the Q1-Q4 sequence.** When the admin asks to add a custom competency, do NOT jump to drafting. Ask these four in order, one at a time:
|
|
58
|
+
|
|
59
|
+
- **Q1. What sales skill are you trying to score?** One sentence in the admin's own words. Anchor for the whole competency.
|
|
60
|
+
- **Q2. What does *good* look like on a call?** 2-3 observable, call-audible behaviors (not internal states).
|
|
61
|
+
- **Q3. What does *not good* look like?** 2-3 concrete behaviors indicating the skill is missing or poorly applied, at the same bar.
|
|
62
|
+
- **Q4. Active right now?** Yes → `IsActive=true` (auto-falls back to inactive if org is at the 8-active cap; script prints an "activate later" hint). No → `IsActive=false`.
|
|
63
|
+
|
|
64
|
+
Do NOT ask about call-filter scope (Enterprise-only, discovery-only, etc.). Competencies apply to all calls today regardless of the `EvaluationScope`/`EvaluationConditions` record fields, so asking creates a false expectation for the admin. The bash primitive still accepts those fields for a future re-enablement — see S5 header — but the conversational flow leaves them defaulted (`AllCalls`) and empty.
|
|
65
|
+
|
|
66
|
+
After Q1-Q4, draft the `EvaluationInstructions` prompt using the **PURPOSE / KEY AREAS / positive-negative-indicators / EXAMPLE** structure mirrored from `assets/best-practice-competencies.json`. Show the draft to the admin — e.g. "I've put together a draft based on your answers, following the same structure as best practices:" — never "best-practice competencies" in admin-facing text; that's the internal asset/script name, not admin language (rule #6). Iterate once if they request changes, then:
|
|
67
|
+
|
|
68
|
+
1. Write the payload to a temp JSON file — `MasterLabel` (from Q1's skill name, title-cased), `EvaluationInstructions` (the drafted prompt), `Description` (a 1-sentence version of Q1), `IsActive` (from Q4). Omit `EvaluationScope`/`EvaluationConditions` — the script defaults to `AllCalls`.
|
|
69
|
+
2. Invoke `create-custom-competency.sh <alias> <payload.json>`.
|
|
70
|
+
3. Delete the temp JSON afterwards.
|
|
71
|
+
4. Chain into S9 verify (passing the just-created `MasterLabel`) to confirm and show the admin what got configured.
|
|
72
|
+
|
|
73
|
+
**Do not skip Q1-Q4.** The eval-readiness bar requires that admins go through a structured authoring flow, not a "just draft me something for X" one-shot. If the admin insists on skipping, still capture the minimum needed for `MasterLabel` + `EvaluationInstructions` — but push back once.
|
|
74
|
+
|
|
75
|
+
## S6 · Edit — `edit-competency.sh <alias> <name-or-id> ...` OR `edit-custom-competency.sh <alias> <name-or-id> ...`
|
|
76
|
+
|
|
77
|
+
Both take `--instructions[-file] <>` and/or `--description <>`. PATCH updates preserve Id, DeveloperName, IsActive, EvaluationScope, SourceCompetencyTemplate. Enforce 16000 / 255 char field caps.
|
|
78
|
+
|
|
79
|
+
Prefer `edit-custom-competency.sh` for competencies created via S5; use `edit-competency.sh` on OOTB or unknown-provenance competencies.
|
|
80
|
+
|
|
81
|
+
## S7 · Activate/deactivate — `toggle-competency.sh <alias> <name-or-id> <activate|deactivate>` OR `toggle-custom-competency.sh <alias> <name-or-id> <activate|deactivate>`
|
|
82
|
+
|
|
83
|
+
Flips `IsActive`. Idempotent. Enforces the 8-active cap on the activate path — refuses to activate if the org is at cap and prints the current active set so the admin can choose which to deactivate. Deactivation preserves historical `EnablementCompetencyEval` records per the entity XML comment. Same generic-vs-custom split as S6.
|
|
84
|
+
|
|
85
|
+
## S8 · Fetch a record — `get-competency.sh <alias> <name-or-id> [--field <name>]` OR `get-custom-competency.sh <alias> <name-or-id> [--field <name>]`
|
|
86
|
+
|
|
87
|
+
Returns the full record (or a single field) so Claude can load the current `EvaluationInstructions` into context before drafting an improvement. Conversational improvement suggestions are Claude's job (see S5 for the reference-prompt library); the resulting write is done via `edit-competency.sh` / `edit-custom-competency.sh`.
|
|
88
|
+
|
|
89
|
+
## S9 · Verify — `verify-ootb-competencies.sh <alias> ["Name" ...]`
|
|
90
|
+
|
|
91
|
+
Confirms expected competencies exist and are active, printing name + evaluation criteria in a markdown table. Run after S4 / S4b / S5 to catch partial installs. No args → full 6-competency OOTB set from `assets/ootb-competencies.json`; explicit `MasterLabel` values → verify a specific subset. Exits 0 only if every expected name exists AND `IsActive=true`.
|
|
92
|
+
|
|
93
|
+
**Carve-out to admin-comms rules #5 and #6.** The S9 table is the ONE place prompt-body content (`EvaluationInstructions`) is deliberately surfaced to the admin — after an install, the admin needs to see the actual names and evaluation criteria, not just a count. On first-time setup, paste the script's table output directly into the chat response. Column labels ("Competency", "Evaluation Instructions") are admin English, not raw entity API names.
|
|
94
|
+
|
|
95
|
+
## S10 · Delete — no dedicated script (yet); use `sf` CLI directly
|
|
96
|
+
|
|
97
|
+
No `delete-competency.sh` yet. Resolve the Id via `list-competencies.sh --verbose` (don't expose it to the admin), then:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
sf data delete record --sobject EnablementCompetencyDef --record-id <Id> \
|
|
101
|
+
--target-org <alias> --use-tooling-api
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Report "Deleted '<MasterLabel>'" — not the Id.
|
|
105
|
+
|
|
106
|
+
**Caveats.** FK-referenced records cannot be deleted — if the competency has `EnablementCompetencyEval` rows attached, DELETE fails on foreign-key constraint; use `toggle-*-competency.sh deactivate` instead (preserves history per the entity XML comment). When in doubt, deactivate first via S7 — frees the active slot even if the subsequent delete fails on FK.
|
|
107
|
+
|
|
108
|
+
## Execution sequence — by admin intent × org state
|
|
109
|
+
|
|
110
|
+
Once Phase 1 classifies the org into State 1a / 2 / 3 / 4, the intent × state matrix below determines which scripts to chain, in what order. **Chain automatically per rule #12** — do not ask permission between steps.
|
|
111
|
+
|
|
112
|
+
| Admin intent | State 1a (no ECI) | State 2 (avail, not enabled) | State 3 (enabled, no comps) | State 4 (enabled, with comps) |
|
|
113
|
+
|---|---|---|---|---|
|
|
114
|
+
| **Enable Call Coaching** (unqualified — no OOTB/custom stated) | Refuse — needs Agentforce for Sales | `enable-call-scoring.sh` → rule #13 ask (OOTB vs custom) | Idempotent — rule #13 ask (OOTB vs custom) | Idempotent — `enable-call-scoring.sh` exits 0, chains into S3 list |
|
|
115
|
+
| **Install OOTB set** (explicitly asked) | (refuse) | `enable-call-scoring.sh` auto-chains into S4 → S9 | `install-ootb-competencies.sh` → S9 | `install-ootb-competencies.sh` (idempotent — skips existing templates) → S9 |
|
|
116
|
+
| **Install best-practice set** | (refuse) | `enable-call-scoring.sh` → `install-best-practice-competencies.sh` → S9 | `install-best-practice-competencies.sh` → S9 | `install-best-practice-competencies.sh` (idempotent) → S9 |
|
|
117
|
+
| **Create custom competency** | (refuse) | `enable-call-scoring.sh` → **Q1-Q4** → `create-custom-competency.sh` → S9 | **Q1-Q4** → `create-custom-competency.sh` → S9 | **Q1-Q4** → `create-custom-competency.sh` → S9 |
|
|
118
|
+
| **Edit competency** | (refuse) | (no competencies to edit) | (no competencies to edit) | `edit-competency.sh` (OOTB) OR `edit-custom-competency.sh` (custom) |
|
|
119
|
+
| **Activate / deactivate** | (refuse) | (n/a) | (n/a) | `toggle-competency.sh` OR `toggle-custom-competency.sh` |
|
|
120
|
+
| **Improve a competency's prompt** | (refuse) | (n/a) | (n/a) | `get-*-competency.sh` (load current) → draft (Claude) → `edit-*-competency.sh` |
|
|
121
|
+
| **List / audit** | (refuse) | `list-competencies.sh` (empty) | `list-competencies.sh` (empty) | `list-competencies.sh` |
|
|
122
|
+
| **Verify OOTB set installed** | (refuse) | (nothing to verify) | (refuse — nothing installed) | `verify-ootb-competencies.sh` |
|
|
123
|
+
| **Delete a competency** | (refuse) | (n/a) | (n/a) | S10 — `sf data delete record` (fall back to S7 deactivate if FK-blocked) |
|
|
124
|
+
|
|
125
|
+
## Chaining checkpoints Claude must respect
|
|
126
|
+
|
|
127
|
+
- `enable-call-scoring.sh` prints `Next: <script>` on stdout — that's a hard chain hint. Run it in the same turn without asking (rule #12), **except** the State 3 hint, which points at `install-ootb-competencies.sh --list` — render that table and ask OOTB-vs-custom (rule #13) before writing anything, unless the admin's original ask already named one.
|
|
128
|
+
- After S4 / S4b / S5, always run S9 verify. Paste its table to the admin (S9 carve-out).
|
|
129
|
+
- After S5, do NOT stop at "created" — always show the admin what got created via S9.
|
|
130
|
+
- Between chained scripts, `ACCESS_TOKEN` and `INSTANCE_URL` propagate through the shared shell env (per Phase 0) — no re-auth.
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Create a single custom Coaching Competency from a JSON payload.
|
|
4
|
+
# Payload must contain: MasterLabel, EvaluationInstructions.
|
|
5
|
+
# Optional: DeveloperName (auto-generated if omitted), Description,
|
|
6
|
+
# EvaluationScope (defaults AllCalls), IsActive (defaults true),
|
|
7
|
+
# SourceCompetencyTemplate (empty for custom).
|
|
8
|
+
#
|
|
9
|
+
# This is the deterministic write primitive for S5 (custom conversational
|
|
10
|
+
# competency creation). Claude drives the conversational drafting;
|
|
11
|
+
# once the prompt is approved, it writes the payload to a temp JSON and
|
|
12
|
+
# invokes this script.
|
|
13
|
+
#
|
|
14
|
+
# Usage: ./create-competency.sh <org-alias> <payload.json>
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
export NO_COLOR=1
|
|
19
|
+
export FORCE_COLOR=0
|
|
20
|
+
|
|
21
|
+
ORG_ALIAS="${1:-}"
|
|
22
|
+
PAYLOAD_FILE="${2:-}"
|
|
23
|
+
|
|
24
|
+
if [[ -z "$ORG_ALIAS" || -z "$PAYLOAD_FILE" ]]; then
|
|
25
|
+
echo "Usage: $0 <org-alias> <payload.json>"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
if [[ ! -f "$PAYLOAD_FILE" ]]; then
|
|
29
|
+
echo "Payload file not found: $PAYLOAD_FILE"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
# Validate payload
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
MASTER_LABEL=$(jq -r '.MasterLabel // empty' "$PAYLOAD_FILE")
|
|
37
|
+
INSTRUCTIONS=$(jq -r '.EvaluationInstructions // empty' "$PAYLOAD_FILE")
|
|
38
|
+
|
|
39
|
+
if [[ -z "$MASTER_LABEL" ]]; then echo "MasterLabel is required"; exit 1; fi
|
|
40
|
+
if [[ -z "$INSTRUCTIONS" ]]; then echo "EvaluationInstructions is required"; exit 1; fi
|
|
41
|
+
|
|
42
|
+
INSTR_LEN=${#INSTRUCTIONS}
|
|
43
|
+
if [[ "$INSTR_LEN" -gt 16000 ]]; then
|
|
44
|
+
echo "EvaluationInstructions is $INSTR_LEN chars — max 16000"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
DESCRIPTION=$(jq -r '.Description // ""' "$PAYLOAD_FILE")
|
|
49
|
+
DESC_LEN=${#DESCRIPTION}
|
|
50
|
+
if [[ "$DESC_LEN" -gt 255 ]]; then
|
|
51
|
+
echo "Description is $DESC_LEN chars — max 255"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
SCOPE=$(jq -r '.EvaluationScope // "AllCalls"' "$PAYLOAD_FILE")
|
|
56
|
+
if [[ "$SCOPE" != "AllCalls" && "$SCOPE" != "SpecificCallsOnly" ]]; then
|
|
57
|
+
echo "EvaluationScope must be AllCalls or SpecificCallsOnly (got: $SCOPE)"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# jq's // treats false as absent; use explicit null-check to preserve IsActive:false.
|
|
62
|
+
IS_ACTIVE=$(jq -r 'if has("IsActive") then .IsActive else true end' "$PAYLOAD_FILE")
|
|
63
|
+
TEMPLATE=$(jq -r '.SourceCompetencyTemplate // ""' "$PAYLOAD_FILE")
|
|
64
|
+
DEV_NAME=$(jq -r '.DeveloperName // empty' "$PAYLOAD_FILE")
|
|
65
|
+
|
|
66
|
+
if [[ -z "$DEV_NAME" ]]; then
|
|
67
|
+
SANITIZED=$(echo "$MASTER_LABEL" | tr -cd '[:alnum:]' | cut -c1-30)
|
|
68
|
+
SUFFIX=$(hexdump -n 3 -e '"%06x"' /dev/urandom)
|
|
69
|
+
DEV_NAME="CCH_${SANITIZED}_${SUFFIX}"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Auth
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
76
|
+
# shellcheck source=shared/auth.sh
|
|
77
|
+
source "$SCRIPT_DIR/shared/auth.sh"
|
|
78
|
+
|
|
79
|
+
resolve_org_auth "$ORG_ALIAS" || exit 1
|
|
80
|
+
|
|
81
|
+
TOOLING_BASE="services/data/v68.0/tooling"
|
|
82
|
+
|
|
83
|
+
# ---------------------------------------------------------------------------
|
|
84
|
+
# 8-active cap: auto-fallback to inactive so the admin's work isn't blocked.
|
|
85
|
+
# ---------------------------------------------------------------------------
|
|
86
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
87
|
+
# shellcheck source=shared/cap.sh
|
|
88
|
+
source "$SCRIPT_DIR/shared/cap.sh"
|
|
89
|
+
# shellcheck source=shared/soql.sh
|
|
90
|
+
source "$SCRIPT_DIR/shared/soql.sh"
|
|
91
|
+
|
|
92
|
+
CAP_FELL_BACK="false"
|
|
93
|
+
if [[ "$IS_ACTIVE" == "true" ]]; then
|
|
94
|
+
ACTIVE_COUNT=$( (sf api request rest \
|
|
95
|
+
"${TOOLING_BASE}/query/?q=SELECT+COUNT()+FROM+EnablementCompetencyDef+WHERE+IsActive=true" \
|
|
96
|
+
--target-org "$ORG_ALIAS" 2>/dev/null || true) | jq -r '.totalSize // 0' 2>/dev/null)
|
|
97
|
+
ACTIVE_COUNT="${ACTIVE_COUNT:-0}"
|
|
98
|
+
if [[ "$ACTIVE_COUNT" -ge "$MAX_ACTIVE_COMPETENCIES" ]]; then
|
|
99
|
+
echo "Warning: Org is at the 8-active competency cap — creating this one as inactive."
|
|
100
|
+
echo " Deactivate an existing competency, then re-activate this one to promote it."
|
|
101
|
+
IS_ACTIVE="false"
|
|
102
|
+
CAP_FELL_BACK="true"
|
|
103
|
+
fi
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# ---------------------------------------------------------------------------
|
|
107
|
+
# Uniqueness check by MasterLabel (to avoid silent duplicates)
|
|
108
|
+
# ---------------------------------------------------------------------------
|
|
109
|
+
LABEL_ENC=$(printf "SELECT Id FROM EnablementCompetencyDef WHERE MasterLabel='%s'" "$(soql_escape "$MASTER_LABEL")" | jq -sRr @uri)
|
|
110
|
+
DUP=$( (sf api request rest "${TOOLING_BASE}/query/?q=${LABEL_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null || true) \
|
|
111
|
+
| jq -r '.totalSize // 0' 2>/dev/null)
|
|
112
|
+
DUP="${DUP:-0}"
|
|
113
|
+
if [[ "$DUP" != "0" ]]; then
|
|
114
|
+
echo "A competency with MasterLabel '$MASTER_LABEL' already exists — refusing to duplicate."
|
|
115
|
+
echo " Use edit-competency.sh to update, or choose a different name."
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# ---------------------------------------------------------------------------
|
|
120
|
+
# Build final payload + POST
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
FINAL=$(jq -n \
|
|
123
|
+
--arg mn "$MASTER_LABEL" \
|
|
124
|
+
--arg dn "$DEV_NAME" \
|
|
125
|
+
--arg tp "$TEMPLATE" \
|
|
126
|
+
--arg de "$DESCRIPTION" \
|
|
127
|
+
--arg ei "$INSTRUCTIONS" \
|
|
128
|
+
--arg sc "$SCOPE" \
|
|
129
|
+
--argjson ia "$IS_ACTIVE" \
|
|
130
|
+
'{
|
|
131
|
+
MasterLabel: $mn,
|
|
132
|
+
DeveloperName: $dn,
|
|
133
|
+
Description: $de,
|
|
134
|
+
EvaluationInstructions: $ei,
|
|
135
|
+
EvaluationScope: $sc,
|
|
136
|
+
IsActive: $ia
|
|
137
|
+
} + (if $tp == "" then {} else {SourceCompetencyTemplate: $tp} end)')
|
|
138
|
+
|
|
139
|
+
echo "Creating: $MASTER_LABEL"
|
|
140
|
+
# No DeveloperName / char count / entity-field leak — rule #5. Scope is
|
|
141
|
+
# admin-facing content ("AllCalls" / "SpecificCallsOnly") so it stays.
|
|
142
|
+
echo " Scope: $SCOPE Active: $IS_ACTIVE"
|
|
143
|
+
|
|
144
|
+
RESP=$(sf api request rest "${TOOLING_BASE}/sobjects/EnablementCompetencyDef" \
|
|
145
|
+
--target-org "$ORG_ALIAS" \
|
|
146
|
+
--method POST \
|
|
147
|
+
--header 'Content-Type: application/json' \
|
|
148
|
+
--body "$FINAL" \
|
|
149
|
+
2>/dev/null) || true
|
|
150
|
+
|
|
151
|
+
if echo "$RESP" | jq -e '.success == true' >/dev/null 2>&1; then
|
|
152
|
+
NEW_ID=$(echo "$RESP" | jq -r '.id')
|
|
153
|
+
# No record Id leak on the primary success line — rule #5. Cap-fallback
|
|
154
|
+
# hint helper prints the activate-later reminder without exposing the Id.
|
|
155
|
+
if [[ "$CAP_FELL_BACK" == "true" ]]; then
|
|
156
|
+
echo "Created inactive (8-active cap), activate later"
|
|
157
|
+
print_cap_footer_activate_hint "$NEW_ID"
|
|
158
|
+
else
|
|
159
|
+
echo "Created"
|
|
160
|
+
fi
|
|
161
|
+
exit 0
|
|
162
|
+
else
|
|
163
|
+
echo "Error: Create failed:"
|
|
164
|
+
echo "$RESP" | jq -c '.' 2>/dev/null || echo "$RESP"
|
|
165
|
+
exit 1
|
|
166
|
+
fi
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# sales_call_scoring: story="custom-competency-crud" owner="W-CUSTOM-CRUD"
|
|
3
|
+
#
|
|
4
|
+
# Create a custom Coaching Competency from a JSON payload. Companion write
|
|
5
|
+
# primitive for the custom-competency story (S5). Parallel to the generic
|
|
6
|
+
# create-competency.sh; kept as its own file so the custom-CRUD story can
|
|
7
|
+
# harden the write path (SpecificCallsOnly filter JSON, richer validation)
|
|
8
|
+
# without touching the OOTB-owned install script.
|
|
9
|
+
#
|
|
10
|
+
# The prompt body in EvaluationInstructions is intentionally NOT a default —
|
|
11
|
+
# callers supply the full PRD/PURPOSE-structured prompt (see
|
|
12
|
+
# assets/best-practice-competencies.json for reference shape).
|
|
13
|
+
#
|
|
14
|
+
# Required fields: MasterLabel, EvaluationInstructions
|
|
15
|
+
# Optional fields: DeveloperName (auto-gen), Description, EvaluationScope
|
|
16
|
+
# (AllCalls|SpecificCallsOnly, default AllCalls),
|
|
17
|
+
# EvaluationConditions (required when SpecificCallsOnly),
|
|
18
|
+
# IsActive (default true),
|
|
19
|
+
# SourceCompetencyTemplate (leave empty for custom).
|
|
20
|
+
#
|
|
21
|
+
# Usage: ./create-custom-competency.sh <org-alias> <payload.json>
|
|
22
|
+
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
|
|
25
|
+
export NO_COLOR=1
|
|
26
|
+
export FORCE_COLOR=0
|
|
27
|
+
|
|
28
|
+
ORG_ALIAS="${1:-}"
|
|
29
|
+
PAYLOAD_FILE="${2:-}"
|
|
30
|
+
|
|
31
|
+
if [[ -z "$ORG_ALIAS" || -z "$PAYLOAD_FILE" ]]; then
|
|
32
|
+
echo "Usage: $0 <org-alias> <payload.json>"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
if [[ ! -f "$PAYLOAD_FILE" ]]; then
|
|
36
|
+
echo "Payload file not found: $PAYLOAD_FILE"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# ---------------------------------------------------------------------------
|
|
41
|
+
# Validate payload
|
|
42
|
+
# ---------------------------------------------------------------------------
|
|
43
|
+
MASTER_LABEL=$(jq -r '.MasterLabel // empty' "$PAYLOAD_FILE")
|
|
44
|
+
INSTRUCTIONS=$(jq -r '.EvaluationInstructions // empty' "$PAYLOAD_FILE")
|
|
45
|
+
|
|
46
|
+
if [[ -z "$MASTER_LABEL" ]]; then echo "MasterLabel is required"; exit 1; fi
|
|
47
|
+
if [[ -z "$INSTRUCTIONS" ]]; then echo "EvaluationInstructions is required"; exit 1; fi
|
|
48
|
+
|
|
49
|
+
INSTR_LEN=${#INSTRUCTIONS}
|
|
50
|
+
if [[ "$INSTR_LEN" -gt 16000 ]]; then
|
|
51
|
+
echo "EvaluationInstructions is $INSTR_LEN chars — max 16000"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
DESCRIPTION=$(jq -r '.Description // ""' "$PAYLOAD_FILE")
|
|
56
|
+
DESC_LEN=${#DESCRIPTION}
|
|
57
|
+
if [[ "$DESC_LEN" -gt 255 ]]; then
|
|
58
|
+
echo "Description is $DESC_LEN chars — max 255"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
SCOPE=$(jq -r '.EvaluationScope // "AllCalls"' "$PAYLOAD_FILE")
|
|
63
|
+
if [[ "$SCOPE" != "AllCalls" && "$SCOPE" != "SpecificCallsOnly" ]]; then
|
|
64
|
+
echo "EvaluationScope must be AllCalls or SpecificCallsOnly (got: $SCOPE)"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# jq's // treats false as absent; use explicit null-check to preserve IsActive:false.
|
|
69
|
+
IS_ACTIVE=$(jq -r 'if has("IsActive") then .IsActive else true end' "$PAYLOAD_FILE")
|
|
70
|
+
TEMPLATE=$(jq -r '.SourceCompetencyTemplate // ""' "$PAYLOAD_FILE")
|
|
71
|
+
DEV_NAME=$(jq -r '.DeveloperName // empty' "$PAYLOAD_FILE")
|
|
72
|
+
|
|
73
|
+
if [[ -z "$DEV_NAME" ]]; then
|
|
74
|
+
SANITIZED=$(echo "$MASTER_LABEL" | tr -cd '[:alnum:]' | cut -c1-30)
|
|
75
|
+
SUFFIX=$(hexdump -n 3 -e '"%06x"' /dev/urandom)
|
|
76
|
+
DEV_NAME="CCH_${SANITIZED}_${SUFFIX}"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# ---------------------------------------------------------------------------
|
|
80
|
+
# Auth
|
|
81
|
+
# ---------------------------------------------------------------------------
|
|
82
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
83
|
+
# shellcheck source=shared/auth.sh
|
|
84
|
+
source "$SCRIPT_DIR/shared/auth.sh"
|
|
85
|
+
|
|
86
|
+
resolve_org_auth "$ORG_ALIAS" || exit 1
|
|
87
|
+
|
|
88
|
+
TOOLING_BASE="services/data/v68.0/tooling"
|
|
89
|
+
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
# 8-active cap: auto-fallback to inactive so the admin's work isn't blocked.
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
# shellcheck source=shared/cap.sh
|
|
94
|
+
source "$SCRIPT_DIR/shared/cap.sh"
|
|
95
|
+
# shellcheck source=shared/soql.sh
|
|
96
|
+
source "$SCRIPT_DIR/shared/soql.sh"
|
|
97
|
+
|
|
98
|
+
CAP_FELL_BACK="false"
|
|
99
|
+
if [[ "$IS_ACTIVE" == "true" ]]; then
|
|
100
|
+
ACTIVE_COUNT=$(query_active_count "$ORG_ALIAS")
|
|
101
|
+
if [[ "$ACTIVE_COUNT" -ge "$MAX_ACTIVE_COMPETENCIES" ]]; then
|
|
102
|
+
print_cap_report "$ORG_ALIAS" "creating '$MASTER_LABEL'"
|
|
103
|
+
IS_ACTIVE="false"
|
|
104
|
+
CAP_FELL_BACK="true"
|
|
105
|
+
fi
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
# ---------------------------------------------------------------------------
|
|
109
|
+
# Uniqueness check by MasterLabel (to avoid silent duplicates)
|
|
110
|
+
# ---------------------------------------------------------------------------
|
|
111
|
+
LABEL_ENC=$(printf "SELECT Id FROM EnablementCompetencyDef WHERE MasterLabel='%s'" "$(soql_escape "$MASTER_LABEL")" | jq -sRr @uri)
|
|
112
|
+
DUP=$( (sf api request rest "${TOOLING_BASE}/query/?q=${LABEL_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null || true) \
|
|
113
|
+
| jq -r '.totalSize // 0' 2>/dev/null)
|
|
114
|
+
DUP="${DUP:-0}"
|
|
115
|
+
if [[ "$DUP" != "0" ]]; then
|
|
116
|
+
echo "A competency with MasterLabel '$MASTER_LABEL' already exists — refusing to duplicate."
|
|
117
|
+
echo " Use edit-custom-competency.sh to update, or choose a different name."
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
# Build final payload + POST
|
|
123
|
+
# ---------------------------------------------------------------------------
|
|
124
|
+
FINAL=$(jq -n \
|
|
125
|
+
--arg mn "$MASTER_LABEL" \
|
|
126
|
+
--arg dn "$DEV_NAME" \
|
|
127
|
+
--arg tp "$TEMPLATE" \
|
|
128
|
+
--arg de "$DESCRIPTION" \
|
|
129
|
+
--arg ei "$INSTRUCTIONS" \
|
|
130
|
+
--arg sc "$SCOPE" \
|
|
131
|
+
--argjson ia "$IS_ACTIVE" \
|
|
132
|
+
'{
|
|
133
|
+
MasterLabel: $mn,
|
|
134
|
+
DeveloperName: $dn,
|
|
135
|
+
Description: $de,
|
|
136
|
+
EvaluationInstructions: $ei,
|
|
137
|
+
EvaluationScope: $sc,
|
|
138
|
+
IsActive: $ia
|
|
139
|
+
} + (if $tp == "" then {} else {SourceCompetencyTemplate: $tp} end)')
|
|
140
|
+
|
|
141
|
+
echo "Creating: $MASTER_LABEL"
|
|
142
|
+
# No DeveloperName / char count / entity-field leak — rule #5.
|
|
143
|
+
echo " Scope: $SCOPE Active: $IS_ACTIVE"
|
|
144
|
+
|
|
145
|
+
RESP=$(sf api request rest "${TOOLING_BASE}/sobjects/EnablementCompetencyDef" \
|
|
146
|
+
--target-org "$ORG_ALIAS" \
|
|
147
|
+
--method POST \
|
|
148
|
+
--header 'Content-Type: application/json' \
|
|
149
|
+
--body "$FINAL" \
|
|
150
|
+
2>/dev/null) || true
|
|
151
|
+
|
|
152
|
+
if echo "$RESP" | jq -e '.success == true' >/dev/null 2>&1; then
|
|
153
|
+
NEW_ID=$(echo "$RESP" | jq -r '.id')
|
|
154
|
+
# No record Id leak — rule #5.
|
|
155
|
+
if [[ "$CAP_FELL_BACK" == "true" ]]; then
|
|
156
|
+
echo "Created inactive (8-active cap), activate later"
|
|
157
|
+
print_cap_footer_activate_hint "$NEW_ID"
|
|
158
|
+
else
|
|
159
|
+
echo "Created"
|
|
160
|
+
fi
|
|
161
|
+
exit 0
|
|
162
|
+
else
|
|
163
|
+
echo "Error: Create failed:"
|
|
164
|
+
echo "$RESP" | jq -c '.' 2>/dev/null || echo "$RESP"
|
|
165
|
+
exit 1
|
|
166
|
+
fi
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Edit a Coaching Competency's MasterLabel (display name), Description,
|
|
4
|
+
# and/or EvaluationInstructions.
|
|
5
|
+
# Preserves Id, DeveloperName, IsActive, EvaluationScope, SourceCompetencyTemplate.
|
|
6
|
+
#
|
|
7
|
+
# --label renames the admin-facing display name (MasterLabel). DeveloperName
|
|
8
|
+
# is NOT renamed — it's the API name used by any downstream references and
|
|
9
|
+
# would risk breaking integrations to change. If you need a new
|
|
10
|
+
# DeveloperName, deactivate + create a fresh record.
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# ./edit-competency.sh <org-alias> <name-or-id> --label "<new-label>"
|
|
14
|
+
# ./edit-competency.sh <org-alias> <name-or-id> --instructions-file <file>
|
|
15
|
+
# ./edit-competency.sh <org-alias> <name-or-id> --description "<new-desc>"
|
|
16
|
+
# ./edit-competency.sh <org-alias> <name-or-id> --instructions "<literal>" # short text only
|
|
17
|
+
# (combine flags to update multiple fields at once)
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
export NO_COLOR=1
|
|
22
|
+
export FORCE_COLOR=0
|
|
23
|
+
|
|
24
|
+
ORG_ALIAS="${1:-}"
|
|
25
|
+
IDENT="${2:-}"
|
|
26
|
+
shift 2 || true
|
|
27
|
+
|
|
28
|
+
if [[ -z "$ORG_ALIAS" || -z "$IDENT" ]]; then
|
|
29
|
+
echo "Usage: $0 <org-alias> <name-or-id> [--label \"<text>\"] [--instructions-file <file>] [--description \"<text>\"] [--instructions \"<text>\"]"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
NEW_LABEL=""
|
|
34
|
+
NEW_INSTRUCTIONS=""
|
|
35
|
+
NEW_DESCRIPTION=""
|
|
36
|
+
|
|
37
|
+
while [[ $# -gt 0 ]]; do
|
|
38
|
+
case "$1" in
|
|
39
|
+
--label)
|
|
40
|
+
NEW_LABEL="$2"
|
|
41
|
+
shift 2
|
|
42
|
+
;;
|
|
43
|
+
--instructions-file)
|
|
44
|
+
if [[ ! -f "$2" ]]; then
|
|
45
|
+
echo "File not found: $2"; exit 1
|
|
46
|
+
fi
|
|
47
|
+
NEW_INSTRUCTIONS=$(cat "$2")
|
|
48
|
+
shift 2
|
|
49
|
+
;;
|
|
50
|
+
--instructions)
|
|
51
|
+
NEW_INSTRUCTIONS="$2"
|
|
52
|
+
shift 2
|
|
53
|
+
;;
|
|
54
|
+
--description)
|
|
55
|
+
NEW_DESCRIPTION="$2"
|
|
56
|
+
shift 2
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
echo "Error: Unknown flag: $1"; exit 1
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
if [[ -z "$NEW_LABEL" && -z "$NEW_INSTRUCTIONS" && -z "$NEW_DESCRIPTION" ]]; then
|
|
65
|
+
echo "Nothing to update — pass --label, --instructions[-file], and/or --description"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [[ -n "$NEW_LABEL" ]]; then
|
|
70
|
+
LEN=${#NEW_LABEL}
|
|
71
|
+
# MasterLabel is a standard platform label field, capped at 80 chars.
|
|
72
|
+
if [[ "$LEN" -gt 80 ]]; then
|
|
73
|
+
echo "MasterLabel is ${LEN} chars — max is 80."
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
if [[ -n "$NEW_INSTRUCTIONS" ]]; then
|
|
79
|
+
LEN=${#NEW_INSTRUCTIONS}
|
|
80
|
+
if [[ "$LEN" -gt 16000 ]]; then
|
|
81
|
+
echo "EvaluationInstructions is ${LEN} chars — max is 16000."
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [[ -n "$NEW_DESCRIPTION" ]]; then
|
|
87
|
+
LEN=${#NEW_DESCRIPTION}
|
|
88
|
+
if [[ "$LEN" -gt 255 ]]; then
|
|
89
|
+
echo "Description is ${LEN} chars — max is 255."
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# Auth
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
98
|
+
# shellcheck source=shared/auth.sh
|
|
99
|
+
source "$SCRIPT_DIR/shared/auth.sh"
|
|
100
|
+
# shellcheck source=shared/soql.sh
|
|
101
|
+
source "$SCRIPT_DIR/shared/soql.sh"
|
|
102
|
+
|
|
103
|
+
resolve_org_auth "$ORG_ALIAS" || exit 1
|
|
104
|
+
|
|
105
|
+
TOOLING_BASE="services/data/v68.0/tooling"
|
|
106
|
+
|
|
107
|
+
# ---------------------------------------------------------------------------
|
|
108
|
+
# Resolve identifier
|
|
109
|
+
# ---------------------------------------------------------------------------
|
|
110
|
+
if [[ "$IDENT" =~ ^1nA[0-9a-zA-Z]{12,15}$ ]]; then
|
|
111
|
+
WHERE="Id='${IDENT}'"
|
|
112
|
+
else
|
|
113
|
+
SAFE=$(soql_escape "$IDENT")
|
|
114
|
+
WHERE="DeveloperName='${SAFE}' OR MasterLabel='${SAFE}'"
|
|
115
|
+
fi
|
|
116
|
+
QUERY_ENC=$(printf 'SELECT Id,MasterLabel,IsActive FROM EnablementCompetencyDef WHERE %s' "$WHERE" | jq -sRr @uri)
|
|
117
|
+
LOOKUP=$(sf api request rest "${TOOLING_BASE}/query/?q=${QUERY_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null) || true
|
|
118
|
+
RC=$(echo "$LOOKUP" | jq -r '.totalSize // 0')
|
|
119
|
+
|
|
120
|
+
if [[ "$RC" == "0" ]]; then echo "No competency matched: $IDENT"; exit 1; fi
|
|
121
|
+
if [[ "$RC" != "1" ]]; then
|
|
122
|
+
echo "Multiple competencies matched '$IDENT' — refusing to bulk-edit."
|
|
123
|
+
echo "$LOOKUP" | jq -r '.records[] | " \(.Id) \(.MasterLabel)"'
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
REC_ID=$(echo "$LOOKUP" | jq -r '.records[0].Id')
|
|
128
|
+
REC_LABEL=$(echo "$LOOKUP" | jq -r '.records[0].MasterLabel')
|
|
129
|
+
REC_ACTIVE=$(echo "$LOOKUP" | jq -r '.records[0].IsActive')
|
|
130
|
+
|
|
131
|
+
echo "$REC_LABEL ($REC_ID) — IsActive=$REC_ACTIVE"
|
|
132
|
+
|
|
133
|
+
# ---------------------------------------------------------------------------
|
|
134
|
+
# Uniqueness gate for rename — mirrors the same check create-competency.sh
|
|
135
|
+
# already runs on create, so a rename can't silently collide with an
|
|
136
|
+
# existing label. Excludes the target record's own Id so no-op renames
|
|
137
|
+
# don't self-collide.
|
|
138
|
+
# ---------------------------------------------------------------------------
|
|
139
|
+
if [[ -n "$NEW_LABEL" && "$NEW_LABEL" != "$REC_LABEL" ]]; then
|
|
140
|
+
LABEL_ENC=$(printf "SELECT Id FROM EnablementCompetencyDef WHERE MasterLabel='%s' AND Id!='%s'" \
|
|
141
|
+
"$(soql_escape "$NEW_LABEL")" "$REC_ID" | jq -sRr @uri)
|
|
142
|
+
DUP=$( (sf api request rest "${TOOLING_BASE}/query/?q=${LABEL_ENC}" --target-org "$ORG_ALIAS" 2>/dev/null || true) \
|
|
143
|
+
| jq -r '.totalSize // 0' 2>/dev/null)
|
|
144
|
+
DUP="${DUP:-0}"
|
|
145
|
+
if [[ "$DUP" != "0" ]]; then
|
|
146
|
+
echo "Another competency already uses label '$NEW_LABEL' — refusing to duplicate."
|
|
147
|
+
echo " Choose a different label, or edit the existing record instead."
|
|
148
|
+
exit 1
|
|
149
|
+
fi
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
# ---------------------------------------------------------------------------
|
|
153
|
+
# Build PATCH payload
|
|
154
|
+
# ---------------------------------------------------------------------------
|
|
155
|
+
PAYLOAD='{}'
|
|
156
|
+
if [[ -n "$NEW_LABEL" ]]; then
|
|
157
|
+
PAYLOAD=$(echo "$PAYLOAD" | jq --arg v "$NEW_LABEL" '. + {MasterLabel: $v}')
|
|
158
|
+
fi
|
|
159
|
+
if [[ -n "$NEW_INSTRUCTIONS" ]]; then
|
|
160
|
+
PAYLOAD=$(echo "$PAYLOAD" | jq --arg v "$NEW_INSTRUCTIONS" '. + {EvaluationInstructions: $v}')
|
|
161
|
+
fi
|
|
162
|
+
if [[ -n "$NEW_DESCRIPTION" ]]; then
|
|
163
|
+
PAYLOAD=$(echo "$PAYLOAD" | jq --arg v "$NEW_DESCRIPTION" '. + {Description: $v}')
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
if RESP_BODY=$(sf api request rest "${TOOLING_BASE}/sobjects/EnablementCompetencyDef/${REC_ID}" \
|
|
167
|
+
--target-org "$ORG_ALIAS" \
|
|
168
|
+
--method PATCH \
|
|
169
|
+
--header 'Content-Type: application/json' \
|
|
170
|
+
--body "$PAYLOAD" \
|
|
171
|
+
2>/dev/null); then
|
|
172
|
+
# Show the new label if renamed, since the pre-rename $REC_LABEL is now stale.
|
|
173
|
+
if [[ -n "$NEW_LABEL" && "$NEW_LABEL" != "$REC_LABEL" ]]; then
|
|
174
|
+
echo "Renamed '$REC_LABEL' → '$NEW_LABEL'"
|
|
175
|
+
else
|
|
176
|
+
echo "Updated $REC_LABEL"
|
|
177
|
+
fi
|
|
178
|
+
[[ -n "$NEW_INSTRUCTIONS" ]] && echo " EvaluationInstructions: ${#NEW_INSTRUCTIONS} chars"
|
|
179
|
+
[[ -n "$NEW_DESCRIPTION" ]] && echo " Description: ${#NEW_DESCRIPTION} chars"
|
|
180
|
+
exit 0
|
|
181
|
+
else
|
|
182
|
+
echo "Error: PATCH failed"
|
|
183
|
+
echo " $RESP_BODY"
|
|
184
|
+
exit 1
|
|
185
|
+
fi
|