@salesforce/afv-skills 1.30.0 → 1.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/agentforce-bot-upgrade/SKILL.md +217 -0
- package/skills/agentforce-bot-upgrade/references/extraction-blueprint.md +242 -0
- package/skills/agentforce-bot-upgrade/references/generate-agent-spec.md +128 -0
- package/skills/agentforce-bot-upgrade/references/handoff-output-format.md +208 -0
- package/skills/agentforce-bot-upgrade/references/input-contract.md +101 -0
- package/skills/agentforce-bot-upgrade/references/mapping-rules.md +113 -0
- package/skills/agentforce-bot-upgrade/references/planner-workflow-reference.md +78 -0
- package/skills/agentforce-bot-upgrade/references/post-conversion-enhancements-reference.md +67 -0
- package/skills/agentforce-bot-upgrade/references/quality-checklist.md +33 -0
- package/skills/agentforce-bot-upgrade/references/sf-cli-bot-reference.md +116 -0
- package/skills/data360-code-extension-generate/SKILL.md +15 -2
- package/skills/dx-devops-work-item-manage/SKILL.md +270 -0
- package/skills/dx-devops-work-item-manage/examples/common-workflows.md +479 -0
- package/skills/dx-devops-work-item-manage/references/cli-commands.md +476 -0
- package/skills/dx-org-manage/SKILL.md +8 -5
- package/skills/dx-org-trial-expiration-check/SKILL.md +239 -0
- package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +588 -0
- package/skills/dx-pkg-post-install-configure/SKILL.md +184 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +202 -35
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-hosting-target.sh +26 -0
- package/skills/experience-ui-bundle-app-coordinate/scripts/check-sfdx-project.sh +15 -0
- package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +29 -5
- package/skills/experience-ui-bundle-custom-app-generate/references/configure-metadata-custom-application.md +1 -1
- package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +30 -0
- package/skills/experience-ui-bundle-features-generate/SKILL.md +86 -11
- package/skills/experience-ui-bundle-features-generate/references/conflict-resolution-schema.json +20 -0
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +14 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +6 -1
- package/skills/experience-ui-bundle-frontend-generate/references/component.md +34 -1
- package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -1
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +19 -8
- package/skills/experience-ui-bundle-metadata-generate/references/csp-metadata-format.md +2 -2
- package/skills/experience-ui-bundle-metadata-generate/scripts/check-api-version.sh +30 -0
- package/skills/experience-ui-bundle-project-generate/SKILL.md +111 -0
- package/skills/experience-ui-bundle-project-generate/scripts/flatten-project.mjs +33 -0
- package/skills/platform-custom-field-generate/SKILL.md +12 -11
- package/skills/platform-custom-field-generate/references/advanced-picklists.md +17 -17
- package/skills/platform-custom-lightning-type-generate/SKILL.md +9 -14
- package/skills/platform-custom-lightning-type-generate/references/widget-rendition.md +27 -111
- package/skills/platform-custom-report-type-generate/SKILL.md +259 -0
- package/skills/platform-custom-report-type-generate/examples/AccountProjectsWithTasks.reportType-meta.xml +51 -0
- package/skills/platform-custom-report-type-generate/examples/AccountsWithIndustry.reportType-meta.xml +27 -0
- package/skills/platform-custom-report-type-generate/examples/AccountsWithProjects.reportType-meta.xml +44 -0
- package/skills/platform-custom-report-type-generate/references/category-values.md +32 -0
- package/skills/platform-custom-report-type-generate/references/errors-and-troubleshooting.md +24 -0
- package/skills/platform-dataspace-access-configure/SKILL.md +318 -0
- package/skills/platform-docs-get/SKILL.md +4 -0
- package/skills/platform-docs-get/scripts/extract_salesforce_doc.py +78 -13
- package/skills/platform-encryption-configure/SKILL.md +122 -0
- package/skills/platform-encryption-configure/assets/EncryptionKey.settings-meta.xml +17 -0
- package/skills/platform-encryption-configure/assets/PlatformEncryption.settings-meta.xml +15 -0
- package/skills/platform-encryption-configure/assets/encrypted-field.field-meta.xml +22 -0
- package/skills/platform-encryption-configure/examples/cache-only-keys.settings-meta.xml +11 -0
- package/skills/platform-encryption-configure/references/encryption-schemes.md +34 -0
- package/skills/platform-encryption-configure/references/key-models.md +34 -0
- package/skills/platform-encryption-configure/references/tenant-secret-lifecycle.md +23 -0
- package/skills/platform-encryption-configure/scripts/validate-encryption-metadata.sh +54 -0
- package/skills/platform-lightning-type-widget-coordinate/SKILL.md +214 -0
- package/skills/platform-lightning-type-widget-coordinate/examples/existing-lightning-type-with-widget-prompt.md +80 -0
- package/skills/platform-lightning-type-widget-coordinate/examples/new-lightning-type-with-widget-prompt.md +75 -0
- package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +67 -0
- package/skills/platform-lightning-type-widget-coordinate/references/lightning-type-discovery.md +124 -0
- package/skills/platform-lightning-type-widget-coordinate/references/validation-gates.md +130 -0
- package/skills/platform-metadata-api-context-get/SKILL.md +13 -10
- package/skills/platform-sharing-owd-configure/SKILL.md +142 -0
- package/skills/platform-sharing-owd-configure/examples/get_owd_output.md +38 -0
- package/skills/platform-sharing-owd-configure/examples/update_owd_output.md +44 -0
- package/skills/platform-sharing-owd-configure/references/access_levels.md +49 -0
- package/skills/platform-sharing-owd-configure/references/metadata_api_approach.md +69 -0
- package/skills/platform-sharing-rules-generate/SKILL.md +89 -19
- package/skills/platform-sharing-rules-generate/examples/test-cases.md +381 -0
- package/skills/platform-widget-generate/SKILL.md +241 -0
- package/skills/platform-widget-generate/examples/conditional.json +73 -0
- package/skills/platform-widget-generate/examples/list-with-foreach.json +66 -0
- package/skills/platform-widget-generate/examples/single-object.json +64 -0
- package/skills/platform-widget-generate/references/schema-from-lightning-type.md +76 -0
- package/skills/platform-widget-generate/references/widget-bundle-layout.md +116 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +130 -0
- package/skills/sales-agentforce-pipeline-management-configure/SKILL.md +268 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/field-completion-template.genAiPromptTemplate-meta.xml +141 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/pipeline_management_flow.flow-meta.xml +548 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.agent +2938 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.bundle-meta.xml +4 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/sfdx-project.json +12 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/bant.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/meddic.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/spiced.txt +11 -0
- package/skills/sales-agentforce-pipeline-management-configure/examples/custom-prompt-instructions.md +317 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/admin-communication.md +355 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/agent-creation.md +383 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/auth-and-cli.md +146 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/automation-matrix.md +23 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/autonomous-updates.md +215 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/canonical-agent-path.md +75 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/data-sources.md +155 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompt-template.md +120 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompts.md +149 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/flags.md +13 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/flow-clone-from-template.md +447 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/metadata-inventory.md +330 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/opportunity-stages.md +246 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/repair-diagnostics.md +265 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/setup-order.md +263 -0
- package/skills/sales-agentforce-pipeline-management-configure/references/soap-api-enablement.md +528 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/CHANGES.md +180 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/README.md +56 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/add-field-suggestion.sh +679 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/create-agent.sh +302 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/create-flow.sh +250 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/define-agent-access.sh +430 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/deploy-settings.sh +77 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-deal-agent.sh +241 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-prerequisites.sh +538 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/flow-debug-and-verify.sh +385 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/retrieve-settings.sh +131 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/setup-all.sh +2791 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-bundle-publish.sh +189 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-detection.sh +239 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/flow-builder.sh +238 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/psg.sh +48 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/soap.sh +140 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/stage-descriptions.sh +448 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/test-opp.sh +166 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-all.sh +636 -0
- package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-prompt-generation.sh +346 -0
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Comprehensive verification of Pipeline Management configuration
|
|
4
|
+
#
|
|
5
|
+
# Checks all components and reports status. Run after setup to confirm
|
|
6
|
+
# everything is working, or to diagnose a partially configured org.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./verify-all.sh <org-alias>
|
|
9
|
+
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
# sf CLI can emit ANSI color codes inside --json stdout, breaking jq parsing.
|
|
13
|
+
# 2>/dev/null only strips stderr; these env vars are the reliable fix (see PM notes).
|
|
14
|
+
export NO_COLOR=1
|
|
15
|
+
export FORCE_COLOR=0
|
|
16
|
+
|
|
17
|
+
# Source shared libraries
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
19
|
+
source "$SCRIPT_DIR/shared/soap.sh"
|
|
20
|
+
source "$SCRIPT_DIR/shared/agent-detection.sh"
|
|
21
|
+
|
|
22
|
+
ORG_ALIAS="${1:-}"
|
|
23
|
+
|
|
24
|
+
if [[ -z "$ORG_ALIAS" ]]; then
|
|
25
|
+
echo "Error: Missing org alias"
|
|
26
|
+
echo "Usage: $0 <org-alias>"
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Validate org alias (prevent shell injection via metacharacters)
|
|
31
|
+
if [[ ! "$ORG_ALIAS" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
|
|
32
|
+
echo "ERROR: Invalid org alias. Only alphanumeric, dots, hyphens, and underscores allowed (must start with alphanumeric)."
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
echo "============================================"
|
|
37
|
+
echo " PIPELINE MANAGEMENT CONFIGURATION STATUS"
|
|
38
|
+
echo "============================================"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "Org: $ORG_ALIAS"
|
|
41
|
+
echo "Date: $(date '+%Y-%m-%d %H:%M:%S')"
|
|
42
|
+
echo ""
|
|
43
|
+
|
|
44
|
+
PASS=0
|
|
45
|
+
WARN=0
|
|
46
|
+
FAIL=0
|
|
47
|
+
|
|
48
|
+
check_pass() { echo " [PASS] $1"; PASS=$((PASS + 1)); }
|
|
49
|
+
check_warn() { echo " [WARN] $1"; WARN=$((WARN + 1)); }
|
|
50
|
+
check_fail() { echo " [FAIL] $1"; FAIL=$((FAIL + 1)); }
|
|
51
|
+
check_error() { echo " [ERROR] $1"; echo " $2"; FAIL=$((FAIL + 1)); }
|
|
52
|
+
|
|
53
|
+
# --- Prerequisites ---
|
|
54
|
+
echo "--- Prerequisites ---"
|
|
55
|
+
|
|
56
|
+
# Get auth details for SOAP checks
|
|
57
|
+
INSTANCE_URL=$(sf org display --target-org "$ORG_ALIAS" --json 2>/dev/null | jq -r '.result.instanceUrl // empty' 2>/dev/null || echo "")
|
|
58
|
+
|
|
59
|
+
# Get access token — newer CLI versions redact it in `sf org display --json`
|
|
60
|
+
# so we use `sf org auth show-access-token --json` which always returns the real token
|
|
61
|
+
ACCESS_TOKEN=$(sf org display --target-org "$ORG_ALIAS" --json 2>/dev/null | jq -r '.result.accessToken // empty' 2>/dev/null || echo "")
|
|
62
|
+
|
|
63
|
+
if [[ -z "$ACCESS_TOKEN" || "$ACCESS_TOKEN" == "null" || "$ACCESS_TOKEN" == *"REDACTED"* ]]; then
|
|
64
|
+
ACCESS_TOKEN=$(echo "y" | sf org auth show-access-token --target-org "$ORG_ALIAS" --no-prompt --json 2>/dev/null | jq -r '.result.accessToken // empty' 2>/dev/null || echo "")
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
if [[ -z "$ACCESS_TOKEN" || "$ACCESS_TOKEN" == "null" ]]; then
|
|
68
|
+
echo " [FAIL] Cannot retrieve access token. Is the org authenticated?"
|
|
69
|
+
echo " Run: sf org login web --instance-url <url> --alias $ORG_ALIAS"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
# Check Pipeline Management (SOAP only)
|
|
74
|
+
PM_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
75
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
76
|
+
-H "SOAPAction: readMetadata" \
|
|
77
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
78
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
79
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
80
|
+
<soapenv:Body><met:readMetadata>
|
|
81
|
+
<met:type>SalesDealAgentSettings</met:type>
|
|
82
|
+
<met:fullNames>SalesDealAgent</met:fullNames>
|
|
83
|
+
</met:readMetadata></soapenv:Body>
|
|
84
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
85
|
+
PM_HTTP_STATUS=$(echo "$PM_RESPONSE" | tail -1)
|
|
86
|
+
PM_XML=$(echo "$PM_RESPONSE" | sed '$d')
|
|
87
|
+
PM_STATUS=$(parse_soap_response "$PM_XML" "enableDealAgent" "$PM_HTTP_STATUS")
|
|
88
|
+
|
|
89
|
+
case "$PM_STATUS" in
|
|
90
|
+
true)
|
|
91
|
+
check_pass "Pipeline Management: enabled"
|
|
92
|
+
;;
|
|
93
|
+
false)
|
|
94
|
+
check_fail "Pipeline Management: DISABLED"
|
|
95
|
+
echo " → Enable via: Setup → Sales → Pipeline Management → Turn On"
|
|
96
|
+
;;
|
|
97
|
+
AUTH_ERROR:*)
|
|
98
|
+
check_error "Pipeline Management: Authentication failed" "${PM_STATUS#AUTH_ERROR:}"
|
|
99
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
100
|
+
;;
|
|
101
|
+
TYPE_UNAVAILABLE:*)
|
|
102
|
+
check_error "Pipeline Management: Not available in this org" "${PM_STATUS#TYPE_UNAVAILABLE:}"
|
|
103
|
+
echo " → Check: org edition and enabled features in Setup"
|
|
104
|
+
;;
|
|
105
|
+
NETWORK_ERROR)
|
|
106
|
+
check_error "Pipeline Management: Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
107
|
+
;;
|
|
108
|
+
*)
|
|
109
|
+
check_fail "Pipeline Management: Unknown status ($PM_STATUS)"
|
|
110
|
+
;;
|
|
111
|
+
esac
|
|
112
|
+
|
|
113
|
+
# Check Einstein GenAI
|
|
114
|
+
GENAI_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
115
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
116
|
+
-H "SOAPAction: readMetadata" \
|
|
117
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
118
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
119
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
120
|
+
<soapenv:Body><met:readMetadata>
|
|
121
|
+
<met:type>EinsteinGptSettings</met:type>
|
|
122
|
+
<met:fullNames>EinsteinGpt</met:fullNames>
|
|
123
|
+
</met:readMetadata></soapenv:Body>
|
|
124
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
125
|
+
GENAI_HTTP_STATUS=$(echo "$GENAI_RESPONSE" | tail -1)
|
|
126
|
+
GENAI_XML=$(echo "$GENAI_RESPONSE" | sed '$d')
|
|
127
|
+
GENAI_STATUS=$(parse_soap_response "$GENAI_XML" "enableEinsteinGptPlatform" "$GENAI_HTTP_STATUS")
|
|
128
|
+
|
|
129
|
+
case "$GENAI_STATUS" in
|
|
130
|
+
true)
|
|
131
|
+
check_pass "Einstein Generative AI: enabled"
|
|
132
|
+
;;
|
|
133
|
+
false)
|
|
134
|
+
check_fail "Einstein Generative AI: DISABLED"
|
|
135
|
+
echo " → Enable via: Setup → Einstein → Einstein Generative AI → Turn On"
|
|
136
|
+
;;
|
|
137
|
+
AUTH_ERROR:*)
|
|
138
|
+
check_error "Einstein Generative AI: Authentication failed" "${GENAI_STATUS#AUTH_ERROR:}"
|
|
139
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
140
|
+
;;
|
|
141
|
+
NETWORK_ERROR)
|
|
142
|
+
check_error "Einstein Generative AI: Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
143
|
+
;;
|
|
144
|
+
*)
|
|
145
|
+
check_fail "Einstein Generative AI: Unknown status ($GENAI_STATUS)"
|
|
146
|
+
;;
|
|
147
|
+
esac
|
|
148
|
+
|
|
149
|
+
# Check Agentforce Agent
|
|
150
|
+
COPILOT_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
151
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
152
|
+
-H "SOAPAction: readMetadata" \
|
|
153
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
154
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
155
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
156
|
+
<soapenv:Body><met:readMetadata>
|
|
157
|
+
<met:type>EinsteinCopilotSettings</met:type>
|
|
158
|
+
<met:fullNames>EinsteinCopilot</met:fullNames>
|
|
159
|
+
</met:readMetadata></soapenv:Body>
|
|
160
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
161
|
+
COPILOT_HTTP_STATUS=$(echo "$COPILOT_RESPONSE" | tail -1)
|
|
162
|
+
COPILOT_XML=$(echo "$COPILOT_RESPONSE" | sed '$d')
|
|
163
|
+
COPILOT_STATUS=$(parse_soap_response "$COPILOT_XML" "enableEinsteinGptCopilot" "$COPILOT_HTTP_STATUS")
|
|
164
|
+
|
|
165
|
+
case "$COPILOT_STATUS" in
|
|
166
|
+
true)
|
|
167
|
+
check_pass "Agentforce Agent: enabled"
|
|
168
|
+
;;
|
|
169
|
+
false)
|
|
170
|
+
check_fail "Agentforce Agent: DISABLED"
|
|
171
|
+
echo " → Enable via: Setup → Einstein → Agentforce Agent → Turn On"
|
|
172
|
+
;;
|
|
173
|
+
AUTH_ERROR:*)
|
|
174
|
+
check_error "Agentforce Agent: Authentication failed" "${COPILOT_STATUS#AUTH_ERROR:}"
|
|
175
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
176
|
+
;;
|
|
177
|
+
NETWORK_ERROR)
|
|
178
|
+
check_error "Agentforce Agent: Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
179
|
+
;;
|
|
180
|
+
*)
|
|
181
|
+
check_fail "Agentforce Agent: Unknown status ($COPILOT_STATUS)"
|
|
182
|
+
;;
|
|
183
|
+
esac
|
|
184
|
+
|
|
185
|
+
# Check Agentforce Studio / Agent Platform (CRITICAL — AgentPlatformSettings
|
|
186
|
+
# .enableAgentPlatform gates the Sales Deal Agent; core rejects Deal Agent
|
|
187
|
+
# enablement when this OrgPreference is off, so a disabled state here explains
|
|
188
|
+
# an otherwise-opaque Deal Agent activation failure).
|
|
189
|
+
AGENT_PLATFORM_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
190
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
191
|
+
-H "SOAPAction: readMetadata" \
|
|
192
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
193
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
194
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
195
|
+
<soapenv:Body><met:readMetadata>
|
|
196
|
+
<met:type>AgentPlatformSettings</met:type>
|
|
197
|
+
<met:fullNames>AgentPlatform</met:fullNames>
|
|
198
|
+
</met:readMetadata></soapenv:Body>
|
|
199
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
200
|
+
AGENT_PLATFORM_HTTP_STATUS=$(echo "$AGENT_PLATFORM_RESPONSE" | tail -1)
|
|
201
|
+
AGENT_PLATFORM_XML=$(echo "$AGENT_PLATFORM_RESPONSE" | sed '$d')
|
|
202
|
+
AGENT_PLATFORM_STATUS=$(parse_soap_response "$AGENT_PLATFORM_XML" "enableAgentPlatform" "$AGENT_PLATFORM_HTTP_STATUS")
|
|
203
|
+
|
|
204
|
+
case "$AGENT_PLATFORM_STATUS" in
|
|
205
|
+
true)
|
|
206
|
+
check_pass "Agentforce Studio (Agent Platform): enabled"
|
|
207
|
+
;;
|
|
208
|
+
false)
|
|
209
|
+
check_fail "Agentforce Studio (Agent Platform): DISABLED"
|
|
210
|
+
echo " → Enable via: Setup → Agentforce Studio → Turn On (gates Deal Agent)"
|
|
211
|
+
;;
|
|
212
|
+
AUTH_ERROR:*)
|
|
213
|
+
check_error "Agentforce Studio (Agent Platform): Authentication failed" "${AGENT_PLATFORM_STATUS#AUTH_ERROR:}"
|
|
214
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
215
|
+
;;
|
|
216
|
+
NETWORK_ERROR)
|
|
217
|
+
check_error "Agentforce Studio (Agent Platform): Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
218
|
+
;;
|
|
219
|
+
*)
|
|
220
|
+
check_fail "Agentforce Studio (Agent Platform): Unknown status ($AGENT_PLATFORM_STATUS)"
|
|
221
|
+
;;
|
|
222
|
+
esac
|
|
223
|
+
|
|
224
|
+
# Check Opportunity Team (CRITICAL — PM flow uses OpportunityTeamMember; without
|
|
225
|
+
# it, flow deployment fails with an OppTeamMemRec error)
|
|
226
|
+
OPP_TEAM_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
227
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
228
|
+
-H "SOAPAction: readMetadata" \
|
|
229
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
230
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
231
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
232
|
+
<soapenv:Body><met:readMetadata>
|
|
233
|
+
<met:type>OpportunitySettings</met:type>
|
|
234
|
+
<met:fullNames>Opportunity</met:fullNames>
|
|
235
|
+
</met:readMetadata></soapenv:Body>
|
|
236
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
237
|
+
OPP_TEAM_HTTP_STATUS=$(echo "$OPP_TEAM_RESPONSE" | tail -1)
|
|
238
|
+
OPP_TEAM_XML=$(echo "$OPP_TEAM_RESPONSE" | sed '$d')
|
|
239
|
+
OPP_TEAM_STATUS=$(parse_soap_response "$OPP_TEAM_XML" "enableOpportunityTeam" "$OPP_TEAM_HTTP_STATUS")
|
|
240
|
+
|
|
241
|
+
case "$OPP_TEAM_STATUS" in
|
|
242
|
+
true)
|
|
243
|
+
check_pass "Opportunity Team: enabled"
|
|
244
|
+
;;
|
|
245
|
+
false)
|
|
246
|
+
check_fail "Opportunity Team: DISABLED (flow deploy fails with OppTeamMemRec error)"
|
|
247
|
+
echo " → Enable via: Setup → Opportunity → Opportunity Team Settings → Turn On"
|
|
248
|
+
;;
|
|
249
|
+
AUTH_ERROR:*)
|
|
250
|
+
check_error "Opportunity Team: Authentication failed" "${OPP_TEAM_STATUS#AUTH_ERROR:}"
|
|
251
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
252
|
+
;;
|
|
253
|
+
NETWORK_ERROR)
|
|
254
|
+
check_error "Opportunity Team: Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
255
|
+
;;
|
|
256
|
+
*)
|
|
257
|
+
check_fail "Opportunity Team: Unknown status ($OPP_TEAM_STATUS)"
|
|
258
|
+
;;
|
|
259
|
+
esac
|
|
260
|
+
|
|
261
|
+
# Check Pipeline Inspection
|
|
262
|
+
PI_RESPONSE=$(curl -s -w "\n%{http_code}" "${INSTANCE_URL}/services/Soap/m/64.0" \
|
|
263
|
+
-H "Content-Type: text/xml; charset=UTF-8" \
|
|
264
|
+
-H "SOAPAction: readMetadata" \
|
|
265
|
+
-d "<?xml version='1.0' encoding='utf-8'?>
|
|
266
|
+
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
|
|
267
|
+
<soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
|
|
268
|
+
<soapenv:Body><met:readMetadata>
|
|
269
|
+
<met:type>OpportunitySettings</met:type>
|
|
270
|
+
<met:fullNames>Opportunity</met:fullNames>
|
|
271
|
+
</met:readMetadata></soapenv:Body>
|
|
272
|
+
</soapenv:Envelope>" 2>/dev/null)
|
|
273
|
+
PI_HTTP_STATUS=$(echo "$PI_RESPONSE" | tail -1)
|
|
274
|
+
PI_XML=$(echo "$PI_RESPONSE" | sed '$d')
|
|
275
|
+
PI_STATUS=$(parse_soap_response "$PI_XML" "enablePipelineInspection" "$PI_HTTP_STATUS")
|
|
276
|
+
|
|
277
|
+
case "$PI_STATUS" in
|
|
278
|
+
true)
|
|
279
|
+
check_pass "Pipeline Inspection: enabled"
|
|
280
|
+
;;
|
|
281
|
+
false)
|
|
282
|
+
check_warn "Pipeline Inspection: DISABLED (suggestions won't show in UI)"
|
|
283
|
+
;;
|
|
284
|
+
AUTH_ERROR:*)
|
|
285
|
+
check_error "Pipeline Inspection: Authentication failed" "${PI_STATUS#AUTH_ERROR:}"
|
|
286
|
+
echo " → Fix: sf org login web --instance-url $INSTANCE_URL --alias $ORG_ALIAS"
|
|
287
|
+
;;
|
|
288
|
+
NETWORK_ERROR)
|
|
289
|
+
check_error "Pipeline Inspection: Cannot verify (network/service error)" "Check instance URL and connectivity"
|
|
290
|
+
;;
|
|
291
|
+
*)
|
|
292
|
+
check_warn "Pipeline Inspection: Unknown status ($PI_STATUS)"
|
|
293
|
+
;;
|
|
294
|
+
esac
|
|
295
|
+
|
|
296
|
+
echo ""
|
|
297
|
+
|
|
298
|
+
# --- Agent ---
|
|
299
|
+
echo "--- Agent ---"
|
|
300
|
+
|
|
301
|
+
AGENT_USER=$(sf data query \
|
|
302
|
+
--query "SELECT Id, Username FROM User WHERE Username LIKE '%salesmanagementagentuser%'" \
|
|
303
|
+
--target-org "$ORG_ALIAS" \
|
|
304
|
+
--json 2>/dev/null | jq -r '.result.records[0].Username // empty' 2>/dev/null || echo "")
|
|
305
|
+
|
|
306
|
+
if [[ -n "$AGENT_USER" ]]; then
|
|
307
|
+
check_pass "Agent user: $AGENT_USER"
|
|
308
|
+
else
|
|
309
|
+
check_fail "Agent user: NOT FOUND"
|
|
310
|
+
fi
|
|
311
|
+
|
|
312
|
+
# Detect the PM bot by AgentTemplate — the same field the scheduled flow
|
|
313
|
+
# uses — instead of a hardcoded DeveloperName.
|
|
314
|
+
BOT_DEF=$(pm_bot_developer_name "$ORG_ALIAS")
|
|
315
|
+
|
|
316
|
+
if [[ -n "$BOT_DEF" ]]; then
|
|
317
|
+
check_pass "BotDefinition: $BOT_DEF (matched by AgentTemplate)"
|
|
318
|
+
else
|
|
319
|
+
check_fail "BotDefinition: NOT FOUND — no bot with a PM AgentTemplate (run create-agent.sh)"
|
|
320
|
+
fi
|
|
321
|
+
|
|
322
|
+
echo ""
|
|
323
|
+
|
|
324
|
+
# --- Permission Set Groups ---
|
|
325
|
+
echo "--- Permission Set Groups ---"
|
|
326
|
+
|
|
327
|
+
PSG_COUNT=$(sf data query \
|
|
328
|
+
--query "SELECT Id, DeveloperName FROM PermissionSetGroup WHERE DeveloperName IN ('SalesManagementUserPsg','SalesManagementAgentUserPsg')" \
|
|
329
|
+
--target-org "$ORG_ALIAS" \
|
|
330
|
+
--use-tooling-api \
|
|
331
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
332
|
+
PSG_COUNT="${PSG_COUNT:-0}"
|
|
333
|
+
|
|
334
|
+
# These two PSGs ship with the Agentforce-for-Sales license, so their presence is a
|
|
335
|
+
# license check — NOT a Pipeline Management enablement indicator. The real functional
|
|
336
|
+
# checks are the agent-user PSG assignment and user PSG assignments below.
|
|
337
|
+
if [[ "$PSG_COUNT" -ge 2 ]]; then
|
|
338
|
+
check_pass "Permission Set Groups (license): both present ($PSG_COUNT/2)"
|
|
339
|
+
else
|
|
340
|
+
check_warn "Permission Set Groups (license): only $PSG_COUNT/2 found — org may lack the Agentforce-for-Sales license"
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
# Check if agent user has PSG
|
|
344
|
+
if [[ -n "$AGENT_USER" ]]; then
|
|
345
|
+
AGENT_USER_ID=$(sf data query \
|
|
346
|
+
--query "SELECT Id FROM User WHERE Username LIKE '%salesmanagementagentuser%'" \
|
|
347
|
+
--target-org "$ORG_ALIAS" \
|
|
348
|
+
--json 2>/dev/null | jq -r '.result.records[0].Id // empty' 2>/dev/null || echo "")
|
|
349
|
+
|
|
350
|
+
if [[ -n "$AGENT_USER_ID" ]]; then
|
|
351
|
+
AGENT_PSG=$(sf data query \
|
|
352
|
+
--query "SELECT Id FROM PermissionSetAssignment WHERE AssigneeId = '${AGENT_USER_ID}' AND PermissionSetGroup.DeveloperName = 'SalesManagementAgentUserPsg'" \
|
|
353
|
+
--target-org "$ORG_ALIAS" \
|
|
354
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
355
|
+
AGENT_PSG="${AGENT_PSG:-0}"
|
|
356
|
+
|
|
357
|
+
if [[ "$AGENT_PSG" -ge 1 ]]; then
|
|
358
|
+
check_pass "Agent PSG assignment: assigned"
|
|
359
|
+
else
|
|
360
|
+
check_warn "Agent PSG assignment: NOT assigned to agent user"
|
|
361
|
+
fi
|
|
362
|
+
fi
|
|
363
|
+
fi
|
|
364
|
+
|
|
365
|
+
# Count users with SalesManagementUserPsg
|
|
366
|
+
USER_PSG_COUNT=$(sf data query \
|
|
367
|
+
--query "SELECT COUNT() FROM PermissionSetAssignment WHERE PermissionSetGroup.DeveloperName = 'SalesManagementUserPsg'" \
|
|
368
|
+
--target-org "$ORG_ALIAS" \
|
|
369
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
370
|
+
USER_PSG_COUNT="${USER_PSG_COUNT:-0}"
|
|
371
|
+
|
|
372
|
+
if [[ "$USER_PSG_COUNT" -ge 1 ]]; then
|
|
373
|
+
check_pass "User PSG assignments: $USER_PSG_COUNT user(s) assigned"
|
|
374
|
+
else
|
|
375
|
+
check_warn "User PSG assignments: 0 users have SalesManagementUserPsg"
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
echo ""
|
|
379
|
+
|
|
380
|
+
# --- Agent Access (W-23242378) ---
|
|
381
|
+
# Users holding SalesManagementUserPsg can only launch the agent if it is added
|
|
382
|
+
# to "Agent Access" on a permission set. This is done via the custom permset
|
|
383
|
+
# Sales_Agent_Access (SetupEntityAccess -> BotDefinition) linked into the PSG.
|
|
384
|
+
echo "--- Agent Access ---"
|
|
385
|
+
|
|
386
|
+
ACCESS_PS_ID=$(sf data query \
|
|
387
|
+
--query "SELECT Id FROM PermissionSet WHERE Name = 'Sales_Agent_Access'" \
|
|
388
|
+
--target-org "$ORG_ALIAS" \
|
|
389
|
+
--json 2>/dev/null | jq -r '.result.records[0].Id // empty' 2>/dev/null || echo "")
|
|
390
|
+
|
|
391
|
+
if [[ -z "$ACCESS_PS_ID" ]]; then
|
|
392
|
+
check_warn "Agent Access permset: 'Sales_Agent_Access' not found (run define-agent-access.sh)"
|
|
393
|
+
else
|
|
394
|
+
check_pass "Agent Access permset: Sales_Agent_Access"
|
|
395
|
+
|
|
396
|
+
# Is the agent (BotDefinition, matched by AgentTemplate) granted on that permset?
|
|
397
|
+
# Query by AgentTemplate only — the `Id IN (SELECT ... FROM BotVersion)` subquery
|
|
398
|
+
# was removed in de77d520 because it hangs 60+ seconds on some orgs. Active-version
|
|
399
|
+
# verification is reported separately by the BotDefinition check above (line ~270).
|
|
400
|
+
if [[ -n "$BOT_DEF" ]]; then
|
|
401
|
+
BOT_DEF_ID=$(sf data query \
|
|
402
|
+
--query "SELECT Id FROM BotDefinition WHERE AgentTemplate IN (${PM_AGENT_TEMPLATES_SOQL}) ORDER BY LastModifiedDate DESC LIMIT 1" \
|
|
403
|
+
--target-org "$ORG_ALIAS" \
|
|
404
|
+
--json 2>/dev/null | jq -r '.result.records[0].Id // empty' 2>/dev/null || echo "")
|
|
405
|
+
|
|
406
|
+
if [[ -n "$BOT_DEF_ID" ]]; then
|
|
407
|
+
ACCESS_COUNT=$(sf data query \
|
|
408
|
+
--query "SELECT COUNT() FROM SetupEntityAccess WHERE ParentId = '${ACCESS_PS_ID}' AND SetupEntityId = '${BOT_DEF_ID}'" \
|
|
409
|
+
--target-org "$ORG_ALIAS" \
|
|
410
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
411
|
+
ACCESS_COUNT="${ACCESS_COUNT:-0}"
|
|
412
|
+
|
|
413
|
+
if [[ "$ACCESS_COUNT" -ge 1 ]]; then
|
|
414
|
+
check_pass "Agent Access grant: $BOT_DEF added to Sales_Agent_Access"
|
|
415
|
+
else
|
|
416
|
+
check_fail "Agent Access grant: agent NOT in Sales_Agent_Access (users cannot launch agent)"
|
|
417
|
+
fi
|
|
418
|
+
fi
|
|
419
|
+
else
|
|
420
|
+
check_warn "Agent Access grant: BotDefinition absent — cannot verify grant"
|
|
421
|
+
fi
|
|
422
|
+
|
|
423
|
+
# Is the custom permset linked into the managed PSG?
|
|
424
|
+
ACCESS_PSG_ID=$(sf data query \
|
|
425
|
+
--query "SELECT Id FROM PermissionSetGroup WHERE DeveloperName = 'SalesManagementUserPsg'" \
|
|
426
|
+
--target-org "$ORG_ALIAS" \
|
|
427
|
+
--use-tooling-api \
|
|
428
|
+
--json 2>/dev/null | jq -r '.result.records[0].Id // empty' 2>/dev/null || echo "")
|
|
429
|
+
|
|
430
|
+
if [[ -n "$ACCESS_PSG_ID" ]]; then
|
|
431
|
+
COMPONENT_COUNT=$(sf data query \
|
|
432
|
+
--query "SELECT COUNT() FROM PermissionSetGroupComponent WHERE PermissionSetGroupId = '${ACCESS_PSG_ID}' AND PermissionSetId = '${ACCESS_PS_ID}'" \
|
|
433
|
+
--target-org "$ORG_ALIAS" \
|
|
434
|
+
--use-tooling-api \
|
|
435
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
436
|
+
COMPONENT_COUNT="${COMPONENT_COUNT:-0}"
|
|
437
|
+
|
|
438
|
+
if [[ "$COMPONENT_COUNT" -ge 1 ]]; then
|
|
439
|
+
check_pass "Agent Access link: Sales_Agent_Access is a component of SalesManagementUserPsg"
|
|
440
|
+
else
|
|
441
|
+
check_warn "Agent Access link: Sales_Agent_Access not linked into SalesManagementUserPsg (may be assigned directly)"
|
|
442
|
+
fi
|
|
443
|
+
fi
|
|
444
|
+
fi
|
|
445
|
+
|
|
446
|
+
echo ""
|
|
447
|
+
|
|
448
|
+
# --- Schedule-Triggered Flow ---
|
|
449
|
+
echo "--- Schedule-Triggered Flow ---"
|
|
450
|
+
|
|
451
|
+
# Check by SourceTemplateId first
|
|
452
|
+
FLOW_QUERY=$(sf data query \
|
|
453
|
+
--query "SELECT Id, ApiName, IsActive FROM FlowDefinitionView WHERE SourceTemplateId='sales_pipe_mgmt__OppSuggGenSchFlow' AND IsTemplate=false" \
|
|
454
|
+
--target-org "$ORG_ALIAS" \
|
|
455
|
+
--json 2>/dev/null)
|
|
456
|
+
|
|
457
|
+
FLOW_NAME=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null | head -1 || echo "")
|
|
458
|
+
FLOW_ACTIVE=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null | head -1 || echo "")
|
|
459
|
+
|
|
460
|
+
# Fallback: check by naming convention
|
|
461
|
+
if [[ -z "$FLOW_NAME" ]]; then
|
|
462
|
+
FLOW_QUERY=$(sf data query \
|
|
463
|
+
--query "SELECT Id, ApiName, IsActive FROM FlowDefinitionView WHERE ApiName LIKE '%OppSuggGen%' AND IsTemplate=false" \
|
|
464
|
+
--target-org "$ORG_ALIAS" \
|
|
465
|
+
--json 2>/dev/null)
|
|
466
|
+
|
|
467
|
+
FLOW_NAME=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null | head -1 || echo "")
|
|
468
|
+
FLOW_ACTIVE=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null | head -1 || echo "")
|
|
469
|
+
fi
|
|
470
|
+
|
|
471
|
+
# Fallback: check by exact deployed name
|
|
472
|
+
if [[ -z "$FLOW_NAME" ]]; then
|
|
473
|
+
FLOW_QUERY=$(sf data query \
|
|
474
|
+
--query "SELECT Id, ApiName, IsActive FROM FlowDefinitionView WHERE ApiName = 'Process_Field_Update_Suggestions' AND IsTemplate=false" \
|
|
475
|
+
--target-org "$ORG_ALIAS" \
|
|
476
|
+
--json 2>/dev/null)
|
|
477
|
+
|
|
478
|
+
FLOW_NAME=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null | head -1 || echo "")
|
|
479
|
+
FLOW_ACTIVE=$(echo "$FLOW_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null | head -1 || echo "")
|
|
480
|
+
fi
|
|
481
|
+
|
|
482
|
+
if [[ -z "$FLOW_NAME" ]]; then
|
|
483
|
+
check_fail "Schedule flow: NOT FOUND (must clone via Setup UI 'Save As')"
|
|
484
|
+
elif [[ "$FLOW_ACTIVE" == "true" ]]; then
|
|
485
|
+
check_pass "Schedule flow: $FLOW_NAME (ACTIVE)"
|
|
486
|
+
else
|
|
487
|
+
check_warn "Schedule flow: $FLOW_NAME (INACTIVE — needs activation)"
|
|
488
|
+
fi
|
|
489
|
+
|
|
490
|
+
# Check template exists
|
|
491
|
+
TEMPLATE_EXISTS=$(sf data query \
|
|
492
|
+
--query "SELECT Id, ApiName FROM FlowDefinitionView WHERE ApiName LIKE '%OppSuggGen%' AND IsTemplate=true" \
|
|
493
|
+
--target-org "$ORG_ALIAS" \
|
|
494
|
+
--json 2>/dev/null | jq -r '.result.records[0].ApiName // empty' 2>/dev/null || echo "")
|
|
495
|
+
|
|
496
|
+
if [[ -n "$TEMPLATE_EXISTS" ]]; then
|
|
497
|
+
check_pass "Template flow: present"
|
|
498
|
+
else
|
|
499
|
+
check_fail "Template flow: NOT provisioned (Pipeline Management may not be fully enabled)"
|
|
500
|
+
fi
|
|
501
|
+
|
|
502
|
+
echo ""
|
|
503
|
+
|
|
504
|
+
# --- Grounding Flows (managed sales_pipe_mgmt) ---
|
|
505
|
+
# Deactivated grounding flows silently kill all suggestion generation.
|
|
506
|
+
echo "--- Grounding Flows ---"
|
|
507
|
+
|
|
508
|
+
GROUNDING_QUERY=$(sf data query \
|
|
509
|
+
--query "SELECT ApiName, IsActive FROM FlowDefinitionView WHERE NamespacePrefix='sales_pipe_mgmt' AND ApiName IN ('GetOppGroundingData','GetRcmdConvTscp')" \
|
|
510
|
+
--target-org "$ORG_ALIAS" \
|
|
511
|
+
--json 2>/dev/null)
|
|
512
|
+
|
|
513
|
+
for GROUNDING_FLOW in GetOppGroundingData GetRcmdConvTscp; do
|
|
514
|
+
GROUNDING_ACTIVE=$(echo "$GROUNDING_QUERY" | jq -r --arg n "$GROUNDING_FLOW" '.result.records[] | select(.ApiName==$n) | .IsActive' 2>/dev/null | head -1)
|
|
515
|
+
if [[ -z "$GROUNDING_ACTIVE" ]]; then
|
|
516
|
+
check_fail "Grounding flow $GROUNDING_FLOW: NOT FOUND (sales_pipe_mgmt namespace not provisioned)"
|
|
517
|
+
elif [[ "$GROUNDING_ACTIVE" == "true" ]]; then
|
|
518
|
+
check_pass "Grounding flow $GROUNDING_FLOW: ACTIVE"
|
|
519
|
+
else
|
|
520
|
+
check_fail "Grounding flow $GROUNDING_FLOW: INACTIVE (suggestions will not generate)"
|
|
521
|
+
fi
|
|
522
|
+
done
|
|
523
|
+
|
|
524
|
+
echo ""
|
|
525
|
+
|
|
526
|
+
# --- Stage Descriptions ---
|
|
527
|
+
echo "--- Stage Descriptions ---"
|
|
528
|
+
|
|
529
|
+
STAGE_COUNT=$(sf data query \
|
|
530
|
+
--query "SELECT MasterLabel FROM OpportunityStage WHERE IsActive = true" \
|
|
531
|
+
--target-org "$ORG_ALIAS" \
|
|
532
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
533
|
+
STAGE_COUNT="${STAGE_COUNT:-0}"
|
|
534
|
+
|
|
535
|
+
DESC_RESULT=$(sf data query \
|
|
536
|
+
--query "SELECT Id FROM OpptStageDescription" \
|
|
537
|
+
--target-org "$ORG_ALIAS" \
|
|
538
|
+
--use-tooling-api \
|
|
539
|
+
--json 2>/dev/null || echo '{"status":1}')
|
|
540
|
+
|
|
541
|
+
# OpptStageDescription may be inaccessible if PM isn't fully enabled
|
|
542
|
+
if echo "$DESC_RESULT" | grep -qi "INVALID_TYPE\|NOT_FOUND\|sObject type.*not supported"; then
|
|
543
|
+
DESC_COUNT="0"
|
|
544
|
+
check_warn "Stage descriptions: OpptStageDescription not accessible (Pipeline Management may not be fully enabled)"
|
|
545
|
+
else
|
|
546
|
+
DESC_COUNT=$(echo "$DESC_RESULT" | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
547
|
+
DESC_COUNT="${DESC_COUNT:-0}"
|
|
548
|
+
|
|
549
|
+
if [[ "$DESC_COUNT" -ge "$STAGE_COUNT" && "$DESC_COUNT" -gt 0 ]]; then
|
|
550
|
+
check_pass "Stage descriptions: $DESC_COUNT/$STAGE_COUNT stages described"
|
|
551
|
+
elif [[ "$DESC_COUNT" -gt 0 ]]; then
|
|
552
|
+
check_warn "Stage descriptions: $DESC_COUNT/$STAGE_COUNT stages (some missing — stage suggestions may fail)"
|
|
553
|
+
else
|
|
554
|
+
check_fail "Stage descriptions: NONE configured (stage suggestions will not work)"
|
|
555
|
+
fi
|
|
556
|
+
fi
|
|
557
|
+
|
|
558
|
+
echo ""
|
|
559
|
+
|
|
560
|
+
# --- Data Sources ---
|
|
561
|
+
echo "--- Data Sources ---"
|
|
562
|
+
|
|
563
|
+
NOTE_COUNT=$(sf data query \
|
|
564
|
+
--query "SELECT COUNT() FROM ContentNote WHERE CreatedDate = LAST_N_DAYS:30" \
|
|
565
|
+
--target-org "$ORG_ALIAS" \
|
|
566
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
567
|
+
NOTE_COUNT="${NOTE_COUNT:-0}"
|
|
568
|
+
|
|
569
|
+
if [[ "$NOTE_COUNT" -gt 0 ]]; then
|
|
570
|
+
check_pass "Recent notes (30d): $NOTE_COUNT"
|
|
571
|
+
else
|
|
572
|
+
check_warn "Recent notes (30d): 0 (agent needs notes to generate suggestions)"
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
OPP_COUNT=$(sf data query \
|
|
576
|
+
--query "SELECT COUNT() FROM Opportunity WHERE IsClosed = false" \
|
|
577
|
+
--target-org "$ORG_ALIAS" \
|
|
578
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
579
|
+
OPP_COUNT="${OPP_COUNT:-0}"
|
|
580
|
+
|
|
581
|
+
if [[ "$OPP_COUNT" -gt 0 ]]; then
|
|
582
|
+
check_pass "Open opportunities: $OPP_COUNT"
|
|
583
|
+
else
|
|
584
|
+
check_warn "Open opportunities: 0 (agent needs open opps to generate suggestions)"
|
|
585
|
+
fi
|
|
586
|
+
|
|
587
|
+
EMAIL_COUNT=$(sf data query \
|
|
588
|
+
--query "SELECT COUNT() FROM EmailMessage WHERE CreatedDate = LAST_N_DAYS:30" \
|
|
589
|
+
--target-org "$ORG_ALIAS" \
|
|
590
|
+
--json 2>/dev/null | jq -r '.result.totalSize // 0' 2>/dev/null | head -1 | tr -cd '0-9' || echo "0")
|
|
591
|
+
EMAIL_COUNT="${EMAIL_COUNT:-0}"
|
|
592
|
+
|
|
593
|
+
if [[ "$EMAIL_COUNT" -gt 0 ]]; then
|
|
594
|
+
check_pass "Recent emails (30d): $EMAIL_COUNT"
|
|
595
|
+
else
|
|
596
|
+
check_warn "Recent emails (30d): 0 (optional — agent can use notes instead)"
|
|
597
|
+
fi
|
|
598
|
+
|
|
599
|
+
echo ""
|
|
600
|
+
|
|
601
|
+
# --- Summary ---
|
|
602
|
+
echo "============================================"
|
|
603
|
+
echo " SUMMARY"
|
|
604
|
+
echo "============================================"
|
|
605
|
+
echo ""
|
|
606
|
+
echo " PASS: $PASS"
|
|
607
|
+
echo " WARN: $WARN"
|
|
608
|
+
echo " FAIL: $FAIL"
|
|
609
|
+
echo ""
|
|
610
|
+
|
|
611
|
+
if [[ "$FAIL" -eq 0 && "$WARN" -eq 0 ]]; then
|
|
612
|
+
echo " Status: FULLY CONFIGURED"
|
|
613
|
+
echo ""
|
|
614
|
+
echo " Pipeline Management is fully operational."
|
|
615
|
+
echo " Suggestions will generate on the next scheduled flow run."
|
|
616
|
+
elif [[ "$FAIL" -eq 0 ]]; then
|
|
617
|
+
echo " Status: CONFIGURED WITH WARNINGS"
|
|
618
|
+
echo ""
|
|
619
|
+
echo " Core functionality is in place. Review warnings above."
|
|
620
|
+
else
|
|
621
|
+
echo " Status: INCOMPLETE — $FAIL issue(s) must be resolved"
|
|
622
|
+
echo ""
|
|
623
|
+
echo " Fix the FAIL items above before Pipeline Management will function."
|
|
624
|
+
echo ""
|
|
625
|
+
echo " Common fixes:"
|
|
626
|
+
[[ "$OPP_TEAM_STATUS" != "true" ]] && echo " - Enable Opportunity Team: ./enable-prerequisites.sh $ORG_ALIAS"
|
|
627
|
+
[[ "$PM_STATUS" != "true" ]] && echo " - Enable Pipeline Management: ./enable-deal-agent.sh $ORG_ALIAS"
|
|
628
|
+
[[ -z "$AGENT_USER" ]] && echo " - Create agent: ./create-agent.sh $ORG_ALIAS"
|
|
629
|
+
[[ -z "$FLOW_NAME" ]] && echo " - Clone flow: Setup UI → Flows → OppSuggGenSchFlow → Save As"
|
|
630
|
+
[[ "${DESC_COUNT:-0}" -eq 0 ]] && echo " - Add stage descriptions: see references/opportunity-stages.md"
|
|
631
|
+
|
|
632
|
+
# Exit with error status when FAIL > 0 (a PM BotDefinition is now REQUIRED)
|
|
633
|
+
exit 1
|
|
634
|
+
fi
|
|
635
|
+
|
|
636
|
+
echo ""
|