@salesforce/afv-skills 1.55.0 → 1.56.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 (220) hide show
  1. package/package.json +1 -1
  2. package/skills/agentforce-generate/SKILL.md +8 -0
  3. package/skills/agentforce-generate/references/actions-reference.md +2 -2
  4. package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
  5. package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
  6. package/skills/agentforce-observe/SKILL.md +13 -9
  7. package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
  8. package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
  9. package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
  10. package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
  11. package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
  12. package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
  13. package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
  14. package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
  15. package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
  16. package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
  17. package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
  18. package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
  19. package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
  20. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
  21. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
  22. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
  23. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
  24. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
  25. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
  26. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
  27. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
  28. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
  29. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
  30. package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
  31. package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
  32. package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
  33. package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
  34. package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
  35. package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
  36. package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
  37. package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
  38. package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
  39. package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
  40. package/skills/dx-org-analyze/SKILL.md +0 -1
  41. package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
  42. package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
  43. package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
  44. package/skills/dx-org-manage/SKILL.md +6 -50
  45. package/skills/dx-org-manage/examples/README.md +10 -16
  46. package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
  47. package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
  48. package/skills/dx-org-shape-manage/SKILL.md +4 -3
  49. package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
  50. package/skills/experience-accessibility-validate/SKILL.md +8 -5
  51. package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
  52. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
  53. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
  54. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
  55. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
  56. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
  57. package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
  58. package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
  59. package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
  60. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
  61. package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
  62. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
  63. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
  64. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
  65. package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
  66. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
  67. package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
  68. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
  69. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
  70. package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
  71. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
  72. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
  73. package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
  74. package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
  75. package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
  76. package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
  77. package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
  78. package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
  79. package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
  80. package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
  81. package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
  82. package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
  83. package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
  84. package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
  85. package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
  86. package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
  87. package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
  88. package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
  89. package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
  90. package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
  91. package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
  92. package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
  93. package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
  94. package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
  95. package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
  96. package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
  97. package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
  98. package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
  99. package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
  100. package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
  101. package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
  102. package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
  103. package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
  104. package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
  105. package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
  106. package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
  107. package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
  108. package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
  109. package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
  110. package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
  111. package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
  112. package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
  113. package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
  114. package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
  115. package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
  116. package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
  117. package/skills/mobile-apps-create/SKILL.md +1 -1
  118. package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
  119. package/skills/platform-sandbox-configure/SKILL.md +108 -133
  120. package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
  121. package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
  122. package/skills/platform-widget-generate/SKILL.md +26 -18
  123. package/skills/platform-widget-generate/examples/formulas.json +191 -0
  124. package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
  125. package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
  126. package/skills/sales-call-scoring-configure/SKILL.md +318 -0
  127. package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
  128. package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
  129. package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
  130. package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
  131. package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
  132. package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
  133. package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
  134. package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
  135. package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
  136. package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
  137. package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
  138. package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
  139. package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
  140. package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
  141. package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
  142. package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
  143. package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
  144. package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
  145. package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
  146. package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
  147. package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
  148. package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
  149. package/skills/service-de-channel-activate/SKILL.md +6 -5
  150. package/skills/service-de-channel-create/SKILL.md +3 -3
  151. package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
  152. package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
  153. package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
  154. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
  155. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
  156. package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
  157. package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
  158. package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
  159. package/skills/service-helpagent-coordinate/SKILL.md +3 -2
  160. package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
  161. package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
  162. package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
  163. package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
  164. package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
  165. package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
  166. package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
  167. package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
  168. package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
  169. package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
  170. package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
  171. package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
  172. package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
  173. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
  174. package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
  175. package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
  176. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
  177. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
  178. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
  179. package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
  180. package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
  181. package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
  182. package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
  183. package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
  184. package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
  185. package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
  186. package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
  187. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
  188. package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
  189. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
  190. package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
  191. package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
  192. package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
  193. package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
  194. package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
  195. package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
  196. package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
  197. package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
  198. package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
  199. package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
  200. package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
  201. package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
  202. package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
  203. package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
  204. package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
  205. package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
  206. package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
  207. package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
  208. package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
  209. package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
  210. package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
  211. package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
  212. package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
  213. package/skills/dx-org-manage/references/cli_flags.md +0 -67
  214. package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
  215. package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
  216. package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
  217. package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
  218. package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
  219. /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
  220. /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Analyze a Field Service Mobile flow and generate a migration assessment.
