@salesforce/afv-skills 1.46.0 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-observe/SKILL.md +32 -4
  3. package/skills/agentforce-observe/references/ahm-alerts.md +719 -0
  4. package/skills/consumer-goods-promotion-bo-api-deploy/SKILL.md +275 -0
  5. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/README.md +32 -0
  6. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls +75 -0
  7. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/SetCommentValue.cls-meta.xml +5 -0
  8. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/interview-answers.json +13 -0
  9. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/copy.json +10 -0
  10. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/create.json +20 -0
  11. package/skills/consumer-goods-promotion-bo-api-deploy/assets/set-comment-value/payloads/update.json +16 -0
  12. package/skills/consumer-goods-promotion-bo-api-deploy/references/conventions-and-payload-rules.md +273 -0
  13. package/skills/consumer-goods-promotion-bo-api-deploy/references/generate-and-wire.md +236 -0
  14. package/skills/consumer-goods-promotion-bo-api-deploy/references/reference-example-set-comment-value.md +132 -0
  15. package/skills/consumer-goods-promotion-bo-api-deploy/references/smoke-and-verify.md +211 -0
  16. package/skills/dx-devops-project-manage/SKILL.md +197 -0
  17. package/skills/dx-devops-project-manage/examples/common-workflows.md +197 -0
  18. package/skills/dx-devops-project-manage/references/cli-commands.md +295 -0
  19. package/skills/dx-devops-project-manage/scripts/create-project.sh +48 -0
  20. package/skills/dx-devops-project-manage/scripts/list-projects.sh +51 -0
  21. package/skills/dx-devops-project-manage/scripts/update-project.sh +96 -0
  22. package/skills/education-cloud-academic-calendar-generate/SKILL.md +225 -0
  23. package/skills/education-cloud-academic-calendar-generate/examples/quarter-calendar.json +47 -0
  24. package/skills/education-cloud-academic-calendar-generate/examples/sample-output.md +57 -0
  25. package/skills/education-cloud-academic-calendar-generate/examples/semester-calendar.json +54 -0
  26. package/skills/education-cloud-academic-calendar-generate/references/calendar-systems.md +127 -0
  27. package/skills/education-cloud-academic-calendar-generate/references/date-validation.md +222 -0
  28. package/skills/education-cloud-academic-calendar-generate/references/foundation_prerequisites.md +40 -0
  29. package/skills/education-cloud-academic-calendar-generate/scripts/validate_calendar_dates.py +143 -0
  30. package/skills/education-cloud-course-catalog-migrate/SKILL.md +321 -0
  31. package/skills/education-cloud-course-catalog-migrate/references/gotchas-detail.md +16 -0
  32. package/skills/education-cloud-course-catalog-migrate/references/gotchas.md +16 -0
  33. package/skills/education-cloud-course-catalog-migrate/references/large-catalog-handling.md +42 -0
  34. package/skills/education-cloud-course-catalog-migrate/scripts/batch_courses.py +36 -0
  35. package/skills/education-cloud-course-catalog-migrate/scripts/detect_linked_courses.py +51 -0
  36. package/skills/education-cloud-course-catalog-migrate/scripts/detect_modality_variants.py +48 -0
  37. package/skills/education-cloud-course-catalog-migrate/scripts/resolve_api_version.py +43 -0
  38. package/skills/education-cloud-course-catalog-migrate/scripts/split_course_code.py +39 -0
  39. package/skills/education-cloud-course-catalog-migrate/scripts/validate_completeness.py +54 -0
  40. package/skills/education-cloud-domain-configure/SKILL.md +234 -0
  41. package/skills/education-cloud-domain-configure/references/dependent-features.md +198 -0
  42. package/skills/education-cloud-domain-configure/references/domain-features/academic-operations.md +386 -0
  43. package/skills/education-cloud-domain-configure/references/domain-features/alumni-relations.md +155 -0
  44. package/skills/education-cloud-domain-configure/references/domain-features/cross-domain-dependencies.md +18 -0
  45. package/skills/education-cloud-domain-configure/references/domain-features/industriessettings-toggle-reference.md +43 -0
  46. package/skills/education-cloud-domain-configure/references/domain-features/mentoring.md +198 -0
  47. package/skills/education-cloud-domain-configure/references/domain-features/recruitment-admissions.md +315 -0
  48. package/skills/education-cloud-domain-configure/references/domain-features/student-management.md +155 -0
  49. package/skills/education-cloud-domain-configure/references/domain-features/student-success.md +249 -0
  50. package/skills/education-cloud-domain-configure/references/domain-features.md +27 -0
  51. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +23 -0
  52. package/skills/education-cloud-domain-configure/references/toggle-write-path.md +67 -0
  53. package/skills/education-cloud-domain-configure/scripts/check_license_provisioned.py +62 -0
  54. package/skills/education-cloud-domain-configure/scripts/check_org_edition.py +44 -0
  55. package/skills/education-cloud-domain-configure/scripts/check_permission_assigned.py +39 -0
  56. package/skills/education-cloud-multi-campus-configure/SKILL.md +7 -0
  57. package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +1 -2
  58. package/skills/education-cloud-student-recruitment-agent-configure/SKILL.md +177 -0
  59. package/skills/education-cloud-student-recruitment-agent-configure/references/agent-and-subagents.md +151 -0
  60. package/skills/education-cloud-student-recruitment-agent-configure/references/customer-narration.md +34 -0
  61. package/skills/education-cloud-student-recruitment-agent-configure/references/execution-model.md +54 -0
  62. package/skills/education-cloud-student-recruitment-agent-configure/references/flows.md +82 -0
  63. package/skills/education-cloud-student-recruitment-agent-configure/references/grounding.md +199 -0
  64. package/skills/education-cloud-student-recruitment-agent-configure/references/permissions.md +183 -0
  65. package/skills/education-cloud-student-recruitment-agent-configure/references/platform-enablement.md +82 -0
  66. package/skills/education-cloud-student-recruitment-agent-configure/references/prerequisites.md +158 -0
  67. package/skills/education-cloud-student-recruitment-agent-configure/references/routing.md +141 -0
  68. package/skills/experience-cms-brand-apply/SKILL.md +5 -5
  69. package/skills/experience-cms-brand-create/SKILL.md +2 -2
  70. package/skills/experience-cms-content-generate/SKILL.md +1 -0
  71. package/skills/experience-cms-content-render/SKILL.md +173 -0
  72. package/skills/experience-cms-content-render/assets/angular/DetailPage.component.ts +25 -0
  73. package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +133 -0
  74. package/skills/experience-cms-content-render/assets/angular/TypeList.component.ts +38 -0
  75. package/skills/experience-cms-content-render/assets/angular/TypeRenderer.component.ts +90 -0
  76. package/skills/experience-cms-content-render/assets/angular/cms-content.component.ts +248 -0
  77. package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +100 -0
  78. package/skills/experience-cms-content-render/assets/react/DetailPage.tsx +20 -0
  79. package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +129 -0
  80. package/skills/experience-cms-content-render/assets/react/TypeList.tsx +40 -0
  81. package/skills/experience-cms-content-render/assets/react/TypeRenderer.tsx +64 -0
  82. package/skills/experience-cms-content-render/assets/react/heuristicRenderer.tsx +310 -0
  83. package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +129 -0
  84. package/skills/experience-cms-content-render/assets/shared/cmsContentType.ts +49 -0
  85. package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +96 -0
  86. package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +55 -0
  87. package/skills/experience-cms-content-render/references/bulk-loading.md +60 -0
  88. package/skills/experience-cms-content-render/references/codegen-guardrails.md +111 -0
  89. package/skills/experience-cms-content-render/references/detail-pages.md +87 -0
  90. package/skills/experience-cms-content-render/references/embed-recipes.md +127 -0
  91. package/skills/experience-cms-content-render/references/failure-modes.md +96 -0
  92. package/skills/experience-cms-content-render/references/heuristic-render-rules.md +131 -0
  93. package/skills/experience-cms-content-render/references/init-scaffold.md +122 -0
  94. package/skills/experience-cms-content-render/references/interaction-model.md +173 -0
  95. package/skills/experience-cms-content-render/references/package-api.md +106 -0
  96. package/skills/experience-cms-content-render/references/schema-sync.md +114 -0
  97. package/skills/experience-cms-content-render/references/styling-scopes.md +65 -0
  98. package/skills/experience-cms-content-render/references/verify.md +49 -0
  99. package/skills/experience-cms-content-type-generate/SKILL.md +2 -2
  100. package/skills/experience-content-media-stock-image-search/SKILL.md +5 -4
  101. package/skills/experience-search-coordinate/SKILL.md +198 -0
  102. package/skills/experience-search-coordinate/assets/search-payload-template.json +25 -0
  103. package/skills/experience-search-coordinate/references/content-route.md +313 -0
  104. package/skills/experience-search-coordinate/references/content-type-discovery.md +57 -0
  105. package/skills/experience-search-coordinate/references/media-route.md +172 -0
  106. package/skills/experience-search-coordinate/references/scope-resolution.md +14 -0
  107. package/skills/experience-ui-bundle-localize/SKILL.md +1 -1
  108. package/skills/experience-ui-bundle-localize/references/i18n-setup.md +5 -3
  109. package/skills/experience-ui-bundle-project-generate/SKILL.md +18 -14
  110. package/skills/experience-ui-bundle-project-generate/references/angular-project-generate.md +22 -0
  111. package/skills/experience-ui-bundle-project-generate/references/react-project-generate.md +20 -0
  112. package/skills/experience-ui-bundle-salesforce-data-access/SKILL.md +58 -54
  113. package/skills/experience-ui-bundle-salesforce-data-access/references/caching.md +6 -0
  114. package/skills/experience-ui-bundle-salesforce-data-access/references/graphiti-cli.md +2 -2
  115. package/skills/experience-ui-bundle-salesforce-data-access/references/migration.md +6 -0
  116. package/skills/experience-ui-bundle-salesforce-data-access/references/rest-and-integration.md +2 -1
  117. package/skills/experience-ui-bundle-salesforce-data-access/references/sdk-api.md +6 -0
  118. package/skills/experience-ui-bundle-site-generate/SKILL.md +59 -8
  119. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-digital-experience.md +8 -3
  120. package/skills/experience-ui-bundle-site-generate/references/configure-metadata-language-settings.md +120 -0
  121. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +336 -0
  122. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +143 -0
  123. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +127 -0
  124. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-deploy-commands.md +116 -0
  125. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +111 -0
  126. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-overview.md +312 -0
  127. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +171 -0
  128. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-state-tracking.md +64 -0
  129. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-2-starter-config-trigger-handlers.md +122 -0
  130. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-overview.md +335 -0
  131. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-4-user-provisioning-user-provisioning-details.md +140 -0
  132. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-execution-state-and-recovery.md +196 -0
  133. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-metadata-cache-generation.md +155 -0
  134. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-overview.md +307 -0
  135. package/skills/life-sciences-fieldsalesrep-coordinate/references/stage-5-visit-creation-visit-creation-data.md +211 -0
  136. package/skills/life-sciences-fieldsalesrep-coordinate/references/state-machine-and-changes.md +108 -0
  137. package/skills/life-sciences-kam-coordinate/SKILL.md +241 -0
  138. package/skills/life-sciences-kam-coordinate/references/orchestration-flow.md +152 -0
  139. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-application-flexipage-mapping.md +79 -0
  140. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-deploy-commands.md +131 -0
  141. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-kam-config-records.md +85 -0
  142. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-lifesci-metadata-deploy.md +112 -0
  143. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-overview.md +202 -0
  144. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-profile-layout-assignments.md +67 -0
  145. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-state-tracking.md +65 -0
  146. package/skills/life-sciences-kam-coordinate/references/stage-2-starter-config-trigger-handlers.md +123 -0
  147. package/skills/life-sciences-kam-coordinate/references/stage-4-participant-role-and-sprint.md +89 -0
  148. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +337 -0
  149. package/skills/life-sciences-kam-coordinate/references/stage-5-data-creation-data.md +248 -0
  150. package/skills/life-sciences-kam-coordinate/references/stage-6-ipad-validation-script.md +35 -0
  151. package/skills/life-sciences-kam-coordinate/references/stage-6-metadata-cache-generation.md +155 -0
  152. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-details.md +146 -0
  153. package/skills/life-sciences-kam-coordinate/references/stage-6-user-provisioning-overview.md +89 -0
  154. package/skills/life-sciences-kam-coordinate/references/state-machine-and-changes.md +114 -0
  155. package/skills/life-sciences-prerequisites-validate/SKILL.md +138 -0
  156. package/skills/life-sciences-prerequisites-validate/references/checks-org-settings.md +190 -0
  157. package/skills/life-sciences-prerequisites-validate/references/checks-user-and-package.md +211 -0
  158. package/skills/life-sciences-territory-configure/SKILL.md +217 -0
  159. package/skills/life-sciences-territory-configure/references/territory-metadata.md +262 -0
  160. package/skills/platform-dsar-policy-manage/SKILL.md +272 -0
  161. package/skills/platform-dsar-policy-manage/references/configure.md +106 -0
  162. package/skills/platform-dsar-policy-manage/references/export-and-history.md +123 -0
  163. package/skills/platform-dsar-policy-manage/references/gap-analysis-guide.md +150 -0
  164. package/skills/platform-dsar-policy-manage/references/gap-scan.md +129 -0
  165. package/skills/platform-dsar-policy-manage/references/headless-sor.md +59 -0
  166. package/skills/platform-dsar-policy-manage/references/report-format.md +59 -0
  167. package/skills/platform-dsar-policy-manage/scripts/tests/__init__.py +0 -0
  168. package/skills/platform-dsar-policy-manage/scripts/tests/test_validate_policy_tree.py +76 -0
  169. package/skills/platform-dsar-policy-manage/scripts/validate-policy-tree.py +130 -0
  170. package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +359 -0
  171. package/skills/platform-salesforce-connect-adapter-generate/references/official-examples.md +69 -0
  172. package/skills/platform-salesforce-connect-adapter-generate/references/scenarios.md +187 -0
  173. package/skills/service-agentforce-channel-configure/SKILL.md +33 -28
  174. package/skills/service-agentforce-human-escalation-configure/SKILL.md +205 -0
  175. package/skills/service-agentforce-human-escalation-configure/assets/escalation-thresholds.instructions.md +37 -0
  176. package/skills/service-agentforce-human-escalation-configure/assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml +173 -0
  177. package/skills/service-agentforce-human-escalation-configure/assets/package.xml +8 -0
  178. package/skills/service-agentforce-human-escalation-configure/assets/sfdx-project.json +5 -0
  179. package/skills/service-agentforce-human-escalation-configure/references/classifier-contracts.md +103 -0
  180. package/skills/service-agentforce-human-escalation-configure/references/escalation-mechanism.md +63 -0
  181. package/skills/service-agentforce-human-escalation-configure/references/failure-policy.md +44 -0
  182. package/skills/service-agentforce-human-escalation-configure/references/nga-escalation.md +57 -0
  183. package/skills/service-agentforce-human-escalation-configure/references/runtime-verification.md +72 -0
  184. package/skills/service-agentforce-human-escalation-configure/scripts/classify-agent-active.mjs +49 -0
  185. package/skills/service-agentforce-human-escalation-configure/scripts/classify-nga-escalation.mjs +166 -0
  186. package/skills/service-agentforce-human-escalation-configure/scripts/extract-outbound-route.mjs +67 -0
  187. package/skills/service-agentforce-human-escalation-configure/scripts/patch-escalation-surfaces.mjs +131 -0
  188. package/skills/service-agentforce-human-escalation-configure/scripts/tests/__init__.py +0 -0
  189. package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +249 -0
  190. package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +899 -0
  191. package/skills/service-agentforce-human-escalation-configure/scripts/verify-and-configure.sh +705 -0
  192. package/skills/service-agentforce-human-escalation-configure/scripts/verify-escalation-config.mjs +89 -0
  193. package/skills/service-de-channel-routing-configure/SKILL.md +13 -5
  194. package/skills/service-de-channel-routing-configure/scripts/tests/test_skill_contract.py +25 -0
  195. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +23 -10
  196. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -48
  197. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +6 -2
  198. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +20 -27
  199. package/skills/service-native-voice-recording-transcription-configure/SKILL.md +47 -27
  200. package/skills/service-native-voice-recording-transcription-configure/references/thunderbird-voice-settings.md +13 -9
  201. package/skills/service-native-voice-recording-transcription-configure/scripts/enable-recording-transcription.sh +104 -45
  202. package/skills/service-omni-agent-users-create/SKILL.md +96 -0
  203. package/skills/service-omni-agent-users-create/assets/create-users.apex.template +80 -0
  204. package/skills/service-omni-agent-users-create/references/apex-patterns.md +135 -0
  205. package/skills/service-omni-agent-users-create/references/apex-template-notes.md +40 -0
  206. package/skills/service-omni-agent-users-create/scripts/detect-and-create.sh +206 -0
  207. package/skills/service-omni-agent-users-create/scripts/detect-existing.sh +122 -0
  208. package/skills/service-omni-agent-users-create/scripts/run-create.sh +298 -0
  209. package/skills/service-omni-agent-users-create/scripts/tests/test_user_create_security.py +171 -0
  210. package/skills/service-omni-agent-work-sharing-configure/SKILL.md +78 -0
  211. package/skills/service-omni-agent-work-sharing-configure/references/api-notes.md +31 -0
  212. package/skills/service-omni-agent-work-sharing-configure/scripts/configure-and-report.sh +186 -0
  213. package/skills/service-omni-agent-work-sharing-configure/scripts/tests/_bootstrap.py +120 -0
  214. package/skills/service-omni-agent-work-sharing-configure/scripts/tests/test_agent_work_sharing_contracts.py +93 -0
  215. package/skills/service-omni-base-settings-configure/SKILL.md +77 -0
  216. package/skills/service-omni-base-settings-configure/assets/force-app/main/default/settings/OmniChannel.settings-meta.xml +8 -0
  217. package/skills/service-omni-base-settings-configure/assets/package.xml +8 -0
  218. package/skills/service-omni-base-settings-configure/assets/sfdx-project.json +12 -0
  219. package/skills/service-omni-base-settings-configure/references/api-notes.md +121 -0
  220. package/skills/service-omni-base-settings-configure/scripts/configure-and-report.sh +164 -0
  221. package/skills/service-omni-base-settings-configure/scripts/detect-existing.sh +69 -0
  222. package/skills/service-omni-channel-setup-coordinate/SKILL.md +168 -0
  223. package/skills/service-omni-channel-setup-coordinate/examples/output-templates.md +161 -0
  224. package/skills/service-omni-channel-setup-coordinate/references/gap-catalog.md +99 -0
  225. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +1542 -0
  226. package/skills/service-omni-channel-setup-coordinate/scripts/tests/__init__.py +0 -0
  227. package/skills/service-omni-channel-setup-coordinate/scripts/tests/_bootstrap.py +223 -0
  228. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +804 -0
  229. package/skills/service-omni-command-center-analyze/SKILL.md +84 -0
  230. package/skills/service-omni-command-center-analyze/references/api-notes.md +54 -0
  231. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +198 -0
  232. package/skills/service-omni-command-center-analyze/scripts/tests/_bootstrap.py +115 -0
  233. package/skills/service-omni-command-center-analyze/scripts/tests/test_command_center_analyze_contracts.py +165 -0
  234. package/skills/service-omni-permission-set-assign/SKILL.md +88 -0
  235. package/skills/service-omni-permission-set-assign/assets/package.xml +8 -0
  236. package/skills/service-omni-permission-set-assign/references/api-notes.md +143 -0
  237. package/skills/service-omni-permission-set-assign/scripts/verify-and-assign.sh +397 -0
  238. package/skills/service-omni-presence-status-deploy/SKILL.md +87 -0
  239. package/skills/service-omni-presence-status-deploy/assets/package.xml +12 -0
  240. package/skills/service-omni-presence-status-deploy/references/api-notes.md +115 -0
  241. package/skills/service-omni-presence-status-deploy/scripts/deploy-and-report.sh +422 -0
  242. package/skills/service-omni-presence-user-config-deploy/SKILL.md +80 -0
  243. package/skills/service-omni-presence-user-config-deploy/references/api-notes.md +60 -0
  244. package/skills/service-omni-presence-user-config-deploy/scripts/deploy-and-report.sh +261 -0
  245. package/skills/service-omni-presence-user-config-deploy/scripts/tests/_bootstrap.py +106 -0
  246. package/skills/service-omni-presence-user-config-deploy/scripts/tests/test_presence_user_config_contracts.py +142 -0
  247. package/skills/service-omni-queue-deploy/SKILL.md +91 -0
  248. package/skills/service-omni-queue-deploy/references/api-notes.md +140 -0
  249. package/skills/service-omni-queue-deploy/scripts/verify-and-align.sh +470 -0
  250. package/skills/service-omni-queue-members-assign/SKILL.md +93 -0
  251. package/skills/service-omni-queue-members-assign/references/api-notes.md +144 -0
  252. package/skills/service-omni-queue-members-assign/scripts/tests/_bootstrap.py +67 -0
  253. package/skills/service-omni-queue-members-assign/scripts/tests/test_queue_members_contracts.py +73 -0
  254. package/skills/service-omni-queue-members-assign/scripts/verify-and-bind.sh +362 -0
  255. package/skills/service-omni-queue-routing-config-deploy/SKILL.md +101 -0
  256. package/skills/service-omni-queue-routing-config-deploy/references/api-notes.md +127 -0
  257. package/skills/service-omni-queue-routing-config-deploy/scripts/tests/_bootstrap.py +90 -0
  258. package/skills/service-omni-queue-routing-config-deploy/scripts/tests/test_queue_routing_config_contracts.py +70 -0
  259. package/skills/service-omni-queue-routing-config-deploy/scripts/upsert-and-report.sh +538 -0
  260. package/skills/service-omni-routing-flow-deploy/SKILL.md +111 -0
  261. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.SkillsBased.flow-meta.xml +94 -0
  262. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.flow-meta.xml +88 -0
  263. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Cases.flow-meta.xml +144 -0
  264. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.SkillsBased.flow-meta.xml +94 -0
  265. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.flow-meta.xml +88 -0
  266. package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCalls.flow-meta.xml +144 -0
  267. package/skills/service-omni-routing-flow-deploy/assets/package.xml +11 -0
  268. package/skills/service-omni-routing-flow-deploy/assets/sfdx-project.json +11 -0
  269. package/skills/service-omni-routing-flow-deploy/references/api-notes.md +265 -0
  270. package/skills/service-omni-routing-flow-deploy/scripts/deploy-and-report.sh +684 -0
  271. package/skills/service-omni-service-channel-configure/SKILL.md +83 -0
  272. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Cases.serviceChannel-meta.xml +9 -0
  273. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Incidents.serviceChannel-meta.xml +9 -0
  274. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/MessagingSessions.serviceChannel-meta.xml +9 -0
  275. package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/VoiceCalls.serviceChannel-meta.xml +9 -0
  276. package/skills/service-omni-service-channel-configure/assets/package.xml +11 -0
  277. package/skills/service-omni-service-channel-configure/assets/sfdx-project.json +12 -0
  278. package/skills/service-omni-service-channel-configure/references/api-notes.md +84 -0
  279. package/skills/service-omni-service-channel-configure/scripts/deploy-and-report.sh +383 -0
  280. package/skills/service-omni-sidebar-configure/SKILL.md +77 -0
  281. package/skills/service-omni-sidebar-configure/references/api-notes.md +51 -0
  282. package/skills/service-omni-sidebar-configure/scripts/enable-and-report.sh +315 -0
  283. package/skills/service-omni-sidebar-configure/scripts/tests/_bootstrap.py +142 -0
  284. package/skills/service-omni-sidebar-configure/scripts/tests/test_sidebar_contracts.py +139 -0
  285. package/skills/service-omni-skills-based-routing-configure/SKILL.md +81 -0
  286. package/skills/service-omni-skills-based-routing-configure/references/api-notes.md +50 -0
  287. package/skills/service-omni-skills-based-routing-configure/scripts/configure-and-report.sh +270 -0
  288. package/skills/service-omni-skills-based-routing-configure/scripts/tests/_bootstrap.py +120 -0
  289. package/skills/service-omni-skills-based-routing-configure/scripts/tests/test_sbr_contracts.py +129 -0
  290. package/skills/service-omni-supervisor-config-deploy/SKILL.md +97 -0
  291. package/skills/service-omni-supervisor-config-deploy/assets/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml +9 -0
  292. package/skills/service-omni-supervisor-config-deploy/assets/package.xml +8 -0
  293. package/skills/service-omni-supervisor-config-deploy/assets/sfdx-project.json +12 -0
  294. package/skills/service-omni-supervisor-config-deploy/references/api-notes.md +205 -0
  295. package/skills/service-omni-supervisor-config-deploy/scripts/deploy-and-report.sh +586 -0
  296. package/skills/service-omni-supervisor-config-deploy/scripts/tests/_bootstrap.py +153 -0
  297. package/skills/service-omni-supervisor-config-deploy/scripts/tests/test_supervisor_config_contracts.py +116 -0
  298. package/skills/service-omni-supervisor-permset-assign/SKILL.md +88 -0
  299. package/skills/service-omni-supervisor-permset-assign/references/api-notes.md +48 -0
  300. package/skills/service-omni-supervisor-permset-assign/scripts/verify-and-assign.sh +316 -0
  301. package/skills/service-omni-supervisor-surface-deploy/SKILL.md +85 -0
  302. package/skills/service-omni-supervisor-surface-deploy/references/api-notes.md +47 -0
  303. package/skills/service-omni-supervisor-surface-deploy/scripts/deploy-and-report.sh +216 -0
  304. package/skills/service-omni-supervisor-surface-deploy/scripts/tests/_bootstrap.py +95 -0
  305. package/skills/service-omni-supervisor-surface-deploy/scripts/tests/test_supervisor_surface_contracts.py +154 -0
  306. package/skills/service-omni-supervisor-users-create/SKILL.md +92 -0
  307. package/skills/service-omni-supervisor-users-create/assets/create-supervisors.apex.template +72 -0
  308. package/skills/service-omni-supervisor-users-create/references/apex-patterns.md +73 -0
  309. package/skills/service-omni-supervisor-users-create/references/apex-template-notes.md +41 -0
  310. package/skills/service-omni-supervisor-users-create/scripts/detect-and-create.sh +197 -0
  311. package/skills/service-omni-supervisor-users-create/scripts/detect-existing.sh +112 -0
  312. package/skills/service-omni-supervisor-users-create/scripts/run-create.sh +296 -0
  313. package/skills/service-omni-work-skill-routing-configure/SKILL.md +80 -0
  314. package/skills/service-omni-work-skill-routing-configure/references/api-notes.md +67 -0
  315. package/skills/service-omni-work-skill-routing-configure/scripts/configure-and-report.sh +262 -0
  316. package/skills/service-omni-work-skill-routing-configure/scripts/tests/_bootstrap.py +121 -0
  317. package/skills/service-omni-work-skill-routing-configure/scripts/tests/test_work_skill_routing_contracts.py +161 -0
