@salesforce/afv-skills 1.46.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/agentforce-observe/SKILL.md +32 -4
- package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
- package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
- package/skills/dx-devops-project-manage/SKILL.md +197 -0
- package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
- package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
- package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
- package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
- package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
- package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
- package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
- package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
- package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
- package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
- package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
- package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
- package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
- package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
- package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
- package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
- package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
- package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
- package/skills/education-cloud-domain-configure/SKILL.md +234 -0
- package/skills/education-cloud-domain-configure/references/dependent-features.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/academic-operations.md +386 -0
- package/skills/education-cloud-domain-configure/references/domain-features/alumni-relations.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/cross-domain-dependencies.md +18 -0
- package/skills/education-cloud-domain-configure/references/domain-features/industriessettings-toggle-reference.md +43 -0
- package/skills/education-cloud-domain-configure/references/domain-features/mentoring.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/recruitment-admissions.md +315 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-management.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-success.md +249 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +27 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +23 -0
- package/skills/education-cloud-domain-configure/references/toggle-write-path.md +67 -0
- package/skills/education-cloud-domain-configure/scripts/check_license_provisioned.py +62 -0
- package/skills/education-cloud-domain-configure/scripts/check_org_edition.py +44 -0
- package/skills/education-cloud-domain-configure/scripts/check_permission_assigned.py +39 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +7 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +1 -2
- package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
- package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
- package/skills/experience-cms-brand-apply/SKILL.md +5 -5
- package/skills/experience-cms-brand-create/SKILL.md +2 -2
- package/skills/experience-cms-content-generate/SKILL.md +1 -0
- package/skills/experience-cms-content-render/SKILL.md +173 -0
- package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
- package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
- package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
- package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
- package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
- package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
- package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
- package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
- package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
- package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
- package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
- package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
- package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
- package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
- package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
- package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
- package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
- package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
- package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
- package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
- package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
- package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
- package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
- package/skills/experience-cms-content-render/references/package-api.md +106 -0
- package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
- package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
- package/skills/experience-cms-content-render/references/verify.md +49 -0
- package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
- package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
- package/skills/experience-search-coordinate/SKILL.md +198 -0
- package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
- package/skills/experience-search-coordinate/references/content-route.md +313 -0
- package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
- package/skills/experience-search-coordinate/references/media-route.md +172 -0
- package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
- package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
- package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
- package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
- package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
- package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
- package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
- package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
- package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
- package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
- package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
- package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
- package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
- package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
- package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
- package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
- package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
- package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
- package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
- package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
- package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
- package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
- package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
- package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
- package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
- package/skills/life-sciences-territory-configure/SKILL.md +217 -0
- package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
- package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
- package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
- package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
- package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
- package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
- package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
- package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
- package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
- package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
- package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
- package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
- package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
- package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
- package/skills/service-agentforce-channel-configure/SKILL.md +33 -28
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +205 -0
- package/skills/service-agentforce-human-escalation-configure/assets/escalation-thresholds.instructions.md +37 -0
- package/skills/service-agentforce-human-escalation-configure/assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml +173 -0
- package/skills/service-agentforce-human-escalation-configure/assets/package.xml +8 -0
- package/skills/service-agentforce-human-escalation-configure/assets/sfdx-project.json +5 -0
- package/skills/service-agentforce-human-escalation-configure/references/classifier-contracts.md +103 -0
- package/skills/service-agentforce-human-escalation-configure/references/escalation-mechanism.md +63 -0
- package/skills/service-agentforce-human-escalation-configure/references/failure-policy.md +44 -0
- package/skills/service-agentforce-human-escalation-configure/references/nga-escalation.md +57 -0
- package/skills/service-agentforce-human-escalation-configure/references/runtime-verification.md +72 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-agent-active.mjs +49 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-nga-escalation.mjs +166 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/extract-outbound-route.mjs +67 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/patch-escalation-surfaces.mjs +131 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +249 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +899 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-and-configure.sh +705 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-escalation-config.mjs +89 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +13 -5
- package/skills/service-de-channel-routing-configure/scripts/tests/test_skill_contract.py +25 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +23 -10
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -48
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +6 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
- package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
- package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
- package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
- package/skills/service-omni-agent-users-create/SKILL.md +96 -0
- package/skills/service-omni-agent-users-create/assets/create-users.apex.template +80 -0
- package/skills/service-omni-agent-users-create/references/apex-patterns.md +135 -0
- package/skills/service-omni-agent-users-create/references/apex-template-notes.md +40 -0
- package/skills/service-omni-agent-users-create/scripts/detect-and-create.sh +206 -0
- package/skills/service-omni-agent-users-create/scripts/detect-existing.sh +122 -0
- package/skills/service-omni-agent-users-create/scripts/run-create.sh +298 -0
- package/skills/service-omni-agent-users-create/scripts/tests/test_user_create_security.py +171 -0
- package/skills/service-omni-agent-work-sharing-configure/SKILL.md +78 -0
- package/skills/service-omni-agent-work-sharing-configure/references/api-notes.md +31 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/configure-and-report.sh +186 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/test_agent_work_sharing_contracts.py +93 -0
- package/skills/service-omni-base-settings-configure/SKILL.md +77 -0
- package/skills/service-omni-base-settings-configure/assets/force-app/main/default/settings/OmniChannel.settings-meta.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/package.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-base-settings-configure/references/api-notes.md +121 -0
- package/skills/service-omni-base-settings-configure/scripts/configure-and-report.sh +164 -0
- package/skills/service-omni-base-settings-configure/scripts/detect-existing.sh +69 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +168 -0
- package/skills/service-omni-channel-setup-coordinate/examples/output-templates.md +161 -0
- package/skills/service-omni-channel-setup-coordinate/references/gap-catalog.md +99 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +1542 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/__init__.py +0 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/_bootstrap.py +223 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +804 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +84 -0
- package/skills/service-omni-command-center-analyze/references/api-notes.md +54 -0
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +198 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/_bootstrap.py +115 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/test_command_center_analyze_contracts.py +165 -0
- package/skills/service-omni-permission-set-assign/SKILL.md +88 -0
- package/skills/service-omni-permission-set-assign/assets/package.xml +8 -0
- package/skills/service-omni-permission-set-assign/references/api-notes.md +143 -0
- package/skills/service-omni-permission-set-assign/scripts/verify-and-assign.sh +397 -0
- package/skills/service-omni-presence-status-deploy/SKILL.md +87 -0
- package/skills/service-omni-presence-status-deploy/assets/package.xml +12 -0
- package/skills/service-omni-presence-status-deploy/references/api-notes.md +115 -0
- package/skills/service-omni-presence-status-deploy/scripts/deploy-and-report.sh +422 -0
- package/skills/service-omni-presence-user-config-deploy/SKILL.md +80 -0
- package/skills/service-omni-presence-user-config-deploy/references/api-notes.md +60 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/deploy-and-report.sh +261 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/_bootstrap.py +106 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/test_presence_user_config_contracts.py +142 -0
- package/skills/service-omni-queue-deploy/SKILL.md +91 -0
- package/skills/service-omni-queue-deploy/references/api-notes.md +140 -0
- package/skills/service-omni-queue-deploy/scripts/verify-and-align.sh +470 -0
- package/skills/service-omni-queue-members-assign/SKILL.md +93 -0
- package/skills/service-omni-queue-members-assign/references/api-notes.md +144 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/_bootstrap.py +67 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/test_queue_members_contracts.py +73 -0
- package/skills/service-omni-queue-members-assign/scripts/verify-and-bind.sh +362 -0
- package/skills/service-omni-queue-routing-config-deploy/SKILL.md +101 -0
- package/skills/service-omni-queue-routing-config-deploy/references/api-notes.md +127 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/_bootstrap.py +90 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/test_queue_routing_config_contracts.py +70 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/upsert-and-report.sh +538 -0
- package/skills/service-omni-routing-flow-deploy/SKILL.md +111 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Cases.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCalls.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/package.xml +11 -0
- package/skills/service-omni-routing-flow-deploy/assets/sfdx-project.json +11 -0
- package/skills/service-omni-routing-flow-deploy/references/api-notes.md +265 -0
- package/skills/service-omni-routing-flow-deploy/scripts/deploy-and-report.sh +684 -0
- package/skills/service-omni-service-channel-configure/SKILL.md +83 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Cases.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Incidents.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/MessagingSessions.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/VoiceCalls.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/package.xml +11 -0
- package/skills/service-omni-service-channel-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-service-channel-configure/references/api-notes.md +84 -0
- package/skills/service-omni-service-channel-configure/scripts/deploy-and-report.sh +383 -0
- package/skills/service-omni-sidebar-configure/SKILL.md +77 -0
- package/skills/service-omni-sidebar-configure/references/api-notes.md +51 -0
- package/skills/service-omni-sidebar-configure/scripts/enable-and-report.sh +315 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/_bootstrap.py +142 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/test_sidebar_contracts.py +139 -0
- package/skills/service-omni-skills-based-routing-configure/SKILL.md +81 -0
- package/skills/service-omni-skills-based-routing-configure/references/api-notes.md +50 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/configure-and-report.sh +270 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/test_sbr_contracts.py +129 -0
- package/skills/service-omni-supervisor-config-deploy/SKILL.md +97 -0
- package/skills/service-omni-supervisor-config-deploy/assets/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml +9 -0
- package/skills/service-omni-supervisor-config-deploy/assets/package.xml +8 -0
- package/skills/service-omni-supervisor-config-deploy/assets/sfdx-project.json +12 -0
- package/skills/service-omni-supervisor-config-deploy/references/api-notes.md +205 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/deploy-and-report.sh +586 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/_bootstrap.py +153 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/test_supervisor_config_contracts.py +116 -0
- package/skills/service-omni-supervisor-permset-assign/SKILL.md +88 -0
- package/skills/service-omni-supervisor-permset-assign/references/api-notes.md +48 -0
- package/skills/service-omni-supervisor-permset-assign/scripts/verify-and-assign.sh +316 -0
- package/skills/service-omni-supervisor-surface-deploy/SKILL.md +85 -0
- package/skills/service-omni-supervisor-surface-deploy/references/api-notes.md +47 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/deploy-and-report.sh +216 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/_bootstrap.py +95 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/test_supervisor_surface_contracts.py +154 -0
- package/skills/service-omni-supervisor-users-create/SKILL.md +92 -0
- package/skills/service-omni-supervisor-users-create/assets/create-supervisors.apex.template +72 -0
- package/skills/service-omni-supervisor-users-create/references/apex-patterns.md +73 -0
- package/skills/service-omni-supervisor-users-create/references/apex-template-notes.md +41 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-and-create.sh +197 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-existing.sh +112 -0
- package/skills/service-omni-supervisor-users-create/scripts/run-create.sh +296 -0
- package/skills/service-omni-work-skill-routing-configure/SKILL.md +80 -0
- package/skills/service-omni-work-skill-routing-configure/references/api-notes.md +67 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/configure-and-report.sh +262 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/_bootstrap.py +121 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/test_work_skill_routing_contracts.py +161 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# verify-and-assign.sh - assign PermissionSets to N supervisor users via PermissionSetAssignment POSTs; idempotent (SOQL detects existing pairs), non-destructive. Args, output contract, exit codes: SKILL.md.
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
if [ $# -lt 1 ]; then
|
|
7
|
+
echo '{"error":"Usage: bash verify-and-assign.sh <org-alias> [<count>] [<permission-set-names-csv>]"}' >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
ORG="$1"
|
|
12
|
+
COUNT="${2:-1}"
|
|
13
|
+
# Default to the standard ContactCenterSupervisor permset (its license-gated perms can't be
|
|
14
|
+
# re-declared in a custom permset), so this skill only assigns permsets already on the org.
|
|
15
|
+
PS_NAMES_CSV="${3:-ContactCenterSupervisor}"
|
|
16
|
+
API_VERSION="v66.0"
|
|
17
|
+
|
|
18
|
+
if ! [[ "$COUNT" =~ ^[0-9]+$ ]] || [ "$COUNT" -lt 1 ] || [ "$COUNT" -gt 5 ]; then
|
|
19
|
+
echo "{\"error\":\"Invalid count '$COUNT' - must be integer 1..5\"}" >&2
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
if ! sf org display --target-org "$ORG" --json >/dev/null 2>&1; then
|
|
24
|
+
echo "{\"error\":\"Org alias '$ORG' is not authenticated.\"}" >&2
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
PS_NAMES_JSON=$(echo "$PS_NAMES_CSV" | jq -R -c 'split(",") | map(gsub("^\\s+|\\s+$"; ""))')
|
|
29
|
+
PS_COUNT=$(echo "$PS_NAMES_JSON" | jq 'length')
|
|
30
|
+
|
|
31
|
+
# Each PermissionSet Name is interpolated into SOQL, so validate its DeveloperName shape before any
|
|
32
|
+
# sf call; an empty CSV is also rejected.
|
|
33
|
+
if [ "$PS_COUNT" -lt 1 ]; then
|
|
34
|
+
echo "{\"error\":\"No permission-set names supplied.\"}" >&2
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
while IFS= read -r ps_name; do
|
|
38
|
+
if ! [[ "$ps_name" =~ ^[A-Za-z][A-Za-z0-9_]{0,79}$ ]]; then
|
|
39
|
+
echo "{\"error\":\"Invalid permission-set name '$ps_name'. Each must start with a letter and contain only letters, digits, and underscores (max 80 chars).\"}" >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
done < <(echo "$PS_NAMES_JSON" | jq -r '.[]')
|
|
43
|
+
|
|
44
|
+
emit_blocked() {
|
|
45
|
+
local msg="$1"
|
|
46
|
+
local click_path="${2:-}"
|
|
47
|
+
local suffix="${3:-}"
|
|
48
|
+
|
|
49
|
+
local manual_actions='[]'
|
|
50
|
+
if [ -n "$click_path" ]; then
|
|
51
|
+
manual_actions=$(jq -n --arg cp "$click_path" '[{id: "MANUAL_FIX", title: "Manual fix required", click_path: $cp}]')
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
jq -n \
|
|
55
|
+
--arg msg "$msg" \
|
|
56
|
+
--arg suf "$suffix" \
|
|
57
|
+
--argjson count "$COUNT" \
|
|
58
|
+
--argjson ps_count "$PS_COUNT" \
|
|
59
|
+
--argjson ma "$manual_actions" \
|
|
60
|
+
'{
|
|
61
|
+
skill: "service-omni-supervisor-permset-assign",
|
|
62
|
+
status: "blocked",
|
|
63
|
+
permission_sets: [],
|
|
64
|
+
org_suffix: (if $suf == "" then null else $suf end),
|
|
65
|
+
requested_count: $count,
|
|
66
|
+
expected_assignment_count: ($count * $ps_count),
|
|
67
|
+
before: null,
|
|
68
|
+
assigned_this_run: [],
|
|
69
|
+
assigned_count: 0,
|
|
70
|
+
reused_count: 0,
|
|
71
|
+
after: null,
|
|
72
|
+
manual_actions: $ma,
|
|
73
|
+
blocking_issue: $msg
|
|
74
|
+
}'
|
|
75
|
+
exit 1
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# emit read-only plan preview JSON and exit 0 (PLAN_ONLY mode)
|
|
79
|
+
emit_plan() {
|
|
80
|
+
local status="$1"
|
|
81
|
+
local detail="$2"
|
|
82
|
+
jq -n \
|
|
83
|
+
--arg status "$status" \
|
|
84
|
+
--arg detail "$detail" \
|
|
85
|
+
'{
|
|
86
|
+
skill: "service-omni-supervisor-permset-assign",
|
|
87
|
+
status: $status,
|
|
88
|
+
plan_mode: true,
|
|
89
|
+
plan_detail: $detail,
|
|
90
|
+
manual_actions: [],
|
|
91
|
+
blocking_issue: null
|
|
92
|
+
}'
|
|
93
|
+
exit 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
ORG_JSON=$(sf data query --target-org "$ORG" \
|
|
97
|
+
--query "SELECT Id, IsSandbox, TrialExpirationDate, OrganizationType FROM Organization LIMIT 1" \
|
|
98
|
+
--json 2>/dev/null)
|
|
99
|
+
|
|
100
|
+
ORG_ID=$(echo "$ORG_JSON" | jq -r '.result.records[0].Id')
|
|
101
|
+
IS_SANDBOX=$(echo "$ORG_JSON" | jq -r '.result.records[0].IsSandbox')
|
|
102
|
+
TRIAL_EXP=$(echo "$ORG_JSON" | jq -r '.result.records[0].TrialExpirationDate // "null"')
|
|
103
|
+
ORG_TYPE=$(echo "$ORG_JSON" | jq -r '.result.records[0].OrganizationType')
|
|
104
|
+
|
|
105
|
+
SAFE_TO_WRITE=false
|
|
106
|
+
if [ "$IS_SANDBOX" = "true" ] \
|
|
107
|
+
|| [ "$TRIAL_EXP" != "null" ] \
|
|
108
|
+
|| [ "$ORG_TYPE" = "Developer Edition" ] \
|
|
109
|
+
|| [ "$ORG_TYPE" = "Base Edition" ]; then
|
|
110
|
+
SAFE_TO_WRITE=true
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
SUFFIX=$(echo "$ORG_ID" | tr '[:upper:]' '[:lower:]' | tail -c 9 | head -c 8)
|
|
114
|
+
|
|
115
|
+
if [ "$SAFE_TO_WRITE" != "true" ]; then
|
|
116
|
+
emit_blocked "Refusing to assign permission sets on a real production customer org (IsSandbox=$IS_SANDBOX, TrialExpirationDate=$TRIAL_EXP, OrganizationType=$ORG_TYPE). Target a sandbox, trial CDO, or Developer Edition org." "" "$SUFFIX"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
PS_IN_CLAUSE=""
|
|
120
|
+
for name in $(echo "$PS_NAMES_JSON" | jq -r '.[]'); do
|
|
121
|
+
if [ -n "$PS_IN_CLAUSE" ]; then PS_IN_CLAUSE="$PS_IN_CLAUSE,"; fi
|
|
122
|
+
PS_IN_CLAUSE="$PS_IN_CLAUSE'$name'"
|
|
123
|
+
done
|
|
124
|
+
|
|
125
|
+
PS_JSON=$(sf data query --target-org "$ORG" \
|
|
126
|
+
--query "SELECT Id, Name, Label FROM PermissionSet WHERE Name IN ($PS_IN_CLAUSE)" \
|
|
127
|
+
--json 2>/dev/null)
|
|
128
|
+
|
|
129
|
+
FOUND_PS_COUNT=$(echo "$PS_JSON" | jq -r '.result.totalSize // 0')
|
|
130
|
+
|
|
131
|
+
# A missing permset can't be self-healed: ContactCenterSupervisor is provisioned by the Service Cloud
|
|
132
|
+
# license and can't be deployed; if absent, the org lacks the license/feature. Report and stop.
|
|
133
|
+
if [ "$FOUND_PS_COUNT" -lt "$PS_COUNT" ]; then
|
|
134
|
+
FOUND_NAMES=$(echo "$PS_JSON" | jq -c '[.result.records[].Name]')
|
|
135
|
+
MISSING_NAMES=$(jq -n --argjson expected "$PS_NAMES_JSON" --argjson found "$FOUND_NAMES" \
|
|
136
|
+
'$expected - $found')
|
|
137
|
+
if [ "${PLAN_ONLY:-}" = "1" ]; then
|
|
138
|
+
emit_plan "action_needed" "PermissionSet(s) $MISSING_NAMES not present on the org. A --run cannot create a Salesforce-standard permset; it requires the Service Cloud license/feature. --plan makes no writes."
|
|
139
|
+
fi
|
|
140
|
+
emit_blocked \
|
|
141
|
+
"Expected PermissionSets $PS_NAMES_JSON; found $FOUND_NAMES. Missing: $MISSING_NAMES. ContactCenterSupervisor is a Salesforce-standard permission set provisioned with the Service Cloud license - it cannot be created by a deploy. Confirm the org has the contact-center supervisor entitlement." \
|
|
142
|
+
"Setup → Permission Sets - confirm 'Contact Center Supervisor' exists. If it is absent, the org lacks the required license/feature; contact Salesforce to enable it." \
|
|
143
|
+
"$SUFFIX"
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
PERMISSION_SETS_JSON=$(echo "$PS_JSON" | jq -c '[.result.records[] | {developer_name: .Name, id: .Id, label: .Label}]')
|
|
147
|
+
PS_IDS_ARR=$(echo "$PS_JSON" | jq -c '[.result.records[].Id]')
|
|
148
|
+
|
|
149
|
+
PS_IDS_IN=""
|
|
150
|
+
for pid in $(echo "$PS_IDS_ARR" | jq -r '.[]'); do
|
|
151
|
+
if [ -n "$PS_IDS_IN" ]; then PS_IDS_IN="$PS_IDS_IN,"; fi
|
|
152
|
+
PS_IDS_IN="$PS_IDS_IN'$pid'"
|
|
153
|
+
done
|
|
154
|
+
|
|
155
|
+
EXPECTED_USERNAMES=()
|
|
156
|
+
for i in $(seq 1 "$COUNT"); do
|
|
157
|
+
EXPECTED_USERNAMES+=("supervisor${i}.${SUFFIX}@example.com")
|
|
158
|
+
done
|
|
159
|
+
|
|
160
|
+
USER_IN_CLAUSE=""
|
|
161
|
+
for un in "${EXPECTED_USERNAMES[@]}"; do
|
|
162
|
+
if [ -n "$USER_IN_CLAUSE" ]; then USER_IN_CLAUSE="$USER_IN_CLAUSE,"; fi
|
|
163
|
+
USER_IN_CLAUSE="$USER_IN_CLAUSE'$un'"
|
|
164
|
+
done
|
|
165
|
+
|
|
166
|
+
# Only active users are valid assignees; filter IsActive=true so an inactive occupant can't satisfy the count.
|
|
167
|
+
U_JSON=$(sf data query --target-org "$ORG" \
|
|
168
|
+
--query "SELECT Id, Username FROM User WHERE Username IN ($USER_IN_CLAUSE) AND IsActive=true" \
|
|
169
|
+
--json 2>/dev/null)
|
|
170
|
+
|
|
171
|
+
U_COUNT=$(echo "$U_JSON" | jq -r '.result.totalSize // 0')
|
|
172
|
+
if [ "$U_COUNT" -lt "$COUNT" ]; then
|
|
173
|
+
FOUND=$(echo "$U_JSON" | jq -c '[.result.records[].Username]')
|
|
174
|
+
emit_blocked \
|
|
175
|
+
"Expected $COUNT ACTIVE supervisor users matching pattern 'supervisor{1..$COUNT}.$SUFFIX@example.com'; found $U_COUNT active ($FOUND). Provision or reactivate the missing supervisor users, then rerun this skill." \
|
|
176
|
+
"" "$SUFFIX"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
USERS_JSON=$(echo "$U_JSON" | jq -c '[.result.records[] | {id: .Id, username: .Username}]')
|
|
180
|
+
USER_IDS_ARR=$(echo "$USERS_JSON" | jq -c '[.[].id]')
|
|
181
|
+
|
|
182
|
+
USER_IDS_IN=""
|
|
183
|
+
for uid in $(echo "$USER_IDS_ARR" | jq -r '.[]'); do
|
|
184
|
+
if [ -n "$USER_IDS_IN" ]; then USER_IDS_IN="$USER_IDS_IN,"; fi
|
|
185
|
+
USER_IDS_IN="$USER_IDS_IN'$uid'"
|
|
186
|
+
done
|
|
187
|
+
|
|
188
|
+
PSA_JSON=$(sf data query --target-org "$ORG" \
|
|
189
|
+
--query "SELECT Id, AssigneeId, PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId IN ($USER_IDS_IN) AND PermissionSetId IN ($PS_IDS_IN)" \
|
|
190
|
+
--json 2>/dev/null)
|
|
191
|
+
|
|
192
|
+
EXISTING_PAIRS=$(echo "$PSA_JSON" | jq -c '[.result.records[] | {user_id: .AssigneeId, permission_set_id: .PermissionSetId}]')
|
|
193
|
+
EXISTING_COUNT=$(echo "$EXISTING_PAIRS" | jq 'length')
|
|
194
|
+
|
|
195
|
+
EXPECTED_PAIRS=$(jq -n --argjson users "$USERS_JSON" --argjson pss "$PERMISSION_SETS_JSON" \
|
|
196
|
+
'[$users[] as $u | $pss[] as $p | {user_id: $u.id, username: $u.username, permission_set_id: $p.id, permission_set_developer_name: $p.developer_name}]')
|
|
197
|
+
|
|
198
|
+
EXPECTED_COUNT=$((COUNT * PS_COUNT))
|
|
199
|
+
|
|
200
|
+
MISSING_PAIRS=$(jq -n --argjson expected "$EXPECTED_PAIRS" --argjson existing "$EXISTING_PAIRS" \
|
|
201
|
+
'[$expected[] | . as $e | select($existing | map(select(.user_id == $e.user_id and .permission_set_id == $e.permission_set_id)) | length == 0)]')
|
|
202
|
+
MISSING_COUNT=$(echo "$MISSING_PAIRS" | jq 'length')
|
|
203
|
+
|
|
204
|
+
# PLAN_ONLY: all detection above is read-only. Report what a --run would do and stop before any write.
|
|
205
|
+
if [ "${PLAN_ONLY:-}" = "1" ]; then
|
|
206
|
+
if [ "$MISSING_COUNT" -eq 0 ]; then
|
|
207
|
+
emit_plan "reused" "All $EXPECTED_COUNT (supervisor x permission-set) assignment(s) already present."
|
|
208
|
+
else
|
|
209
|
+
emit_plan "action_needed" "Would assign $MISSING_COUNT missing of $EXPECTED_COUNT expected (supervisor x permission-set) pair(s)."
|
|
210
|
+
fi
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
ASSIGNED_THIS_RUN='[]'
|
|
214
|
+
ASSIGNED_COUNT=0
|
|
215
|
+
PARTIAL_ERRORS=()
|
|
216
|
+
|
|
217
|
+
if [ "$MISSING_COUNT" -gt 0 ]; then
|
|
218
|
+
for row in $(echo "$MISSING_PAIRS" | jq -c '.[]'); do
|
|
219
|
+
USER_ID=$(echo "$row" | jq -r '.user_id')
|
|
220
|
+
USERNAME=$(echo "$row" | jq -r '.username')
|
|
221
|
+
PS_ID=$(echo "$row" | jq -r '.permission_set_id')
|
|
222
|
+
PS_DEV_NAME=$(echo "$row" | jq -r '.permission_set_developer_name')
|
|
223
|
+
|
|
224
|
+
POST_STDERR="$(mktemp)"
|
|
225
|
+
POST_RESULT=$(sf api request rest --target-org "$ORG" \
|
|
226
|
+
"/services/data/$API_VERSION/sobjects/PermissionSetAssignment" \
|
|
227
|
+
--method POST \
|
|
228
|
+
--body "{\"AssigneeId\":\"$USER_ID\",\"PermissionSetId\":\"$PS_ID\"}" 2>"$POST_STDERR" || true)
|
|
229
|
+
|
|
230
|
+
POST_SUCCESS=$(echo "$POST_RESULT" | jq -r '.success // false' 2>/dev/null || echo "false")
|
|
231
|
+
|
|
232
|
+
if [ "$POST_SUCCESS" = "true" ]; then
|
|
233
|
+
PSA_ID=$(echo "$POST_RESULT" | jq -r '.id')
|
|
234
|
+
ASSIGNED_THIS_RUN=$(echo "$ASSIGNED_THIS_RUN" | jq -c \
|
|
235
|
+
--arg uid "$USER_ID" --arg un "$USERNAME" \
|
|
236
|
+
--arg psdn "$PS_DEV_NAME" --arg psaid "$PSA_ID" \
|
|
237
|
+
'. + [{user_id: $uid, username: $un, permission_set_developer_name: $psdn, assignment_id: $psaid}]')
|
|
238
|
+
ASSIGNED_COUNT=$((ASSIGNED_COUNT + 1))
|
|
239
|
+
else
|
|
240
|
+
ERR_CODE=$(echo "$POST_RESULT" | jq -r 'if type == "array" then .[0].errorCode else .errorCode // "UNKNOWN" end' 2>/dev/null || echo "UNKNOWN")
|
|
241
|
+
ERR_MSG=$(echo "$POST_RESULT" | jq -r 'if type == "array" then .[0].message else .message // "Unknown POST error" end' 2>/dev/null || echo "Unknown POST error")
|
|
242
|
+
|
|
243
|
+
if [ "$ERR_CODE" = "UNKNOWN" ] && [ -z "$POST_RESULT" ]; then
|
|
244
|
+
ERR_MSG=$(grep -v '^Warning:' "$POST_STDERR" | head -1 || echo "sf CLI produced no output")
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
if [ "$ERR_CODE" = "DUPLICATE_VALUE" ]; then
|
|
248
|
+
:
|
|
249
|
+
else
|
|
250
|
+
PARTIAL_ERRORS+=("$USERNAME ($USER_ID) → $PS_DEV_NAME: $ERR_CODE - $ERR_MSG")
|
|
251
|
+
fi
|
|
252
|
+
fi
|
|
253
|
+
rm -f "$POST_STDERR"
|
|
254
|
+
done
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
AFTER_PSA_JSON=$(sf data query --target-org "$ORG" \
|
|
258
|
+
--query "SELECT AssigneeId, PermissionSetId FROM PermissionSetAssignment WHERE AssigneeId IN ($USER_IDS_IN) AND PermissionSetId IN ($PS_IDS_IN)" \
|
|
259
|
+
--json 2>/dev/null)
|
|
260
|
+
|
|
261
|
+
AFTER_PAIRS=$(echo "$AFTER_PSA_JSON" | jq -c '[.result.records[] | {user_id: .AssigneeId, permission_set_id: .PermissionSetId}]')
|
|
262
|
+
AFTER_COUNT=$(echo "$AFTER_PAIRS" | jq 'length')
|
|
263
|
+
|
|
264
|
+
REUSED_COUNT=$EXISTING_COUNT
|
|
265
|
+
|
|
266
|
+
if [ ${#PARTIAL_ERRORS[@]} -gt 0 ] || [ "$AFTER_COUNT" -lt "$EXPECTED_COUNT" ]; then
|
|
267
|
+
STATUS="partial"
|
|
268
|
+
BLOCKING_ISSUE="Partial assign: after re-query, $AFTER_COUNT of $EXPECTED_COUNT expected pairs are present. Failures: ${PARTIAL_ERRORS[*]:-"(none; count mismatch only)"}"
|
|
269
|
+
elif [ "$ASSIGNED_COUNT" -eq 0 ]; then
|
|
270
|
+
STATUS="reused"
|
|
271
|
+
BLOCKING_ISSUE=""
|
|
272
|
+
else
|
|
273
|
+
STATUS="assigned"
|
|
274
|
+
BLOCKING_ISSUE=""
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
BLOCKING_JQ_ARG='null'
|
|
278
|
+
if [ -n "$BLOCKING_ISSUE" ]; then
|
|
279
|
+
BLOCKING_JQ_ARG=$(jq -n --arg s "$BLOCKING_ISSUE" '$s')
|
|
280
|
+
fi
|
|
281
|
+
|
|
282
|
+
jq -n \
|
|
283
|
+
--arg status "$STATUS" \
|
|
284
|
+
--argjson pss "$PERMISSION_SETS_JSON" \
|
|
285
|
+
--arg suf "$SUFFIX" \
|
|
286
|
+
--argjson count "$COUNT" \
|
|
287
|
+
--argjson expected "$EXPECTED_COUNT" \
|
|
288
|
+
--argjson before_pairs "$EXISTING_PAIRS" \
|
|
289
|
+
--argjson before_count "$EXISTING_COUNT" \
|
|
290
|
+
--argjson assigned "$ASSIGNED_THIS_RUN" \
|
|
291
|
+
--argjson assigned_count "$ASSIGNED_COUNT" \
|
|
292
|
+
--argjson reused_count "$REUSED_COUNT" \
|
|
293
|
+
--argjson after_pairs "$AFTER_PAIRS" \
|
|
294
|
+
--argjson after_count "$AFTER_COUNT" \
|
|
295
|
+
--argjson blocking "$BLOCKING_JQ_ARG" \
|
|
296
|
+
'{
|
|
297
|
+
skill: "service-omni-supervisor-permset-assign",
|
|
298
|
+
status: $status,
|
|
299
|
+
permission_sets: $pss,
|
|
300
|
+
org_suffix: $suf,
|
|
301
|
+
requested_count: $count,
|
|
302
|
+
expected_assignment_count: $expected,
|
|
303
|
+
before: {
|
|
304
|
+
existing_assignment_pairs: $before_pairs,
|
|
305
|
+
existing_count: $before_count
|
|
306
|
+
},
|
|
307
|
+
assigned_this_run: $assigned,
|
|
308
|
+
assigned_count: $assigned_count,
|
|
309
|
+
reused_count: $reused_count,
|
|
310
|
+
after: {
|
|
311
|
+
assignment_pairs: $after_pairs,
|
|
312
|
+
assignment_count: $after_count
|
|
313
|
+
},
|
|
314
|
+
manual_actions: [],
|
|
315
|
+
blocking_issue: $blocking
|
|
316
|
+
}'
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: service-omni-supervisor-surface-deploy
|
|
3
|
+
description: "Use to populate the Omni-Channel Supervisor action + tab surface on an existing OmniSupervisorConfig by inserting the standard OmniSupervisorConfigAction and OmniSupervisorConfigTab companion rows via the Data API, idempotent (inserts only the missing types). Requires an OmniSupervisorConfig from service-omni-supervisor-config-deploy. Triggers: give the supervisor the standard action buttons and tabs, add Wallboard/Agents/Queues tabs to Omni Supervisor, configure supervisor actions like Change Queues/Skills. Do not use to create the supervisor configuration itself, create supervisor users, assign the supervisor permission set, or add custom-action / FlexiPage / AWS-dashboard / AI-agent surfaces (those need an external reference and must be set up in Setup)."
|
|
4
|
+
allowed-tools: Bash Read Write Edit Glob Grep
|
|
5
|
+
metadata:
|
|
6
|
+
version: "1.0"
|
|
7
|
+
domains: ["Service"]
|
|
8
|
+
minApiVersion: "66.0"
|
|
9
|
+
relatedSkills:
|
|
10
|
+
- "service-omni-command-center-analyze"
|
|
11
|
+
- "service-omni-supervisor-config-deploy"
|
|
12
|
+
- "service-omni-supervisor-permset-assign"
|
|
13
|
+
accessCheck:
|
|
14
|
+
- type: license
|
|
15
|
+
value: ServiceCloud
|
|
16
|
+
cliTools:
|
|
17
|
+
- tool: ["jq"]
|
|
18
|
+
semver: ">=1.6"
|
|
19
|
+
- tool: ["python3"]
|
|
20
|
+
semver: ">=3.8"
|
|
21
|
+
- tool: ["sf"]
|
|
22
|
+
semver: ">=2.139.6"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# service-omni-supervisor-surface-deploy
|
|
26
|
+
|
|
27
|
+
Populate the Omni-Channel Supervisor **surface** — the action buttons and tabs a supervisor sees — on an existing `OmniSupervisorConfig`. `OmniSupervisorConfigAction` and `OmniSupervisorConfigTab` are createable child sObjects (`OmniSupervisorConfigId`, a `*Type` picklist, and `DisplayOrder`), so the surface is populated with plain Data API inserts against the parent config's Id rather than by re-deploying the whole `OmniSupervisorConfig` metadata document. That keeps this leaf independent of `service-omni-supervisor-config-deploy` (which owns the user/queue companions inside the metadata file) and lets it run idempotently — it inserts only the types that are missing.
|
|
28
|
+
|
|
29
|
+
## Inputs
|
|
30
|
+
|
|
31
|
+
`bash scripts/deploy-and-report.sh <org-alias> [config_developer_name]`
|
|
32
|
+
|
|
33
|
+
- `org-alias` (required) — must resolve via `sf org display --target-org <alias>`.
|
|
34
|
+
- `config_developer_name` (optional) — the `OmniSupervisorConfig.DeveloperName` to populate. Omit it when the org has exactly one config; the skill resolves it. With multiple configs and no name, the skill blocks and lists them.
|
|
35
|
+
|
|
36
|
+
Env overrides (both CSV of picklist values; defaults are the reference-free standard set):
|
|
37
|
+
|
|
38
|
+
- `SUPERVISOR_ACTIONS` — default `AllAgents.ChangeQueues,AllAgents.ChangeSkills,AllAgents.ChangeGroups,AllAgents.AssignLearning,QueuesBacklog.ManageQueues`.
|
|
39
|
+
- `SUPERVISOR_TABS` — default `Wallboard,Agents,QueuesBacklog,AssignedWork,SkillsBacklog`.
|
|
40
|
+
- `PLAN_ONLY=1` — report intent (existing vs. requested) and stop before any write.
|
|
41
|
+
|
|
42
|
+
## Preconditions and safety
|
|
43
|
+
|
|
44
|
+
- Target org authenticated via `sf` CLI, Service Cloud license present, `sf` CLI ≥ 2.139.6.
|
|
45
|
+
- An `OmniSupervisorConfig` exists — provisioned by `service-omni-supervisor-config-deploy`. If none exists (or the named one is absent), the skill blocks with a `target_skill` pointer.
|
|
46
|
+
- **Production guardrail:** the script computes `safe_to_write` as `IsSandbox` OR `TrialExpirationDate != null` OR `OrganizationType` in {Developer Edition, Base Edition}, and blocks with no override when it is false.
|
|
47
|
+
|
|
48
|
+
## Run
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
bash scripts/deploy-and-report.sh <org-alias> [config_developer_name]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
It resolves the parent config, reads the surface rows already present, inserts only the missing action/tab types (appending `DisplayOrder` after the current maximum), and emits JSON to stdout.
|
|
55
|
+
|
|
56
|
+
## Behavior
|
|
57
|
+
|
|
58
|
+
**Reference-free types only.** The companion rows expose no reference field, so only self-contained types can be inserted headlessly. The skill accepts the standard set (`SAFE_ACTIONS` / `SAFE_TABS` in `references/api-notes.md`) and **blocks up front** on any type that needs an external reference — `*.CustomAction`, `*.AWSDashboard`, `FlexipageType`, `AIAgents`, `AgentforceSDR` — pointing you to Setup. Requesting a type outside the supported vocabulary also blocks before any write.
|
|
59
|
+
|
|
60
|
+
**Idempotency.** The requested types are diffed against the rows already on the config; existing types are reported as `reused` and never re-inserted, missing types are inserted and reported as `created`. `status` is `created` when anything was inserted, otherwise `reused`. Re-running the skill unchanged makes no writes.
|
|
61
|
+
|
|
62
|
+
**Ordering.** New rows are appended: `DisplayOrder` starts one above the current maximum for that companion type, preserving any ordering already configured in Setup.
|
|
63
|
+
|
|
64
|
+
## Output contract
|
|
65
|
+
|
|
66
|
+
A single JSON object to stdout. `status` is one of `created`, `reused`, `blocked`, or (with `PLAN_ONLY=1`) `action_needed`. The object also carries `config` (`developer_name`, `id`), `actions` and `tabs` (each with `requested`, `created`, `reused`, `count`), `manual_actions`, and `blocking_issue` (`null` unless `status: blocked`).
|
|
67
|
+
|
|
68
|
+
Org-side spot-check:
|
|
69
|
+
|
|
70
|
+
```sql
|
|
71
|
+
SELECT OmniSupervisorActionType, DisplayOrder FROM OmniSupervisorConfigAction WHERE OmniSupervisorConfigId = :configId ORDER BY DisplayOrder
|
|
72
|
+
SELECT OmniSupervisorTabType, DisplayOrder FROM OmniSupervisorConfigTab WHERE OmniSupervisorConfigId = :configId ORDER BY DisplayOrder
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Limitations
|
|
76
|
+
|
|
77
|
+
- Populates only the reference-free standard action and tab types. Custom actions, FlexiPage tabs, AWS dashboards, and AI-agent surfaces need an external reference and must be configured in Setup.
|
|
78
|
+
- Does not create, rename, or delete the parent `OmniSupervisorConfig`, its user/queue companions, or supervisor users/permission sets.
|
|
79
|
+
- Does not remove surface rows — it only adds missing ones (no destructive reconciliation).
|
|
80
|
+
|
|
81
|
+
## References
|
|
82
|
+
|
|
83
|
+
| File | When to read |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `references/api-notes.md` | The full `OmniSupervisorActionType` / `OmniSupervisorTabType` vocabulary, which types are reference-free, and companion-row insert semantics |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Omni Supervisor surface (Action + Tab) - API notes
|
|
2
|
+
|
|
3
|
+
## What this leaf writes
|
|
4
|
+
|
|
5
|
+
Plain Data API inserts, one row per missing type:
|
|
6
|
+
|
|
7
|
+
- `OmniSupervisorConfigAction` - createable fields: `OmniSupervisorConfigId`, `OmniSupervisorActionType` (picklist), `DisplayOrder`.
|
|
8
|
+
- `OmniSupervisorConfigTab` - createable fields: `OmniSupervisorConfigId`, `OmniSupervisorTabType` (picklist), `DisplayOrder`.
|
|
9
|
+
|
|
10
|
+
Both are companions of `OmniSupervisorConfig`. Because they are createable child sObjects, the surface is populated without re-deploying the parent `OmniSupervisorConfig` metadata document - that document is owned by `service-omni-supervisor-config-deploy` and carries the user/queue companions. Splitting the surface into a Data API leaf keeps the two skills from fighting over the same whole-document metadata file.
|
|
11
|
+
|
|
12
|
+
## Why "reference-free types only"
|
|
13
|
+
|
|
14
|
+
Neither companion exposes a reference field in `describe` (only `OmniSupervisorConfigId`, the `*Type`, and `DisplayOrder` are createable). So a type that needs to point at something external cannot be expressed as a bare row and must be configured in Setup. This leaf blocks up front on:
|
|
15
|
+
|
|
16
|
+
- Action types matching `*.CustomAction` or `*.AWSDashboard`.
|
|
17
|
+
- Tab types `FlexipageType`, `AIAgents`, `AgentforceSDR`.
|
|
18
|
+
|
|
19
|
+
## OmniSupervisorActionType vocabulary (org-verified, API 66)
|
|
20
|
+
|
|
21
|
+
Reference-free (this leaf's `SAFE_ACTIONS`, and the default set):
|
|
22
|
+
|
|
23
|
+
- `AllAgents.ChangeQueues`
|
|
24
|
+
- `AllAgents.ChangeSkills`
|
|
25
|
+
- `AllAgents.ChangeGroups`
|
|
26
|
+
- `AllAgents.AssignLearning`
|
|
27
|
+
- `QueuesBacklog.ManageQueues`
|
|
28
|
+
|
|
29
|
+
Reference-required (blocked - configure in Setup): `AllAgents.CustomAction`, `AllAgents.AWSDashboard`, `AgentDetails.CustomAction`, `QueuesBacklog.CustomAction`, `QueuesBacklog.AWSDashboard`, `QueueDetails.CustomAction`, `AssignedWork.CustomAction`, `AssignedWork.AWSDashboard`, `AssignedWorkDetails.CustomAction`, `SkillsBacklog.CustomAction`, `SkillsBacklog.AWSDashboard`, `SkillDetails.CustomAction`.
|
|
30
|
+
|
|
31
|
+
## OmniSupervisorTabType vocabulary (org-verified, API 66)
|
|
32
|
+
|
|
33
|
+
Reference-free (this leaf's `SAFE_TABS`): `Wallboard`, `Agents`, `QueuesBacklog`, `AssignedWork`, `SkillsBacklog`, `Reports`, `Alerts`. The default set is the first five (the core supervisor panels); `Reports` and `Alerts` are accepted when requested explicitly.
|
|
34
|
+
|
|
35
|
+
Reference-required (blocked - configure in Setup): `FlexipageType`, `AIAgents`, `AgentforceSDR`.
|
|
36
|
+
|
|
37
|
+
## Idempotency and ordering
|
|
38
|
+
|
|
39
|
+
The requested types are diffed against the rows already on the config (`SELECT OmniSupervisorActionType/OmniSupervisorTabType ... WHERE OmniSupervisorConfigId = :id`). Existing types are reported `reused`; missing types are inserted. New `DisplayOrder` values start one above the current maximum for that companion, so ordering already configured in Setup is preserved and re-runs make no writes.
|
|
40
|
+
|
|
41
|
+
`DisplayOrder` is not required to be unique across rows; appending after the maximum simply keeps newly added items at the end of the supervisor's list.
|
|
42
|
+
|
|
43
|
+
## Related
|
|
44
|
+
|
|
45
|
+
- `service-omni-supervisor-config-deploy` - creates the parent `OmniSupervisorConfig` and its user/queue companions (prerequisite).
|
|
46
|
+
- `service-omni-supervisor-permset-assign` - grants supervisors the `ContactCenterSupervisor` permission set.
|
|
47
|
+
- `service-omni-command-center-analyze` - reports whether the org is on the classic supervisor surface vs. Command Center V2.
|