@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,131 @@
1
+ #!/usr/bin/env node
2
+ // Idempotent in-place patcher for canEscalate + outboundRoute surfaces; refuses (exit 4) if no safe insertion point. XSD order + modes: references/classifier-contracts.md.
3
+
4
+ import { readFileSync, writeFileSync } from 'node:fs';
5
+
6
+ const [mode, filePath, flowName, escalationMessageArg] = process.argv.slice(2);
7
+ if (!mode || !filePath) {
8
+ process.stderr.write('usage: node patch-escalation-surfaces.mjs <canEscalate|outboundRoute> <file> [flowApiName] [escalationMessage]\n');
9
+ process.exit(2);
10
+ }
11
+
12
+ const xmlEscape = (s) => String(s)
13
+ .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
14
+
15
+ let text;
16
+ try {
17
+ text = readFileSync(filePath, 'utf8');
18
+ } catch {
19
+ process.stderr.write(`error: cannot read ${filePath}\n`);
20
+ process.exit(2);
21
+ }
22
+
23
+ const done = (summary) => { process.stdout.write(JSON.stringify(summary) + '\n'); process.exit(0); };
24
+ const refuse = (msg) => { process.stderr.write(`refuse: ${msg}\n`); process.exit(4); };
25
+
26
+ // Return {index, indent} of the earliest top-level opening tag from `tags` found in `hay`
27
+ // (searched from offset `from`), along with the leading whitespace on that tag's line.
28
+ const firstTag = (hay, tags, from = 0) => {
29
+ const scope = hay.slice(from);
30
+ let best = null;
31
+ for (const t of tags) {
32
+ const re = new RegExp(`([ \\t]*)<${t}(?=[ >/])`, 'g');
33
+ for (const m of scope.matchAll(re)) {
34
+ const idx = from + m.index;
35
+ if (best === null || idx < best.index) best = { index: idx, indent: m[1] || '' };
36
+ break; // first match of this tag is enough
37
+ }
38
+ }
39
+ return best;
40
+ };
41
+
42
+ if (mode === 'canEscalate') {
43
+ // Idempotent: normalize an existing <canEscalate> to true.
44
+ if (/<canEscalate>[\s\S]*?<\/canEscalate>/.test(text)) {
45
+ const next = text.replace(/<canEscalate>[\s\S]*?<\/canEscalate>/, '<canEscalate>true</canEscalate>');
46
+ if (next !== text) writeFileSync(filePath, next);
47
+ done({ mode, changed: next !== text, action: 'set-existing' });
48
+ }
49
+ const rootOpen = text.match(/<GenAiPlugin\b[^>]*>/);
50
+ if (!rootOpen) refuse('no <GenAiPlugin> root element found');
51
+ let searchFrom = rootOpen.index + rootOpen[0].length;
52
+ // Skip PAST any <aiPluginUtterances> blocks first - they legally precede canEscalate and each
53
+ // one carries a nested <developerName>, which would otherwise be mistaken for the top-level anchor.
54
+ const utteranceCloses = [...text.matchAll(/<\/aiPluginUtterances>/g)];
55
+ if (utteranceCloses.length) {
56
+ const last = utteranceCloses[utteranceCloses.length - 1];
57
+ searchFrom = last.index + '</aiPluginUtterances>'.length;
58
+ }
59
+ // canEscalate must come BEFORE the first of these top-level siblings.
60
+ const anchor = firstTag(text, [
61
+ 'description', 'developerName', 'genAiFunctions', 'genAiPluginInstructions',
62
+ 'language', 'localActionLinks', 'localActions', 'localDeveloperName',
63
+ 'masterLabel', 'pluginType', 'scope', 'source',
64
+ ], searchFrom);
65
+ if (!anchor) refuse('no post-canEscalate sibling (description/developerName/masterLabel/...) found; refusing to guess placement');
66
+ const indent = anchor.indent || ' ';
67
+ const insertion = `${indent}<canEscalate>true</canEscalate>\n`;
68
+ const followingTag = text.slice(anchor.index).match(/<([A-Za-z]+)/)[1];
69
+ const next = text.slice(0, anchor.index) + insertion + text.slice(anchor.index);
70
+ writeFileSync(filePath, next);
71
+ done({ mode, changed: true, action: 'inserted-before-' + followingTag });
72
+ }
73
+
74
+ if (mode === 'outboundRoute') {
75
+ if (!flowName) { process.stderr.write('error: outboundRoute requires <flowApiName>\n'); process.exit(2); }
76
+ const escMsg = xmlEscape(escalationMessageArg || 'Transferring you to a live support agent.');
77
+ const MESSAGING_SURFACES = new Set(['Messaging', 'CustomerWebClient']);
78
+
79
+ const surfaces = [...text.matchAll(/<plannerSurfaces>([\s\S]*?)<\/plannerSurfaces>/g)];
80
+ if (surfaces.length === 0) refuse('no <plannerSurfaces> block found; refusing to invent one');
81
+ const chosen = surfaces.find((m) => {
82
+ const t = m[1].match(/<surfaceType>\s*([^<]*?)\s*<\/surfaceType>/);
83
+ return t && MESSAGING_SURFACES.has(t[1].trim());
84
+ });
85
+ if (!chosen) refuse('no Messaging-class planner surface (surfaceType Messaging|CustomerWebClient) found');
86
+
87
+ const innerStart = chosen.index + '<plannerSurfaces>'.length;
88
+ const innerEnd = chosen.index + chosen[0].length - '</plannerSurfaces>'.length;
89
+ const inner = text.slice(innerStart, innerEnd);
90
+
91
+ // Idempotent: an existing outboundRouteConfigs already targeting this flow -> normalize the type only.
92
+ const existing = [...inner.matchAll(/<outboundRouteConfigs>([\s\S]*?)<\/outboundRouteConfigs>/g)]
93
+ .find((c) => {
94
+ const n = c[1].match(/<outboundRouteName>\s*([^<]*?)\s*<\/outboundRouteName>/);
95
+ return n && n[1].trim() === flowName;
96
+ });
97
+ if (existing) {
98
+ const block = existing[0];
99
+ let newBlock = block;
100
+ if (/<outboundRouteType>[\s\S]*?<\/outboundRouteType>/.test(block)) {
101
+ newBlock = block.replace(/<outboundRouteType>[\s\S]*?<\/outboundRouteType>/, '<outboundRouteType>OmniChannelFlow</outboundRouteType>');
102
+ } else {
103
+ newBlock = block.replace(/<\/outboundRouteConfigs>/, ' <outboundRouteType>OmniChannelFlow</outboundRouteType>\n </outboundRouteConfigs>');
104
+ }
105
+ if (newBlock === block) done({ mode, changed: false, action: 'already-configured' });
106
+ const newInner = inner.replace(block, newBlock);
107
+ const next = text.slice(0, innerStart) + newInner + text.slice(innerEnd);
108
+ writeFileSync(filePath, next);
109
+ done({ mode, changed: true, action: 'normalized-type' });
110
+ }
111
+
112
+ // Insert a fresh block BEFORE <surface> to honor the AiPlannerSurfaceDef XSD sequence
113
+ // (...outboundRouteConfigs*, surface, surfaceType). <surface> is required, so it must be present.
114
+ const surfaceAnchor = firstTag(inner, ['surface']);
115
+ if (!surfaceAnchor) refuse('Messaging planner surface has no <surface> element; refusing to guess insertion point');
116
+ const indent = surfaceAnchor.indent || ' ';
117
+ const childIndent = indent + ' ';
118
+ const block =
119
+ `${indent}<outboundRouteConfigs>\n` +
120
+ `${childIndent}<escalationMessage>${escMsg}</escalationMessage>\n` +
121
+ `${childIndent}<outboundRouteName>${xmlEscape(flowName)}</outboundRouteName>\n` +
122
+ `${childIndent}<outboundRouteType>OmniChannelFlow</outboundRouteType>\n` +
123
+ `${indent}</outboundRouteConfigs>\n`;
124
+ const newInner = inner.slice(0, surfaceAnchor.index) + block + inner.slice(surfaceAnchor.index);
125
+ const next = text.slice(0, innerStart) + newInner + text.slice(innerEnd);
126
+ writeFileSync(filePath, next);
127
+ done({ mode, changed: true, action: 'inserted-before-surface' });
128
+ }
129
+
130
+ process.stderr.write(`error: unknown mode '${mode}'\n`);
131
+ process.exit(2);
@@ -0,0 +1,249 @@
1
+ """Shared paths + fake-`sf` harness for the escalation-configure contract suite (org-free, network-free; drives the bash+Node skill via subprocess, asserting exit codes + emitted JSON)."""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+ import subprocess
6
+ import tempfile
7
+ from pathlib import Path
8
+
9
+ # skills/ root is three levels up (.../<skill>/scripts/tests/_bootstrap.py).
10
+ SKILLS_ROOT = Path(__file__).resolve().parents[3]
11
+
12
+ SKILL_DIR = "service-agentforce-human-escalation-configure"
13
+ SCRIPT = f"{SKILL_DIR}/scripts/verify-and-configure.sh"
14
+ # The ITSM coordinator's advancement gate - exercised for the escalation verdict mapping.
15
+ VERDICT_SCRIPT = "service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs"
16
+
17
+ # A fake `sf` that reports a PRODUCTION customer org so the safe_to_write guard must refuse.
18
+ # A fake `project deploy` returns a sentinel so a guard bypass would surface loudly.
19
+ _FAKE_SF_PROD = r"""#!/usr/bin/env bash
20
+ sub="${1:-} ${2:-}"; args="$*"
21
+ case "$sub" in
22
+ "org display") echo '{"status":0,"result":{"id":"00Dxx0000000000EAA"}}'; exit 0;;
23
+ "data query")
24
+ if printf '%s' "$args" | grep -q "FROM Organization"; then
25
+ echo '{"status":0,"result":{"records":[{"Id":"00Dxx0000000000EAA","IsSandbox":false,"TrialExpirationDate":null,"OrganizationType":"Enterprise Edition"}]}}'
26
+ else
27
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
28
+ fi
29
+ exit 0;;
30
+ "project deploy")
31
+ echo '{"status":1,"result":{"success":false},"message":"FAKE_SF_DEPLOY_SHOULD_NOT_BE_REACHED"}'; exit 1;;
32
+ *) echo '{"status":0,"result":{}}'; exit 0;;
33
+ esac
34
+ """
35
+
36
+ # A fake `sf` for a SANDBOX org where every deterministic surface already resolves (active agent,
37
+ # MessagingChannel, queue + QueueSobject + QRC, active RoutingFlow) and `project retrieve` writes
38
+ # canEscalate=true / an outboundRouteName so the doc-driven surfaces verify true. The FAKE_* env vars
39
+ # below toggle each surface off to exercise the block/create paths; a GroupMember POST flips membership
40
+ # via a marker file (stateful convergence); canonical QRC id 0RC000000000001AAA makes create+adopt converge.
41
+ _FAKE_SF_SANDBOX = r"""#!/usr/bin/env bash
42
+ sub="${1:-} ${2:-}"; args="$*"
43
+ SELF_DIR="$(cd "$(dirname "$0")" && pwd)"
44
+ AGENT_ACTIVE="${FAKE_AGENT_ACTIVE:-1}"
45
+ MC_PRESENT="${FAKE_MC_PRESENT:-1}"
46
+ QS_PRESENT="${FAKE_QS_PRESENT:-1}"
47
+ QRC_PRESENT="${FAKE_QRC_PRESENT:-1}"
48
+ QUEUE_PRESENT="${FAKE_QUEUE_PRESENT:-1}"
49
+ QUEUE_BOUND="${FAKE_QUEUE_BOUND:-1}"
50
+ QUEUE_MEMBERS="${FAKE_QUEUE_MEMBERS:-1}"
51
+ ROUTE_TYPE="${FAKE_ROUTE_TYPE:-OmniChannelFlow}"
52
+ ROUTE_SURFACE="${FAKE_ROUTE_SURFACE:-Messaging}"
53
+ # FAKE_GENAI_MD=0 → org exposes no GenAiPlugin/GenAiPlannerBundle metadata types (the escalation
54
+ # preflight must then BLOCK before any write). Default 1 → the authoring metadata is exposed.
55
+ GENAI_MD="${FAKE_GENAI_MD:-1}"
56
+ # FAKE_MODEL pins the authoring model the org advertises: classic (GenAiPlugin+GenAiPlannerBundle),
57
+ # nga (AiAuthoringBundle, no GenAiPlannerBundle), or none. Empty => derive from GENAI_MD (1=classic,0=none).
58
+ MODEL="${FAKE_MODEL:-}"
59
+ if [ -z "$MODEL" ]; then [ "$GENAI_MD" = "1" ] && MODEL="classic" || MODEL="none"; fi
60
+ TARGET_MODEL="${FAKE_TARGET_MODEL:-$MODEL}"
61
+ # FAKE_NGA_SURFACE=1 => retrieved AiAuthoringBundle contains connection messaging: + @utils.escalate
62
+ # (Service escalation surface present). 0 => neither (surface missing => INCOMPLETE on nga).
63
+ NGA_SURFACE="${FAKE_NGA_SURFACE:-1}"
64
+ RC_ID="0RC000000000001AAA"
65
+ # Opt-in call log: when FAKE_SF_CALLLOG points at a file, append every invocation's args so a
66
+ # test can prove which mutations did (or did NOT) happen - e.g. idempotent re-runs create nothing.
67
+ if [ -n "${FAKE_SF_CALLLOG:-}" ]; then printf '%s\n' "$args" >> "$FAKE_SF_CALLLOG"; fi
68
+ _has_members() { [ "$QUEUE_MEMBERS" = "1" ] || [ -f "$SELF_DIR/.gm_added" ]; }
69
+ case "$sub" in
70
+ "org display") echo '{"status":0,"result":{"id":"00Dxx0000000000EAA"}}'; exit 0;;
71
+ "org list")
72
+ if printf '%s' "$args" | grep -q "metadata-types"; then
73
+ case "$MODEL" in
74
+ classic) echo '{"status":0,"result":{"metadataObjects":[{"xmlName":"Bot"},{"xmlName":"GenAiPlugin"},{"xmlName":"GenAiPlannerBundle"}]}}';;
75
+ nga) echo '{"status":0,"result":{"metadataObjects":[{"xmlName":"Bot"},{"xmlName":"AiAuthoringBundle"},{"xmlName":"GenAiPlugin"}]}}';;
76
+ both) echo '{"status":0,"result":{"metadataObjects":[{"xmlName":"Bot"},{"xmlName":"AiAuthoringBundle"},{"xmlName":"GenAiPlugin"},{"xmlName":"GenAiPlannerBundle"}]}}';;
77
+ *) echo '{"status":0,"result":{"metadataObjects":[{"xmlName":"Bot"},{"xmlName":"BotTemplate"},{"xmlName":"BotBlock"}]}}';;
78
+ esac
79
+ else
80
+ echo '{"status":0,"result":{}}'
81
+ fi
82
+ exit 0;;
83
+ "data query")
84
+ if printf '%s' "$args" | grep -q "FROM Organization"; then
85
+ echo '{"status":0,"result":{"records":[{"Id":"00Dxx0000000000EAA","IsSandbox":true,"TrialExpirationDate":null,"OrganizationType":"Developer Edition"}]}}'
86
+ elif printf '%s' "$args" | grep -q "FROM BotDefinition"; then
87
+ if [ "$AGENT_ACTIVE" = "1" ]; then
88
+ echo '{"status":0,"result":{"records":[{"Id":"0Xx000000000001AAA","DeveloperName":"Support_Agent","MasterLabel":"Support Agent","BotVersions":{"records":[{"Id":"04V000000000001AAA","Status":"Active"}]}}],"totalSize":1}}'
89
+ else
90
+ echo '{"status":0,"result":{"records":[{"Id":"0Xx000000000001AAA","DeveloperName":"Support_Agent","MasterLabel":"Support Agent","BotVersions":{"records":[{"Id":"04V000000000001AAA","Status":"Inactive"}]}}],"totalSize":1}}'
91
+ fi
92
+ elif printf '%s' "$args" | grep -q "FROM MessagingChannel"; then
93
+ if [ "$MC_PRESENT" = "1" ]; then
94
+ echo '{"status":0,"result":{"records":[{"Id":"0M9000000000001AAA","DeveloperName":"Support_Chat"}],"totalSize":1}}'
95
+ else
96
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
97
+ fi
98
+ elif printf '%s' "$args" | grep -q "FROM QueueSobject"; then
99
+ if [ "$QS_PRESENT" = "1" ]; then
100
+ echo '{"status":0,"result":{"records":[{"Id":"0Q9000000000001AAA"}],"totalSize":1}}'
101
+ else
102
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
103
+ fi
104
+ elif printf '%s' "$args" | grep -q "FROM QueueRoutingConfig"; then
105
+ if [ "$QRC_PRESENT" = "1" ]; then
106
+ echo '{"status":0,"result":{"records":[{"Id":"'"$RC_ID"'","DeveloperName":"Human_Support_Queue_RC"}],"totalSize":1}}'
107
+ else
108
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
109
+ fi
110
+ elif printf '%s' "$args" | grep -q "FROM FlowDefinitionView"; then
111
+ echo '{"status":0,"result":{"records":[{"ApiName":"Human_Escalation_Outbound_Flow","ActiveVersionId":"301000000000001AAA"}],"totalSize":1}}'
112
+ elif printf '%s' "$args" | grep -q "FROM GroupMember"; then
113
+ if _has_members; then
114
+ echo '{"status":0,"result":{"records":[{"UserOrGroupId":"005000000000001AAA"}],"totalSize":1}}'
115
+ else
116
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
117
+ fi
118
+ elif printf '%s' "$args" | grep -q "FROM User"; then
119
+ if printf '%s' "$args" | grep -q "COUNT(Id)"; then
120
+ if _has_members; then
121
+ echo '{"status":0,"result":{"records":[{"c":1}],"totalSize":1}}'
122
+ else
123
+ echo '{"status":0,"result":{"records":[{"c":0}],"totalSize":1}}'
124
+ fi
125
+ else
126
+ # Id-by-username (assignment path) → an active user row.
127
+ echo '{"status":0,"result":{"records":[{"Id":"005000000000002AAA"}],"totalSize":1}}'
128
+ fi
129
+ elif printf '%s' "$args" | grep -q "FROM Group"; then
130
+ if [ "$QUEUE_PRESENT" = "1" ]; then
131
+ if [ "$QUEUE_BOUND" = "1" ]; then
132
+ echo '{"status":0,"result":{"records":[{"Id":"00G000000000001AAA","QueueRoutingConfigId":"'"$RC_ID"'"}],"totalSize":1}}'
133
+ else
134
+ echo '{"status":0,"result":{"records":[{"Id":"00G000000000001AAA","QueueRoutingConfigId":null}],"totalSize":1}}'
135
+ fi
136
+ else
137
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
138
+ fi
139
+ else
140
+ echo '{"status":0,"result":{"records":[],"totalSize":0}}'
141
+ fi
142
+ exit 0;;
143
+ "api request")
144
+ # Data API POST/PATCH (QueueSobject bind, QueueRoutingConfig create, Group.QueueRoutingConfigId bind).
145
+ if printf '%s' "$args" | grep -q "sobjects/QueueRoutingConfig"; then
146
+ echo '{"success":true,"id":"'"$RC_ID"'"}'
147
+ elif printf '%s' "$args" | grep -q "sobjects/QueueSobject"; then
148
+ echo '{"success":true,"id":"0Q9000000000009AAA"}'
149
+ elif printf '%s' "$args" | grep -q "sobjects/GroupMember"; then
150
+ touch "$SELF_DIR/.gm_added"
151
+ echo '{"success":true,"id":"0GM00000000001AAA"}'
152
+ else
153
+ # Group PATCH → 204 empty body on success.
154
+ echo ''
155
+ fi
156
+ exit 0;;
157
+ "project retrieve")
158
+ dir=$(printf '%s' "$args" | sed -n 's/.*--target-metadata-dir[ =]\([^ ]*\).*/\1/p'); dir="${dir:-.}"
159
+ mkdir -p "$dir"
160
+ if printf '%s' "$args" | grep -q "AiAuthoringBundle:"; then
161
+ [ "$TARGET_MODEL" = "nga" ] || [ "$TARGET_MODEL" = "both" ] || exit 1
162
+ if [ "$NGA_SURFACE" = "1" ]; then
163
+ cat > "$dir/Support_Agent.agent" <<'AGENT'
164
+ start_agent support_agent:
165
+ connection messaging:
166
+ end_user_client: customer_web_client
167
+ reasoning:
168
+ actions:
169
+ human_handoff: @utils.escalate
170
+ description: "Transfer the user to a human agent."
171
+ AGENT
172
+ else
173
+ cat > "$dir/Support_Agent.agent" <<'AGENT'
174
+ start_agent support_agent:
175
+ reasoning:
176
+ actions:
177
+ answer: @actions.AnswerQuestionWithKnowledge
178
+ AGENT
179
+ fi
180
+ elif printf '%s' "$args" | grep -q "GenAiPlugin:"; then
181
+ echo '<canEscalate>true</canEscalate>' > "$dir/plugin.xml"
182
+ elif printf '%s' "$args" | grep -q "GenAiPlannerBundle:"; then
183
+ [ "$TARGET_MODEL" = "classic" ] || [ "$TARGET_MODEL" = "both" ] || exit 1
184
+ cat > "$dir/bundle.xml" <<BXML
185
+ <GenAiPlannerBundle>
186
+ <plannerSurfaces>
187
+ <surfaceType>${ROUTE_SURFACE}</surfaceType>
188
+ <outboundRouteConfigs>
189
+ <escalationMessage>Transferring you to a live support agent.</escalationMessage>
190
+ <outboundRouteName>Human_Escalation_Outbound_Flow</outboundRouteName>
191
+ <outboundRouteType>${ROUTE_TYPE}</outboundRouteType>
192
+ </outboundRouteConfigs>
193
+ </plannerSurfaces>
194
+ </GenAiPlannerBundle>
195
+ BXML
196
+ fi
197
+ echo '{"status":0,"result":{"success":true}}'; exit 0;;
198
+ "project deploy")
199
+ echo '{"status":0,"result":{"success":true,"files":[{"fullName":"Human_Escalation_Outbound_Flow","type":"Flow","state":"Created"}]}}'; exit 0;;
200
+ *) echo '{"status":0,"result":{}}'; exit 0;;
201
+ esac
202
+ """
203
+
204
+
205
+ def run(args, path_prefix=None, scrub_sf=False, extra_env=None):
206
+ """Run the orchestrator; return (returncode, merged stdout+stderr)."""
207
+ env = dict(os.environ)
208
+ if scrub_sf:
209
+ kept = [d for d in env.get("PATH", "").split(os.pathsep)
210
+ if d and not os.path.exists(os.path.join(d, "sf"))]
211
+ env["PATH"] = os.pathsep.join(kept)
212
+ if path_prefix:
213
+ env["PATH"] = path_prefix + os.pathsep + env.get("PATH", "")
214
+ if extra_env:
215
+ env.update({k: str(v) for k, v in extra_env.items()})
216
+ proc = subprocess.run(
217
+ ["bash", str(SKILLS_ROOT / SCRIPT), *args],
218
+ capture_output=True, text=True, env=env, cwd=str(SKILLS_ROOT),
219
+ )
220
+ return proc.returncode, (proc.stdout or "") + (proc.stderr or "")
221
+
222
+
223
+ def run_node(script_rel, args):
224
+ """Run a bundled Node helper; return (returncode, stdout)."""
225
+ proc = subprocess.run(
226
+ ["node", str(SKILLS_ROOT / script_rel), *args],
227
+ capture_output=True, text=True, cwd=str(SKILLS_ROOT),
228
+ )
229
+ return proc.returncode, (proc.stdout or "")
230
+
231
+
232
+ class FakeSf:
233
+ """Context manager: a temp dir holding an executable fake `sf` first on PATH."""
234
+
235
+ def __init__(self, body=_FAKE_SF_PROD):
236
+ self._body = body
237
+ self._tmp = None
238
+
239
+ def __enter__(self):
240
+ self._tmp = tempfile.mkdtemp(prefix="esc-fake-sf-")
241
+ sf = Path(self._tmp) / "sf"
242
+ sf.write_text(self._body)
243
+ sf.chmod(0o755)
244
+ return self._tmp
245
+
246
+ def __exit__(self, *exc):
247
+ import shutil
248
+ if self._tmp:
249
+ shutil.rmtree(self._tmp, ignore_errors=True)