@@ -0,0 +1,586 @@
1
+ #!/usr/bin/env bash
2
+ # deploy-and-report.sh - deploy a selected OmniSupervisorConfig (Profile scope + Queue list + Supervisor-user list) in one atomic, production-guarded Metadata deploy (async + poll); idempotent. Args, behavior, exit codes: SKILL.md.
3
+
4
+ set -euo pipefail
5
+
6
+ if [ $# -lt 1 ]; then
7
+ echo '{"error":"Missing required argument: org-alias","usage":"bash deploy-and-report.sh <org-alias> [supervisor_count] [additional_queues_csv] [profiles_csv] [skill_visibility] [config_developer_name]"}' >&2
8
+ exit 1
9
+ fi
10
+
11
+ ORG="$1"
12
+ SUPERVISOR_COUNT="${2:-1}"
13
+ ADDITIONAL_QUEUES_CSV="${3:-}"
14
+ SKILL_VISIBILITY_INPUT="${5:-${OMNI_SUPERVISOR_SKILL_VISIBILITY:-}}"
15
+ CONFIG_DEVELOPER_NAME="${6:-${OMNI_SUPERVISOR_CONFIG_DEVELOPER_NAME:-Omni_Supervisor}}"
16
+ CONFIG_MASTER_LABEL_INPUT="${OMNI_SUPERVISOR_CONFIG_MASTER_LABEL:-}"
17
+
18
+ if ! [[ "$CONFIG_DEVELOPER_NAME" =~ ^[A-Za-z][A-Za-z0-9_]{0,79}$ ]]; then
19
+ echo "{\"error\":\"Invalid config_developer_name '$CONFIG_DEVELOPER_NAME'. It must start with a letter and contain only A-Z, a-z, 0-9, or _ (maximum 80 characters).\"}" >&2
20
+ exit 1
21
+ fi
22
+
23
+ case "$SKILL_VISIBILITY_INPUT" in
24
+ ""|AllSkills|AnySkill) ;;
25
+ *)
26
+ echo "{\"error\":\"Invalid skill_visibility '$SKILL_VISIBILITY_INPUT'. Allowed: AllSkills, AnySkill\"}" >&2
27
+ exit 1
28
+ ;;
29
+ esac
30
+
31
+ if ! [[ "$SUPERVISOR_COUNT" =~ ^[0-9]+$ ]] || [ "$SUPERVISOR_COUNT" -lt 1 ] || [ "$SUPERVISOR_COUNT" -gt 5 ]; then
32
+ echo "{\"error\":\"Invalid supervisor_count '$SUPERVISOR_COUNT'. Must be integer 1..5\"}" >&2
33
+ exit 1
34
+ fi
35
+
36
+ if ! sf org display --target-org "$ORG" --json >/dev/null 2>&1; then
37
+ echo "{\"error\":\"Org alias '$ORG' is not authenticated.\"}" >&2
38
+ exit 1
39
+ fi
40
+
41
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
42
+ ASSETS_DIR="$(cd "$SCRIPT_DIR/../assets" && pwd)"
43
+ TEMPLATE_XML="$ASSETS_DIR/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml"
44
+
45
+ emit_blocked() {
46
+ local reason="$1"
47
+ local click_path="$2"
48
+ jq -n \
49
+ --arg skill "service-omni-supervisor-config-deploy" \
50
+ --arg reason "$reason" \
51
+ --arg click_path "$click_path" \
52
+ --arg config_developer_name "$CONFIG_DEVELOPER_NAME" \
53
+ '{
54
+ skill: $skill,
55
+ status: "blocked",
56
+ config_developer_name: $config_developer_name,
57
+ config_id: null,
58
+ supervisor_users_bound: [],
59
+ supervisor_users_count: 0,
60
+ queues_bound: [],
61
+ queues_count: 0,
62
+ deploy_id: null,
63
+ state: null,
64
+ manual_actions: [$click_path],
65
+ blocking_issue: $reason
66
+ }'
67
+ exit 1
68
+ }
69
+
70
+ # emit read-only plan preview JSON and exit 0 (PLAN_ONLY mode)
71
+ emit_plan() {
72
+ local status="$1"
73
+ local detail="$2"
74
+ jq -n \
75
+ --arg status "$status" \
76
+ --arg detail "$detail" \
77
+ --arg config_developer_name "$CONFIG_DEVELOPER_NAME" \
78
+ '{
79
+ skill: "service-omni-supervisor-config-deploy",
80
+ status: $status,
81
+ plan_mode: true,
82
+ plan_detail: $detail,
83
+ config_developer_name: $config_developer_name,
84
+ manual_actions: [],
85
+ blocking_issue: null
86
+ }'
87
+ exit 0
88
+ }
89
+
90
+ # Safe-to-write guard: sandbox / CDO / trial / DE only
91
+ ORG_JSON=$(sf data query --target-org "$ORG" --json \
92
+ -q "SELECT Id, IsSandbox, TrialExpirationDate, OrganizationType FROM Organization LIMIT 1") || {
93
+ emit_blocked "Failed to query Organization for safe_to_write guard." "Verify org auth: sf org display --target-org $ORG"
94
+ }
95
+ ORG_ID=$(echo "$ORG_JSON" | jq -r '.result.records[0].Id')
96
+ IS_SANDBOX=$(echo "$ORG_JSON" | jq -r '.result.records[0].IsSandbox')
97
+ TRIAL_EXP=$(echo "$ORG_JSON" | jq -r '.result.records[0].TrialExpirationDate')
98
+ ORG_TYPE=$(echo "$ORG_JSON" | jq -r '.result.records[0].OrganizationType')
99
+
100
+ SAFE="false"
101
+ if [ "$IS_SANDBOX" = "true" ]; then SAFE="true"; fi
102
+ if [ "$TRIAL_EXP" != "null" ] && [ "$TRIAL_EXP" != "" ]; then SAFE="true"; fi
103
+ if [ "$ORG_TYPE" = "Developer Edition" ] || [ "$ORG_TYPE" = "Base Edition" ]; then SAFE="true"; fi
104
+
105
+ if [ "$SAFE" != "true" ]; then
106
+ emit_blocked \
107
+ "Refusing to deploy to non-sandbox, non-trial, non-DE org (IsSandbox=$IS_SANDBOX, TrialExpirationDate=$TRIAL_EXP, OrganizationType=$ORG_TYPE). Target a sandbox, CDO, trial, or Developer Edition org." \
108
+ "Verify org type: sf org display --target-org $ORG"
109
+ fi
110
+
111
+ # Org suffix (chars 11-18 of the Org Id, lowercased) scopes the supervisor-user search to THIS org
112
+ # (users-create provisions supervisor{N}.<suffix>@example.com).
113
+ SUFFIX=$(echo -n "${ORG_ID:10:8}" | tr '[:upper:]' '[:lower:]')
114
+
115
+ # Discover supervisor users for THIS org's suffix
116
+ SUPER_USERS_JSON=$(sf data query --target-org "$ORG" --json \
117
+ -q "SELECT Id, Username, Profile.Name FROM User WHERE Username LIKE 'supervisor%.${SUFFIX}@example.com' AND IsActive=true ORDER BY Username LIMIT $SUPERVISOR_COUNT" 2>/dev/null || echo '{}')
118
+
119
+ # Distinguish query failure from a clean zero-result: only a parseable records array is authoritative.
120
+ if ! echo "$SUPER_USERS_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
121
+ emit_blocked \
122
+ "Supervisor-user discovery query was inconclusive (not a clean result set): $(echo "$SUPER_USERS_JSON" | head -c 200). Not proceeding on an inconclusive read." \
123
+ "Verify org auth and retry"
124
+ fi
125
+
126
+ FOUND_COUNT=$(echo "$SUPER_USERS_JSON" | jq -r '.result.records | length')
127
+
128
+ # Require the requested number of active supervisors - a partial set would deploy a config that
129
+ # monitors fewer supervisors than the operator asked for, silently under-provisioning.
130
+ if [ "$FOUND_COUNT" -lt "$SUPERVISOR_COUNT" ]; then
131
+ emit_blocked \
132
+ "Expected $SUPERVISOR_COUNT active supervisor user(s) matching 'supervisor{1..N}.${SUFFIX}@example.com'; found only $FOUND_COUNT. Provision or reactivate the missing supervisor users, then rerun this skill." \
133
+ ""
134
+ fi
135
+
136
+ SUPERVISOR_USERNAMES=$(echo "$SUPER_USERS_JSON" | jq -r '.result.records[].Username')
137
+ SUPERVISOR_IDS=$(echo "$SUPER_USERS_JSON" | jq -r '[.result.records[].Id]')
138
+
139
+ # Build <omniSupervisorConfigUser> blocks
140
+ SUPERVISOR_USERS_XML=""
141
+ while IFS= read -r uname; do
142
+ [ -z "$uname" ] && continue
143
+ SUPERVISOR_USERS_XML+=" <omniSupervisorConfigUser>
144
+ <user>$uname</user>
145
+ </omniSupervisorConfigUser>
146
+ "
147
+ done <<< "$SUPERVISOR_USERNAMES"
148
+
149
+ # Optional <omniSupervisorConfigProfile> companions. Core resolves config by user first, falling back
150
+ # to profile only when a supervisor has no user row; since we bind every supervisor by user, profile
151
+ # companions are omitted by default. Supply a profiles CSV (4th arg) of metadata fullNames to opt in.
152
+ PROFILES_CSV_OVERRIDE="${4:-}"
153
+ PROFILE_SCOPE_XML=""
154
+ RESOLVED_PROFILE_META=""
155
+ if [ -n "$PROFILES_CSV_OVERRIDE" ]; then
156
+ # Only profiles that actually exist on the org can be deployed; a missing one fails the deploy with
157
+ # "no Profile named <X> found", so validate each supplied fullName up front.
158
+ META_PROFILE_FULLNAMES=$(sf org list metadata -m Profile -o "$ORG" --json 2>/dev/null | jq -r '.result[]?.fullName' 2>/dev/null || echo "")
159
+ # `|| true`: grep -v exits 1 when every line is blank (e.g. profiles_csv is just "," ), which under
160
+ # set -euo pipefail would kill the script mid-flight instead of yielding an empty list.
161
+ PROFILE_NAMES=$(printf '%s' "$PROFILES_CSV_OVERRIDE" | tr ',' '\n' | sed 's/^ *//;s/ *$//' | grep -v '^$' || true)
162
+ UNRESOLVED_PROFILES=""
163
+ while IFS= read -r pname; do
164
+ [ -z "$pname" ] && continue
165
+ if ! [[ "$pname" =~ ^[A-Za-z0-9_]{1,80}$ ]]; then
166
+ emit_blocked "Invalid profile fullName '$pname' in profiles_csv (allowed: A-Z a-z 0-9 _; pass metadata fullNames such as Standard,ServiceCloud)." "sf org list metadata -m Profile -o $ORG"
167
+ fi
168
+ if printf '%s\n' "$META_PROFILE_FULLNAMES" | grep -Fxq "$pname"; then
169
+ if ! printf '%s\n' "$RESOLVED_PROFILE_META" | grep -Fxq "$pname"; then
170
+ RESOLVED_PROFILE_META+="$pname
171
+ "
172
+ p_esc=$(printf '%s' "$pname" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')
173
+ PROFILE_SCOPE_XML+=" <omniSupervisorConfigProfile>
174
+ <profile>$p_esc</profile>
175
+ </omniSupervisorConfigProfile>
176
+ "
177
+ fi
178
+ else
179
+ UNRESOLVED_PROFILES+="$pname "
180
+ fi
181
+ done <<< "$PROFILE_NAMES"
182
+ if [ -n "$UNRESOLVED_PROFILES" ]; then
183
+ emit_blocked \
184
+ "profiles_csv contained profile fullName(s) not present on this org: $(printf '%s' "$UNRESOLVED_PROFILES" | sed 's/ *$//'). Pass metadata fullNames that exist (see 'sf org list metadata -m Profile')." \
185
+ "sf org list metadata -m Profile -o $ORG"
186
+ fi
187
+ fi
188
+
189
+ # Resolve the queues to bind: a caller-supplied CSV is authoritative (actual upstream queues), else
190
+ # fall back to canonical demo names. Either way, verify each queue exists before binding.
191
+ if [ -n "$ADDITIONAL_QUEUES_CSV" ]; then
192
+ IFS=',' read -ra REQUESTED_QUEUES <<< "$ADDITIONAL_QUEUES_CSV"
193
+ ALL_QUEUES=()
194
+ for q in "${REQUESTED_QUEUES[@]}"; do
195
+ q_trimmed=$(echo "$q" | xargs)
196
+ [ -n "$q_trimmed" ] && ALL_QUEUES+=("$q_trimmed")
197
+ done
198
+ QUEUE_SOURCE="caller_supplied"
199
+ else
200
+ ALL_QUEUES=("CaseQueue" "messagingqueue")
201
+ QUEUE_SOURCE="canonical_default"
202
+ fi
203
+
204
+ QUEUE_LIST_XML=""
205
+ QUEUES_BOUND_JSON="[]"
206
+ MISSING_QUEUES=()
207
+ for q in "${ALL_QUEUES[@]}"; do
208
+ # Validate DeveloperName shape (SOQL-injection guard) before querying.
209
+ if ! [[ "$q" =~ ^[A-Za-z0-9_]{1,80}$ ]]; then
210
+ emit_blocked "Invalid queue DeveloperName '$q' (allowed: A-Z a-z 0-9 _). Fix the queues argument." "Pass valid queue DeveloperNames"
211
+ fi
212
+ Q_JSON=$(sf data query --target-org "$ORG" --json \
213
+ -q "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='$q' LIMIT 1" 2>/dev/null || echo '{}')
214
+ if ! echo "$Q_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
215
+ emit_blocked "Queue existence check for '$q' was inconclusive: $(echo "$Q_JSON" | head -c 160). Not proceeding on an inconclusive read." "Verify org auth and retry"
216
+ fi
217
+ Q_EXISTS=$(echo "$Q_JSON" | jq -r '.result.records | length')
218
+ if [ "$Q_EXISTS" -ge 1 ]; then
219
+ QUEUE_LIST_XML+=" <omniSupervisorConfigQueue>
220
+ <queue>$q</queue>
221
+ </omniSupervisorConfigQueue>
222
+ "
223
+ QUEUES_BOUND_JSON=$(echo "$QUEUES_BOUND_JSON" | jq --arg q "$q" '. + [$q]')
224
+ else
225
+ MISSING_QUEUES+=("$q")
226
+ fi
227
+ done
228
+
229
+ QUEUES_COUNT=$(echo "$QUEUES_BOUND_JSON" | jq -r 'length')
230
+
231
+ # Every requested queue must exist; block if ANY is absent (dropping one would under-provision silently).
232
+ if [ "${#MISSING_QUEUES[@]}" -gt 0 ]; then
233
+ emit_blocked \
234
+ "Requested queue(s) not found on org: ${MISSING_QUEUES[*]} (of requested: ${ALL_QUEUES[*]}). Every requested queue must exist before the supervisor config can bind it. Run service-omni-queue-deploy first, or pass only queue DeveloperName(s) that exist as the 3rd argument." \
235
+ "bash ../service-omni-queue-deploy/scripts/verify-and-align.sh $ORG"
236
+ fi
237
+
238
+ if [ "$QUEUES_COUNT" -lt 1 ]; then
239
+ emit_blocked \
240
+ "No queues resolved to bind (checked: ${ALL_QUEUES[*]}). Run service-omni-queue-deploy first, or pass the actual queue DeveloperName(s) as the 3rd argument." \
241
+ "bash ../service-omni-queue-deploy/scripts/verify-and-align.sh $ORG"
242
+ fi
243
+
244
+ # A metadata redeploy replaces the config's Data API action/tab companions. Snapshot every
245
+ # reference-free companion before updating an existing config and restore it after the deploy.
246
+ # Unknown/reference-bearing rows are blocked before deploy because recreating an incomplete row
247
+ # would be worse than leaving the existing config untouched.
248
+ SAFE_ACTIONS="AllAgents.ChangeQueues AllAgents.ChangeSkills AllAgents.ChangeGroups AllAgents.AssignLearning QueuesBacklog.ManageQueues"
249
+ SAFE_TABS="Wallboard Agents QueuesBacklog AssignedWork SkillsBacklog Reports Alerts"
250
+ in_list() {
251
+ local needle="$1"; shift
252
+ local candidate
253
+ for candidate in "$@"; do [ "$candidate" = "$needle" ] && return 0; done
254
+ return 1
255
+ }
256
+
257
+ CFG_EXIST_JSON=$(sf data query --target-org "$ORG" --json \
258
+ -q "SELECT Id, MasterLabel, SkillVisibility FROM OmniSupervisorConfig WHERE DeveloperName='$CONFIG_DEVELOPER_NAME' LIMIT 1" 2>/dev/null || echo '{}')
259
+ if ! echo "$CFG_EXIST_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
260
+ emit_blocked "OmniSupervisorConfig discovery was inconclusive. Not deploying because existing skill visibility and surface companions cannot be preserved safely." "Verify org auth and retry"
261
+ fi
262
+
263
+ EXISTING_CONFIG_ID=$(echo "$CFG_EXIST_JSON" | jq -r '.result.records[0].Id // ""')
264
+ EXISTING_MASTER_LABEL=$(echo "$CFG_EXIST_JSON" | jq -r '.result.records[0].MasterLabel // ""')
265
+ EXISTING_SKILL_VISIBILITY=$(echo "$CFG_EXIST_JSON" | jq -r '.result.records[0].SkillVisibility // ""')
266
+ CONFIG_MASTER_LABEL="${CONFIG_MASTER_LABEL_INPUT:-${EXISTING_MASTER_LABEL:-${CONFIG_DEVELOPER_NAME//_/ }}}"
267
+ CONFIG_MASTER_LABEL_XML=$(printf '%s' "$CONFIG_MASTER_LABEL" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&apos;/g')
268
+ SKILL_VISIBILITY="${SKILL_VISIBILITY_INPUT:-${EXISTING_SKILL_VISIBILITY:-AllSkills}}"
269
+ case "$SKILL_VISIBILITY" in
270
+ AllSkills|AnySkill) ;;
271
+ *) emit_blocked "Existing OmniSupervisorConfig has unsupported SkillVisibility '$SKILL_VISIBILITY'; pass AllSkills or AnySkill explicitly as the 5th argument." "Review Omni Supervisor configuration in Setup" ;;
272
+ esac
273
+
274
+ SNAPSHOT_ACTIONS='[]'
275
+ SNAPSHOT_TABS='[]'
276
+ if [ -n "$EXISTING_CONFIG_ID" ]; then
277
+ ACTIONS_JSON=$(sf data query --target-org "$ORG" --json \
278
+ -q "SELECT OmniSupervisorActionType, DisplayOrder FROM OmniSupervisorConfigAction WHERE OmniSupervisorConfigId='$EXISTING_CONFIG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
279
+ TABS_JSON=$(sf data query --target-org "$ORG" --json \
280
+ -q "SELECT OmniSupervisorTabType, DisplayOrder FROM OmniSupervisorConfigTab WHERE OmniSupervisorConfigId='$EXISTING_CONFIG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
281
+ if ! echo "$ACTIONS_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1 \
282
+ || ! echo "$TABS_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
283
+ emit_blocked "Existing supervisor surface discovery was inconclusive; its actions and tabs cannot be safely restored after a metadata deploy." "Verify OmniSupervisorConfigAction and OmniSupervisorConfigTab access, then retry"
284
+ fi
285
+ SNAPSHOT_ACTIONS=$(echo "$ACTIONS_JSON" | jq -c '[.result.records[] | {type:.OmniSupervisorActionType, order:.DisplayOrder}]')
286
+ SNAPSHOT_TABS=$(echo "$TABS_JSON" | jq -c '[.result.records[] | {type:.OmniSupervisorTabType, order:.DisplayOrder}]')
287
+ while IFS= read -r surface_type; do
288
+ [ -z "$surface_type" ] && continue
289
+ if ! in_list "$surface_type" $SAFE_ACTIONS; then
290
+ emit_blocked "Existing supervisor action '$surface_type' cannot be safely restored by this skill; no deploy was attempted." "Preserve or reconfigure this action manually in Setup"
291
+ fi
292
+ done < <(echo "$SNAPSHOT_ACTIONS" | jq -r '.[].type')
293
+ while IFS= read -r surface_type; do
294
+ [ -z "$surface_type" ] && continue
295
+ if ! in_list "$surface_type" $SAFE_TABS; then
296
+ emit_blocked "Existing supervisor tab '$surface_type' cannot be safely restored by this skill; no deploy was attempted." "Preserve or reconfigure this tab manually in Setup"
297
+ fi
298
+ done < <(echo "$SNAPSHOT_TABS" | jq -r '.[].type')
299
+ fi
300
+
301
+ # PLAN_ONLY: prerequisites (supervisor users + queues) are validated above; report whether the
302
+ # OmniSupervisorConfig already exists (read-only) and stop before materializing/deploying.
303
+ if [ "${PLAN_ONLY:-}" = "1" ]; then
304
+ if [ -n "$EXISTING_CONFIG_ID" ]; then
305
+ emit_plan "reused" "OmniSupervisorConfig '$CONFIG_DEVELOPER_NAME' already exists; a --run would reconcile supervisor users and $QUEUES_COUNT queue(s), preserve SkillVisibility=$SKILL_VISIBILITY, and restore its existing action/tab surface."
306
+ else
307
+ emit_plan "action_needed" "Would deploy OmniSupervisorConfig '$CONFIG_DEVELOPER_NAME' binding supervisor users + $QUEUES_COUNT queue(s)."
308
+ fi
309
+ fi
310
+
311
+ # Materialize the token-substituted deploy artifact under /tmp/ (mktemp -d + 0700; the artifact holds
312
+ # resolved usernames and is removed by the cleanup trap).
313
+ STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
314
+ umask 077
315
+ mkdir -p /tmp/omni-supervisor-config-deploy
316
+ chmod 700 /tmp/omni-supervisor-config-deploy 2>/dev/null || true
317
+ WORK_DIR="$(mktemp -d "/tmp/omni-supervisor-config-deploy/${STAMP}.XXXXXX")"
318
+ chmod 700 "$WORK_DIR"
319
+ trap 'rm -rf "$WORK_DIR"' EXIT
320
+ mkdir -p "$WORK_DIR/force-app/main/default/omniSupervisorConfigs"
321
+
322
+ cp "$ASSETS_DIR/sfdx-project.json" "$WORK_DIR/sfdx-project.json"
323
+ PACKAGE_CONTENT=$(cat "$ASSETS_DIR/package.xml")
324
+ PACKAGE_CONTENT="${PACKAGE_CONTENT/Omni_Supervisor/$CONFIG_DEVELOPER_NAME}"
325
+ printf '%s' "$PACKAGE_CONTENT" > "$WORK_DIR/package.xml"
326
+
327
+ TEMPLATE_CONTENT=$(cat "$TEMPLATE_XML")
328
+
329
+ RESOLVED_XML="${TEMPLATE_CONTENT/__SUPERVISOR_USERS_XML__/$SUPERVISOR_USERS_XML}"
330
+ RESOLVED_XML="${RESOLVED_XML/__PROFILE_SCOPE_XML__/$PROFILE_SCOPE_XML}"
331
+ RESOLVED_XML="${RESOLVED_XML/__QUEUE_LIST_XML__/$QUEUE_LIST_XML}"
332
+ RESOLVED_XML="${RESOLVED_XML/__SKILL_VISIBILITY__/$SKILL_VISIBILITY}"
333
+ RESOLVED_XML="${RESOLVED_XML/__MASTER_LABEL__/$CONFIG_MASTER_LABEL_XML}"
334
+
335
+ DEPLOY_XML_PATH="$WORK_DIR/force-app/main/default/omniSupervisorConfigs/$CONFIG_DEVELOPER_NAME.omniSupervisorConfig-meta.xml"
336
+ printf '%s' "$RESOLVED_XML" > "$DEPLOY_XML_PATH"
337
+
338
+ # Deploy --async + poll so a synchronous ClientTimeoutError under org load can't produce a false failure.
339
+ cd "$WORK_DIR"
340
+ START_JSON=$(sf project deploy start --manifest package.xml --target-org "$ORG" --async --json 2>/dev/null || true)
341
+ DEPLOY_ID=$(echo "$START_JSON" | jq -r '.result.id // ""')
342
+
343
+ if [ -z "$DEPLOY_ID" ]; then
344
+ RAW_ERR=$(echo "$START_JSON" | jq -c '.result // .' 2>/dev/null | head -c 800)
345
+ emit_blocked \
346
+ "Could not start the OmniSupervisorConfig deploy (no job id returned). Raw: $RAW_ERR" \
347
+ "Retry: sf project deploy start --manifest package.xml --target-org $ORG"
348
+ fi
349
+
350
+ # Poll to a terminal state. Budget ~20 min (80 * 15s) - comfortably above the 705s/1178s
351
+ # retrieves observed on loaded CDOs, and resilient because each report call is non-blocking.
352
+ DEPLOY_JSON="$START_JSON"
353
+ POLL_STATUS=""
354
+ for _ in $(seq 1 80); do
355
+ REPORT_JSON=$(sf project deploy report --job-id "$DEPLOY_ID" --target-org "$ORG" --json 2>/dev/null || true)
356
+ CUR_STATUS=$(echo "$REPORT_JSON" | jq -r '.result.status // ""')
357
+ case "$CUR_STATUS" in
358
+ Succeeded|Failed|SucceededPartial|Canceled)
359
+ DEPLOY_JSON="$REPORT_JSON"; POLL_STATUS="$CUR_STATUS"; break ;;
360
+ esac
361
+ sleep 15
362
+ done
363
+
364
+ if [ -z "$POLL_STATUS" ]; then
365
+ emit_blocked \
366
+ "OmniSupervisorConfig deploy job $DEPLOY_ID did not reach a terminal state within the ~20 min poll budget (server may still be processing under load)." \
367
+ "Check status: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
368
+ fi
369
+
370
+ DEPLOY_ID=$(echo "$DEPLOY_JSON" | jq -r '.result.id // ""')
371
+ DEPLOY_STATUS=$(echo "$DEPLOY_JSON" | jq -r '.result.status // .status // ""')
372
+
373
+ # Only a fully "Succeeded" deploy is acceptable (SucceededPartial may mean the config never landed).
374
+ if [ "$DEPLOY_STATUS" != "Succeeded" ]; then
375
+ RAW_ERR=$(echo "$DEPLOY_JSON" | jq -c '.result // .' 2>/dev/null | head -c 800)
376
+ jq -n \
377
+ --arg deploy_id "$DEPLOY_ID" \
378
+ --arg raw "$RAW_ERR" \
379
+ --arg config_developer_name "$CONFIG_DEVELOPER_NAME" \
380
+ '{
381
+ skill: "service-omni-supervisor-config-deploy",
382
+ status: "blocked",
383
+ config_developer_name: $config_developer_name,
384
+ config_id: null,
385
+ supervisor_users_bound: [],
386
+ supervisor_users_count: 0,
387
+ queues_bound: [],
388
+ queues_count: 0,
389
+ deploy_id: $deploy_id,
390
+ state: "Failed",
391
+ manual_actions: [("Inspect deploy: sf project deploy report --job-id " + $deploy_id)],
392
+ blocking_issue: ("Metadata deploy did not succeed. Raw: " + $raw)
393
+ }'
394
+ exit 1
395
+ fi
396
+
397
+ STATE=$(echo "$DEPLOY_JSON" | jq -r --arg config_developer_name "$CONFIG_DEVELOPER_NAME" '.result.files[] | select(.fullName==$config_developer_name and .type=="OmniSupervisorConfig") | .state' | head -1)
398
+ STATE="${STATE:-unknown}"
399
+
400
+ # Map the deploy state to a status. An UNRECOGNIZED state must NOT silently become "reused"
401
+ # (that would mask a component that never actually deployed) - treat it as a hard failure.
402
+ case "$STATE" in
403
+ Unchanged) STATUS="reused" ;;
404
+ Changed) STATUS="updated" ;;
405
+ Created) STATUS="created" ;;
406
+ *)
407
+ emit_blocked \
408
+ "Deploy reported '$DEPLOY_STATUS' but the OmniSupervisorConfig component state was '$STATE' (not Unchanged/Changed/Created). Cannot confirm the config landed." \
409
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
410
+ ;;
411
+ esac
412
+
413
+ # Fetch config_id post-deploy (missing Id after success = hard failure). Bounded retry with backoff
414
+ # converts transient latency into a definitive read; the guards below still fail closed.
415
+ CFG_ID=""
416
+ CFG_ID_SLEEP=10
417
+ for cfg_attempt in $(seq 1 5); do
418
+ CFG_JSON=$(sf data query --target-org "$ORG" --json \
419
+ -q "SELECT Id FROM OmniSupervisorConfig WHERE DeveloperName='$CONFIG_DEVELOPER_NAME' LIMIT 1" 2>/dev/null || echo '{}')
420
+ if echo "$CFG_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
421
+ CFG_ID=$(echo "$CFG_JSON" | jq -r '.result.records[0].Id // ""')
422
+ [ -n "$CFG_ID" ] && break
423
+ fi
424
+ if [ "$cfg_attempt" -lt 5 ]; then sleep "$CFG_ID_SLEEP"; CFG_ID_SLEEP=$((CFG_ID_SLEEP + 10)); fi
425
+ done
426
+
427
+ if [ -z "$CFG_ID" ]; then
428
+ emit_blocked \
429
+ "Deploy reported '$DEPLOY_STATUS' (state=$STATE) but OmniSupervisorConfig '$CONFIG_DEVELOPER_NAME' is not queryable afterward (after retry) - the config did not persist." \
430
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
431
+ fi
432
+
433
+ # The parent metadata deploy can remove the config's action/tab rows. Restore only the validated
434
+ # snapshot and verify it by re-querying. The companion surface skill remains responsible for adding
435
+ # any new standard rows requested by the coordinator.
436
+ ACTIONS_RESTORED=0
437
+ TABS_RESTORED=0
438
+ CURRENT_ACTIONS_JSON=$(sf data query --target-org "$ORG" --json \
439
+ -q "SELECT OmniSupervisorActionType, DisplayOrder FROM OmniSupervisorConfigAction WHERE OmniSupervisorConfigId='$CFG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
440
+ CURRENT_TABS_JSON=$(sf data query --target-org "$ORG" --json \
441
+ -q "SELECT OmniSupervisorTabType, DisplayOrder FROM OmniSupervisorConfigTab WHERE OmniSupervisorConfigId='$CFG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
442
+ if ! echo "$CURRENT_ACTIONS_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1 \
443
+ || ! echo "$CURRENT_TABS_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
444
+ emit_blocked "Config deployed, but the post-deploy supervisor surface read was inconclusive; missing rows cannot be restored safely." "Review the Omni Supervisor surface in Setup"
445
+ fi
446
+ while IFS= read -r row; do
447
+ [ -z "$row" ] && continue
448
+ surface_type=$(echo "$row" | jq -r '.type')
449
+ display_order=$(echo "$row" | jq -r '.order')
450
+ if echo "$CURRENT_ACTIONS_JSON" | jq -e --arg type "$surface_type" \
451
+ 'any(.result.records[]?; .OmniSupervisorActionType == $type)' >/dev/null 2>&1; then
452
+ continue
453
+ fi
454
+ CREATE_JSON=$(sf data create record --target-org "$ORG" --json \
455
+ --sobject OmniSupervisorConfigAction \
456
+ --values "OmniSupervisorConfigId=$CFG_ID OmniSupervisorActionType=$surface_type DisplayOrder=$display_order" 2>/dev/null || true)
457
+ if [ "$(echo "$CREATE_JSON" | jq -r '.result.success // false' 2>/dev/null)" != "true" ]; then
458
+ emit_blocked "Config deployed, but existing supervisor action '$surface_type' could not be restored." "Restore the action in Omni Supervisor Setup, then retry"
459
+ fi
460
+ ACTIONS_RESTORED=$((ACTIONS_RESTORED + 1))
461
+ done < <(echo "$SNAPSHOT_ACTIONS" | jq -c '.[]')
462
+ while IFS= read -r row; do
463
+ [ -z "$row" ] && continue
464
+ surface_type=$(echo "$row" | jq -r '.type')
465
+ display_order=$(echo "$row" | jq -r '.order')
466
+ if echo "$CURRENT_TABS_JSON" | jq -e --arg type "$surface_type" \
467
+ 'any(.result.records[]?; .OmniSupervisorTabType == $type)' >/dev/null 2>&1; then
468
+ continue
469
+ fi
470
+ CREATE_JSON=$(sf data create record --target-org "$ORG" --json \
471
+ --sobject OmniSupervisorConfigTab \
472
+ --values "OmniSupervisorConfigId=$CFG_ID OmniSupervisorTabType=$surface_type DisplayOrder=$display_order" 2>/dev/null || true)
473
+ if [ "$(echo "$CREATE_JSON" | jq -r '.result.success // false' 2>/dev/null)" != "true" ]; then
474
+ emit_blocked "Config deployed, but existing supervisor tab '$surface_type' could not be restored." "Restore the tab in Omni Supervisor Setup, then retry"
475
+ fi
476
+ TABS_RESTORED=$((TABS_RESTORED + 1))
477
+ done < <(echo "$SNAPSHOT_TABS" | jq -c '.[]')
478
+
479
+ VERIFY_ACTIONS_JSON=$(sf data query --target-org "$ORG" --json \
480
+ -q "SELECT OmniSupervisorActionType, DisplayOrder FROM OmniSupervisorConfigAction WHERE OmniSupervisorConfigId='$CFG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
481
+ VERIFY_TABS_JSON=$(sf data query --target-org "$ORG" --json \
482
+ -q "SELECT OmniSupervisorTabType, DisplayOrder FROM OmniSupervisorConfigTab WHERE OmniSupervisorConfigId='$CFG_ID' ORDER BY DisplayOrder" 2>/dev/null || echo '{}')
483
+ if ! echo "$VERIFY_ACTIONS_JSON" | jq -e --argjson expected "$SNAPSHOT_ACTIONS" '
484
+ [.result.records[]?.OmniSupervisorActionType] as $actual |
485
+ all($expected[]; (.type as $type | $actual | index($type) != null))' >/dev/null 2>&1 \
486
+ || ! echo "$VERIFY_TABS_JSON" | jq -e --argjson expected "$SNAPSHOT_TABS" '
487
+ [.result.records[]?.OmniSupervisorTabType] as $actual |
488
+ all($expected[]; (.type as $type | $actual | index($type) != null))' >/dev/null 2>&1; then
489
+ emit_blocked "Config deployed, but post-deploy verification could not confirm every existing supervisor action and tab was restored." "Review the Omni Supervisor surface in Setup"
490
+ fi
491
+
492
+ # Companion-record verification: the parent existing doesn't prove the child user/queue rows landed.
493
+ # Query the child sObjects scoped to this config and require at least the counts we asked to bind.
494
+ # Bounded retry with backoff (children can lag the parent); only a parseable array is authoritative.
495
+ CFG_USER_JSON='{}'
496
+ CFG_USER_COUNT=0
497
+ CFG_USER_SLEEP=10
498
+ for cu_attempt in $(seq 1 5); do
499
+ CFG_USER_JSON=$(sf data query --target-org "$ORG" --json \
500
+ -q "SELECT Id FROM OmniSupervisorConfigUser WHERE OmniSupervisorConfigId='$CFG_ID'" 2>/dev/null || echo '{}')
501
+ if echo "$CFG_USER_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
502
+ CFG_USER_COUNT=$(echo "$CFG_USER_JSON" | jq -r '.result.records | length')
503
+ [ "$CFG_USER_COUNT" -ge "$FOUND_COUNT" ] && break
504
+ fi
505
+ if [ "$cu_attempt" -lt 5 ]; then sleep "$CFG_USER_SLEEP"; CFG_USER_SLEEP=$((CFG_USER_SLEEP + 10)); fi
506
+ done
507
+ if ! echo "$CFG_USER_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
508
+ emit_blocked \
509
+ "Companion OmniSupervisorConfigUser verification was inconclusive (after retry): $(echo "$CFG_USER_JSON" | head -c 160). Cannot confirm supervisor users bound; not proceeding on an inconclusive read." \
510
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
511
+ fi
512
+ CFG_USER_COUNT=$(echo "$CFG_USER_JSON" | jq -r '.result.records | length')
513
+
514
+ CFG_QUEUE_JSON='{}'
515
+ CFG_QUEUE_COUNT=0
516
+ CFG_QUEUE_SLEEP=10
517
+ for cq_attempt in $(seq 1 5); do
518
+ CFG_QUEUE_JSON=$(sf data query --target-org "$ORG" --json \
519
+ -q "SELECT Id FROM OmniSupervisorConfigQueue WHERE OmniSupervisorConfigId='$CFG_ID'" 2>/dev/null || echo '{}')
520
+ if echo "$CFG_QUEUE_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
521
+ CFG_QUEUE_COUNT=$(echo "$CFG_QUEUE_JSON" | jq -r '.result.records | length')
522
+ [ "$CFG_QUEUE_COUNT" -ge "$QUEUES_COUNT" ] && break
523
+ fi
524
+ if [ "$cq_attempt" -lt 5 ]; then sleep "$CFG_QUEUE_SLEEP"; CFG_QUEUE_SLEEP=$((CFG_QUEUE_SLEEP + 10)); fi
525
+ done
526
+ if ! echo "$CFG_QUEUE_JSON" | jq -e '.result.records | arrays' >/dev/null 2>&1; then
527
+ emit_blocked \
528
+ "Companion OmniSupervisorConfigQueue verification was inconclusive (after retry): $(echo "$CFG_QUEUE_JSON" | head -c 160). Cannot confirm queues bound; not proceeding on an inconclusive read." \
529
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
530
+ fi
531
+ CFG_QUEUE_COUNT=$(echo "$CFG_QUEUE_JSON" | jq -r '.result.records | length')
532
+
533
+ if [ "$CFG_USER_COUNT" -lt "$FOUND_COUNT" ]; then
534
+ emit_blocked \
535
+ "Deploy reported '$DEPLOY_STATUS' (state=$STATE) and the parent config persisted, but only $CFG_USER_COUNT of $FOUND_COUNT intended supervisor-user companion record(s) are present on OmniSupervisorConfig '$CFG_ID'. The config is under-provisioned." \
536
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
537
+ fi
538
+ if [ "$CFG_QUEUE_COUNT" -lt "$QUEUES_COUNT" ]; then
539
+ emit_blocked \
540
+ "Deploy reported '$DEPLOY_STATUS' (state=$STATE) and the parent config persisted, but only $CFG_QUEUE_COUNT of $QUEUES_COUNT intended queue companion record(s) are present on OmniSupervisorConfig '$CFG_ID'. The config is under-provisioned." \
541
+ "Inspect deploy: sf project deploy report --job-id $DEPLOY_ID --target-org $ORG"
542
+ fi
543
+
544
+ # Emit skill-report JSON
545
+ jq -n \
546
+ --arg status "$STATUS" \
547
+ --arg config_developer_name "$CONFIG_DEVELOPER_NAME" \
548
+ --arg cfg_id "$CFG_ID" \
549
+ --argjson supervisor_ids "$SUPERVISOR_IDS" \
550
+ --arg supervisor_count "$FOUND_COUNT" \
551
+ --argjson queues_bound "$QUEUES_BOUND_JSON" \
552
+ --arg queues_count "$QUEUES_COUNT" \
553
+ --arg queue_source "$QUEUE_SOURCE" \
554
+ --arg cfg_user_count "$CFG_USER_COUNT" \
555
+ --arg cfg_queue_count "$CFG_QUEUE_COUNT" \
556
+ --arg deploy_id "$DEPLOY_ID" \
557
+ --arg state "$STATE" \
558
+ --arg skill_visibility "$SKILL_VISIBILITY" \
559
+ --argjson actions_snapshot "$(echo "$SNAPSHOT_ACTIONS" | jq 'length')" \
560
+ --argjson actions_restored "$ACTIONS_RESTORED" \
561
+ --argjson tabs_snapshot "$(echo "$SNAPSHOT_TABS" | jq 'length')" \
562
+ --argjson tabs_restored "$TABS_RESTORED" \
563
+ '{
564
+ skill: "service-omni-supervisor-config-deploy",
565
+ status: $status,
566
+ config_developer_name: $config_developer_name,
567
+ config_id: (if $cfg_id == "" then null else $cfg_id end),
568
+ supervisor_users_bound: $supervisor_ids,
569
+ supervisor_users_count: ($supervisor_count | tonumber),
570
+ queues_bound: $queues_bound,
571
+ queues_count: ($queues_count | tonumber),
572
+ queue_source: $queue_source,
573
+ verified_companion_user_count: ($cfg_user_count | tonumber),
574
+ verified_companion_queue_count: ($cfg_queue_count | tonumber),
575
+ deploy_id: $deploy_id,
576
+ state: $state,
577
+ skill_visibility: $skill_visibility,
578
+ surface_preservation: {
579
+ actions_snapshot: $actions_snapshot,
580
+ actions_restored: $actions_restored,
581
+ tabs_snapshot: $tabs_snapshot,
582
+ tabs_restored: $tabs_restored
583
+ },
584
+ manual_actions: [],
585
+ blocking_issue: null
586
+ }'