@salesforce/afv-skills 1.14.0 → 1.16.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 (365) hide show
  1. package/package.json +1 -1
  2. package/skills/activating-datacloud/SKILL.md +0 -1
  3. package/skills/analyzing-omnistudio-dependencies/SKILL.md +0 -1
  4. package/skills/applying-slds/SKILL.md +322 -0
  5. package/skills/applying-slds/checklists.md +83 -0
  6. package/skills/applying-slds/examples.md +283 -0
  7. package/skills/applying-slds/guidance/README.md +83 -0
  8. package/skills/applying-slds/guidance/blueprints-index.md +213 -0
  9. package/skills/applying-slds/guidance/icons-guidance.md +186 -0
  10. package/skills/applying-slds/guidance/overviews/borders.md +236 -0
  11. package/skills/applying-slds/guidance/overviews/color.md +266 -0
  12. package/skills/applying-slds/guidance/overviews/display-density.md +366 -0
  13. package/skills/applying-slds/guidance/overviews/icons.md +240 -0
  14. package/skills/applying-slds/guidance/overviews/illustrations.md +235 -0
  15. package/skills/applying-slds/guidance/overviews/shadows.md +176 -0
  16. package/skills/applying-slds/guidance/overviews/spacing.md +216 -0
  17. package/skills/applying-slds/guidance/overviews/typography.md +323 -0
  18. package/skills/applying-slds/guidance/overviews/utilities.md +542 -0
  19. package/skills/applying-slds/guidance/slds-development-guide.md +288 -0
  20. package/skills/applying-slds/guidance/styling-hooks/borders.md +202 -0
  21. package/skills/applying-slds/guidance/styling-hooks/color/expressive-palette-hooks.md +153 -0
  22. package/skills/applying-slds/guidance/styling-hooks/color/index.md +171 -0
  23. package/skills/applying-slds/guidance/styling-hooks/color/semantic/accent-hooks.md +204 -0
  24. package/skills/applying-slds/guidance/styling-hooks/color/semantic/feedback-hooks.md +768 -0
  25. package/skills/applying-slds/guidance/styling-hooks/color/semantic/surface-hooks.md +337 -0
  26. package/skills/applying-slds/guidance/styling-hooks/color/system-hooks.md +132 -0
  27. package/skills/applying-slds/guidance/styling-hooks/index.md +327 -0
  28. package/skills/applying-slds/guidance/styling-hooks/shadows.md +238 -0
  29. package/skills/applying-slds/guidance/styling-hooks/spacing.md +254 -0
  30. package/skills/applying-slds/guidance/styling-hooks/typography.md +448 -0
  31. package/skills/applying-slds/guidance/utilities/alignment.md +119 -0
  32. package/skills/applying-slds/guidance/utilities/borders.md +131 -0
  33. package/skills/applying-slds/guidance/utilities/box.md +125 -0
  34. package/skills/applying-slds/guidance/utilities/color.md +165 -0
  35. package/skills/applying-slds/guidance/utilities/dark-mode.md +111 -0
  36. package/skills/applying-slds/guidance/utilities/description-list.md +168 -0
  37. package/skills/applying-slds/guidance/utilities/floats.md +117 -0
  38. package/skills/applying-slds/guidance/utilities/grid.md +264 -0
  39. package/skills/applying-slds/guidance/utilities/horizontal-list.md +110 -0
  40. package/skills/applying-slds/guidance/utilities/hyphenation.md +84 -0
  41. package/skills/applying-slds/guidance/utilities/index.md +205 -0
  42. package/skills/applying-slds/guidance/utilities/interactions.md +89 -0
  43. package/skills/applying-slds/guidance/utilities/layout.md +109 -0
  44. package/skills/applying-slds/guidance/utilities/line-clamp.md +131 -0
  45. package/skills/applying-slds/guidance/utilities/margin.md +155 -0
  46. package/skills/applying-slds/guidance/utilities/media-object.md +161 -0
  47. package/skills/applying-slds/guidance/utilities/name-value-list.md +152 -0
  48. package/skills/applying-slds/guidance/utilities/padding.md +155 -0
  49. package/skills/applying-slds/guidance/utilities/position.md +177 -0
  50. package/skills/applying-slds/guidance/utilities/print.md +114 -0
  51. package/skills/applying-slds/guidance/utilities/scrollable.md +126 -0
  52. package/skills/applying-slds/guidance/utilities/sizing.md +190 -0
  53. package/skills/applying-slds/guidance/utilities/themes.md +121 -0
  54. package/skills/applying-slds/guidance/utilities/truncate.md +127 -0
  55. package/skills/applying-slds/guidance/utilities/typography.md +166 -0
  56. package/skills/applying-slds/guidance/utilities/vertical-list.md +166 -0
  57. package/skills/applying-slds/guidance/utilities/visibility.md +228 -0
  58. package/skills/applying-slds/metadata/README.md +84 -0
  59. package/skills/applying-slds/metadata/blueprints/components/accordion.yaml +304 -0
  60. package/skills/applying-slds/metadata/blueprints/components/activity-timeline.yaml +92 -0
  61. package/skills/applying-slds/metadata/blueprints/components/alert.yaml +103 -0
  62. package/skills/applying-slds/metadata/blueprints/components/app-launcher.yaml +94 -0
  63. package/skills/applying-slds/metadata/blueprints/components/avatar-group.yaml +81 -0
  64. package/skills/applying-slds/metadata/blueprints/components/avatar.yaml +97 -0
  65. package/skills/applying-slds/metadata/blueprints/components/badges.yaml +102 -0
  66. package/skills/applying-slds/metadata/blueprints/components/brand-band.yaml +198 -0
  67. package/skills/applying-slds/metadata/blueprints/components/breadcrumbs.yaml +95 -0
  68. package/skills/applying-slds/metadata/blueprints/components/builder-header.yaml +192 -0
  69. package/skills/applying-slds/metadata/blueprints/components/button-groups.yaml +82 -0
  70. package/skills/applying-slds/metadata/blueprints/components/button-icons.yaml +295 -0
  71. package/skills/applying-slds/metadata/blueprints/components/buttons.yaml +230 -0
  72. package/skills/applying-slds/metadata/blueprints/components/cards.yaml +124 -0
  73. package/skills/applying-slds/metadata/blueprints/components/carousel.yaml +140 -0
  74. package/skills/applying-slds/metadata/blueprints/components/chat.yaml +179 -0
  75. package/skills/applying-slds/metadata/blueprints/components/checkbox-button-group.yaml +192 -0
  76. package/skills/applying-slds/metadata/blueprints/components/checkbox-button.yaml +204 -0
  77. package/skills/applying-slds/metadata/blueprints/components/checkbox-toggle.yaml +177 -0
  78. package/skills/applying-slds/metadata/blueprints/components/checkbox.yaml +108 -0
  79. package/skills/applying-slds/metadata/blueprints/components/color-picker.yaml +172 -0
  80. package/skills/applying-slds/metadata/blueprints/components/combobox.yaml +136 -0
  81. package/skills/applying-slds/metadata/blueprints/components/counter.yaml +147 -0
  82. package/skills/applying-slds/metadata/blueprints/components/data-tables.yaml +157 -0
  83. package/skills/applying-slds/metadata/blueprints/components/datepickers.yaml +130 -0
  84. package/skills/applying-slds/metadata/blueprints/components/datetime-picker.yaml +155 -0
  85. package/skills/applying-slds/metadata/blueprints/components/docked-composer.yaml +201 -0
  86. package/skills/applying-slds/metadata/blueprints/components/docked-form-footer.yaml +161 -0
  87. package/skills/applying-slds/metadata/blueprints/components/docked-utility-bar.yaml +175 -0
  88. package/skills/applying-slds/metadata/blueprints/components/drop-zone.yaml +115 -0
  89. package/skills/applying-slds/metadata/blueprints/components/dueling-picklist.yaml +196 -0
  90. package/skills/applying-slds/metadata/blueprints/components/dynamic-icons.yaml +128 -0
  91. package/skills/applying-slds/metadata/blueprints/components/dynamic-menu.yaml +141 -0
  92. package/skills/applying-slds/metadata/blueprints/components/expandable-section.yaml +115 -0
  93. package/skills/applying-slds/metadata/blueprints/components/expression.yaml +143 -0
  94. package/skills/applying-slds/metadata/blueprints/components/feeds.yaml +125 -0
  95. package/skills/applying-slds/metadata/blueprints/components/file-selector.yaml +154 -0
  96. package/skills/applying-slds/metadata/blueprints/components/files.yaml +119 -0
  97. package/skills/applying-slds/metadata/blueprints/components/form-element.yaml +145 -0
  98. package/skills/applying-slds/metadata/blueprints/components/global-header.yaml +120 -0
  99. package/skills/applying-slds/metadata/blueprints/components/global-navigation.yaml +100 -0
  100. package/skills/applying-slds/metadata/blueprints/components/icons.yaml +138 -0
  101. package/skills/applying-slds/metadata/blueprints/components/illustration.yaml +205 -0
  102. package/skills/applying-slds/metadata/blueprints/components/input.yaml +151 -0
  103. package/skills/applying-slds/metadata/blueprints/components/list-builder.yaml +127 -0
  104. package/skills/applying-slds/metadata/blueprints/components/lookups.yaml +132 -0
  105. package/skills/applying-slds/metadata/blueprints/components/map.yaml +118 -0
  106. package/skills/applying-slds/metadata/blueprints/components/menus.yaml +134 -0
  107. package/skills/applying-slds/metadata/blueprints/components/modals.yaml +152 -0
  108. package/skills/applying-slds/metadata/blueprints/components/notifications.yaml +88 -0
  109. package/skills/applying-slds/metadata/blueprints/components/page-headers.yaml +135 -0
  110. package/skills/applying-slds/metadata/blueprints/components/panels.yaml +149 -0
  111. package/skills/applying-slds/metadata/blueprints/components/path.yaml +154 -0
  112. package/skills/applying-slds/metadata/blueprints/components/picklist.yaml +125 -0
  113. package/skills/applying-slds/metadata/blueprints/components/pills.yaml +154 -0
  114. package/skills/applying-slds/metadata/blueprints/components/popovers.yaml +120 -0
  115. package/skills/applying-slds/metadata/blueprints/components/progress-bar.yaml +110 -0
  116. package/skills/applying-slds/metadata/blueprints/components/progress-indicator.yaml +133 -0
  117. package/skills/applying-slds/metadata/blueprints/components/progress-ring.yaml +102 -0
  118. package/skills/applying-slds/metadata/blueprints/components/prompt.yaml +126 -0
  119. package/skills/applying-slds/metadata/blueprints/components/publishers.yaml +178 -0
  120. package/skills/applying-slds/metadata/blueprints/components/radio-button-group.yaml +172 -0
  121. package/skills/applying-slds/metadata/blueprints/components/radio-group.yaml +112 -0
  122. package/skills/applying-slds/metadata/blueprints/components/rich-text-editor.yaml +135 -0
  123. package/skills/applying-slds/metadata/blueprints/components/scoped-notifications.yaml +188 -0
  124. package/skills/applying-slds/metadata/blueprints/components/scoped-tabs.yaml +97 -0
  125. package/skills/applying-slds/metadata/blueprints/components/select.yaml +127 -0
  126. package/skills/applying-slds/metadata/blueprints/components/setup-assistant.yaml +152 -0
  127. package/skills/applying-slds/metadata/blueprints/components/slider.yaml +111 -0
  128. package/skills/applying-slds/metadata/blueprints/components/spinners.yaml +135 -0
  129. package/skills/applying-slds/metadata/blueprints/components/split-view.yaml +112 -0
  130. package/skills/applying-slds/metadata/blueprints/components/summary-detail.yaml +103 -0
  131. package/skills/applying-slds/metadata/blueprints/components/tabs.yaml +138 -0
  132. package/skills/applying-slds/metadata/blueprints/components/textarea.yaml +116 -0
  133. package/skills/applying-slds/metadata/blueprints/components/tiles.yaml +108 -0
  134. package/skills/applying-slds/metadata/blueprints/components/timepicker.yaml +111 -0
  135. package/skills/applying-slds/metadata/blueprints/components/toast.yaml +154 -0
  136. package/skills/applying-slds/metadata/blueprints/components/tooltips.yaml +107 -0
  137. package/skills/applying-slds/metadata/blueprints/components/tree-grid.yaml +116 -0
  138. package/skills/applying-slds/metadata/blueprints/components/trees.yaml +116 -0
  139. package/skills/applying-slds/metadata/blueprints/components/trial-bar.yaml +112 -0
  140. package/skills/applying-slds/metadata/blueprints/components/vertical-navigation.yaml +130 -0
  141. package/skills/applying-slds/metadata/blueprints/components/vertical-tabs.yaml +140 -0
  142. package/skills/applying-slds/metadata/blueprints/components/visual-picker.yaml +150 -0
  143. package/skills/applying-slds/metadata/blueprints/components/welcome-mat.yaml +136 -0
  144. package/skills/applying-slds/metadata/hooks-index.json +6272 -0
  145. package/skills/applying-slds/metadata/icon-metadata.json +38466 -0
  146. package/skills/applying-slds/metadata/utilities-index.json +21912 -0
  147. package/skills/applying-slds/references/component-selection.md +112 -0
  148. package/skills/applying-slds/references/icons-decision-guide.md +124 -0
  149. package/skills/applying-slds/references/styling-decision-guide.md +228 -0
  150. package/skills/applying-slds/references/utilities-quick-ref.md +125 -0
  151. package/skills/applying-slds/scripts/search-blueprints.cjs +117 -0
  152. package/skills/applying-slds/scripts/search-hooks.cjs +139 -0
  153. package/skills/applying-slds/scripts/search-icons.cjs +174 -0
  154. package/skills/applying-slds/scripts/search-utilities.cjs +161 -0
  155. package/skills/building-mobile-apps/SKILL.md +0 -1
  156. package/skills/building-omnistudio-callable-apex/SKILL.md +0 -1
  157. package/skills/building-omnistudio-datamapper/SKILL.md +0 -1
  158. package/skills/building-omnistudio-flexcard/SKILL.md +0 -1
  159. package/skills/building-omnistudio-integration-procedure/SKILL.md +0 -1
  160. package/skills/building-omnistudio-omniscript/SKILL.md +0 -1
  161. package/skills/building-sf-integrations/SKILL.md +0 -1
  162. package/skills/configuring-connected-apps/SKILL.md +0 -1
  163. package/skills/connecting-datacloud/SKILL.md +0 -1
  164. package/skills/creating-b2b-commerce-store/SKILL.md +0 -1
  165. package/skills/debugging-apex-logs/SKILL.md +0 -1
  166. package/skills/deploying-metadata/SKILL.md +0 -1
  167. package/skills/deploying-omnistudio-datapacks/SKILL.md +0 -1
  168. package/skills/developing-agentforce/SKILL.md +0 -1
  169. package/skills/fetching-salesforce-docs/SKILL.md +0 -1
  170. package/skills/generating-custom-lightning-type/SKILL.md +17 -39
  171. package/skills/generating-custom-lightning-type/assets/primitive-types-and-constraints.md +41 -0
  172. package/skills/generating-custom-lightning-type/references/widget-rendition.md +124 -0
  173. package/skills/generating-lwc-components/SKILL.md +0 -1
  174. package/skills/generating-mermaid-diagrams/SKILL.md +0 -1
  175. package/skills/generating-visual-diagrams/SKILL.md +0 -1
  176. package/skills/handling-sf-data/SKILL.md +0 -1
  177. package/skills/harmonizing-datacloud/SKILL.md +0 -1
  178. package/skills/integrating-b2b-commerce-open-code-components/SKILL.md +0 -1
  179. package/skills/investigating-agentforce-architecture/README.md +156 -0
  180. package/skills/investigating-agentforce-architecture/SKILL.md +230 -0
  181. package/skills/investigating-agentforce-architecture/assets/cli/describe_sobject.yaml +16 -0
  182. package/skills/investigating-agentforce-architecture/assets/cli/describe_tooling_sobject.yaml +17 -0
  183. package/skills/investigating-agentforce-architecture/assets/cli/list_metadata_genaiprompttemplate.yaml +17 -0
  184. package/skills/investigating-agentforce-architecture/assets/cli/org_display.yaml +15 -0
  185. package/skills/investigating-agentforce-architecture/assets/cli/retrieve_genai_plugin.yaml +18 -0
  186. package/skills/investigating-agentforce-architecture/assets/cli/show_access_token.yaml +27 -0
  187. package/skills/investigating-agentforce-architecture/assets/mermaid/action_tree.mmd +20 -0
  188. package/skills/investigating-agentforce-architecture/assets/mermaid/data_flow.mmd +19 -0
  189. package/skills/investigating-agentforce-architecture/assets/mermaid/dependency_graph.mmd +19 -0
  190. package/skills/investigating-agentforce-architecture/assets/mermaid/invocation_sequence.mmd +20 -0
  191. package/skills/investigating-agentforce-architecture/assets/mermaid/planner_state.mmd +18 -0
  192. package/skills/investigating-agentforce-architecture/assets/soql/apex_class_bodies_by_ids.soql +3 -0
  193. package/skills/investigating-agentforce-architecture/assets/soql/apex_class_bodies_by_names.soql +3 -0
  194. package/skills/investigating-agentforce-architecture/assets/soql/bot_definition_details.soql +3 -0
  195. package/skills/investigating-agentforce-architecture/assets/soql/bot_version_lookup.soql +4 -0
  196. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_by_ids.soql +3 -0
  197. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_ids_by_names.soql +3 -0
  198. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_view_by_durable_ids.soql +4 -0
  199. package/skills/investigating-agentforce-architecture/assets/soql/flow_metadata_by_id.soql +3 -0
  200. package/skills/investigating-agentforce-architecture/assets/soql/functions_by_plugins.soql +5 -0
  201. package/skills/investigating-agentforce-architecture/assets/soql/planner_attrs_by_parent_ids.soql +3 -0
  202. package/skills/investigating-agentforce-architecture/assets/soql/planner_bundle_functions.soql +3 -0
  203. package/skills/investigating-agentforce-architecture/assets/soql/planner_definition_by_agent_chain.soql +3 -0
  204. package/skills/investigating-agentforce-architecture/assets/soql/plugin_functions_by_plugin_ids.soql +3 -0
  205. package/skills/investigating-agentforce-architecture/assets/soql/plugin_instructions_by_plugin_ids.soql +3 -0
  206. package/skills/investigating-agentforce-architecture/assets/soql/plugins_by_planner.soql +4 -0
  207. package/skills/investigating-agentforce-architecture/references/architecture_sections.md +243 -0
  208. package/skills/investigating-agentforce-architecture/references/contract.json +244 -0
  209. package/skills/investigating-agentforce-architecture/references/soql_fields.md +512 -0
  210. package/skills/investigating-agentforce-architecture/scripts/_shared/__init__.py +1 -0
  211. package/skills/investigating-agentforce-architecture/scripts/_shared/fs_guard.py +329 -0
  212. package/skills/investigating-agentforce-architecture/scripts/_shared/paths.py +110 -0
  213. package/skills/investigating-agentforce-architecture/scripts/_shared/runtime.py +59 -0
  214. package/skills/investigating-agentforce-architecture/scripts/_shared/sql.py +10 -0
  215. package/skills/investigating-agentforce-architecture/scripts/cache_check.py +234 -0
  216. package/skills/investigating-agentforce-architecture/scripts/config.py +131 -0
  217. package/skills/investigating-agentforce-architecture/scripts/fetch_soql.py +689 -0
  218. package/skills/investigating-agentforce-architecture/scripts/finalize.py +295 -0
  219. package/skills/investigating-agentforce-architecture/scripts/main.py +2835 -0
  220. package/skills/investigating-agentforce-architecture/scripts/metadata_listing.py +265 -0
  221. package/skills/investigating-agentforce-architecture/scripts/parallel_retrieve.py +69 -0
  222. package/skills/investigating-agentforce-architecture/scripts/parse_bundle.py +215 -0
  223. package/skills/investigating-agentforce-architecture/scripts/parse_wave.py +845 -0
  224. package/skills/investigating-agentforce-architecture/scripts/probe_channels.py +302 -0
  225. package/skills/investigating-agentforce-architecture/scripts/render_architecture.py +1043 -0
  226. package/skills/investigating-agentforce-architecture/scripts/resolve_bot.py +255 -0
  227. package/skills/investigating-agentforce-architecture/scripts/resolve_invocation_target.py +130 -0
  228. package/skills/investigating-agentforce-architecture/scripts/rest_client.py +763 -0
  229. package/skills/investigating-agentforce-architecture/scripts/retrieve_planner.py +13 -0
  230. package/skills/investigating-agentforce-architecture/scripts/sf_cli.py +242 -0
  231. package/skills/investigating-agentforce-architecture/scripts/soql_loader.py +253 -0
  232. package/skills/investigating-agentforce-architecture/scripts/summarize_tree.py +143 -0
  233. package/skills/investigating-agentforce-architecture/scripts/tests/__init__.py +0 -0
  234. package/skills/investigating-agentforce-architecture/scripts/tests/_bootstrap.py +23 -0
  235. package/skills/investigating-agentforce-architecture/scripts/tests/fixtures/__init__.py +0 -0
  236. package/skills/investigating-agentforce-architecture/scripts/tests/fixtures/genai_payloads.py +400 -0
  237. package/skills/investigating-agentforce-architecture/scripts/tests/test_cache_check.py +307 -0
  238. package/skills/investigating-agentforce-architecture/scripts/tests/test_cache_check_main.py +283 -0
  239. package/skills/investigating-agentforce-architecture/scripts/tests/test_config.py +115 -0
  240. package/skills/investigating-agentforce-architecture/scripts/tests/test_end_to_end_fixture.py +651 -0
  241. package/skills/investigating-agentforce-architecture/scripts/tests/test_finalize.py +278 -0
  242. package/skills/investigating-agentforce-architecture/scripts/tests/test_flow_children_inflation.py +582 -0
  243. package/skills/investigating-agentforce-architecture/scripts/tests/test_fs_guard.py +113 -0
  244. package/skills/investigating-agentforce-architecture/scripts/tests/test_iterative_wave_b.py +478 -0
  245. package/skills/investigating-agentforce-architecture/scripts/tests/test_main_pipeline.py +3359 -0
  246. package/skills/investigating-agentforce-architecture/scripts/tests/test_parallel_retrieve.py +131 -0
  247. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_bundle.py +400 -0
  248. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave.py +644 -0
  249. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_classifiers.py +224 -0
  250. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_helpers.py +380 -0
  251. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_main.py +397 -0
  252. package/skills/investigating-agentforce-architecture/scripts/tests/test_per_branch_visited.py +244 -0
  253. package/skills/investigating-agentforce-architecture/scripts/tests/test_probe_channels.py +359 -0
  254. package/skills/investigating-agentforce-architecture/scripts/tests/test_probe_cli_recipes.py +185 -0
  255. package/skills/investigating-agentforce-architecture/scripts/tests/test_render_architecture.py +810 -0
  256. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_bot.py +203 -0
  257. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_creds.py +157 -0
  258. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_invocation_target.py +145 -0
  259. package/skills/investigating-agentforce-architecture/scripts/tests/test_rest_client.py +1253 -0
  260. package/skills/investigating-agentforce-architecture/scripts/tests/test_runtime_override.py +100 -0
  261. package/skills/investigating-agentforce-architecture/scripts/tests/test_sf_cli.py +261 -0
  262. package/skills/investigating-agentforce-architecture/scripts/tests/test_signature_stamping.py +466 -0
  263. package/skills/investigating-agentforce-architecture/scripts/tests/test_soql_loader.py +501 -0
  264. package/skills/investigating-agentforce-architecture/scripts/tests/test_summarize_tree.py +241 -0
  265. package/skills/investigating-agentforce-architecture/scripts/tests/test_write_emit_ctx.py +480 -0
  266. package/skills/investigating-agentforce-architecture/tools/emit_env.py +157 -0
  267. package/skills/investigating-agentforce-architecture/tools/emit_result.py +262 -0
  268. package/skills/investigating-agentforce-architecture/tools/sanitize.py +33 -0
  269. package/skills/investigating-agentforce-architecture/tools/write_emit_ctx.py +332 -0
  270. package/skills/investigating-agentforce-d360/README.md +123 -0
  271. package/skills/investigating-agentforce-d360/SKILL.md +163 -0
  272. package/skills/investigating-agentforce-d360/assets/dc/app_generation.sql +51 -0
  273. package/skills/investigating-agentforce-d360/assets/dc/content_category.sql +44 -0
  274. package/skills/investigating-agentforce-d360/assets/dc/content_quality.sql +41 -0
  275. package/skills/investigating-agentforce-d360/assets/dc/discover_sessions.sql +36 -0
  276. package/skills/investigating-agentforce-d360/assets/dc/feedback.sql +47 -0
  277. package/skills/investigating-agentforce-d360/assets/dc/feedback_details.sql +38 -0
  278. package/skills/investigating-agentforce-d360/assets/dc/gateway_records.sql +45 -0
  279. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_llm.sql +50 -0
  280. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_metadata.sql +44 -0
  281. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_tags.sql +42 -0
  282. package/skills/investigating-agentforce-d360/assets/dc/gateway_requests.sql +89 -0
  283. package/skills/investigating-agentforce-d360/assets/dc/gateway_responses.sql +43 -0
  284. package/skills/investigating-agentforce-d360/assets/dc/generations.sql +52 -0
  285. package/skills/investigating-agentforce-d360/assets/dc/interactions.sql +53 -0
  286. package/skills/investigating-agentforce-d360/assets/dc/messages.sql +53 -0
  287. package/skills/investigating-agentforce-d360/assets/dc/messaging_session.sql +37 -0
  288. package/skills/investigating-agentforce-d360/assets/dc/moment_interactions.sql +34 -0
  289. package/skills/investigating-agentforce-d360/assets/dc/moments.sql +39 -0
  290. package/skills/investigating-agentforce-d360/assets/dc/participants.sql +48 -0
  291. package/skills/investigating-agentforce-d360/assets/dc/sessions.sql +78 -0
  292. package/skills/investigating-agentforce-d360/assets/dc/steps.sql +64 -0
  293. package/skills/investigating-agentforce-d360/assets/dc/tag_associations.sql +46 -0
  294. package/skills/investigating-agentforce-d360/assets/dc/tag_definition_associations.sql +37 -0
  295. package/skills/investigating-agentforce-d360/assets/dc/tag_definitions.sql +50 -0
  296. package/skills/investigating-agentforce-d360/assets/dc/tags.sql +37 -0
  297. package/skills/investigating-agentforce-d360/assets/dc/telemetry_spans.sql +55 -0
  298. package/skills/investigating-agentforce-d360/references/artifacts.md +50 -0
  299. package/skills/investigating-agentforce-d360/references/dc_dmo_fields.md +823 -0
  300. package/skills/investigating-agentforce-d360/references/dc_pipeline_contract.md +608 -0
  301. package/skills/investigating-agentforce-d360/scripts/_shared/__init__.py +2 -0
  302. package/skills/investigating-agentforce-d360/scripts/_shared/cli_override.py +98 -0
  303. package/skills/investigating-agentforce-d360/scripts/_shared/fs_guard.py +334 -0
  304. package/skills/investigating-agentforce-d360/scripts/_shared/paths.py +155 -0
  305. package/skills/investigating-agentforce-d360/scripts/_shared/runtime.py +59 -0
  306. package/skills/investigating-agentforce-d360/scripts/_shared/sql.py +14 -0
  307. package/skills/investigating-agentforce-d360/scripts/assemble_dc.py +1624 -0
  308. package/skills/investigating-agentforce-d360/scripts/config.py +45 -0
  309. package/skills/investigating-agentforce-d360/scripts/dc.py +188 -0
  310. package/skills/investigating-agentforce-d360/scripts/discover_sessions.py +556 -0
  311. package/skills/investigating-agentforce-d360/scripts/fetch_dc.py +1045 -0
  312. package/skills/investigating-agentforce-d360/scripts/render_dc.py +1750 -0
  313. package/skills/investigating-agentforce-d360/scripts/resolve_session.py +264 -0
  314. package/skills/investigating-agentforce-d360/scripts/storage.py +92 -0
  315. package/skills/investigating-agentforce-d360/scripts/tests/__init__.py +0 -0
  316. package/skills/investigating-agentforce-d360/scripts/tests/_bootstrap.py +15 -0
  317. package/skills/investigating-agentforce-d360/scripts/tests/fixtures/__init__.py +0 -0
  318. package/skills/investigating-agentforce-d360/scripts/tests/fixtures/synthetic_session.py +424 -0
  319. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_bootstrap_and_mode.py +115 -0
  320. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_gateway_direct.py +220 -0
  321. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_gateway_direct_integration.py +158 -0
  322. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_helpers.py +287 -0
  323. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_integration.py +247 -0
  324. package/skills/investigating-agentforce-d360/scripts/tests/test_dc_and_resolve_session.py +433 -0
  325. package/skills/investigating-agentforce-d360/scripts/tests/test_discover_sessions.py +458 -0
  326. package/skills/investigating-agentforce-d360/scripts/tests/test_discover_sessions_grep_ci.py +193 -0
  327. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_helpers.py +266 -0
  328. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_identity.py +528 -0
  329. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_main.py +251 -0
  330. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_waterfall.py +229 -0
  331. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_waterfall_full.py +283 -0
  332. package/skills/investigating-agentforce-d360/scripts/tests/test_identity_coherence.py +327 -0
  333. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_branches.py +256 -0
  334. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_gateway_direct.py +130 -0
  335. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_helpers.py +291 -0
  336. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_integration.py +220 -0
  337. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_planner_llm_calls.py +284 -0
  338. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_show_prompts_gating.py +215 -0
  339. package/skills/investigating-agentforce-d360/scripts/tests/test_resolve_from_disk.py +100 -0
  340. package/skills/investigating-agentforce-d360/scripts/tests/test_resolve_session_main.py +149 -0
  341. package/skills/investigating-agentforce-d360/scripts/tests/test_runtime_override.py +104 -0
  342. package/skills/investigating-agentforce-d360/scripts/tests/test_session_shape.py +95 -0
  343. package/skills/investigating-agentforce-d360/scripts/tests/test_session_shape_dropped_by_stdm.py +85 -0
  344. package/skills/managing-managed-event-subscription/SKILL.md +152 -0
  345. package/skills/managing-managed-event-subscription/assets/managed-event-subscription-template.xml +20 -0
  346. package/skills/managing-managed-event-subscription/references/delete-guide.md +57 -0
  347. package/skills/managing-managed-event-subscription/references/topic-name-formats.md +26 -0
  348. package/skills/managing-managed-event-subscription/references/update-constraints.md +30 -0
  349. package/skills/modeling-omnistudio-epc-catalog/SKILL.md +0 -1
  350. package/skills/observing-agentforce/SKILL.md +0 -1
  351. package/skills/orchestrating-datacloud/SKILL.md +0 -1
  352. package/skills/preparing-datacloud/SKILL.md +0 -1
  353. package/skills/querying-soql/SKILL.md +0 -1
  354. package/skills/retrieving-datacloud/SKILL.md +0 -1
  355. package/skills/running-apex-tests/SKILL.md +0 -1
  356. package/skills/running-code-analyzer/SKILL.md +0 -1
  357. package/skills/segmenting-datacloud/SKILL.md +0 -1
  358. package/skills/testing-agentforce/SKILL.md +0 -1
  359. package/skills/uplifting-components-to-slds2/SKILL.md +3 -2
  360. package/skills/uplifting-components-to-slds2/references/color-hooks-decision-guide.md +30 -9
  361. package/skills/uplifting-components-to-slds2/references/examples.md +24 -6
  362. package/skills/validating-slds/SKILL.md +262 -0
  363. package/skills/validating-slds/references/quality-checks.md +308 -0
  364. package/skills/validating-slds/references/report-format.md +302 -0
  365. package/skills/validating-slds/scripts/analyze-quality.cjs +521 -0
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ """Bot + version resolution via two sf data query calls.
3
+
4
+ Replaces the old agent's Phase 0b–0e (bot/version SOQL, natural-key sort,
5
+ error-block assembly) + Phase 1's parallel BotDefinition SOQL. One process,
6
+ one RESULT-block emission point.
7
+
8
+ Flow:
9
+ 1. `sf data query` for BotVersion WHERE BotDefinition.DeveloperName=$AGENT_API_NAME.
10
+ 2. If 0 rows → follow-up query for AVAILABLE_BOTS, emit STATUS=AGENT_NOT_FOUND.
11
+ 3. Natural-key sort versions (v10 > v9 > v2 > v1); pick explicit match or
12
+ Active highest-numbered auto-pick.
13
+ 4. If no match → emit STATUS=AGENT_VERSION_NOT_FOUND with AVAILABLE_VERSIONS
14
+ in `v5(Active),v4(Inactive),...` form.
15
+ 5. Run a second `sf data query` for BotDefinition (MasterLabel, Description,
16
+ AgentType, Type, AgentTemplate, BotSource) and write `_bot_definition.json`
17
+ for parse_wave.py.
18
+
19
+ On success, prints eval-friendly KV lines to stdout:
20
+ BOT_FOUND=true
21
+ BOT_ID=<18-char>
22
+ BOT_MASTER_LABEL=<shlex-quoted>
23
+ AGENT_VERSION=<resolved version>
24
+ VERSION_AUTO_PICKED=true|false
25
+
26
+ Also writes `$WORK_DIR/_bot_versions.json` + `$WORK_DIR/_bot_definition.json`
27
+ as raw sidecars (archived into the cache by finalize.py).
28
+
29
+ Usage:
30
+ eval "$(python3 resolve_bot.py)"
31
+
32
+ Inputs (env):
33
+ ORG_ALIAS required — sf CLI target org alias
34
+ AGENT_API_NAME required — BotDefinition.DeveloperName
35
+ AGENT_VERSION optional — explicit BotVersion.DeveloperName (if empty, auto-pick)
36
+ WORK_DIR required — sidecar JSON landing area
37
+ ORG_ID_15 optional — used for error-block context
38
+ ORG_ID_18 optional — used for error-block context
39
+ ERROR_TEE optional — tee path for error RESULT blocks
40
+
41
+ Outputs:
42
+ stdout on success: eval-able KV lines (above)
43
+ stdout on error: full STATUS=AGENT_NOT_FOUND|AGENT_VERSION_NOT_FOUND block
44
+ files: $WORK_DIR/_bot_versions.json, _bot_definition.json, _all_bots.json (on miss)
45
+ exit 0 on success, 1 on any failure branch
46
+ """
47
+ import json
48
+ import os
49
+ import pathlib
50
+ import re
51
+ import shlex
52
+ import subprocess
53
+ import sys
54
+
55
+
56
+ def scrub(s) -> str:
57
+ if not isinstance(s, str):
58
+ s = "" if s is None else str(s)
59
+ bad = set("`$\"\\\r\t\0\n")
60
+ return "".join(c for c in s if c not in bad)
61
+
62
+
63
+ def emit_error_block(status: str, error_detail: str, extras: dict) -> None:
64
+ """Write a terminal RESULT block to stdout + $ERROR_TEE, then exit 1."""
65
+ lines = [
66
+ "=== RESULT ===",
67
+ f"STATUS={status}",
68
+ f"ERROR_DETAIL={scrub(error_detail)}",
69
+ f"AGENT_API_NAME={scrub(os.environ.get('AGENT_API_NAME', ''))}",
70
+ f"ORG_ID_15={scrub(os.environ.get('ORG_ID_15', ''))}",
71
+ f"ORG_ID_18={scrub(os.environ.get('ORG_ID_18', ''))}",
72
+ ]
73
+ for k, v in extras.items():
74
+ lines.append(f"{k}={scrub(v)}")
75
+ block = "\n".join(lines) + "\n"
76
+
77
+ tee_path = os.environ.get("ERROR_TEE")
78
+ if tee_path:
79
+ try:
80
+ p = pathlib.Path(tee_path)
81
+ p.parent.mkdir(parents=True, exist_ok=True)
82
+ tmp = p.with_suffix(p.suffix + ".tmp")
83
+ tmp.write_text(block)
84
+ os.replace(tmp, p)
85
+ except OSError:
86
+ pass
87
+
88
+ sys.stdout.write(block)
89
+ sys.exit(1)
90
+
91
+
92
+ def run_sf_query(query: str, out_path: pathlib.Path, org_alias: str) -> dict:
93
+ """Run `sf data query --json` and return parsed JSON (or {} on failure)."""
94
+ try:
95
+ result = subprocess.run(
96
+ ["sf", "data", "query",
97
+ "--target-org", org_alias,
98
+ "--json",
99
+ "--query", query],
100
+ capture_output=True, text=True, timeout=60,
101
+ )
102
+ except (subprocess.TimeoutExpired, FileNotFoundError) as e:
103
+ emit_error_block(
104
+ "AUTH_REQUIRED",
105
+ f"sf data query failed ({type(e).__name__}: {e}) — check sf CLI install + auth",
106
+ {},
107
+ )
108
+ return {} # unreachable
109
+ if result.returncode != 0:
110
+ # Print stderr to help user debug, then bail as AUTH_REQUIRED (most
111
+ # common cause is the target-org alias not being logged in)
112
+ emit_error_block(
113
+ "AUTH_REQUIRED",
114
+ f"sf data query returned rc={result.returncode}: {result.stderr[:200]}",
115
+ {},
116
+ )
117
+ try:
118
+ out_path.write_text(result.stdout)
119
+ return json.loads(result.stdout)
120
+ except (OSError, json.JSONDecodeError) as e:
121
+ emit_error_block(
122
+ "AUTH_REQUIRED",
123
+ f"sf data query JSON parse error: {e}",
124
+ {},
125
+ )
126
+ return {} # unreachable
127
+
128
+
129
+ def natural_key(v: str):
130
+ return [int(p) if p.isdigit() else p for p in re.split(r"(\d+)", v or "")]
131
+
132
+
133
+ def main() -> int:
134
+ try:
135
+ org_alias = os.environ["ORG_ALIAS"]
136
+ agent_api_name = os.environ["AGENT_API_NAME"]
137
+ work_dir = pathlib.Path(os.environ["WORK_DIR"])
138
+ except KeyError as e:
139
+ sys.stderr.write(f"resolve_bot.py: missing env {e}\n")
140
+ return 1
141
+
142
+ # Defense-in-depth: bash harness pre-validates AGENT_API_NAME via
143
+ # fs_guard, but importers that call resolve_bot.main() directly bypass
144
+ # that gate — and the SOQL below is built with f-strings. Re-validate
145
+ # here so the regex check is local to the SOQL construction. Mirrors
146
+ # fetch_soql.py's belt-and-braces validation.
147
+ from config import fs_guard # re-exported from _shared/
148
+ try:
149
+ fs_guard.validate_api_name(agent_api_name, label="AGENT_API_NAME")
150
+ except fs_guard.ValidationError as e:
151
+ emit_error_block("INVALID_INPUT", str(e), {})
152
+ return 1 # unreachable
153
+
154
+ explicit_version = os.environ.get("AGENT_VERSION", "").strip()
155
+ work_dir.mkdir(parents=True, exist_ok=True)
156
+
157
+ # --- Step 1: BotVersion query (with BotDefinition join) ---
158
+ q_versions = (
159
+ "SELECT Id, DeveloperName, Status, BotDefinitionId, "
160
+ "BotDefinition.DeveloperName, BotDefinition.MasterLabel "
161
+ f"FROM BotVersion WHERE BotDefinition.DeveloperName='{agent_api_name}'"
162
+ )
163
+ versions_json = run_sf_query(q_versions, work_dir / "_bot_versions.json", org_alias)
164
+ records = (versions_json.get("result") or {}).get("records") or []
165
+
166
+ # --- Step 2: AGENT_NOT_FOUND branch ---
167
+ if not records:
168
+ q_all = "SELECT DeveloperName FROM BotDefinition ORDER BY DeveloperName"
169
+ all_bots = run_sf_query(q_all, work_dir / "_all_bots.json", org_alias)
170
+ bots_csv = ",".join(
171
+ r.get("DeveloperName", "")
172
+ for r in ((all_bots.get("result") or {}).get("records") or [])
173
+ if r.get("DeveloperName")
174
+ )
175
+ emit_error_block(
176
+ "AGENT_NOT_FOUND",
177
+ f"BotDefinition.DeveloperName '{agent_api_name}' not found in org {org_alias}",
178
+ {"AVAILABLE_BOTS": bots_csv},
179
+ )
180
+ return 1 # unreachable
181
+
182
+ # --- Step 3: sort (natural-key, DESC) + pick ---
183
+ records.sort(key=lambda r: natural_key(r.get("DeveloperName") or ""), reverse=True)
184
+ picked = None
185
+ if explicit_version:
186
+ for v in records:
187
+ if v.get("DeveloperName") == explicit_version:
188
+ picked = v
189
+ break
190
+ version_auto_picked = False
191
+ else:
192
+ for v in records:
193
+ if v.get("Status") == "Active":
194
+ picked = v
195
+ break
196
+ version_auto_picked = True
197
+
198
+ # --- Step 4: AGENT_VERSION_NOT_FOUND branch ---
199
+ if not picked:
200
+ vers_csv = ",".join(
201
+ f"{v.get('DeveloperName', '?')}({v.get('Status', '?')})"
202
+ for v in records
203
+ )
204
+ requested = explicit_version or "<auto-pick>"
205
+ emit_error_block(
206
+ "AGENT_VERSION_NOT_FOUND",
207
+ f"No matching BotVersion under BotDefinition {agent_api_name} (requested: '{requested}')",
208
+ {
209
+ "AVAILABLE_VERSIONS": vers_csv,
210
+ "BOT_ID": picked.get("BotDefinitionId") if picked else (records[0].get("BotDefinitionId") or ""),
211
+ },
212
+ )
213
+ return 1 # unreachable
214
+
215
+ bot_id = picked.get("BotDefinitionId") or ""
216
+ bd_node = picked.get("BotDefinition") or {}
217
+ bot_master_label = bd_node.get("MasterLabel") or ""
218
+ chosen_version = picked.get("DeveloperName") or ""
219
+
220
+ # --- Step 5: BotDefinition metadata (for parse_wave.py enrichment) ---
221
+ q_def = (
222
+ "SELECT DeveloperName, MasterLabel, Description, AgentType, Type, "
223
+ "AgentTemplate, BotSource FROM BotDefinition "
224
+ f"WHERE DeveloperName='{agent_api_name}' LIMIT 1"
225
+ )
226
+ try:
227
+ result = subprocess.run(
228
+ ["sf", "data", "query",
229
+ "--target-org", org_alias,
230
+ "--json",
231
+ "--query", q_def],
232
+ capture_output=True, text=True, timeout=30,
233
+ )
234
+ if result.returncode == 0:
235
+ (work_dir / "_bot_definition.json").write_text(result.stdout)
236
+ else:
237
+ # Non-fatal; parse_wave.py tolerates an empty bot_definition.json
238
+ (work_dir / "_bot_definition.json").write_text('{"result":{"records":[]}}')
239
+ except (subprocess.TimeoutExpired, FileNotFoundError):
240
+ (work_dir / "_bot_definition.json").write_text('{"result":{"records":[]}}')
241
+
242
+ # --- Success: emit eval-friendly lines ---
243
+ out_lines = [
244
+ "BOT_FOUND=true",
245
+ f"BOT_ID={shlex.quote(bot_id)}",
246
+ f"BOT_MASTER_LABEL={shlex.quote(bot_master_label)}",
247
+ f"AGENT_VERSION={shlex.quote(chosen_version)}",
248
+ f"VERSION_AUTO_PICKED={'true' if version_auto_picked else 'false'}",
249
+ ]
250
+ sys.stdout.write("\n".join(out_lines) + "\n")
251
+ return 0
252
+
253
+
254
+ if __name__ == "__main__":
255
+ sys.exit(main())
@@ -0,0 +1,130 @@
1
+ """NGA InvocationTarget ID-prefix router.
2
+
3
+ NGA bots store Salesforce Ids in GenAiFunctionDefinition.InvocationTarget,
4
+ not DeveloperNames. This module resolves the kind by the 3-char key prefix.
5
+
6
+ unknown prefixes MUST NEVER raise — Salesforce is free to introduce
7
+ new NGA target types (e.g., a hypothetical `0aN...` AgentCapability) and
8
+ the skill must degrade gracefully. Callers use `resolve_or_unresolved` to
9
+ append a `_unresolved[]` entry with a diagnostic reason and get back
10
+ `("unknown", "skip")` so the wave orchestrator can keep parsing.
11
+
12
+ Invariants:
13
+ * Only the 3-char prefix is consulted for Id-based routing — 15-char
14
+ and 18-char Ids both map the same way.
15
+ * `standard_action` kind is selected by caller context (bundle's
16
+ `invocationTargetType == "standardInvocableAction"`), not by prefix —
17
+ standard actions have no Id. Its presence in the Kind union is
18
+ scaffolding for call-site type-checking.
19
+ * `REGISTERED_PREFIXES` exposes the known prefix set as a frozenset for
20
+ tests and probe-channel validation.
21
+ """
22
+ from __future__ import annotations
23
+
24
+ import re
25
+ from typing import Literal
26
+
27
+ Kind = Literal[
28
+ "apex",
29
+ "flow_definition",
30
+ "flow_version",
31
+ "prompt_template",
32
+ "standard_action",
33
+ "unknown",
34
+ ]
35
+ Channel = Literal[
36
+ "tooling_soql",
37
+ "retrieve_required",
38
+ "skip",
39
+ ]
40
+
41
+ _PREFIX_MAP: dict[str, tuple[Kind, Channel]] = {
42
+ "01p": ("apex", "tooling_soql"),
43
+ "300": ("flow_definition", "tooling_soql"),
44
+ "301": ("flow_version", "tooling_soql"),
45
+ "0hf": ("prompt_template", "retrieve_required"),
46
+ }
47
+
48
+ # public reverse-lookup set. `frozenset` (not set) so callers can't
49
+ # mutate the authoritative table by accident.
50
+ REGISTERED_PREFIXES: frozenset[str] = frozenset(_PREFIX_MAP.keys())
51
+
52
+ # Salesforce Ids are 15 or 18 chars, alphanumeric only. This is the gate
53
+ # between "could be a real Id with an unknown prefix" (treat as an NGA
54
+ # addition we don't know about yet) and "garbage input" (empty, wrong
55
+ # length, bad characters — treat as invalid format).
56
+ _SF_ID_RE = re.compile(r"^[A-Za-z0-9]+$")
57
+ _SF_ID_LENGTHS = frozenset({15, 18})
58
+
59
+
60
+ def looks_like_sf_id(id_str: object) -> bool:
61
+ """True iff `id_str` is a 15- or 18-char alphanumeric string.
62
+
63
+ promoted from module-private `_looks_like_sf_id`
64
+ so `main._route` can gate calls to `resolve_or_unresolved` on the
65
+ Id shape without reaching into a leading-underscore symbol (same
66
+ surface). Underscore form retained as a deprecated alias.
67
+ """
68
+ if not isinstance(id_str, str):
69
+ return False
70
+ if len(id_str) not in _SF_ID_LENGTHS:
71
+ return False
72
+ return bool(_SF_ID_RE.match(id_str))
73
+
74
+
75
+ # backcompat alias — deprecated; use `looks_like_sf_id`.
76
+ _looks_like_sf_id = looks_like_sf_id
77
+
78
+
79
+ def resolve_target_id(id_str: str) -> tuple[Kind, Channel]:
80
+ """Return (kind, resolvable_via) for a Salesforce Id.
81
+
82
+ unknown prefixes NEVER raise — callers observing ("unknown", "skip")
83
+ are expected to route through `resolve_or_unresolved` (or equivalent)
84
+ to append an `_unresolved[]` entry. This function stays pure — it does
85
+ not mutate any caller state, does not log.
86
+ """
87
+ if not id_str or not isinstance(id_str, str) or len(id_str) < 3:
88
+ return ("unknown", "skip")
89
+ prefix = id_str[:3]
90
+ return _PREFIX_MAP.get(prefix, ("unknown", "skip"))
91
+
92
+
93
+ def resolve_or_unresolved(
94
+ id_str: object,
95
+ unresolved: list[dict],
96
+ ) -> tuple[Kind, Channel]:
97
+ """Like `resolve_target_id` but records failures into `unresolved`.
98
+
99
+ semantics:
100
+ * Valid Salesforce Id (15 or 18 alphanumeric chars) with known prefix:
101
+ route as usual. `unresolved` untouched.
102
+ * Valid Id shape, unknown prefix: append
103
+ `{"id": <id>, "reason": f"unknown-id-prefix:{id[:3]}"}` and
104
+ return ("unknown", "skip"). This is the "NGA shipped a new type"
105
+ path — the wave orchestrator keeps running.
106
+ * Not an Id shape (empty/None/wrong length/bad chars): append
107
+ `{"id": str(id_str), "reason": "invalid-id-format"}` and return
108
+ ("unknown", "skip"). Distinct reason so triage can tell "NGA
109
+ added something new" apart from "caller passed us garbage."
110
+
111
+ `unresolved` is mutated in place — same contract as `_unresolved[]`
112
+ throughout the skill. Caller owns the list.
113
+ """
114
+ if _looks_like_sf_id(id_str):
115
+ kind, channel = resolve_target_id(id_str) # type: ignore[arg-type]
116
+ if kind == "unknown":
117
+ # Real Id shape, prefix we don't recognize — record the prefix
118
+ # so triage can add it to _PREFIX_MAP.
119
+ unresolved.append({
120
+ "id": id_str,
121
+ "reason": f"unknown-id-prefix:{id_str[:3]}", # type: ignore[index]
122
+ })
123
+ return (kind, channel)
124
+
125
+ # Not a valid Id shape — empty, None, wrong length, or bad chars.
126
+ unresolved.append({
127
+ "id": str(id_str),
128
+ "reason": "invalid-id-format",
129
+ })
130
+ return ("unknown", "skip")