@salesforce/afv-skills 1.53.0 → 1.55.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 (51) hide show
  1. package/package.json +1 -1
  2. package/skills/dx-org-analyze/README.md +310 -0
  3. package/skills/dx-org-analyze/SKILL.md +261 -0
  4. package/skills/dx-org-analyze/references/collection-details.md +88 -0
  5. package/skills/dx-org-analyze/references/report-format.md +67 -0
  6. package/skills/dx-org-analyze/scripts/collect_org_data.py +823 -0
  7. package/skills/dx-org-analyze/scripts/compute_diff.py +1103 -0
  8. package/skills/dx-org-analyze/scripts/introspect_org.py +436 -0
  9. package/skills/dx-org-analyze/tests/README.md +46 -0
  10. package/skills/dx-org-analyze/tests/fixtures/org_a.json +76 -0
  11. package/skills/dx-org-analyze/tests/fixtures/org_b.json +70 -0
  12. package/skills/dx-org-analyze/tests/test_compute_diff.sh +284 -0
  13. package/skills/dx-org-analyze/tests/test_consistency.sh +428 -0
  14. package/skills/experience-design-validate/SKILL.md +163 -0
  15. package/skills/experience-design-validate/references/ai.md +54 -0
  16. package/skills/experience-design-validate/references/components.md +61 -0
  17. package/skills/experience-design-validate/references/craft.md +158 -0
  18. package/skills/experience-design-validate/references/data.md +59 -0
  19. package/skills/experience-design-validate/references/forms-flows.md +57 -0
  20. package/skills/experience-design-validate/references/interaction.md +53 -0
  21. package/skills/experience-design-validate/references/navigation.md +51 -0
  22. package/skills/experience-design-validate/references/performance.md +56 -0
  23. package/skills/experience-design-validate/references/records.md +60 -0
  24. package/skills/experience-design-validate/references/responsive.md +48 -0
  25. package/skills/experience-design-validate/references/scoring-rubric.md +257 -0
  26. package/skills/experience-design-validate/references/state.md +53 -0
  27. package/skills/experience-design-validate/references/trust.md +47 -0
  28. package/skills/experience-design-validate/references/usability.md +35 -0
  29. package/skills/experience-design-validate/references/visual-system.md +183 -0
  30. package/skills/service-agentforce-contact-center-coordinate/SKILL.md +170 -0
  31. package/skills/service-agentforce-contact-center-coordinate/assets/escalation-flow.flow-meta.xml +72 -0
  32. package/skills/service-agentforce-contact-center-coordinate/assets/omni-flow.flow-meta.xml +85 -0
  33. package/skills/service-agentforce-contact-center-coordinate/assets/report-template.md +52 -0
  34. package/skills/service-agentforce-contact-center-coordinate/references/agentforce-prerequisite.md +31 -0
  35. package/skills/service-agentforce-contact-center-coordinate/references/messaging_channel.md +76 -0
  36. package/skills/service-agentforce-contact-center-coordinate/references/number_management_api.md +78 -0
  37. package/skills/service-agentforce-contact-center-coordinate/references/omni-flow-routing.md +74 -0
  38. package/skills/service-agentforce-contact-center-coordinate/references/setup_summary.md +36 -0
  39. package/skills/service-agentforce-contact-center-coordinate/references/verification_and_errors.md +42 -0
  40. package/skills/service-agentforce-contact-center-coordinate/scripts/check-agentforce-prereq.sh +54 -0
  41. package/skills/service-agentforce-contact-center-coordinate/scripts/create-routing-flows.sh +49 -0
  42. package/skills/service-agentforce-contact-center-coordinate/scripts/create-voice-agent.sh +73 -0
  43. package/skills/service-agentforce-contact-center-coordinate/scripts/create-voice-channel.sh +66 -0
  44. package/skills/service-agentforce-contact-center-coordinate/scripts/fetch-numbers.sh +21 -0
  45. package/skills/service-agentforce-contact-center-coordinate/scripts/lib.sh +46 -0
  46. package/skills/service-agentforce-contact-center-coordinate/scripts/prepare-agent-workdir.sh +21 -0
  47. package/skills/service-agentforce-contact-center-coordinate/scripts/procure-number.sh +24 -0
  48. package/skills/service-agentforce-contact-center-coordinate/scripts/resolve-acc-queue.sh +27 -0
  49. package/skills/service-agentforce-contact-center-coordinate/scripts/resolve-channel-line.sh +37 -0
  50. package/skills/service-agentforce-contact-center-coordinate/scripts/resolve-flow-definition.sh +33 -0
  51. package/skills/service-agentforce-contact-center-coordinate/scripts/verify-number-live.sh +63 -0
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env bash
2
+ # Tests for compute_diff.py using fixture data.
3
+ # Validates diff computation, drift score, and report output.
4
+ #
5
+ # Usage: bash tests/test_compute_diff.sh
6
+ # Exit 0 on all-pass, 1 on any failure.
7
+
8
+ set -u
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ COMPUTE="$SCRIPT_DIR/../scripts/compute_diff.py"
12
+ FIXTURES="$SCRIPT_DIR/fixtures"
13
+ TMPDIR=$(mktemp -d)
14
+ trap "rm -rf $TMPDIR" EXIT
15
+
16
+ PASS=0
17
+ FAIL=0
18
+
19
+ pass() { echo " PASS: $1"; PASS=$((PASS + 1)); }
20
+ fail() { echo " FAIL: $1"; FAIL=$((FAIL + 1)); }
21
+
22
+ # ============================================================
23
+ echo "=== Test 1: Produces JSON and markdown output ==="
24
+ # ============================================================
25
+
26
+ python3 "$COMPUTE" \
27
+ --org-a "$FIXTURES/org_a.json" \
28
+ --org-b "$FIXTURES/org_b.json" \
29
+ --output "$TMPDIR/diff" \
30
+ --format both \
31
+ --org-a-label "OrgA" \
32
+ --org-b-label "OrgB" >/dev/null 2>&1
33
+
34
+ if [[ -f "$TMPDIR/diff.json" ]]; then
35
+ pass "JSON output created"
36
+ else
37
+ fail "JSON output not created"
38
+ fi
39
+
40
+ if [[ -f "$TMPDIR/diff.md" ]]; then
41
+ pass "Markdown output created"
42
+ else
43
+ fail "Markdown output not created"
44
+ fi
45
+
46
+ # ============================================================
47
+ echo ""
48
+ echo "=== Test 2: JSON structure has required keys ==="
49
+ # ============================================================
50
+
51
+ if [[ -f "$TMPDIR/diff.json" ]]; then
52
+ for key in "metadata_stats" "permissions" "org_values" "drift"; do
53
+ if python3 -c "import json; d=json.load(open('$TMPDIR/diff.json')); assert '$key' in d" 2>/dev/null; then
54
+ pass "JSON has key '$key'"
55
+ else
56
+ fail "JSON missing key '$key'"
57
+ fi
58
+ done
59
+ fi
60
+
61
+ # ============================================================
62
+ echo ""
63
+ echo "=== Test 3: Drift score is computed correctly ==="
64
+ # ============================================================
65
+
66
+ if [[ -f "$TMPDIR/diff.json" ]]; then
67
+ python3 -c "
68
+ import json
69
+ d = json.load(open('$TMPDIR/diff.json'))['drift']
70
+ assert 0 <= d['overall'] <= 100, f'overall out of range: {d[\"overall\"]}'
71
+ assert 0 <= d['metadata'] <= 100
72
+ assert 0 <= d['permission'] <= 100
73
+ assert 0 <= d['profile'] <= 100
74
+ assert d['level'] in ('LOW', 'MODERATE', 'HIGH', 'CRITICAL')
75
+ print(f' overall={d[\"overall\"]}% level={d[\"level\"]}')
76
+ " 2>/dev/null && pass "Drift score valid and in range" || fail "Drift score invalid"
77
+ fi
78
+
79
+ # ============================================================
80
+ echo ""
81
+ echo "=== Test 4: Metadata diff detects known differences ==="
82
+ # ============================================================
83
+
84
+ if [[ -f "$TMPDIR/diff.json" ]]; then
85
+ python3 -c "
86
+ import json
87
+ stats = json.load(open('$TMPDIR/diff.json'))['metadata_stats']
88
+ apex = [s for s in stats if s['type'] == 'ApexClass'][0]
89
+ assert apex['a_only'] == 1, f'Expected 1 a_only ApexClass, got {apex[\"a_only\"]}'
90
+ assert apex['b_only'] == 1, f'Expected 1 b_only ApexClass, got {apex[\"b_only\"]}'
91
+ assert apex['shared'] == 1, f'Expected 1 shared ApexClass, got {apex[\"shared\"]}'
92
+ assert 'OnlyInA' in apex['a_only_names']
93
+ assert 'OnlyInB' in apex['b_only_names']
94
+ assert 'SharedClass' in apex['shared_names']
95
+ co = [s for s in stats if s['type'] == 'CustomObject'][0]
96
+ assert co['a_only'] == 1 and co['b_only'] == 0
97
+ " 2>/dev/null && pass "Metadata diff correct for fixtures" || fail "Metadata diff wrong"
98
+ fi
99
+
100
+ # ============================================================
101
+ echo ""
102
+ echo "=== Test 5: Permission diff detects known differences ==="
103
+ # ============================================================
104
+
105
+ if [[ -f "$TMPDIR/diff.json" ]]; then
106
+ python3 -c "
107
+ import json
108
+ p = json.load(open('$TMPDIR/diff.json'))['permissions']
109
+ assert 'ApiEnabled' in p['a_only'], f'ApiEnabled should be a_only'
110
+ assert 'ApexRest' in p['a_only'], f'ApexRest should be a_only'
111
+ assert 'DisabledInA' in p['b_only'], f'DisabledInA should be b_only'
112
+ assert 'OnlyInB' in p['b_only'], f'OnlyInB should be b_only'
113
+ assert p['shared_count'] == 1, f'Expected 1 shared perm, got {p[\"shared_count\"]}'
114
+ " 2>/dev/null && pass "Permission diff correct for fixtures" || fail "Permission diff wrong"
115
+ fi
116
+
117
+ # ============================================================
118
+ echo ""
119
+ echo "=== Test 6: Org values diff detects known differences ==="
120
+ # ============================================================
121
+
122
+ if [[ -f "$TMPDIR/diff.json" ]]; then
123
+ python3 -c "
124
+ import json
125
+ v = json.load(open('$TMPDIR/diff.json'))['org_values']
126
+ names = [d['name'] for d in v['diffs']]
127
+ assert 'OrgEdition' in names, 'OrgEdition should differ'
128
+ assert 'MaxCustomObjects' in names, 'MaxCustomObjects should differ'
129
+ assert 'DataStorage' in names, 'DataStorage should differ'
130
+ assert 'SharedValue' not in names, 'SharedValue should not differ'
131
+ assert v['total'] == 4, f'Expected 4 total values, got {v[\"total\"]}'
132
+ assert len(v['diffs']) == 3, f'Expected 3 diffs, got {len(v[\"diffs\"])}'
133
+ " 2>/dev/null && pass "Org values diff correct for fixtures" || fail "Org values diff wrong"
134
+ fi
135
+
136
+ # ============================================================
137
+ echo ""
138
+ echo "=== Test 7: Managed packages excluded from diff ==="
139
+ # ============================================================
140
+
141
+ if [[ -f "$TMPDIR/diff.json" ]]; then
142
+ python3 -c "
143
+ import json
144
+ stats = json.load(open('$TMPDIR/diff.json'))['metadata_stats']
145
+ apex = [s for s in stats if s['type'] == 'ApexClass'][0]
146
+ assert 'ManagedPkg' not in apex['a_only_names'], 'ManagedPkg should be excluded'
147
+ assert apex['a_count'] == 2, f'Expected 2 custom ApexClass in A (excl managed), got {apex[\"a_count\"]}'
148
+ " 2>/dev/null && pass "Managed packages excluded" || fail "Managed packages not excluded"
149
+ fi
150
+
151
+ # ============================================================
152
+ echo ""
153
+ echo "=== Test 8: Markdown report has required sections ==="
154
+ # ============================================================
155
+
156
+ if [[ -f "$TMPDIR/diff.md" ]]; then
157
+ for section in "Drift Score" "Summary Statistics" "Detailed Differences" "Org Permissions" "Org Values"; do
158
+ if grep -qF "$section" "$TMPDIR/diff.md"; then
159
+ pass "Markdown has section: $section"
160
+ else
161
+ fail "Markdown missing section: $section"
162
+ fi
163
+ done
164
+ fi
165
+
166
+ # ============================================================
167
+ echo ""
168
+ echo "=== Test 9: Markdown uses provided labels ==="
169
+ # ============================================================
170
+
171
+ if [[ -f "$TMPDIR/diff.md" ]]; then
172
+ if grep -qF "OrgA" "$TMPDIR/diff.md" && grep -qF "OrgB" "$TMPDIR/diff.md"; then
173
+ pass "Markdown uses custom labels OrgA/OrgB"
174
+ else
175
+ fail "Markdown not using custom labels"
176
+ fi
177
+ fi
178
+
179
+ # ============================================================
180
+ echo ""
181
+ echo "=== Test 10: Installed package diff ==="
182
+ # ============================================================
183
+
184
+ if [[ -f "$TMPDIR/diff.json" ]]; then
185
+ python3 -c "
186
+ import json
187
+ p = json.load(open('$TMPDIR/diff.json'))['installed_packages']
188
+ assert p['a_total'] == 3, f'Expected 3 packages in A, got {p[\"a_total\"]}'
189
+ assert p['b_total'] == 3, f'Expected 3 packages in B, got {p[\"b_total\"]}'
190
+ assert len(p['a_only']) == 1, f'Expected 1 a_only package, got {len(p[\"a_only\"])}'
191
+ assert p['a_only'][0]['namespace'] == 'apkg', f'Expected apkg, got {p[\"a_only\"][0][\"namespace\"]}'
192
+ assert len(p['b_only']) == 1, f'Expected 1 b_only package, got {len(p[\"b_only\"])}'
193
+ assert p['b_only'][0]['namespace'] == 'bpkg'
194
+ assert len(p['version_mismatches']) == 1, f'Expected 1 version mismatch, got {len(p[\"version_mismatches\"])}'
195
+ assert p['version_mismatches'][0]['namespace'] == 'vmpkg'
196
+ assert p['version_mismatches'][0]['a_version'] == '3.1'
197
+ assert p['version_mismatches'][0]['b_version'] == '4.0'
198
+ assert len(p['identical']) == 1, f'Expected 1 identical package, got {len(p[\"identical\"])}'
199
+ assert p['identical'][0]['namespace'] == 'sharedpkg'
200
+ " 2>/dev/null && pass "Package diff correct for fixtures" || fail "Package diff wrong"
201
+ fi
202
+
203
+ # ============================================================
204
+ echo ""
205
+ echo "=== Test 11: Markdown has installed packages section ==="
206
+ # ============================================================
207
+
208
+ if [[ -f "$TMPDIR/diff.md" ]]; then
209
+ if grep -qF "Installed Packages" "$TMPDIR/diff.md"; then
210
+ pass "Markdown has Installed Packages section"
211
+ else
212
+ fail "Markdown missing Installed Packages section"
213
+ fi
214
+ if grep -qF "Version Mismatch" "$TMPDIR/diff.md" && grep -qF "vmpkg" "$TMPDIR/diff.md"; then
215
+ pass "Markdown shows version mismatch details"
216
+ else
217
+ fail "Markdown missing version mismatch details"
218
+ fi
219
+ fi
220
+
221
+ # ============================================================
222
+ echo ""
223
+ echo "=== Test 12: License diff ==="
224
+ # ============================================================
225
+
226
+ if [[ -f "$TMPDIR/diff.json" ]]; then
227
+ python3 -c "
228
+ import json
229
+ lic = json.load(open('$TMPDIR/diff.json'))['licenses']
230
+ u = lic['user']
231
+ assert u['a_count'] == 3 and u['b_count'] == 3
232
+ assert len(u['a_only']) == 1, f'Expected 1 a_only user license, got {len(u[\"a_only\"])}'
233
+ assert u['a_only'][0]['Name'] == 'OnlyInA License'
234
+ assert len(u['b_only']) == 1
235
+ assert u['b_only'][0]['Name'] == 'OnlyInB License'
236
+ assert len(u['diffs']) == 1, f'Expected 1 user license diff, got {len(u[\"diffs\"])}'
237
+ assert u['diffs'][0]['name'] == 'Salesforce'
238
+ assert u['diffs'][0]['a_total'] == 10
239
+ assert u['diffs'][0]['b_total'] == 25
240
+ ps = lic['permission_set']
241
+ assert len(ps['diffs']) == 1
242
+ assert ps['diffs'][0]['name'] == 'SalesforceCPQ'
243
+ " 2>/dev/null && pass "License diff correct for fixtures" || fail "License diff wrong"
244
+ fi
245
+
246
+ # ============================================================
247
+ echo ""
248
+ echo "=== Test 13: Markdown has licenses section ==="
249
+ # ============================================================
250
+
251
+ if [[ -f "$TMPDIR/diff.md" ]]; then
252
+ if grep -qF "Licenses" "$TMPDIR/diff.md"; then
253
+ pass "Markdown has Licenses section"
254
+ else
255
+ fail "Markdown missing Licenses section"
256
+ fi
257
+ fi
258
+
259
+ # ============================================================
260
+ echo ""
261
+ echo "=== Test 14: Exits 1 on missing input file ==="
262
+ # ============================================================
263
+
264
+ python3 "$COMPUTE" \
265
+ --org-a "/nonexistent/file.json" \
266
+ --org-b "$FIXTURES/org_b.json" \
267
+ --output "$TMPDIR/fail" 2>/dev/null
268
+
269
+ if [[ $? -eq 1 ]]; then
270
+ pass "Exits 1 on missing input"
271
+ else
272
+ fail "Should exit 1 on missing input"
273
+ fi
274
+
275
+ # ============================================================
276
+ echo ""
277
+ echo "================================================"
278
+ echo "Results: $PASS passed, $FAIL failed"
279
+ echo "================================================"
280
+
281
+ if [[ $FAIL -gt 0 ]]; then
282
+ exit 1
283
+ fi
284
+ exit 0