@salesforce/afv-skills 1.47.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/education-cloud-domain-configure/SKILL.md +234 -0
- package/skills/education-cloud-domain-configure/references/dependent-features.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/academic-operations.md +386 -0
- package/skills/education-cloud-domain-configure/references/domain-features/alumni-relations.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/cross-domain-dependencies.md +18 -0
- package/skills/education-cloud-domain-configure/references/domain-features/industriessettings-toggle-reference.md +43 -0
- package/skills/education-cloud-domain-configure/references/domain-features/mentoring.md +198 -0
- package/skills/education-cloud-domain-configure/references/domain-features/recruitment-admissions.md +315 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-management.md +155 -0
- package/skills/education-cloud-domain-configure/references/domain-features/student-success.md +249 -0
- package/skills/education-cloud-domain-configure/references/domain-features.md +27 -0
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +23 -0
- package/skills/education-cloud-domain-configure/references/toggle-write-path.md +67 -0
- package/skills/education-cloud-domain-configure/scripts/check_license_provisioned.py +62 -0
- package/skills/education-cloud-domain-configure/scripts/check_org_edition.py +44 -0
- package/skills/education-cloud-domain-configure/scripts/check_permission_assigned.py +39 -0
- package/skills/education-cloud-multi-campus-configure/SKILL.md +7 -0
- package/skills/education-cloud-multi-campus-configure/references/foundation_prerequisites.md +4 -3
- package/skills/service-agentforce-channel-configure/SKILL.md +33 -28
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +205 -0
- package/skills/service-agentforce-human-escalation-configure/assets/escalation-thresholds.instructions.md +37 -0
- package/skills/service-agentforce-human-escalation-configure/assets/force-app/main/default/flows/Human_Escalation_Outbound_Flow.flow-meta.xml +173 -0
- package/skills/service-agentforce-human-escalation-configure/assets/package.xml +8 -0
- package/skills/service-agentforce-human-escalation-configure/assets/sfdx-project.json +5 -0
- package/skills/service-agentforce-human-escalation-configure/references/classifier-contracts.md +103 -0
- package/skills/service-agentforce-human-escalation-configure/references/escalation-mechanism.md +63 -0
- package/skills/service-agentforce-human-escalation-configure/references/failure-policy.md +44 -0
- package/skills/service-agentforce-human-escalation-configure/references/nga-escalation.md +57 -0
- package/skills/service-agentforce-human-escalation-configure/references/runtime-verification.md +72 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-agent-active.mjs +49 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/classify-nga-escalation.mjs +166 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/extract-outbound-route.mjs +67 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/patch-escalation-surfaces.mjs +131 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/__init__.py +0 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +249 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +899 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-and-configure.sh +705 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/verify-escalation-config.mjs +89 -0
- package/skills/service-de-channel-routing-configure/SKILL.md +13 -5
- package/skills/service-de-channel-routing-configure/scripts/tests/test_skill_contract.py +25 -0
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +23 -10
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +63 -48
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +6 -2
- package/skills/service-omni-agent-users-create/SKILL.md +96 -0
- package/skills/service-omni-agent-users-create/assets/create-users.apex.template +80 -0
- package/skills/service-omni-agent-users-create/references/apex-patterns.md +135 -0
- package/skills/service-omni-agent-users-create/references/apex-template-notes.md +40 -0
- package/skills/service-omni-agent-users-create/scripts/detect-and-create.sh +206 -0
- package/skills/service-omni-agent-users-create/scripts/detect-existing.sh +122 -0
- package/skills/service-omni-agent-users-create/scripts/run-create.sh +298 -0
- package/skills/service-omni-agent-users-create/scripts/tests/test_user_create_security.py +171 -0
- package/skills/service-omni-agent-work-sharing-configure/SKILL.md +78 -0
- package/skills/service-omni-agent-work-sharing-configure/references/api-notes.md +31 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/configure-and-report.sh +186 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-agent-work-sharing-configure/scripts/tests/test_agent_work_sharing_contracts.py +93 -0
- package/skills/service-omni-base-settings-configure/SKILL.md +77 -0
- package/skills/service-omni-base-settings-configure/assets/force-app/main/default/settings/OmniChannel.settings-meta.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/package.xml +8 -0
- package/skills/service-omni-base-settings-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-base-settings-configure/references/api-notes.md +121 -0
- package/skills/service-omni-base-settings-configure/scripts/configure-and-report.sh +164 -0
- package/skills/service-omni-base-settings-configure/scripts/detect-existing.sh +69 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +168 -0
- package/skills/service-omni-channel-setup-coordinate/examples/output-templates.md +161 -0
- package/skills/service-omni-channel-setup-coordinate/references/gap-catalog.md +99 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +1542 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/__init__.py +0 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/_bootstrap.py +223 -0
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +804 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +84 -0
- package/skills/service-omni-command-center-analyze/references/api-notes.md +54 -0
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +198 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/_bootstrap.py +115 -0
- package/skills/service-omni-command-center-analyze/scripts/tests/test_command_center_analyze_contracts.py +165 -0
- package/skills/service-omni-permission-set-assign/SKILL.md +88 -0
- package/skills/service-omni-permission-set-assign/assets/package.xml +8 -0
- package/skills/service-omni-permission-set-assign/references/api-notes.md +143 -0
- package/skills/service-omni-permission-set-assign/scripts/verify-and-assign.sh +397 -0
- package/skills/service-omni-presence-status-deploy/SKILL.md +87 -0
- package/skills/service-omni-presence-status-deploy/assets/package.xml +12 -0
- package/skills/service-omni-presence-status-deploy/references/api-notes.md +115 -0
- package/skills/service-omni-presence-status-deploy/scripts/deploy-and-report.sh +422 -0
- package/skills/service-omni-presence-user-config-deploy/SKILL.md +80 -0
- package/skills/service-omni-presence-user-config-deploy/references/api-notes.md +60 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/deploy-and-report.sh +261 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/_bootstrap.py +106 -0
- package/skills/service-omni-presence-user-config-deploy/scripts/tests/test_presence_user_config_contracts.py +142 -0
- package/skills/service-omni-queue-deploy/SKILL.md +91 -0
- package/skills/service-omni-queue-deploy/references/api-notes.md +140 -0
- package/skills/service-omni-queue-deploy/scripts/verify-and-align.sh +470 -0
- package/skills/service-omni-queue-members-assign/SKILL.md +93 -0
- package/skills/service-omni-queue-members-assign/references/api-notes.md +144 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/_bootstrap.py +67 -0
- package/skills/service-omni-queue-members-assign/scripts/tests/test_queue_members_contracts.py +73 -0
- package/skills/service-omni-queue-members-assign/scripts/verify-and-bind.sh +362 -0
- package/skills/service-omni-queue-routing-config-deploy/SKILL.md +101 -0
- package/skills/service-omni-queue-routing-config-deploy/references/api-notes.md +127 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/_bootstrap.py +90 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/tests/test_queue_routing_config_contracts.py +70 -0
- package/skills/service-omni-queue-routing-config-deploy/scripts/upsert-and-report.sh +538 -0
- package/skills/service-omni-routing-flow-deploy/SKILL.md +111 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Case_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_Cases.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.SkillsBased.flow-meta.xml +94 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCall_Trigger.flow-meta.xml +88 -0
- package/skills/service-omni-routing-flow-deploy/assets/force-app/main/default/flows/Omni_Route_VoiceCalls.flow-meta.xml +144 -0
- package/skills/service-omni-routing-flow-deploy/assets/package.xml +11 -0
- package/skills/service-omni-routing-flow-deploy/assets/sfdx-project.json +11 -0
- package/skills/service-omni-routing-flow-deploy/references/api-notes.md +265 -0
- package/skills/service-omni-routing-flow-deploy/scripts/deploy-and-report.sh +684 -0
- package/skills/service-omni-service-channel-configure/SKILL.md +83 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Cases.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/Incidents.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/MessagingSessions.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/force-app/main/default/serviceChannels/VoiceCalls.serviceChannel-meta.xml +9 -0
- package/skills/service-omni-service-channel-configure/assets/package.xml +11 -0
- package/skills/service-omni-service-channel-configure/assets/sfdx-project.json +12 -0
- package/skills/service-omni-service-channel-configure/references/api-notes.md +84 -0
- package/skills/service-omni-service-channel-configure/scripts/deploy-and-report.sh +383 -0
- package/skills/service-omni-sidebar-configure/SKILL.md +77 -0
- package/skills/service-omni-sidebar-configure/references/api-notes.md +51 -0
- package/skills/service-omni-sidebar-configure/scripts/enable-and-report.sh +315 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/_bootstrap.py +142 -0
- package/skills/service-omni-sidebar-configure/scripts/tests/test_sidebar_contracts.py +139 -0
- package/skills/service-omni-skills-based-routing-configure/SKILL.md +81 -0
- package/skills/service-omni-skills-based-routing-configure/references/api-notes.md +50 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/configure-and-report.sh +270 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/_bootstrap.py +120 -0
- package/skills/service-omni-skills-based-routing-configure/scripts/tests/test_sbr_contracts.py +129 -0
- package/skills/service-omni-supervisor-config-deploy/SKILL.md +97 -0
- package/skills/service-omni-supervisor-config-deploy/assets/force-app/main/default/omniSupervisorConfigs/Omni_Supervisor.omniSupervisorConfig-meta.xml +9 -0
- package/skills/service-omni-supervisor-config-deploy/assets/package.xml +8 -0
- package/skills/service-omni-supervisor-config-deploy/assets/sfdx-project.json +12 -0
- package/skills/service-omni-supervisor-config-deploy/references/api-notes.md +205 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/deploy-and-report.sh +586 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/_bootstrap.py +153 -0
- package/skills/service-omni-supervisor-config-deploy/scripts/tests/test_supervisor_config_contracts.py +116 -0
- package/skills/service-omni-supervisor-permset-assign/SKILL.md +88 -0
- package/skills/service-omni-supervisor-permset-assign/references/api-notes.md +48 -0
- package/skills/service-omni-supervisor-permset-assign/scripts/verify-and-assign.sh +316 -0
- package/skills/service-omni-supervisor-surface-deploy/SKILL.md +85 -0
- package/skills/service-omni-supervisor-surface-deploy/references/api-notes.md +47 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/deploy-and-report.sh +216 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/_bootstrap.py +95 -0
- package/skills/service-omni-supervisor-surface-deploy/scripts/tests/test_supervisor_surface_contracts.py +154 -0
- package/skills/service-omni-supervisor-users-create/SKILL.md +92 -0
- package/skills/service-omni-supervisor-users-create/assets/create-supervisors.apex.template +72 -0
- package/skills/service-omni-supervisor-users-create/references/apex-patterns.md +73 -0
- package/skills/service-omni-supervisor-users-create/references/apex-template-notes.md +41 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-and-create.sh +197 -0
- package/skills/service-omni-supervisor-users-create/scripts/detect-existing.sh +112 -0
- package/skills/service-omni-supervisor-users-create/scripts/run-create.sh +296 -0
- package/skills/service-omni-work-skill-routing-configure/SKILL.md +80 -0
- package/skills/service-omni-work-skill-routing-configure/references/api-notes.md +67 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/configure-and-report.sh +262 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/_bootstrap.py +121 -0
- package/skills/service-omni-work-skill-routing-configure/scripts/tests/test_work_skill_routing_contracts.py +161 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# configure-and-report.sh - WRITE entry point (plan|run): detect the five OmniChannelSettings toggles and, when any are off and safe_to_write, deploy canonical settings + re-verify. Args, JSON status contract, exit codes: SKILL.md.
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
if [ $# -lt 2 ]; then
|
|
7
|
+
echo '{"status":"blocked","blocking_issue":"Missing required args","usage":"bash configure-and-report.sh <plan|run> <org-alias>"}' >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
MODE="$1"
|
|
12
|
+
ORG="$2"
|
|
13
|
+
|
|
14
|
+
case "$MODE" in
|
|
15
|
+
plan|run) ;;
|
|
16
|
+
*)
|
|
17
|
+
echo "{\"status\":\"blocked\",\"blocking_issue\":\"Invalid mode '$MODE'. Expected 'plan' or 'run'.\"}" >&2
|
|
18
|
+
exit 1
|
|
19
|
+
;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
23
|
+
DETECT_SCRIPT="$SCRIPT_DIR/detect-existing.sh"
|
|
24
|
+
ASSETS_DIR="$(cd "$SCRIPT_DIR/../assets" && pwd)"
|
|
25
|
+
|
|
26
|
+
if [ ! -f "$DETECT_SCRIPT" ]; then
|
|
27
|
+
echo "{\"status\":\"blocked\",\"blocking_issue\":\"Sibling script not found: $DETECT_SCRIPT\"}" >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Step 1 - detect current settings
|
|
32
|
+
DETECT_EXIT=0
|
|
33
|
+
BEFORE_JSON=$(bash "$DETECT_SCRIPT" "$ORG" 2>&1) || DETECT_EXIT=$?
|
|
34
|
+
|
|
35
|
+
if [ "$DETECT_EXIT" -ne 0 ] || ! echo "$BEFORE_JSON" | jq -e . >/dev/null 2>&1; then
|
|
36
|
+
jq -n --arg raw "$BEFORE_JSON" --argjson exit "$DETECT_EXIT" \
|
|
37
|
+
'{status:"blocked",blocking_issue:("detect-existing.sh failed (exit " + ($exit|tostring) + ")"),before_raw:$raw}'
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
ALL_ENABLED=$(echo "$BEFORE_JSON" | jq -r '.all_enabled')
|
|
42
|
+
|
|
43
|
+
# Step 2 - already fully enabled → reused (both modes)
|
|
44
|
+
if [ "$ALL_ENABLED" = "true" ]; then
|
|
45
|
+
jq -n --argjson before "$BEFORE_JSON" \
|
|
46
|
+
'{status:"reused",all_enabled:true,before:$before,after:$before,deploy_id:null,safe_to_write:true,
|
|
47
|
+
manual_actions:[{id:"login_behavior",title:"Omni-Channel login behavior (UI-only)",detail:"The Omni-Channel utility auto-open-on-login behavior is a UI-only setting not exposed via the Metadata API. Set it manually if desired: Setup → Omni-Channel → Omni-Channel Settings."}]}'
|
|
48
|
+
exit 0
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Step 3 - plan mode never deploys
|
|
52
|
+
if [ "$MODE" = "plan" ]; then
|
|
53
|
+
jq -n --argjson before "$BEFORE_JSON" \
|
|
54
|
+
'{
|
|
55
|
+
status:"action_needed",
|
|
56
|
+
all_enabled:false,
|
|
57
|
+
action_required:"One or more OmniChannelSettings toggles are disabled. Re-run in run mode to deploy.",
|
|
58
|
+
before:$before,
|
|
59
|
+
after:null,
|
|
60
|
+
deploy_id:null,
|
|
61
|
+
manual_actions:[{id:"login_behavior",title:"Omni-Channel login behavior (UI-only)",detail:"The Omni-Channel utility auto-open-on-login behavior is a UI-only setting not exposed via the Metadata API. Set it manually if desired: Setup → Omni-Channel → Omni-Channel Settings."}]
|
|
62
|
+
}'
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Step 4 - run mode: safe_to_write guard (settings deploy mutates the org)
|
|
67
|
+
ORG_GUARD_JSON=$(sf data query --target-org "$ORG" \
|
|
68
|
+
--query "SELECT IsSandbox, TrialExpirationDate, OrganizationType FROM Organization LIMIT 1" \
|
|
69
|
+
--json 2>/dev/null) || {
|
|
70
|
+
jq -n --arg raw "$(printf '%s' "$ORG_GUARD_JSON" | head -c 300)" \
|
|
71
|
+
'{status:"blocked",blocking_issue:("Failed to query Organization for safe_to_write guard: " + $raw)}'
|
|
72
|
+
exit 1
|
|
73
|
+
}
|
|
74
|
+
IS_SANDBOX=$(echo "$ORG_GUARD_JSON" | jq -r '.result.records[0].IsSandbox')
|
|
75
|
+
TRIAL_EXP=$(echo "$ORG_GUARD_JSON" | jq -r '.result.records[0].TrialExpirationDate // "null"')
|
|
76
|
+
ORG_TYPE=$(echo "$ORG_GUARD_JSON" | jq -r '.result.records[0].OrganizationType')
|
|
77
|
+
|
|
78
|
+
SAFE_TO_WRITE=false
|
|
79
|
+
if [ "$IS_SANDBOX" = "true" ] \
|
|
80
|
+
|| [ "$TRIAL_EXP" != "null" ] \
|
|
81
|
+
|| [ "$ORG_TYPE" = "Developer Edition" ] \
|
|
82
|
+
|| [ "$ORG_TYPE" = "Base Edition" ]; then
|
|
83
|
+
SAFE_TO_WRITE=true
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [ "$SAFE_TO_WRITE" != "true" ]; then
|
|
87
|
+
jq -n --argjson before "$BEFORE_JSON" \
|
|
88
|
+
--arg is_sandbox "$IS_SANDBOX" --arg trial "$TRIAL_EXP" --arg type "$ORG_TYPE" \
|
|
89
|
+
'{
|
|
90
|
+
status:"blocked",
|
|
91
|
+
blocking_issue:("Refusing to deploy OmniChannelSettings to a real production customer org (IsSandbox=" + $is_sandbox + ", TrialExpirationDate=" + $trial + ", OrganizationType=" + $type + ")."),
|
|
92
|
+
before:$before,
|
|
93
|
+
safe_to_write:false,
|
|
94
|
+
deploy_id:null
|
|
95
|
+
}'
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
if [ ! -f "$ASSETS_DIR/sfdx-project.json" ]; then
|
|
100
|
+
echo "{\"status\":\"blocked\",\"blocking_issue\":\"Assets DX project not found at $ASSETS_DIR\"}" >&2
|
|
101
|
+
exit 1
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Step 5 - deploy the canonical settings
|
|
105
|
+
SETTINGS_SOURCE="$ASSETS_DIR/force-app/main/default/settings/OmniChannel.settings-meta.xml"
|
|
106
|
+
DEPLOY_JSON=$(cd "$ASSETS_DIR" && sf project deploy start --target-org "$ORG" \
|
|
107
|
+
--source-dir "$SETTINGS_SOURCE" --json 2>/dev/null || true)
|
|
108
|
+
|
|
109
|
+
DEPLOY_SUCCESS=$(echo "$DEPLOY_JSON" | jq -r '.result.success // false' 2>/dev/null)
|
|
110
|
+
DEPLOY_STATUS=$(echo "$DEPLOY_JSON" | jq -r '.result.status // .status // ""' 2>/dev/null)
|
|
111
|
+
DEPLOY_ID=$(echo "$DEPLOY_JSON" | jq -r '.result.id // ""' 2>/dev/null)
|
|
112
|
+
|
|
113
|
+
if [ "$DEPLOY_SUCCESS" != "true" ] || [ "$DEPLOY_STATUS" = "SucceededPartial" ]; then
|
|
114
|
+
FAILURES=$(echo "$DEPLOY_JSON" | jq -r '.result.details.componentFailures // [] | map(.problem) | join("; ")' 2>/dev/null)
|
|
115
|
+
if [ -z "$FAILURES" ] || [ "$FAILURES" = "null" ]; then
|
|
116
|
+
FAILURES=$(echo "$DEPLOY_JSON" | jq -r '.message // .result.errorMessage // "Unknown deploy error"' 2>/dev/null)
|
|
117
|
+
fi
|
|
118
|
+
jq -n --argjson before "$BEFORE_JSON" --arg raw "$FAILURES" --arg did "$DEPLOY_ID" \
|
|
119
|
+
'{
|
|
120
|
+
status:"blocked",
|
|
121
|
+
blocking_issue:("OmniChannelSettings deploy did not fully succeed: " + $raw),
|
|
122
|
+
before:$before,
|
|
123
|
+
after:null,
|
|
124
|
+
safe_to_write:true,
|
|
125
|
+
deploy_id:(if $did == "" then null else $did end)
|
|
126
|
+
}'
|
|
127
|
+
exit 1
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Step 6 - re-detect and verify all five toggles are now enabled
|
|
131
|
+
AFTER_EXIT=0
|
|
132
|
+
AFTER_JSON=$(bash "$DETECT_SCRIPT" "$ORG" 2>&1) || AFTER_EXIT=$?
|
|
133
|
+
|
|
134
|
+
if [ "$AFTER_EXIT" -ne 0 ] || ! echo "$AFTER_JSON" | jq -e . >/dev/null 2>&1; then
|
|
135
|
+
jq -n --argjson before "$BEFORE_JSON" --arg raw "$AFTER_JSON" --arg did "$DEPLOY_ID" \
|
|
136
|
+
'{status:"blocked",blocking_issue:"Post-deploy re-detect failed",before:$before,after_raw:$raw,deploy_id:(if $did == "" then null else $did end)}'
|
|
137
|
+
exit 1
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
AFTER_ALL=$(echo "$AFTER_JSON" | jq -r '.all_enabled')
|
|
141
|
+
|
|
142
|
+
if [ "$AFTER_ALL" != "true" ]; then
|
|
143
|
+
jq -n --argjson before "$BEFORE_JSON" --argjson after "$AFTER_JSON" --arg did "$DEPLOY_ID" \
|
|
144
|
+
'{
|
|
145
|
+
status:"blocked",
|
|
146
|
+
blocking_issue:"Deploy reported success but post-verify shows not all OmniChannelSettings toggles are enabled.",
|
|
147
|
+
before:$before,
|
|
148
|
+
after:$after,
|
|
149
|
+
safe_to_write:true,
|
|
150
|
+
deploy_id:(if $did == "" then null else $did end)
|
|
151
|
+
}'
|
|
152
|
+
exit 1
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
jq -n --argjson before "$BEFORE_JSON" --argjson after "$AFTER_JSON" --arg did "$DEPLOY_ID" \
|
|
156
|
+
'{
|
|
157
|
+
status:"configured",
|
|
158
|
+
all_enabled:true,
|
|
159
|
+
before:$before,
|
|
160
|
+
after:$after,
|
|
161
|
+
safe_to_write:true,
|
|
162
|
+
deploy_id:(if $did == "" then null else $did end),
|
|
163
|
+
manual_actions:[{id:"login_behavior",title:"Omni-Channel login behavior (UI-only)",detail:"The Omni-Channel utility auto-open-on-login behavior is a UI-only setting not exposed via the Metadata API. Set it manually if desired: Setup → Omni-Channel → Omni-Channel Settings."}]
|
|
164
|
+
}'
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# detect-existing.sh - read-only probe of OmniChannelSettings (five toggle values + all_enabled); deterministic, no side effects. Args, output, 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 detect-existing.sh <org-alias>"}' >&2
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
ORG="$1"
|
|
12
|
+
|
|
13
|
+
# Verify org is authenticated (fail fast, do not retrieve if org auth is broken)
|
|
14
|
+
if ! sf org display --target-org "$ORG" --json >/dev/null 2>&1; then
|
|
15
|
+
echo "{\"error\":\"Org alias '$ORG' is not authenticated. Run: sf org login web -a $ORG -r <my-domain-url>\"}" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Retrieve Settings:OmniChannel into a per-invocation temp DX project.
|
|
20
|
+
# Metadata retrieve is slow (~1-2 min); this is expected and unavoidable.
|
|
21
|
+
WORK="$(mktemp -d)"
|
|
22
|
+
trap 'rm -rf "$WORK"' EXIT
|
|
23
|
+
|
|
24
|
+
cat > "$WORK/sfdx-project.json" <<'EOF'
|
|
25
|
+
{"packageDirectories":[{"path":"force-app","default":true}],"sourceApiVersion":"66.0"}
|
|
26
|
+
EOF
|
|
27
|
+
mkdir -p "$WORK/force-app/main/default"
|
|
28
|
+
|
|
29
|
+
if ! (cd "$WORK" && sf project retrieve start --target-org "$ORG" --metadata "Settings:OmniChannel" --json >/dev/null 2>&1); then
|
|
30
|
+
echo "{\"error\":\"Metadata retrieve failed for Settings:OmniChannel on org '$ORG'. This is often transient (UNKNOWN_EXCEPTION) - retry once.\"}" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
SETTINGS_RELATIVE_PATH="force-app/main/default/settings/OmniChannel.settings-meta.xml"
|
|
35
|
+
XML="$WORK/$SETTINGS_RELATIVE_PATH"
|
|
36
|
+
if [ ! -f "$XML" ]; then
|
|
37
|
+
echo "{\"error\":\"Retrieve succeeded but expected file not found: $SETTINGS_RELATIVE_PATH. Org may not have Omni-Channel provisioned.\"}" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Parse each toggle from the retrieved XML; a missing element means absent (treat as false).
|
|
42
|
+
parse_toggle() {
|
|
43
|
+
local name="$1"
|
|
44
|
+
local val
|
|
45
|
+
val=$(grep -oE "<${name}>(true|false)</${name}>" "$XML" | head -1 | sed -E "s|</?${name}>||g" || true)
|
|
46
|
+
if [ "$val" = "true" ]; then echo true; else echo false; fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
T1=$(parse_toggle enableOmniAutoLoginPrompt)
|
|
50
|
+
T2=$(parse_toggle enableOmniChannel)
|
|
51
|
+
T3=$(parse_toggle enableOmniSecondaryRoutingPriority)
|
|
52
|
+
T4=$(parse_toggle enableOmniSkillsRouting)
|
|
53
|
+
T5=$(parse_toggle enableOmniStatusCapModel)
|
|
54
|
+
|
|
55
|
+
ALL=false
|
|
56
|
+
if [ "$T1" = "true" ] && [ "$T2" = "true" ] && [ "$T3" = "true" ] && [ "$T4" = "true" ] && [ "$T5" = "true" ]; then
|
|
57
|
+
ALL=true
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
cat <<EOF
|
|
61
|
+
{
|
|
62
|
+
"enableOmniAutoLoginPrompt": $T1,
|
|
63
|
+
"enableOmniChannel": $T2,
|
|
64
|
+
"enableOmniSecondaryRoutingPriority": $T3,
|
|
65
|
+
"enableOmniSkillsRouting": $T4,
|
|
66
|
+
"enableOmniStatusCapModel": $T5,
|
|
67
|
+
"all_enabled": $ALL
|
|
68
|
+
}
|
|
69
|
+
EOF
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: service-omni-channel-setup-coordinate
|
|
3
|
+
description: "Use to stand up Omni-Channel setup headlessly on Salesforce: base settings, agent users, service channels, routing configs, queues (create and align) and members, presence statuses, permission assignments, the classic Omni Supervisor config plus its action/tab surface, and — for Case and VoiceCall — the record-triggered routing flow. Supports Case, Incident, MessagingSession, and VoiceCall targets; reuses existing records and creates what is missing. Opt-in extras: presence user config, Omni sidebar, skills-based routing, and field-based WorkSkillRouting; also reports (read-only) whether the org is on the classic supervisor surface or Command Center V2. Triggers: set up Omni-Channel, configure Omni routing, provision Omni agents or supervisors, configure Case/Incident/Messaging/Voice routing. Do not use for Agentforce agents or bots, a single existing Omni field change, bare metadata deployment (use platform-metadata-deploy), or to enable Command Center V2 (not writable via the Metadata API)."
|
|
4
|
+
allowed-tools: Bash Read Write Edit Glob Grep AskUserQuestion TodoWrite
|
|
5
|
+
metadata:
|
|
6
|
+
version: "1.0"
|
|
7
|
+
domains: ["Service"]
|
|
8
|
+
minApiVersion: "66.0"
|
|
9
|
+
relatedSkills:
|
|
10
|
+
- "platform-metadata-deploy"
|
|
11
|
+
- "service-agentforce-human-escalation-configure"
|
|
12
|
+
- "service-omni-agent-users-create"
|
|
13
|
+
- "service-omni-base-settings-configure"
|
|
14
|
+
- "service-omni-command-center-analyze"
|
|
15
|
+
- "service-omni-permission-set-assign"
|
|
16
|
+
- "service-omni-presence-status-deploy"
|
|
17
|
+
- "service-omni-presence-user-config-deploy"
|
|
18
|
+
- "service-omni-queue-deploy"
|
|
19
|
+
- "service-omni-queue-members-assign"
|
|
20
|
+
- "service-omni-queue-routing-config-deploy"
|
|
21
|
+
- "service-omni-routing-flow-deploy"
|
|
22
|
+
- "service-omni-service-channel-configure"
|
|
23
|
+
- "service-omni-sidebar-configure"
|
|
24
|
+
- "service-omni-skills-based-routing-configure"
|
|
25
|
+
- "service-omni-supervisor-config-deploy"
|
|
26
|
+
- "service-omni-supervisor-permset-assign"
|
|
27
|
+
- "service-omni-supervisor-surface-deploy"
|
|
28
|
+
- "service-omni-supervisor-users-create"
|
|
29
|
+
- "service-omni-work-skill-routing-configure"
|
|
30
|
+
accessCheck:
|
|
31
|
+
- type: license
|
|
32
|
+
value: ServiceCloud
|
|
33
|
+
cliTools:
|
|
34
|
+
- tool: ["jq"]
|
|
35
|
+
semver: ">=1.6"
|
|
36
|
+
- tool: ["python3"]
|
|
37
|
+
semver: ">=3.8"
|
|
38
|
+
- tool: ["sf"]
|
|
39
|
+
semver: ">=2.139.6"
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
# service-omni-channel-setup-coordinate
|
|
43
|
+
|
|
44
|
+
Align an org toward a working Omni-Channel setup: detect what already exists and create or deploy only the missing pieces, up to a routed environment with agents, queues, presence statuses, and permissions. Full create-and-bind routing (queue + `QueueRoutingConfig` + outbound routing flow) is provided for `Case` and `VoiceCall`; `Incident` and `MessagingSession` are **verified/adopted only** by this coordinator — it reports their state and reuses existing config but does not create a missing queue/QRC/flow for them (use `service-agentforce-human-escalation-configure` for a created-and-bound `MessagingSession` handoff). This is a coordinator — it sequences the child leaf skills against a canonical set of steps and performs no writes of its own. Each leaf owns one primitive; the coordinator resolves per-org IDs, passes them between leaves, and enforces a shared reuse-vs-create and safety contract. It blocks with a click-path only for prerequisites an operator must action (a missing feature license, or a target sObject that is not enabled).
|
|
45
|
+
|
|
46
|
+
`python3` is listed only because the bundled contract tests (`scripts/tests/test_omni_contracts.py`) use it; running the coordinator itself needs only `jq` and `sf`.
|
|
47
|
+
|
|
48
|
+
## Inputs
|
|
49
|
+
|
|
50
|
+
Confirm these once, up front, before any write:
|
|
51
|
+
|
|
52
|
+
- Agent count (default `3`, range `1..10`) and supervisor count (default `1`, range `1..5`).
|
|
53
|
+
- Real login email (used for password-reset flows).
|
|
54
|
+
- `routing_targets` (default `["Case"]`) — any subset of `Case | Incident | MessagingSession | VoiceCall`. Only `Case` and `VoiceCall` get full create-queue + QRC + routing-flow; `Incident` and `MessagingSession` are verified/adopted (report-only).
|
|
55
|
+
- Service-channel strategy — reuse standard (`Cases`, `sfdc_livemessage`, default) or create a custom channel.
|
|
56
|
+
- Agent/supervisor profile — the driver provisions users on the `Service Cloud User` profile by default (Omni needs a Service Cloud license). Some orgs ship that license under a differently named profile (e.g. `Service Cloud`); override via `OMNI_AGENT_PROFILE` / `OMNI_SUPERVISOR_PROFILE` without editing the script. The user-create leaves block if the named profile is absent.
|
|
57
|
+
- Runtime proof (optional) — `OMNI_RUNTIME_PROOF=1` makes the routing-flow leaf fire the trigger (fail-soft); `OMNI_RUNTIME_PROOF_REQUIRED=1` makes proof blocking. QueueBased proof requires `PendingServiceRouting` or `AgentWork`. SkillsBased proof requires a `PendingServiceRouting` with at least one `SkillRequirement`, which is the acceptance signal that `WorkSkillRouting` actually ran. The throwaway record is always cleaned up.
|
|
58
|
+
- Queue selection (optional) — set `OMNI_CASE_QUEUE_DEVELOPER_NAME`, `OMNI_VOICE_QUEUE_DEVELOPER_NAME`, `OMNI_INCIDENT_QUEUE_DEVELOPER_NAME`, or `OMNI_MESSAGING_QUEUE_DEVELOPER_NAME` when the target must use a specific existing or canonical queue. Without an override, each leaf uses its target-derived default.
|
|
59
|
+
- Routing-config selection (optional) — set `OMNI_CASE_ROUTING_CONFIG_DEVELOPER_NAME` or `OMNI_VOICE_ROUTING_CONFIG_DEVELOPER_NAME` to select an existing QRC explicitly. When only a queue override is supplied, the coordinator first adopts that queue's linked `QueueRoutingConfig.DeveloperName`; it creates the canonical QRC only when the queue has no linked config.
|
|
60
|
+
- Queue routing controls (optional) — `OMNI_QRC_PUSH_TIMEOUT` sets the agent acceptance timeout and `OMNI_QRC_CAPACITY_PERCENTAGE` selects percentage capacity (for example, `100` for a VoiceCall that consumes the agent's full capacity). The coordinator passes both values to every QRC target.
|
|
61
|
+
- Routing mode — `OMNI_ROUTING_TYPE=QueueBased|SkillsBased` is optional. When all four `OMNI_WSR_ENTITY` / `OMNI_WSR_FIELD` / `OMNI_WSR_SKILL` / `OMNI_WSR_VALUE` inputs are supplied, the coordinator infers `SkillsBased`; otherwise it defaults to `QueueBased`. SkillsBased uses `OMNI_SKILL_OPTION=RunSBRRules` (the default), binds the provisioned agents to `OMNI_SBR_SKILL` (defaults to `OMNI_WSR_SKILL`), authors the WorkSkillRouting rule, and only then activates the flow. An incomplete mapping or mismatched SBR/WSR skill is rejected before any write. `OMNI_WSR_LABEL` optionally names the rule.
|
|
62
|
+
- Rep-experience stages (optional, default off) — `OMNI_REP_EXPERIENCE=1` adds presence user config (decline + decline reason + ACW) and the Omni sidebar. `OMNI_CONSOLE_APP=<app DeveloperName>` targets a specific console app; empty auto-detects one.
|
|
63
|
+
- Supervisor surface (always, after the config) — once `OmniSupervisorConfig` exists, the coordinator populates its standard action + tab surface (`OmniSupervisorConfigAction` / `OmniSupervisorConfigTab`) via the Data API. Just before the classic config deploy it also runs a read-only Command Center analysis that reports whether the org is on the classic surface or Command Center V2.
|
|
64
|
+
- Supervisor-config selection (optional) — set `OMNI_SUPERVISOR_CONFIG_DEVELOPER_NAME` to the exact classic `OmniSupervisorConfig.DeveloperName` that both the config and surface stages must reconcile. It defaults to `Omni_Supervisor`; use the override whenever the org has multiple configs so the coordinator never guesses. `OMNI_SUPERVISOR_CONFIG_MASTER_LABEL` optionally supplies the label when creating a new selected config.
|
|
65
|
+
|
|
66
|
+
Run it in plan or run mode:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bash scripts/integration-driver.sh --plan <org-alias> [agent_count] [routing_targets_csv] [supervisor_count]
|
|
70
|
+
bash scripts/integration-driver.sh --run <org-alias> [agent_count] [routing_targets_csv] [supervisor_count]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`--plan` is a full read-only preview: each leaf runs its own detector and reports `reused`, `action_needed`, or `blocked`; a leaf whose prerequisite is not yet in place is reported as pending work rather than probed, so a plan never shows a misleading red for a step that is simply earlier in the sequence. A clean plan (all `reused`, exit 0) means the org is already configured; any yellow (exit 2) means work remains.
|
|
74
|
+
|
|
75
|
+
## Preconditions and safety
|
|
76
|
+
|
|
77
|
+
- Authenticated org via `sf` CLI using the My Domain URL (not `.lightning.force.com`).
|
|
78
|
+
- Service Cloud license with headroom for the agent count.
|
|
79
|
+
- `Incident` targets require the Incident Management feature enabled; `MessagingSession` requires Enhanced Messaging; `VoiceCall` requires Service Cloud Voice. The readiness check hard-fails with a click-path when a requested target sObject is absent.
|
|
80
|
+
- **Production guardrail:** `safe_to_write` is `true` iff any of `IsSandbox = true`, `TrialExpirationDate != null`, or `OrganizationType IN ('Developer Edition', 'Base Edition')`. The run hard-refuses when it is false. CDOs return `IsSandbox=false` with a non-null `TrialExpirationDate` and must be permitted, so `IsSandbox` alone is never the guard.
|
|
81
|
+
|
|
82
|
+
Readiness check (silent, mandatory, before any leaf runs):
|
|
83
|
+
|
|
84
|
+
1. `sf org display` → confirm the org alias is authenticated; refuse (exit 1) if not.
|
|
85
|
+
2. `Organization` (`IsSandbox`, `TrialExpirationDate`, `OrganizationType`) → compute `safe_to_write`; refuse (exit 1) if false.
|
|
86
|
+
3. Preflight entity availability → for each **non-`Case`** routing target, confirm the sObject exists via `EntityDefinition`; a missing target hard-fails with a feature-enablement click-path (exit 2). `Case` is assumed present and skipped.
|
|
87
|
+
|
|
88
|
+
Omni-Channel base-settings enablement is not a separate upfront probe — it is detected by the base-settings leaf (step 1), and downstream Omni-dependent leaves are deferred as pending in `--plan` until it is on. The driver does not pre-check `UserLicense` headroom or `ServicePresenceStatus`/`QueueRoutingConfig` availability in this readiness pass.
|
|
89
|
+
|
|
90
|
+
## Skills this coordinates
|
|
91
|
+
|
|
92
|
+
The coordinator delegates every write to a leaf skill. sObject-specific leaves (3, 5, 6, 6c, 7) loop once per routing target; the rest run once. For SkillsBased routing, steps 6a and 6b complete before any trigger flow is activated. Step 10a (`command-center-analyze`) is a read-only advisory and always runs. Step 11a (`supervisor-surface-deploy`) always runs after the supervisor config succeeds. Leaves 12–13 are the opt-in rep-experience stages (`OMNI_REP_EXPERIENCE=1`).
|
|
93
|
+
|
|
94
|
+
| # | Child skill | Role |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| 1 | `service-omni-base-settings-configure` | Deploy `Settings:OmniChannel` (5 toggles) |
|
|
97
|
+
| 2 | `service-omni-agent-users-create` | Provision the requested agent users |
|
|
98
|
+
| 3 | `service-omni-service-channel-configure` | Reuse the standard `ServiceChannel` for the target sObject, or deploy the canonical XML |
|
|
99
|
+
| 4 | `service-omni-queue-routing-config-deploy` | Upsert the target's `QueueRoutingConfig` (e.g. `Case_Routing_Config`, `Voice_Routing_Config`) |
|
|
100
|
+
| 5 | `service-omni-queue-deploy` | Discover or create (`--create-if-missing`) a `Queue` bound to the target sObject; align it to the QRC |
|
|
101
|
+
| 6 | `service-omni-queue-members-assign` | Assign users to the discovered queue |
|
|
102
|
+
| 6a | `service-omni-skills-based-routing-configure` | *(SkillsBased only)* Ensure the `Skill` and active agents' `SkillUser` bindings exist |
|
|
103
|
+
| 6b | `service-omni-work-skill-routing-configure` | *(SkillsBased only)* Author the required field-value → Skill rule before flow activation |
|
|
104
|
+
| 6c | `service-omni-routing-flow-deploy` | Deploy the record-triggered QueueBased or SkillsBased `Flow` for `Case`/`VoiceCall`; SkillsBased passes `skillOption=RunSBRRules` |
|
|
105
|
+
| 7 | `service-omni-presence-status-deploy` | Deploy `Available_<sObject>` bound to the matching channel and ensure a universal `Busy` status |
|
|
106
|
+
| 8 | `service-omni-permission-set-assign` | Assign the `Omni_Agent` PermissionSet to agent users; self-heals the bundled metadata when absent (run mode only) |
|
|
107
|
+
| 9 | `service-omni-supervisor-users-create` | Provision supervisor users |
|
|
108
|
+
| 10 | `service-omni-supervisor-permset-assign` | Assign the standard `ContactCenterSupervisor` PermissionSet to supervisor users |
|
|
109
|
+
| 10a | `service-omni-command-center-analyze` | **Read-only advisory** — report whether the org is on the classic supervisor surface or Command Center V2; never writes, never hard-blocks |
|
|
110
|
+
| 11 | `service-omni-supervisor-config-deploy` | Deploy `OmniSupervisorConfig` binding supervisor users to the queues discovered in step 5 |
|
|
111
|
+
| 11a | `service-omni-supervisor-surface-deploy` | Populate the supervisor **action + tab surface** (`OmniSupervisorConfigAction` / `OmniSupervisorConfigTab`) on the config from step 11 |
|
|
112
|
+
| 12 | `service-omni-presence-user-config-deploy` | *(opt-in)* Deploy `PresenceUserConfig` + `PresenceDeclineReason` (decline + ACW) and assign the provisioned agents |
|
|
113
|
+
| 13 | `service-omni-sidebar-configure` | *(opt-in)* Set `CustomApplication.isOmniPinnedViewEnabled=true` to pin the Omni utility region on a console app |
|
|
114
|
+
| — | `platform-metadata-deploy` | Underlying Metadata API deploys used by the deploy leaves |
|
|
115
|
+
|
|
116
|
+
## Behavior
|
|
117
|
+
|
|
118
|
+
**Reuse-vs-create contract (enforced for every entity).** Query by `DeveloperName` (or the natural key); reuse a standard record when present (`Cases`, `sfdc_livemessage`); create from the leaf's bundled definition when nothing exists; reconcile idempotently when a same-named custom record exists — never duplicate, rename, or mutate the identity of a standard or managed record.
|
|
119
|
+
|
|
120
|
+
**Ordering and gating.** Leaves run in dependency order. Base settings are a hard prerequisite for every write below. For SkillsBased routing, agent `SkillUser` bindings (6a) and the `WorkSkillRouting` rule (6b) must succeed before the routing-flow leaf (6c) can activate the trigger. The flow also requires the queue (5) and its members (6), and it round-trips `FlowDefinitionView.ActiveVersionId` to prove the flow is Active. A required runtime proof does not pass merely because a PSR exists: SkillsBased requires at least one `SkillRequirement` on that PSR.
|
|
121
|
+
|
|
122
|
+
**Supervisor path.** Supervisor users (9) use the same Anonymous Apex `System.setPassword` model as agent users. Because a password literal can be captured in an `ApexLog` when a debug TraceFlag is active, both user-create leaves fail closed *before* the first `System.setPassword`: they prove via a SOQL-filtered Tooling API query (`ExpirationDate > now`) that no active TraceFlag exists for the running user, and if that cannot be positively proven they set no password at all (users left ACTIVE and `reset_required`, with a `security_warning`). They never delete logs, so unrelated audit logs are untouched. The supervisor permset leaf (10) assigns the standard `ContactCenterSupervisor` — never the custom `Omni_Supervisor`, whose license-gated permissions fail assignment — and a contract test asserts this wiring. After the supervisor permset, a read-only Command Center analysis (10a) reports the org's supervisor surface (classic vs Command Center V2); it never writes and never hard-blocks (ambiguous detection is yellow, a clean read green). Once the config lands (11), the surface leaf (11a) inserts the standard action + tab companions (`OmniSupervisorConfigAction` / `OmniSupervisorConfigTab`) against the config's Id — plain Data API rows, so no metadata-file redeploy — and is idempotent (only missing types are inserted). It runs only after the config succeeds; a skipped or failed config skips the surface with a dependency note.
|
|
123
|
+
|
|
124
|
+
**Optional rep-experience stages.** With `OMNI_REP_EXPERIENCE=1`, presence user config (12) deploys a validator-safe `PresenceUserConfig` with its decline reason and assigns every resolved agent username, including reused users. Sidebar (13) pins the Omni utility region on `OMNI_CONSOLE_APP`, or auto-detects a single console app. SkillsBased routing is not a cosmetic rep-experience stage: when requested, its SkillUser and WorkSkillRouting prerequisites run before flow activation.
|
|
125
|
+
|
|
126
|
+
**Login-behavior gap.** The login-behavior radio (Setup → Omni-Channel Settings → "Define login behavior when an agent opens a new window/tab") has no public API on v66. After base settings deploy, the coordinator surfaces the exact click-path; it does not attempt to flip it via `enableOmniAutoLoginPrompt`, which deploys but does not drive the radio. See `references/gap-catalog.md`.
|
|
127
|
+
|
|
128
|
+
**Credentials.** Generated passwords are moved into a single restricted `CREDENTIALS.json` (mode 0600) and redacted from every other artifact. The write is atomic and fail-closed: on any redaction or verification failure the plaintext artifact is removed and the run aborts, so no plaintext password is left in the artifacts directory. The operator reads `CREDENTIALS.json` once, distributes securely, then deletes it.
|
|
129
|
+
|
|
130
|
+
## Output contract
|
|
131
|
+
|
|
132
|
+
The one deliverable is a single report file. As the final action you MUST use the `Write` tool to save the complete report to `omni-coordinate-report.md` in the current working directory — never deliver it only in chat. In `--run` mode it states what *is* (created resource, reused standard record, resolved decision) — no hedging. In `--plan` mode it states each leaf's honest disposition (`reused` / `action_needed` / pending) plus the coordinator's plan JSON (`dry_run: true`). Each leaf also writes its full JSON outcome (including every created record Id and deploy Id) to a per-skill artifact under the run's artifacts directory — that is the audit trail; user-facing output uses human-readable names, not record Ids. See `examples/output-templates.md` for the report shape.
|
|
133
|
+
|
|
134
|
+
**Run artifacts (run mode).** Alongside the per-skill artifacts, a `--run` writes three files into the run's artifacts directory (paths echoed in the report JSON as `run_log`, `deploy_ids_file`, `teardown_script`): `run.log` (sanitized, human-readable step sequence and result), `deploy_ids.json` (a provenance manifest — each entry's `provenance` is `created` / `updated` / `reused`, with resource ids, a `before` snapshot, and a pointer to the authoritative per-skill artifact), and `teardown.sh` (an auto-generated, **dry-run** reverse-dependency-order plan). The teardown script prints what a teardown would `REMOVE` (run-created), `RESTORE` (updated, with prior values), or `KEEP` (adopted/reused — never deleted) and makes no changes; destructive execution stays manual by design (see Limitations).
|
|
135
|
+
|
|
136
|
+
Report content rules:
|
|
137
|
+
|
|
138
|
+
- Report concrete outcomes, never intentions.
|
|
139
|
+
- Surface the login-behavior click-path whenever setup ran, even if the operator declined to turn the radio.
|
|
140
|
+
- Surface any hard fail from step 5 (no queue bound) as a manual action with a click-path.
|
|
141
|
+
|
|
142
|
+
## Limitations
|
|
143
|
+
|
|
144
|
+
- Routing-flow deploy covers `Case` and `VoiceCall` only.
|
|
145
|
+
- Classic `OmniSupervisorConfig` (including its action + tab surface) only. Command Center V2 (Enhanced Omni-Channel) is reported by the read-only analysis step but not enabled — the org preference is not writable via the Metadata API. The surface leaf populates only the reference-free standard action/tab types; custom-action, FlexiPage, AWS-dashboard, and AI-agent surfaces need an external reference and must be set up in Setup.
|
|
146
|
+
- The rep-experience stages (presence user config, decline reasons, sidebar) run only with `OMNI_REP_EXPERIENCE=1`. SkillsBased routing is selected explicitly or inferred from a complete `OMNI_WSR_*` mapping and runs independently of that flag.
|
|
147
|
+
- Teardown is **plan-only**: `--run` emits `deploy_ids.json` (a provenance manifest) and a dry-run `teardown.sh` that prints the reverse-order removal/restore plan, but does not execute destructive changes. Automated reversal is deliberately deferred until every leaf emits a normalized provenance block and the reversal is validated live — metadata-deployed components need destructiveChanges deploys and adopted records must never be deleted. Reversal today is a manual operator task guided by the plan and the per-skill artifacts.
|
|
148
|
+
|
|
149
|
+
### Use-case coverage (current)
|
|
150
|
+
|
|
151
|
+
| Use case | Status | What is / isn't headless |
|
|
152
|
+
| --- | --- | --- |
|
|
153
|
+
| Case routing | Ready | Full create-and-bind thread (queue + QRC + members + routing flow), idempotent; runtime `PendingServiceRouting` proof optional. |
|
|
154
|
+
| VoiceCall / AFCC routing | Conditional | QRC + queue + members + routing flow are deployable, but require a **provisioned Amazon/AFCC contact center** and a live Voice runtime to prove end-to-end. Contact-center provisioning is the caller's responsibility. |
|
|
155
|
+
| Open CTI → AFCC migration | Partial | The coordinator creates the Omni routing resources; it does not provision or migrate the contact center itself. |
|
|
156
|
+
| Incident routing | Partial | Service channel + presence are supported; the coordinator **verifies/adopts** Incident routing but does not create a missing queue/QRC/flow for it. |
|
|
157
|
+
| Generic MessagingSession routing | Partial | Service channel + presence supported; full create-and-bind is delegated to `service-agentforce-human-escalation-configure`, not run generically here. |
|
|
158
|
+
| Classic Omni Supervisor | Ready | Users, permissions, config, queues/users, and the action/tab surface companions are all implemented. |
|
|
159
|
+
| Command Center V2 | Detection only | The read-only analysis step reports classic vs V2; the org preference `CommandCenterForServiceV2` is **not writable via the Metadata API** (tracked: W-23827287) and must be enabled in Setup. |
|
|
160
|
+
| Supervisor monitoring OrgValues | Not implemented | `OmniSuperConvMonitor`, `OmniSuperAgentSneakpeek`, `OmniSuperClientSneakpeek`, `OmniSuperWhisper`, `OmniSuperAdminSkillQueue` are OrgValues with no proven supported external write API. |
|
|
161
|
+
| Omni Inbox | Not implemented | The sidebar leaf pins the Omni sidebar (`isOmniPinnedViewEnabled`); it does not create or configure Omni Inbox, a console app, or utility items. |
|
|
162
|
+
|
|
163
|
+
## References
|
|
164
|
+
|
|
165
|
+
| File | When to read |
|
|
166
|
+
|---|---|
|
|
167
|
+
| `references/gap-catalog.md` | The headless gaps (login-behavior radio, Agentforce routing target, Field Service skills routing) and how the coordinator handles each |
|
|
168
|
+
| `examples/output-templates.md` | Before emitting the report — canonical Setup Summary, Skill Outcomes, and Manual Actions blocks |
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Report templates
|
|
2
|
+
|
|
3
|
+
Read this reference before emitting the final report. Every coordinator run produces exactly one user-facing artifact: `report.md`. This file defines its structure so every run's report is consistent and easy to read.
|
|
4
|
+
|
|
5
|
+
**Rule:** report concrete outcomes only. No hedges ("will create", "to be resolved", "pending confirmation"), no padding — dense, declarative lines.
|
|
6
|
+
|
|
7
|
+
The coordinator runs a dependency-ordered setup of the child skills (see `SKILL.md` → *Skills this coordinates*). The report is a **Skill Outcomes** table. Each skill's status is one of `Done` (created/updated/deployed/configured/bound/assigned), `Reused`, `Skipped`, `Blocked`, or `Blocked (dependency)` — the last is emitted when a prerequisite skill went red and the dependent skill was intentionally not run.
|
|
8
|
+
|
|
9
|
+
**Credentials never appear in `report.md`.** Generated passwords are written once to a restricted `CREDENTIALS.json` (mode 0600) and redacted from every other artifact. The report points the operator at that file; it never prints a plaintext password.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Template A — Full run (happy path)
|
|
14
|
+
|
|
15
|
+
Use when every skill completed successfully (or was correctly reused/skipped for idempotency).
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
# Omni-Channel Setup Report (via service-omni-channel-setup-coordinate)
|
|
19
|
+
|
|
20
|
+
## Setup Summary
|
|
21
|
+
| Field | Value |
|
|
22
|
+
|---|---|
|
|
23
|
+
| Org | mytestorg (Sandbox) |
|
|
24
|
+
| Agents / Supervisors provisioned | 5 / 1 |
|
|
25
|
+
| Routing targets | Case, MessagingSession |
|
|
26
|
+
| Service Channel strategy | Reused standard: Cases, sfdc_livemessage |
|
|
27
|
+
|
|
28
|
+
## Skill Outcomes
|
|
29
|
+
| # | Skill | Target(s) | Status | Notes |
|
|
30
|
+
|---|---|---|---|---|
|
|
31
|
+
| 1 | base-settings-configure | — | Reused | All 5 OmniChannel toggles already enabled |
|
|
32
|
+
| 2 | agent-users-create | — | Done | 5 agent users created |
|
|
33
|
+
| 3 | service-channel-configure | Case, MessagingSession | Reused | Standard Cases + sfdc_livemessage channels |
|
|
34
|
+
| 4 | queue-routing-config-deploy | Case | Done | Case_Routing_Config upserted (MostAvailable, weight 5) |
|
|
35
|
+
| 5 | queue-deploy | Case, MessagingSession | Done | Case queue aligned to Case_Routing_Config; messaging queue reused |
|
|
36
|
+
| 6 | queue-members-assign | Case, MessagingSession | Done | 5 agents bound to each target queue |
|
|
37
|
+
| 7 | routing-flow-deploy | Case | Done | Case routing flow deployed and active |
|
|
38
|
+
| 8 | presence-status-deploy | Case, MessagingSession | Done | Available_Case + Available_Messaging bound; Busy universal (reused) |
|
|
39
|
+
| 9 | permission-set-assign | — | Done | Omni_Agent assigned to 5 agents |
|
|
40
|
+
| 10 | supervisor-users-create | — | Done | 1 supervisor user created |
|
|
41
|
+
| 11 | supervisor-permset-assign | — | Done | ContactCenterSupervisor assigned to 1 supervisor |
|
|
42
|
+
| 12 | supervisor-config-deploy | — | Done | Omni_SupervisorCfg bound 1 supervisor + 2 discovered queues |
|
|
43
|
+
|
|
44
|
+
## Manual Actions Required
|
|
45
|
+
- **Login-behavior radio** — open Setup → Omni-Channel Settings → "Define login behavior when an agent opens a new window/tab" → select the desired option → Save. The `enableOmniAutoLoginPrompt` boolean deploys but does not drive this radio on v66.
|
|
46
|
+
|
|
47
|
+
## Artifacts
|
|
48
|
+
- `CREDENTIALS.json` (mode 0600) — generated agent + supervisor passwords. Read once, distribute securely, then delete (`rm -f`). Passwords are redacted from all other artifacts.
|
|
49
|
+
- Per-skill JSON artifacts + `.stderr.log` under the run's artifacts directory.
|
|
50
|
+
|
|
51
|
+
## Blocking Issues
|
|
52
|
+
None.
|
|
53
|
+
|
|
54
|
+
## Next Action
|
|
55
|
+
Read `CREDENTIALS.json` for the agent login, then log in, open the Service Console, click the Omni-Channel widget, set status to Online, and create a Case with Priority=Medium to observe routing.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Template B — Partial run (a skill went red; dependents skipped)
|
|
61
|
+
|
|
62
|
+
Use when a prerequisite skill failed and the coordinator correctly skipped its dependents as `Blocked (dependency)`. The overall run is `red`; the report names the single blocker.
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
# Omni-Channel Setup Report (via service-omni-channel-setup-coordinate)
|
|
66
|
+
|
|
67
|
+
## Setup Summary
|
|
68
|
+
| Field | Value |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Org | mytestorg (CDO) |
|
|
71
|
+
| Agents / Supervisors provisioned | 5 / 1 |
|
|
72
|
+
| Routing targets | Case |
|
|
73
|
+
| Service Channel strategy | Reused standard: Cases |
|
|
74
|
+
|
|
75
|
+
## Skill Outcomes
|
|
76
|
+
| # | Skill | Target(s) | Status | Notes |
|
|
77
|
+
|---|---|---|---|---|
|
|
78
|
+
| 1 | base-settings-configure | — | Blocked | Deploy returned SucceededPartial; OmniChannel toggle did not stick |
|
|
79
|
+
| 2 | agent-users-create | — | Done | 5 agent users created |
|
|
80
|
+
| 3 | service-channel-configure | Case | Blocked (dependency) | base-settings did not succeed |
|
|
81
|
+
| 4 | queue-routing-config-deploy | Case | Blocked (dependency) | base-settings did not succeed |
|
|
82
|
+
| 5 | queue-deploy | Case | Blocked (dependency) | base-settings did not succeed |
|
|
83
|
+
| 6 | queue-members-assign | Case | Blocked (dependency) | queue-deploy did not succeed |
|
|
84
|
+
| 7 | routing-flow-deploy | Case | Blocked (dependency) | queue-members did not succeed |
|
|
85
|
+
| 8 | presence-status-deploy | Case | Blocked (dependency) | base-settings did not succeed |
|
|
86
|
+
| 9 | permission-set-assign | — | Done | Omni_Agent assigned to 5 agents |
|
|
87
|
+
| 10 | supervisor-users-create | — | Done | 1 supervisor user created |
|
|
88
|
+
| 11 | supervisor-permset-assign | — | Done | ContactCenterSupervisor assigned to 1 supervisor |
|
|
89
|
+
| 12 | supervisor-config-deploy | — | Blocked (dependency) | base-settings did not succeed |
|
|
90
|
+
|
|
91
|
+
## Manual Actions Required
|
|
92
|
+
- **Login-behavior radio** — (as in Template A)
|
|
93
|
+
|
|
94
|
+
## Artifacts
|
|
95
|
+
- `CREDENTIALS.json` (mode 0600) — generated agent + supervisor passwords. Read once, distribute securely, then delete.
|
|
96
|
+
- Per-skill JSON artifacts + `.stderr.log` under the run's artifacts directory.
|
|
97
|
+
|
|
98
|
+
## Blocking Issues
|
|
99
|
+
base-settings-configure returned SucceededPartial and the OmniChannel toggle did not persist on re-verify — every skill that requires Omni enabled was skipped as a dependency block.
|
|
100
|
+
|
|
101
|
+
## Next Action
|
|
102
|
+
Inspect the base-settings deploy for the org, resolve the partial-deploy failure, then re-invoke the coordinator (idempotent — completed skills are reused).
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Template C — Hard-stop before setup
|
|
108
|
+
|
|
109
|
+
Use when the readiness check failed and no writes were made — e.g. license shortfall, missing entity, production org without acknowledgement.
|
|
110
|
+
|
|
111
|
+
Fill **only** Setup Summary and Blocking Issues. Mark every skill row `Not started`. Point Next Action at the one thing that unblocks the run.
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+
# Omni-Channel Setup Report (via service-omni-channel-setup-coordinate)
|
|
115
|
+
|
|
116
|
+
## Setup Summary
|
|
117
|
+
| Field | Value |
|
|
118
|
+
|---|---|
|
|
119
|
+
| Org | mytestorg (Production) |
|
|
120
|
+
| Agents / Supervisors requested | 5 / 1 |
|
|
121
|
+
| Routing targets | Case |
|
|
122
|
+
|
|
123
|
+
## Skill Outcomes
|
|
124
|
+
| # | Skill | Status |
|
|
125
|
+
|---|---|---|
|
|
126
|
+
| 1–12 | all skills | Not started — blocked at readiness check |
|
|
127
|
+
|
|
128
|
+
## Blocking Issues
|
|
129
|
+
Target org is Production (IsSandbox=false, no TrialExpirationDate, OrganizationType=Enterprise Edition). safe_to_write=false; the coordinator refuses writes against production customer orgs.
|
|
130
|
+
|
|
131
|
+
## Next Action
|
|
132
|
+
Switch to a sandbox, CDO (trial), or Developer Edition alias and re-invoke.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Report-quality checklist
|
|
138
|
+
|
|
139
|
+
Before emitting, mentally verify:
|
|
140
|
+
|
|
141
|
+
- [ ] Header ends with `(via service-omni-channel-setup-coordinate)`
|
|
142
|
+
- [ ] Every skill row's `Status` reflects the tracked state — not a hard-coded default
|
|
143
|
+
- [ ] A dependent skill whose prerequisite went red is shown as `Blocked (dependency)`, never `Done`
|
|
144
|
+
- [ ] The login-behavior click-path is surfaced whenever setup ran (even if the operator declines to turn the radio)
|
|
145
|
+
- [ ] **No plaintext passwords appear in the report** — they live only in `CREDENTIALS.json` (mode 0600); the report points the operator there
|
|
146
|
+
- [ ] **No Salesforce record IDs appear in the user-facing report** — human-readable names only
|
|
147
|
+
- [ ] A production org (`IsSandbox=false`, no `TrialExpirationDate`, non-DE/Base) was refused before setup started
|
|
148
|
+
- [ ] `Blocking Issues` is either `None.` or exactly one blocker (the coordinator should not chain multiple issues)
|
|
149
|
+
- [ ] `Next Action` is exactly one line — the single next step
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Anti-patterns to avoid
|
|
154
|
+
|
|
155
|
+
- AVOID: "Will create Omni_Demo_Cases_Queue" — say `Done` and list what was created, not what you plan to do
|
|
156
|
+
- AVOID: "Attempting to configure supervisor..." — the report emits after the action; describe the outcome, not the attempt
|
|
157
|
+
- AVOID: A plaintext password in `Next Action` or anywhere else in the report — point at `CREDENTIALS.json` instead
|
|
158
|
+
- AVOID: Salesforce record IDs in Skill Outcomes notes — human-readable DeveloperNames only, never `0C5RZ0000001I1J0AU`
|
|
159
|
+
- AVOID: Multi-line Blocking Issues — collapse to one line; if multiple issues, the coordinator should have stopped after the first
|
|
160
|
+
- AVOID: Preamble ("Here is the report you requested...") — jump straight to `# Omni-Channel Setup Report`
|
|
161
|
+
- AVOID: Design-doc padding ("The coordinator orchestrates multiple skills...") — the report is a status log, not a spec
|