4
+
5
+ Usage:
6
+ python3 analyze_flow.py <input_flow.xml> <output_analysis.json>
7
+
8
+ Outputs a JSON report with:
9
+ - Screen and field inventory
10
+ - Component compatibility mapping (via the authoritative capability catalog)
11
+ - A Data Capture Gap Report: components with NO DC equivalent + capability gaps
12
+ - Automation complexity
13
+ - Risk score (GREEN/YELLOW/RED)
14
+ - Manual intervention checklist
15
+
16
+ Classification is keyed on the REAL FSM Flow vocabulary (fieldType first,
17
+ extensionName only for ComponentInstance) via scripts/fsm_dc_catalog.py — NOT
18
+ Lightning component names. See reference/fsm-dc-capability-catalog.md.
19
+ """
20
+
21
+ import sys
22
+ import json
23
+ import os
24
+ import xml.etree.ElementTree as ET
25
+ from typing import Dict, List, Any
26
+
27
+ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
28
+ import fsm_dc_catalog as catalog
29
+ import flow_input # noqa: E402
30
+ from flow_xml_utils import NS, _findtext, _findall, _findall_deep # noqa: E402,F401
31
+ import cud_analysis # noqa: E402
32
+
33
+
34
+ def analyze_flow(root: ET.Element) -> Dict[str, Any]:
35
+ """Generate analysis from a validated flow root.
36
+
37
+ Input is the <Flow> element returned by flow_input.load_and_validate_flow;
38
+ parsing and validation happen there, not here.
39
+ """
40
+ flow_name = _findtext(root, 'label') or 'Unknown'
41
+ process_type = _findtext(root, 'processType') or 'Unknown'
42
+ api_version = _findtext(root, 'apiVersion') or '(unspecified)'
43
+
44
+ screens = _findall_deep(root, 'screens')
45
+ screen_count = len(screens)
46
+
47
+ fields: List[Dict[str, Any]] = []
48
+ manual_steps: List[str] = []
49
+ # Gap report: FSM components that will NOT migrate to DC.
50
+ component_gaps: List[Dict[str, Any]] = []
51
+
52
+ for screen_idx, screen in enumerate(screens, 1):
53
+ screen_name = _findtext(screen, 'name') or f'Screen{screen_idx}'
54
+ screen_label = _findtext(screen, 'label') or screen_name
55
+
56
+ for field in _findall(screen, 'fields'):
57
+ field_name = _findtext(field, 'name')
58
+ field_type = _findtext(field, 'fieldType')
59
+ data_type = _findtext(field, 'dataType')
60
+ extension = _findtext(field, 'extensionName')
61
+
62
+ result = catalog.classify(field_type, data_type, extension)
63
+ status = result['status']
64
+
65
+ fields.append({
66
+ 'name': field_name,
67
+ 'screen': screen_label,
68
+ 'fieldType': field_type,
69
+ 'dataType': data_type,
70
+ 'extensionName': extension,
71
+ 'dcExtension': result['dc_extension'],
72
+ 'dcFieldType': result['dc_field_type'],
73
+ 'status': status,
74
+ 'note': result['note'],
75
+ })
76
+
77
+ if catalog.is_gap(status):
78
+ component_gaps.append({
79
+ 'field': field_name,
80
+ 'screen': screen_label,
81
+ 'fieldType': field_type,
82
+ 'extensionName': extension,
83
+ 'status': status,
84
+ 'reason': result['note'],
85
+ })
86
+ manual_steps.append(
87
+ f'{status}: field "{field_name}" ({field_type}'
88
+ f'{"/" + extension if extension else ""}) on screen '
89
+ f'"{screen_label}" — {result["note"]}'
90
+ )
91
+
92
+ # Automation elements
93
+ automation = {
94
+ 'decisions': len(_findall_deep(root, 'decisions')),
95
+ 'recordLookups': len(_findall_deep(root, 'recordLookups')),
96
+ 'recordCreates': len(_findall_deep(root, 'recordCreates')),
97
+ 'recordUpdates': len(_findall_deep(root, 'recordUpdates')),
98
+ 'recordDeletes': len(_findall_deep(root, 'recordDeletes')),
99
+ 'apexCalls': len(_findall_deep(root, 'actionCalls')),
100
+ 'subflowCalls': len(_findall_deep(root, 'subflows')),
101
+ 'loops': len(_findall_deep(root, 'loops')),
102
+ }
103
+
104
+ # Capability-level gaps that this specific flow actually triggers.
105
+ triggered_capability_gaps = _triggered_capability_gaps(root, automation)
106
+
107
+ if automation['apexCalls'] > 0:
108
+ manual_steps.append('Convert Apex callouts to record lookups (Data Capture is offline-first — no Apex at runtime)')
109
+ if automation['subflowCalls'] > 0:
110
+ manual_steps.append('Ensure subflows are DataCaptureFlow type and contain no CUD; inline or convert AutoLaunched subflows')
111
+
112
+ # Coverage counts
113
+ mapped_count = sum(1 for f in fields if f['status'] == catalog.MAPPED)
114
+ gap_count = len(component_gaps)
115
+ total_fields = len(fields)
116
+
117
+ cud_report = cud_analysis.analyze_cud_placement(root)
118
+ cud_placement = {
119
+ 'hasMidFlowCud': cud_report.has_midflow,
120
+ 'compliant': [n.name for n in cud_report.cud_nodes if n.verdict == 'compliant'],
121
+ 'safeConsolidate': [n.name for n in cud_report.cud_nodes
122
+ if n.verdict == 'safe_consolidate'],
123
+ 'unsafeManual': [
124
+ {'node': n.name, 'position': n.position,
125
+ 'reason': '; '.join(n.blockers) or 'mid-flow CUD'}
126
+ for n in cud_report.cud_nodes if n.verdict == 'unsafe_manual'
127
+ ],
128
+ }
129
+ for n in cud_report.cud_nodes:
130
+ if n.verdict == 'safe_consolidate':
131
+ manual_steps.append(
132
+ f"Mid-flow {n.op} '{n.name}' (position {n.position}) — safe to "
133
+ f"consolidate to end-of-flow.")
134
+ elif n.verdict == 'unsafe_manual':
135
+ manual_steps.append(
136
+ f"Mid-flow {n.op} '{n.name}' (position {n.position}) — unsafe: "
137
+ f"{'; '.join(n.blockers)}. Restructure manually.")
138
+
139
+ # Risk score
140
+ if gap_count == 0 and automation['apexCalls'] == 0 and automation['subflowCalls'] == 0:
141
+ risk_score = 'GREEN'
142
+ elif total_fields and gap_count <= total_fields * 0.2:
143
+ risk_score = 'YELLOW'
144
+ else:
145
+ risk_score = 'RED'
146
+
147
+ # WI-8: a hazardous-but-deployable mid-flow CUD must never read GREEN.
148
+ if cud_placement['unsafeManual'] and risk_score == 'GREEN':
149
+ risk_score = 'YELLOW'
150
+
151
+ analysis = {
152
+ 'flowName': flow_name,
153
+ 'processType': process_type,
154
+ 'apiVersion': api_version,
155
+ 'screenCount': screen_count,
156
+ 'fieldCount': total_fields,
157
+ 'fields': fields,
158
+ 'automation': automation,
159
+ 'coverage': {
160
+ 'mapped': mapped_count,
161
+ 'gaps': gap_count,
162
+ },
163
+ # AC#3: the gap-detection output section, feeding WI-7/WI-10.
164
+ 'dataCaptureGapReport': {
165
+ 'componentGaps': component_gaps,
166
+ 'capabilityGaps': triggered_capability_gaps,
167
+ 'hasGaps': bool(component_gaps or triggered_capability_gaps),
168
+ },
169
+ 'cudPlacement': cud_placement,
170
+ 'riskScore': risk_score,
171
+ 'manualSteps': manual_steps,
172
+ }
173
+
174
+ return analysis
175
+
176
+
177
+ def _triggered_capability_gaps(root: ET.Element, automation: Dict[str, int]) -> List[Dict[str, str]]:
178
+ """Filter the catalog's capability gaps down to the ones this flow triggers."""
179
+ triggered: List[Dict[str, str]] = []
180
+ gaps = {g['gap']: g for g in catalog.capability_gaps()}
181
+
182
+ # No actions/buttons — triggered by PlainButtons fields OR actionCalls.
183
+ has_plain_buttons = any(
184
+ (_findtext(f, 'fieldType') == 'PlainButtons')
185
+ for s in _findall_deep(root, 'screens')
186
+ for f in _findall(s, 'fields')
187
+ )
188
+ if has_plain_buttons:
189
+ triggered.append(gaps['No actions / buttons'])
190
+
191
+ if automation['apexCalls'] > 0:
192
+ triggered.append(gaps['No Apex / action calls'])
193
+
194
+ # Fault paths — any element carrying a <faultConnector>.
195
+ if _findall_deep(root, 'faultConnector'):
196
+ triggered.append(gaps['No fault paths'])
197
+
198
+ if automation['subflowCalls'] > 0:
199
+ triggered.append(gaps['Subflows: DC-type only, no CUD'])
200
+
201
+ cud = automation['recordCreates'] + automation['recordUpdates'] + automation['recordDeletes']
202
+ if cud > 0:
203
+ triggered.append(gaps['CUD only at end of flow'])
204
+
205
+ return triggered
206
+
207
+
208
+ def main():
209
+ if len(sys.argv) != 3:
210
+ print(f"[ERROR] Missing required argument. "
211
+ f"Usage: {sys.argv[0]} <input_flow.xml> <output_analysis.json>\n"
212
+ f"Example: {sys.argv[0]} "
213
+ f"force-app/main/default/flows/MyFlow.flow-meta.xml /tmp/analysis.json",
214
+ file=sys.stderr)
215
+ sys.exit(2)
216
+
217
+ input_path = sys.argv[1]
218
+ output_path = sys.argv[2]
219
+
220
+ try:
221
+ root, warnings = flow_input.load_and_validate_flow(input_path)
222
+ except flow_input.FlowValidationError as e:
223
+ print(e.message, file=sys.stderr)
224
+ sys.exit(1)
225
+
226
+ for w in warnings:
227
+ print(w.message, file=sys.stderr)
228
+
229
+ analysis = analyze_flow(root)
230
+
231
+ with open(output_path, 'w') as f:
232
+ json.dump(analysis, f, indent=2)
233
+
234
+ print(f"\n{'='*60}")
235
+ print(f"Migration Analysis: {analysis['flowName']}")
236
+ print(f"{'='*60}")
237
+ print(f"Process Type: {analysis['processType']}")
238
+ print(f"API Version: {analysis['apiVersion']}")
239
+ print(f"Screens: {analysis['screenCount']}")
240
+ print(f"Fields: {analysis['fieldCount']}")
241
+ print(f"\nComponent Coverage:")
242
+ print(f" Mapped to DC: {analysis['coverage']['mapped']} fields")
243
+ print(f" Gaps (no path): {analysis['coverage']['gaps']} fields")
244
+ print(f"\nAutomation Elements:")
245
+ for key, count in analysis['automation'].items():
246
+ if count > 0:
247
+ print(f" {key}: {count}")
248
+
249
+ gap_report = analysis['dataCaptureGapReport']
250
+ print(f"\n{'─'*60}")
251
+ print(f"DATA CAPTURE GAP REPORT")
252
+ print(f"{'─'*60}")
253
+ if not gap_report['hasGaps']:
254
+ print(" No functionality gaps detected — all components map to DC.")
255
+ else:
256
+ if gap_report['componentGaps']:
257
+ print(f" Components with no DC equivalent ({len(gap_report['componentGaps'])}):")
258
+ for g in gap_report['componentGaps']:
259
+ ext = f"/{g['extensionName']}" if g['extensionName'] else ''
260
+ print(f" - [{g['status']}] {g['field']} ({g['fieldType']}{ext})")
261
+ print(f" {g['reason']}")
262
+ if gap_report['capabilityGaps']:
263
+ print(f" Capability-level gaps triggered ({len(gap_report['capabilityGaps'])}):")
264
+ for g in gap_report['capabilityGaps']:
265
+ print(f" - {g['gap']}: {g['detail']}")
266
+
267
+ print(f"\nRisk Score: {analysis['riskScore']}")
268
+ if analysis['manualSteps']:
269
+ print(f"\nManual Steps Required ({len(analysis['manualSteps'])}):")
270
+ for step in analysis['manualSteps']:
271
+ print(f" - {step}")
272
+
273
+ print(f"\nFull analysis written to: {output_path}\n")
274
+
275
+
276
+ if __name__ == '__main__':
277
+ main()