@salesforce/afv-skills 1.31.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.
Files changed (98) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-bot-upgrade/SKILL.md +217 -0
  3. package/skills/agentforce-bot-upgrade/references/extraction-blueprint.md +242 -0
  4. package/skills/agentforce-bot-upgrade/references/generate-agent-spec.md +128 -0
  5. package/skills/agentforce-bot-upgrade/references/handoff-output-format.md +208 -0
  6. package/skills/agentforce-bot-upgrade/references/input-contract.md +101 -0
  7. package/skills/agentforce-bot-upgrade/references/mapping-rules.md +113 -0
  8. package/skills/agentforce-bot-upgrade/references/planner-workflow-reference.md +78 -0
  9. package/skills/agentforce-bot-upgrade/references/post-conversion-enhancements-reference.md +67 -0
  10. package/skills/agentforce-bot-upgrade/references/quality-checklist.md +33 -0
  11. package/skills/agentforce-bot-upgrade/references/sf-cli-bot-reference.md +116 -0
  12. package/skills/dx-devops-work-item-manage/SKILL.md +270 -0
  13. package/skills/dx-devops-work-item-manage/examples/common-workflows.md +479 -0
  14. package/skills/dx-devops-work-item-manage/references/cli-commands.md +476 -0
  15. package/skills/dx-org-manage/SKILL.md +8 -5
  16. package/skills/dx-org-trial-expiration-check/SKILL.md +239 -0
  17. package/skills/dx-org-trial-expiration-check/scripts/check_expiration.sh +588 -0
  18. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +12 -9
  19. package/skills/experience-ui-bundle-custom-app-generate/SKILL.md +29 -5
  20. package/skills/experience-ui-bundle-custom-app-generate/references/configure-metadata-custom-application.md +1 -1
  21. package/skills/experience-ui-bundle-custom-app-generate/scripts/resolve-uibundle-path.sh +30 -0
  22. package/skills/experience-ui-bundle-features-generate/SKILL.md +86 -11
  23. package/skills/experience-ui-bundle-features-generate/references/conflict-resolution-schema.json +20 -0
  24. package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +14 -0
  25. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +6 -1
  26. package/skills/experience-ui-bundle-frontend-generate/references/component.md +34 -1
  27. package/skills/experience-ui-bundle-frontend-generate/references/page.md +1 -1
  28. package/skills/experience-ui-bundle-project-generate/SKILL.md +111 -0
  29. package/skills/experience-ui-bundle-project-generate/scripts/flatten-project.mjs +33 -0
  30. package/skills/platform-custom-lightning-type-generate/SKILL.md +9 -14
  31. package/skills/platform-custom-lightning-type-generate/references/widget-rendition.md +27 -111
  32. package/skills/platform-lightning-type-widget-coordinate/SKILL.md +214 -0
  33. package/skills/platform-lightning-type-widget-coordinate/examples/existing-lightning-type-with-widget-prompt.md +80 -0
  34. package/skills/platform-lightning-type-widget-coordinate/examples/new-lightning-type-with-widget-prompt.md +75 -0
  35. package/skills/platform-lightning-type-widget-coordinate/references/build-plan-format.md +67 -0
  36. package/skills/platform-lightning-type-widget-coordinate/references/lightning-type-discovery.md +124 -0
  37. package/skills/platform-lightning-type-widget-coordinate/references/validation-gates.md +130 -0
  38. package/skills/platform-sharing-owd-configure/SKILL.md +142 -0
  39. package/skills/platform-sharing-owd-configure/examples/get_owd_output.md +38 -0
  40. package/skills/platform-sharing-owd-configure/examples/update_owd_output.md +44 -0
  41. package/skills/platform-sharing-owd-configure/references/access_levels.md +49 -0
  42. package/skills/platform-sharing-owd-configure/references/metadata_api_approach.md +69 -0
  43. package/skills/platform-sharing-rules-generate/SKILL.md +89 -19
  44. package/skills/platform-sharing-rules-generate/examples/test-cases.md +381 -0
  45. package/skills/platform-widget-generate/SKILL.md +241 -0
  46. package/skills/platform-widget-generate/examples/conditional.json +73 -0
  47. package/skills/platform-widget-generate/examples/list-with-foreach.json +66 -0
  48. package/skills/platform-widget-generate/examples/single-object.json +64 -0
  49. package/skills/platform-widget-generate/references/schema-from-lightning-type.md +76 -0
  50. package/skills/platform-widget-generate/references/widget-bundle-layout.md +116 -0
  51. package/skills/platform-widget-generate/references/widget-meta-directives.md +130 -0
  52. package/skills/sales-agentforce-pipeline-management-configure/SKILL.md +268 -0
  53. package/skills/sales-agentforce-pipeline-management-configure/assets/field-completion-template.genAiPromptTemplate-meta.xml +141 -0
  54. package/skills/sales-agentforce-pipeline-management-configure/assets/pipeline_management_flow.flow-meta.xml +548 -0
  55. package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.agent +2938 -0
  56. package/skills/sales-agentforce-pipeline-management-configure/assets/sales_management_agent.bundle-meta.xml +4 -0
  57. package/skills/sales-agentforce-pipeline-management-configure/assets/sfdx-project.json +12 -0
  58. package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/bant.txt +11 -0
  59. package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/meddic.txt +11 -0
  60. package/skills/sales-agentforce-pipeline-management-configure/assets/stage-descriptions/spiced.txt +11 -0
  61. package/skills/sales-agentforce-pipeline-management-configure/examples/custom-prompt-instructions.md +317 -0
  62. package/skills/sales-agentforce-pipeline-management-configure/references/admin-communication.md +355 -0
  63. package/skills/sales-agentforce-pipeline-management-configure/references/agent-creation.md +383 -0
  64. package/skills/sales-agentforce-pipeline-management-configure/references/auth-and-cli.md +146 -0
  65. package/skills/sales-agentforce-pipeline-management-configure/references/automation-matrix.md +23 -0
  66. package/skills/sales-agentforce-pipeline-management-configure/references/autonomous-updates.md +215 -0
  67. package/skills/sales-agentforce-pipeline-management-configure/references/canonical-agent-path.md +75 -0
  68. package/skills/sales-agentforce-pipeline-management-configure/references/data-sources.md +155 -0
  69. package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompt-template.md +120 -0
  70. package/skills/sales-agentforce-pipeline-management-configure/references/field-completion-prompts.md +149 -0
  71. package/skills/sales-agentforce-pipeline-management-configure/references/flags.md +13 -0
  72. package/skills/sales-agentforce-pipeline-management-configure/references/flow-clone-from-template.md +447 -0
  73. package/skills/sales-agentforce-pipeline-management-configure/references/metadata-inventory.md +330 -0
  74. package/skills/sales-agentforce-pipeline-management-configure/references/opportunity-stages.md +246 -0
  75. package/skills/sales-agentforce-pipeline-management-configure/references/repair-diagnostics.md +265 -0
  76. package/skills/sales-agentforce-pipeline-management-configure/references/setup-order.md +263 -0
  77. package/skills/sales-agentforce-pipeline-management-configure/references/soap-api-enablement.md +528 -0
  78. package/skills/sales-agentforce-pipeline-management-configure/scripts/CHANGES.md +180 -0
  79. package/skills/sales-agentforce-pipeline-management-configure/scripts/README.md +56 -0
  80. package/skills/sales-agentforce-pipeline-management-configure/scripts/add-field-suggestion.sh +679 -0
  81. package/skills/sales-agentforce-pipeline-management-configure/scripts/create-agent.sh +302 -0
  82. package/skills/sales-agentforce-pipeline-management-configure/scripts/create-flow.sh +250 -0
  83. package/skills/sales-agentforce-pipeline-management-configure/scripts/define-agent-access.sh +430 -0
  84. package/skills/sales-agentforce-pipeline-management-configure/scripts/deploy-settings.sh +77 -0
  85. package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-deal-agent.sh +241 -0
  86. package/skills/sales-agentforce-pipeline-management-configure/scripts/enable-prerequisites.sh +538 -0
  87. package/skills/sales-agentforce-pipeline-management-configure/scripts/flow-debug-and-verify.sh +385 -0
  88. package/skills/sales-agentforce-pipeline-management-configure/scripts/retrieve-settings.sh +131 -0
  89. package/skills/sales-agentforce-pipeline-management-configure/scripts/setup-all.sh +2791 -0
  90. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-bundle-publish.sh +189 -0
  91. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/agent-detection.sh +239 -0
  92. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/flow-builder.sh +238 -0
  93. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/psg.sh +48 -0
  94. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/soap.sh +140 -0
  95. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/stage-descriptions.sh +448 -0
  96. package/skills/sales-agentforce-pipeline-management-configure/scripts/shared/test-opp.sh +166 -0
  97. package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-all.sh +636 -0
  98. package/skills/sales-agentforce-pipeline-management-configure/scripts/verify-prompt-generation.sh +346 -0
@@ -0,0 +1,302 @@
1
+ #!/bin/bash
2
+
3
+ # Verify and ensure Pipeline Management agent is functional.
4
+ #
5
+ # CRITICAL: BotDefinition:SalesAgent is REQUIRED for a functional Pipeline Management agent.
6
+ # Users need an interactive Sales Agent they can chat with, which requires the BotDefinition.
7
+ # The agent user + PSG provision the backend identity, but without the BotDefinition,
8
+ # users CANNOT interact with the Sales Agent via chat/conversation interface.
9
+ #
10
+ # This script ensures:
11
+ # Step 1: Agent user exists with SalesManagementAgentUserPsg assigned
12
+ # Step 2: BotDefinition:SalesAgent is created and activated (via authoring bundle)
13
+ # Step 3: Both are verified functional (backend + user-facing)
14
+ #
15
+ # If the agent user exists but BotDefinition is missing, the script CREATES it.
16
+ # If BotDefinition creation fails, the script EXITS 1 (setup incomplete).
17
+ #
18
+ # Usage: ./create-agent.sh <org-alias>
19
+
20
+ set -euo pipefail
21
+
22
+ # sf CLI can emit ANSI color codes inside --json stdout, breaking jq parsing.
23
+ # 2>/dev/null only strips stderr; these env vars are the reliable fix (see PM notes).
24
+ export NO_COLOR=1
25
+ export FORCE_COLOR=0
26
+
27
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
28
+
29
+ # Source shared library
30
+ source "$SCRIPT_DIR/shared/agent-bundle-publish.sh"
31
+
32
+ # Define Agent Access (W-23242378) so human users holding SalesManagementUserPsg
33
+ # can launch the agent. Idempotent; exits gracefully if no active bot exists.
34
+ define_agent_access() {
35
+ local org="$1"
36
+ if [[ -f "$SCRIPT_DIR/define-agent-access.sh" ]]; then
37
+ echo ""
38
+ echo "=== Defining Agent Access (W-23242378) ==="
39
+ local rc=0
40
+ bash "$SCRIPT_DIR/define-agent-access.sh" "$org" || rc=$?
41
+ if [[ $rc -ne 0 ]]; then
42
+ echo " Warning: Agent Access definition failed (exit $rc) — see above"
43
+ return $rc
44
+ fi
45
+ fi
46
+ }
47
+
48
+ ORG_ALIAS="${1:-}"
49
+
50
+ if [[ -z "$ORG_ALIAS" ]]; then
51
+ echo "Error: Missing org alias"
52
+ echo "Usage: $0 <org-alias>"
53
+ exit 1
54
+ fi
55
+
56
+ echo "Verifying Pipeline Management agent setup"
57
+ echo ""
58
+
59
+ # --- Step 1: Check functional indicators (agent user + PSG) ---
60
+ echo "=== Step 1: Checking agent user (primary functional indicator) ==="
61
+ AGENT_USER=$(sf data query \
62
+ --query "SELECT Id, Username FROM User WHERE Username LIKE '%salesmanagementagentuser%'" \
63
+ --target-org "$ORG_ALIAS" \
64
+ --json 2>/dev/null | jq -r '.result.records[0] // empty' 2>/dev/null || echo "")
65
+
66
+ if [[ -n "$AGENT_USER" ]]; then
67
+ AGENT_USERNAME=$(echo "$AGENT_USER" | jq -r '.Username')
68
+ AGENT_USER_ID=$(echo "$AGENT_USER" | jq -r '.Id')
69
+ echo " Agent user found: $AGENT_USERNAME"
70
+ echo ""
71
+
72
+ # Check PSG assignment
73
+ PSG_ASSIGNED=$(sf data query \
74
+ --query "SELECT PermissionSetGroup.DeveloperName FROM PermissionSetAssignment WHERE AssigneeId = '${AGENT_USER_ID}' AND PermissionSetGroup.DeveloperName = 'SalesManagementAgentUserPsg'" \
75
+ --target-org "$ORG_ALIAS" \
76
+ --json 2>/dev/null | jq -r '.result.records[0] // empty' 2>/dev/null || echo "")
77
+
78
+ if [[ -n "$PSG_ASSIGNED" ]]; then
79
+ echo " PSG assigned: SalesManagementAgentUserPsg ✓"
80
+ else
81
+ echo " Warning: SalesManagementAgentUserPsg not assigned — attempting assignment..."
82
+ PSG_ID=$(sf data query \
83
+ --query "SELECT Id FROM PermissionSetGroup WHERE DeveloperName = 'SalesManagementAgentUserPsg'" \
84
+ --target-org "$ORG_ALIAS" \
85
+ --json 2>/dev/null | jq -r '.result.records[0].Id // empty')
86
+ if [[ -n "$PSG_ID" ]]; then
87
+ sf data create record --sobject PermissionSetAssignment \
88
+ --values "AssigneeId='${AGENT_USER_ID}' PermissionSetGroupId='${PSG_ID}'" \
89
+ --target-org "$ORG_ALIAS" --json 2>/dev/null >/dev/null \
90
+ && echo " PSG assigned successfully ✓" \
91
+ || echo " Assignment failed (may already be assigned)"
92
+ fi
93
+ fi
94
+ echo ""
95
+
96
+ # Determine architecture — match the bot by AgentTemplate (the field the
97
+ # scheduled flow uses), not by hardcoded DeveloperName.
98
+ echo "=== Architecture Detection ==="
99
+ EXISTING_BOT=$(pm_bot_developer_name "$ORG_ALIAS")
100
+
101
+ if [[ -n "$EXISTING_BOT" ]]; then
102
+ echo " Architecture: Standalone Bot (BotDefinition:$EXISTING_BOT matched by AgentTemplate)"
103
+ echo ""
104
+
105
+ # A BotDefinition can exist yet have no ACTIVE version — the state
106
+ # auto-provisioning leaves it in. Without an active version the scheduled
107
+ # flow never adds the agent user to opportunity teams (no suggestions) and
108
+ # Agent Access can't be defined. Activate the latest version if needed.
109
+ BOT_ACTIVE_COUNT=$(pm_bot_active_version_count "$ORG_ALIAS")
110
+ if [[ "$BOT_ACTIVE_COUNT" -ge 1 ]]; then
111
+ echo " BotVersion: active ✓"
112
+ else
113
+ echo " BotVersion: no active version — activating (auto-provisioned bots land Inactive)..."
114
+ if ! activate_pm_bot_if_inactive "$ORG_ALIAS"; then
115
+ echo ""
116
+ echo " BLOCKER: BotDefinition:$EXISTING_BOT exists but has no active version and activation failed."
117
+ echo " The scheduled flow will not generate suggestions until the agent is active."
118
+ echo " Resolve via Setup → Agents → $EXISTING_BOT → activate, then re-run: $0 $ORG_ALIAS"
119
+ exit 1
120
+ fi
121
+ fi
122
+
123
+ echo ""
124
+ echo "Agent setup is FUNCTIONAL."
125
+ echo " - Agent user: $AGENT_USERNAME"
126
+ echo " - PSG: SalesManagementAgentUserPsg"
127
+ echo " - BotDefinition: $EXISTING_BOT (active)"
128
+ echo " - Schedule-triggered flow will run as this user"
129
+ echo ""
130
+ echo "No further agent creation/deployment needed."
131
+ define_agent_access "$ORG_ALIAS"
132
+ exit $?
133
+ else
134
+ echo " Architecture: Platform Copilot (no standalone BotDefinition found)"
135
+ echo " Attempting to create Sales Agent BotDefinition for user interaction..."
136
+ echo ""
137
+
138
+ # Use shared library function to publish and activate agent
139
+ if publish_and_activate_agent "$ORG_ALIAS" "exit" "plain"; then
140
+ echo ""
141
+ echo "Agent setup is COMPLETE."
142
+ echo " - Agent user: $AGENT_USERNAME"
143
+ echo " - PSG: SalesManagementAgentUserPsg"
144
+ echo " - BotDefinition: ${AGENT_API_NAME:-SalesAgent} (ACTIVE, version $AGENT_VERSION)"
145
+ echo " - Schedule-triggered flow will run as this user"
146
+ define_agent_access "$ORG_ALIAS"
147
+ exit $?
148
+ fi
149
+ # If function returned non-zero, it already exited (on-error="exit")
150
+ fi
151
+ fi
152
+
153
+ # --- Step 2: No agent user found — need remediation ---
154
+ echo " Agent user NOT found."
155
+ echo ""
156
+ echo "=== Step 2: Attempting SOAP toggle to re-provision agent user + PSGs ==="
157
+ echo " (The toggle re-creates the agent user and permission set groups only."
158
+ echo " It does NOT create BotDefinition:SalesAgent — that comes from the bundle"
159
+ echo " publish in Step 3 below.)"
160
+
161
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
162
+ AUTH_INFO=$(sf org display --target-org "$ORG_ALIAS" --json 2>/dev/null)
163
+ ACCESS_TOKEN=$(echo "$AUTH_INFO" | jq -r '.result.accessToken')
164
+ INSTANCE_URL=$(echo "$AUTH_INFO" | jq -r '.result.instanceUrl')
165
+
166
+ # Newer CLI versions redact accessToken — use show-access-token fallback
167
+ if [[ -z "$ACCESS_TOKEN" || "$ACCESS_TOKEN" == "null" || "$ACCESS_TOKEN" == *"REDACTED"* ]]; then
168
+ 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')
169
+ fi
170
+
171
+ if [[ -z "$ACCESS_TOKEN" || "$ACCESS_TOKEN" == "null" ]]; then
172
+ echo "Error: Could not retrieve org credentials. Is the org authenticated?"
173
+ exit 1
174
+ fi
175
+
176
+ # Pre-check: Is org in "partially enabled" state (PSGs exist but enableDealAgent=false)?
177
+ # In that state, the toggle is harmful — disable may succeed but re-enable will fail.
178
+ PM_READ=$(curl -s "${INSTANCE_URL}/services/Soap/m/64.0" \
179
+ -H "Content-Type: text/xml; charset=UTF-8" \
180
+ -H "SOAPAction: readMetadata" \
181
+ -d "<?xml version='1.0' encoding='utf-8'?>
182
+ <soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
183
+ <soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
184
+ <soapenv:Body><met:readMetadata><met:type>SalesDealAgentSettings</met:type><met:fullNames>SalesDealAgent</met:fullNames></met:readMetadata></soapenv:Body>
185
+ </soapenv:Envelope>" 2>/dev/null | grep -o "<enableDealAgent>[^<]*" | grep -o "true\|false" || echo "")
186
+
187
+ # PSG existence does NOT count as a partial signal — SalesManagementUserPsg /
188
+ # SalesManagementAgentUserPsg ship with the Agentforce-for-Sales license and exist
189
+ # in never-configured orgs. The real partial signals (with enableDealAgent=false)
190
+ # are a cloned scheduled flow or a PM BotDefinition. (The agent user was already
191
+ # ruled out in Step 1 above.)
192
+ PM_FLOW_EXISTS=$(pm_flow_clone_exists "$ORG_ALIAS")
193
+ PM_BOT_EXISTS=$(pm_bot_count "$ORG_ALIAS")
194
+
195
+ if [[ "$PM_READ" != "true" && ( "${PM_FLOW_EXISTS:-0}" -ge 1 || "${PM_BOT_EXISTS:-0}" -ge 1 ) ]]; then
196
+ echo "Detected partial-enablement state: enableDealAgent reads false but PM components exist (flow=$PM_FLOW_EXISTS bot=$PM_BOT_EXISTS)."
197
+ echo ""
198
+ echo " The SOAP toggle is NOT safe in this state (re-enable may fail mid-provisioning)."
199
+ echo " This org was likely provisioned via org template."
200
+ echo ""
201
+ echo " To resolve:"
202
+ echo " 1. Open: ${INSTANCE_URL}/lightning/setup/PipelineManagement/home"
203
+ echo " 2. Enable Pipeline Management in the Setup UI"
204
+ echo " 3. Wait 2-5 minutes for agent user provisioning"
205
+ echo " 4. Re-run this script"
206
+ exit 0
207
+ fi
208
+
209
+ echo " Using SOAP toggle to re-provision agent user + PSGs (NOT the BotDefinition)..."
210
+ echo " WARNING: This will temporarily disable Pipeline Management (~40 seconds)."
211
+ echo ""
212
+
213
+ # Disable Pipeline Management
214
+ echo " Disabling Pipeline Management..."
215
+ DISABLE_RESPONSE=$(curl -s -X POST "${INSTANCE_URL}/services/Soap/m/64.0" \
216
+ -H "Content-Type: text/xml; charset=utf-8" \
217
+ -H "SOAPAction: update" \
218
+ -d "<?xml version='1.0' encoding='utf-8'?>
219
+ <soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
220
+ <soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
221
+ <soapenv:Body><met:updateMetadata>
222
+ <met:metadata xsi:type='met:SalesDealAgentSettings' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
223
+ <met:fullName>SalesDealAgent</met:fullName>
224
+ <met:enableDealAgent>false</met:enableDealAgent>
225
+ </met:metadata>
226
+ </met:updateMetadata></soapenv:Body>
227
+ </soapenv:Envelope>")
228
+
229
+ if echo "$DISABLE_RESPONSE" | grep -q "<success>true</success>"; then
230
+ echo " Disabled successfully. Waiting 10 seconds..."
231
+ sleep 10
232
+
233
+ # Re-enable Pipeline Management
234
+ echo " Re-enabling Pipeline Management..."
235
+ ENABLE_RESPONSE=$(curl -s -X POST "${INSTANCE_URL}/services/Soap/m/64.0" \
236
+ -H "Content-Type: text/xml; charset=utf-8" \
237
+ -H "SOAPAction: update" \
238
+ -d "<?xml version='1.0' encoding='utf-8'?>
239
+ <soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:met='http://soap.sforce.com/2006/04/metadata'>
240
+ <soapenv:Header><met:SessionHeader><met:sessionId>${ACCESS_TOKEN}</met:sessionId></met:SessionHeader></soapenv:Header>
241
+ <soapenv:Body><met:updateMetadata>
242
+ <met:metadata xsi:type='met:SalesDealAgentSettings' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
243
+ <met:fullName>SalesDealAgent</met:fullName>
244
+ <met:enableDealAgent>true</met:enableDealAgent>
245
+ <met:enableDealAgentAutoApproveAllTasks>false</met:enableDealAgentAutoApproveAllTasks>
246
+ </met:metadata>
247
+ </met:updateMetadata></soapenv:Body>
248
+ </soapenv:Envelope>")
249
+
250
+ if echo "$ENABLE_RESPONSE" | grep -q "<success>true</success>"; then
251
+ echo " Re-enabled successfully. Waiting 30 seconds for provisioning..."
252
+ sleep 30
253
+ else
254
+ echo " Error: Failed to re-enable Pipeline Management"
255
+ echo "$ENABLE_RESPONSE" | grep -o '<message>[^<]*</message>' | sed 's/<[^>]*>//g' | head -1 || true
256
+ exit 1
257
+ fi
258
+ else
259
+ ERR_MSG=$(echo "$DISABLE_RESPONSE" | grep -o '<message>[^<]*</message>' | sed 's/<[^>]*>//g' | head -1 || echo "unknown error")
260
+ echo " SOAP toggle failed: $ERR_MSG"
261
+ echo ""
262
+ fi
263
+
264
+ # Check if agent user was provisioned
265
+ AGENT_USER_CHECK=$(sf data query \
266
+ --query "SELECT Id, Username FROM User WHERE Username LIKE '%salesmanagementagentuser%'" \
267
+ --target-org "$ORG_ALIAS" \
268
+ --json 2>/dev/null | jq -r '.result.records[0].Username // empty' 2>/dev/null || echo "")
269
+
270
+ if [[ -n "$AGENT_USER_CHECK" ]]; then
271
+ echo ""
272
+ echo " Agent user provisioned: $AGENT_USER_CHECK"
273
+ echo " BotDefinition:SalesAgent is still missing — the toggle does not create it."
274
+ echo " Proceeding to Step 3 to publish the authoring bundle."
275
+ fi
276
+
277
+ # --- Step 3: Last resort — authoring bundle deployment ---
278
+ echo ""
279
+ echo "=== Step 3: Attempting authoring bundle deployment (last resort) ==="
280
+
281
+ # Use shared library function with return-on-error behavior
282
+ if publish_and_activate_agent "$ORG_ALIAS" "return" "plain"; then
283
+ echo " Agent deployed and activated via authoring bundle"
284
+ define_agent_access "$ORG_ALIAS"
285
+ exit $?
286
+ else
287
+ echo " Authoring bundle publish/activate failed"
288
+ fi
289
+
290
+ # --- All approaches failed ---
291
+ echo ""
292
+ echo "=== BLOCKER: Agent provisioning failed ==="
293
+ echo ""
294
+ echo " No agent user was created via any automated method."
295
+ echo " Suggestions cannot generate without the agent user."
296
+ echo ""
297
+ echo " Manual resolution:"
298
+ echo " 1. Open: ${INSTANCE_URL}/lightning/setup/PipelineManagement/home"
299
+ echo " 2. Disable Pipeline Management, wait 30 seconds, re-enable"
300
+ echo " 3. Wait 2-5 minutes for agent user provisioning"
301
+ echo " 4. Re-run: $0 $ORG_ALIAS"
302
+ exit 1
@@ -0,0 +1,250 @@
1
+ #!/bin/bash
2
+
3
+ # Detect, create/deploy, and activate Pipeline Management suggestion processing flow
4
+ #
5
+ # Strategy (in order of preference):
6
+ # 1. Check if flow clone already exists (by SourceTemplateId or naming convention)
7
+ # 2. If missing: deploy from pre-retrieved template (assets/pipeline_management_flow.flow-meta.xml)
8
+ # 3. If deploy fails: instruct user to perform Setup UI "Save As" from managed template
9
+ # 4. If exists but inactive: activate via retrieve → transform → deploy
10
+ #
11
+ # The template (assets/) was retrieved from a live org with Pipeline Management enabled.
12
+ # It contains the complete flow logic including sourceTemplate reference, so the deployed
13
+ # flow registers as a proper clone of sales_pipe_mgmt__OppSuggGenSchFlow.
14
+ #
15
+ # Usage: ./create-flow.sh <org-alias>
16
+
17
+ set -euo pipefail
18
+
19
+ # sf CLI can emit ANSI color codes inside --json stdout, breaking jq parsing.
20
+ # 2>/dev/null only strips stderr; these env vars are the reliable fix (see PM notes).
21
+ export NO_COLOR=1
22
+ export FORCE_COLOR=0
23
+
24
+ # Cross-platform sed -i (macOS requires '' arg, GNU does not)
25
+ sed_inplace() {
26
+ if [[ "$OSTYPE" == "darwin"* ]]; then
27
+ sed -i '' "$@"
28
+ else
29
+ sed -i "$@"
30
+ fi
31
+ }
32
+
33
+ ORG_ALIAS="${1:-}"
34
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
35
+
36
+ if [[ -z "$ORG_ALIAS" ]]; then
37
+ echo "Error: Missing org alias"
38
+ echo "Usage: $0 <org-alias>"
39
+ exit 1
40
+ fi
41
+
42
+ echo "Pipeline Management Flow: Detect + Deploy + Activate"
43
+ echo ""
44
+
45
+ TEMPLATE_NAME="sales_pipe_mgmt__OppSuggGenSchFlow"
46
+ FLOW_API_NAME="Process_Field_Update_Suggestions"
47
+
48
+ # --- Detection ---
49
+ echo -n "Checking if flow clone exists... "
50
+
51
+ # Attempt 1: Query by SourceTemplateId (verified field on FlowDefinitionView in API v67.0)
52
+ EXISTING_QUERY=$(sf data query \
53
+ --query "SELECT Id, ApiName, IsActive, SourceTemplateId FROM FlowDefinitionView WHERE SourceTemplateId = '${TEMPLATE_NAME}' AND IsTemplate = false" \
54
+ --target-org "$ORG_ALIAS" \
55
+ --json 2>/dev/null)
56
+
57
+ EXISTING_FLOW=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null || echo "")
58
+ IS_ACTIVE=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null || echo "")
59
+
60
+ # Attempt 2: Fallback to naming convention match
61
+ if [[ -z "$EXISTING_FLOW" ]]; then
62
+ EXISTING_QUERY=$(sf data query \
63
+ --query "SELECT Id, ApiName, IsActive FROM FlowDefinitionView WHERE ApiName LIKE '%OppSuggGen%' AND IsTemplate = false" \
64
+ --target-org "$ORG_ALIAS" \
65
+ --json 2>/dev/null)
66
+
67
+ EXISTING_FLOW=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null || echo "")
68
+ IS_ACTIVE=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null || echo "")
69
+ fi
70
+
71
+ # Attempt 3: Check by standard API name
72
+ if [[ -z "$EXISTING_FLOW" ]]; then
73
+ EXISTING_QUERY=$(sf data query \
74
+ --query "SELECT Id, ApiName, IsActive FROM FlowDefinitionView WHERE ApiName = '${FLOW_API_NAME}'" \
75
+ --target-org "$ORG_ALIAS" \
76
+ --json 2>/dev/null)
77
+
78
+ EXISTING_FLOW=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].ApiName // empty' 2>/dev/null || echo "")
79
+ IS_ACTIVE=$(echo "$EXISTING_QUERY" | jq -r '.result.records[0].IsActive // empty' 2>/dev/null || echo "")
80
+ fi
81
+
82
+ # --- Flow Not Found: Deploy from Template ---
83
+ if [[ -z "$EXISTING_FLOW" ]]; then
84
+ echo "not found"
85
+ echo ""
86
+
87
+ TEMPLATE_FILE="$SCRIPT_DIR/../assets/pipeline_management_flow.flow-meta.xml"
88
+
89
+ if [[ -f "$TEMPLATE_FILE" ]]; then
90
+ echo "Deploying flow from pre-retrieved template..."
91
+ echo " Template: assets/pipeline_management_flow.flow-meta.xml"
92
+ echo " API Name: $FLOW_API_NAME"
93
+ echo ""
94
+
95
+ # Ensure sfdx-project.json exists
96
+ if [[ ! -f "sfdx-project.json" ]]; then
97
+ cat > sfdx-project.json << 'EOF'
98
+ {"packageDirectories": [{"path": "force-app", "default": true}], "sourceApiVersion": "67.0"}
99
+ EOF
100
+ fi
101
+
102
+ FLOW_DIR="force-app/main/default/flows"
103
+ mkdir -p "$FLOW_DIR"
104
+ FLOW_FILE="${FLOW_DIR}/${FLOW_API_NAME}.flow-meta.xml"
105
+ cp "$TEMPLATE_FILE" "$FLOW_FILE"
106
+
107
+ # Update startDate to today
108
+ TODAY=$(date +%Y-%m-%d)
109
+ sed_inplace "s|<startDate>[^<]*</startDate>|<startDate>${TODAY}</startDate>|g" "$FLOW_FILE"
110
+
111
+ echo " Schedule start: $TODAY (daily at 11:55 UTC)"
112
+ echo " Status: Active"
113
+ echo ""
114
+
115
+ # Deploy
116
+ echo " Deploying..."
117
+ DEPLOY_RESULT=$(sf project deploy start --source-dir "$FLOW_FILE" --target-org "$ORG_ALIAS" --json 2>/dev/null || echo '{"status":1}')
118
+
119
+ if echo "$DEPLOY_RESULT" | jq -e '.status == 0' >/dev/null 2>&1; then
120
+ EXISTING_FLOW="$FLOW_API_NAME"
121
+ IS_ACTIVE="true"
122
+ echo " Deploy SUCCEEDED"
123
+ echo ""
124
+ echo "Flow '$FLOW_API_NAME' deployed and activated."
125
+ echo "Suggestions will generate daily at 11:55 UTC."
126
+ else
127
+ DEPLOY_ERR=$(echo "$DEPLOY_RESULT" | jq -r '.result.details.componentFailures[0].problem // .message // "unknown"' 2>/dev/null || echo "unknown")
128
+ echo " Deploy FAILED: $DEPLOY_ERR"
129
+ echo ""
130
+ echo "Falling back to manual Setup UI clone..."
131
+ echo ""
132
+ fi
133
+ fi
134
+
135
+ # If still no flow, guide user through UI
136
+ if [[ -z "$EXISTING_FLOW" ]]; then
137
+ echo "ACTION REQUIRED: Clone the template manually via Setup UI."
138
+ echo ""
139
+ echo " The template flow is in the 'sales_pipe_mgmt' managed namespace."
140
+ echo ""
141
+ echo " Steps:"
142
+ echo " 1. Open Setup -> Flows"
143
+ echo " 2. Find 'Process Field Update Suggestions' (marked with template icon)"
144
+ echo " 3. Open the flow -> click 'Save As'"
145
+ echo " 4. Label: 'Process Field Update Suggestions' -> Save"
146
+ echo " 5. Click 'Activate' on the new flow"
147
+ echo " 6. Re-run this script to verify"
148
+ echo ""
149
+ exit 1
150
+ fi
151
+ fi
152
+
153
+ # --- Flow Found ---
154
+ if [[ -n "$EXISTING_FLOW" ]]; then
155
+ echo "found: $EXISTING_FLOW (active: $IS_ACTIVE)"
156
+ echo ""
157
+ fi
158
+
159
+ # --- Already Active ---
160
+ if [[ "$IS_ACTIVE" == "true" ]]; then
161
+ echo "Flow '$EXISTING_FLOW' is ACTIVE."
162
+ echo "Suggestions will generate on schedule. No action needed."
163
+ echo ""
164
+ echo "Done."
165
+ exit 0
166
+ fi
167
+
168
+ # --- Exists But Inactive: Activate ---
169
+ echo "Flow '$EXISTING_FLOW' exists but is INACTIVE. Activating..."
170
+ echo ""
171
+
172
+ # Ensure sfdx-project.json exists for retrieve/deploy
173
+ if [[ ! -f "sfdx-project.json" ]]; then
174
+ cat > sfdx-project.json << 'EOF'
175
+ {"packageDirectories": [{"path": "force-app", "default": true}], "sourceApiVersion": "67.0"}
176
+ EOF
177
+ fi
178
+
179
+ FLOW_DIR="force-app/main/default/flows"
180
+ mkdir -p "$FLOW_DIR"
181
+
182
+ # Retrieve the CLONE (not the template — the clone is in the org's namespace and IS retrievable)
183
+ echo " Retrieving flow metadata..."
184
+ sf project retrieve start \
185
+ --metadata "Flow:${EXISTING_FLOW}" \
186
+ --target-org "$ORG_ALIAS" \
187
+ --json 2>/dev/null >/dev/null || true
188
+
189
+ FLOW_FILE="${FLOW_DIR}/${EXISTING_FLOW}.flow-meta.xml"
190
+
191
+ if [[ ! -f "$FLOW_FILE" ]]; then
192
+ echo " Warning: Could not retrieve flow file."
193
+ echo " Activate manually: Setup -> Flows -> ${EXISTING_FLOW} -> Activate"
194
+ exit 1
195
+ fi
196
+
197
+ echo " Retrieved successfully."
198
+
199
+ # Transform status to Active
200
+ echo " Setting status to Active..."
201
+ sed_inplace 's|<status>Draft</status>|<status>Active</status>|g' "$FLOW_FILE"
202
+ sed_inplace 's|<status>Obsolete</status>|<status>Active</status>|g' "$FLOW_FILE"
203
+
204
+ # Deploy
205
+ echo " Deploying activated flow..."
206
+ DEPLOY_RESULT=$(sf project deploy start \
207
+ --metadata "Flow:${EXISTING_FLOW}" \
208
+ --target-org "$ORG_ALIAS" \
209
+ --json 2>/dev/null)
210
+
211
+ if echo "$DEPLOY_RESULT" | jq -e '.status == 0' >/dev/null 2>&1; then
212
+ echo " Deployed successfully."
213
+ else
214
+ ERROR_MSG=$(echo "$DEPLOY_RESULT" | jq -r '.message // .result.details.componentFailures[0].problem // "unknown error"' 2>/dev/null || echo "unknown error")
215
+ echo " Warning: Deploy may have failed: $ERROR_MSG"
216
+ echo " Activate manually: Setup -> Flows -> ${EXISTING_FLOW} -> Activate"
217
+ fi
218
+
219
+ echo ""
220
+
221
+ # --- Final Verification ---
222
+ echo "Verifying final state..."
223
+ sleep 2 # Brief propagation wait
224
+
225
+ VERIFY_RESULT=$(sf data query \
226
+ --query "SELECT ApiName, IsActive FROM FlowDefinitionView WHERE ApiName = '${EXISTING_FLOW}'" \
227
+ --target-org "$ORG_ALIAS" \
228
+ --json 2>/dev/null)
229
+
230
+ FINAL_ACTIVE=$(echo "$VERIFY_RESULT" | jq -r '.result.records[0].IsActive // "unknown"' 2>/dev/null || echo "unknown")
231
+
232
+ if [[ "$FINAL_ACTIVE" == "true" ]]; then
233
+ echo " Flow: $EXISTING_FLOW"
234
+ echo " Status: ACTIVE"
235
+ echo ""
236
+ echo "Flow activated successfully. Suggestions will generate on schedule."
237
+ else
238
+ echo " Flow: $EXISTING_FLOW"
239
+ echo " Status: $FINAL_ACTIVE"
240
+ echo ""
241
+ echo " Flow may need manual activation via Setup UI."
242
+ fi
243
+
244
+ echo ""
245
+ echo "Done."
246
+ echo ""
247
+ echo "Next steps:"
248
+ echo " 1. Verify agent is active (./create-agent.sh $ORG_ALIAS)"
249
+ echo " 2. Configure opportunity stages (see references/opportunity-stages.md)"
250
+ echo " 3. Wait for schedule to trigger, or test with manual notes/emails"