@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,424 @@
1
+ """Synthetic session fixture for d360 integration tests.
2
+
3
+ Provides:
4
+
5
+ - ``IDS`` a flat namespace of all UUIDs/keys used so tests
6
+ can assert against specific values.
7
+ - ``make_rows()`` returns ``{dmo_name: [row, ...]}`` for the 24 DMOs
8
+ `assemble_dc` reads. Self-consistent: every
9
+ Step.GenerationId references a Generation row, etc.
10
+ - ``make_manifest`` returns the dc._session_manifest.json shape.
11
+ - ``write_to_disk`` materializes the whole fixture under a session dir
12
+ so tests that drive the public ``assemble_dc.assemble``
13
+ can use ``tmp_path`` + DATA_ROOT redirect without
14
+ duplicating layout knowledge.
15
+
16
+ Shape rules:
17
+ - Timestamps anchored on 2026-04-22T10:00:00Z; offsets in seconds.
18
+ - All ssot__Id__c values are 18-char-stable strings (not real Salesforce
19
+ IDs) — assemble_dc only key-equality-checks them.
20
+ - HTML escaping applied to AttributeText__c so the trace_id fallback
21
+ path exercises real code.
22
+ - parameters__c on gateway_responses uses the "-escaped JSON shape
23
+ real DC emits.
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import html
28
+ import json
29
+ from copy import deepcopy
30
+ from pathlib import Path
31
+ from typing import Any, Dict, List
32
+
33
+
34
+ # -----------------------------------------------------------------------------
35
+ # IDs — exposed flat for cross-test assertions
36
+ # -----------------------------------------------------------------------------
37
+
38
+
39
+ class _IDs:
40
+ SID = "019dface-0000-7000-8000-000000000001"
41
+ """Agent session UUID. Valid UUIDv7 so window decode works."""
42
+
43
+ ORG_ID_15 = "00D000000000ABC"
44
+ ORG_ID_18 = "00D000000000ABCDEF"
45
+ AGENT_API = "DemoAgent"
46
+ AGENT_VERSION = "v5"
47
+ BOT_ID = "0Xx000000000DemoBot"
48
+
49
+ # Interactions
50
+ IXN_START = "ixn-start-001"
51
+ IXN_TURN = "ixn-turn-002"
52
+ IXN_END = "ixn-end-003"
53
+
54
+ # Steps within the TURN
55
+ STEP_TOPIC = "step-topic-001"
56
+ STEP_ACTION = "step-action-002"
57
+ STEP_GUARDRAIL = "step-guardrail-003"
58
+
59
+ # Gateway audit chain — one declared, one timestamp-window-only
60
+ GW_REQ_DECLARED = "gw-req-declared-001"
61
+ GW_REQ_WINDOW = "gw-req-window-002"
62
+ GW_RESP_DECLARED = "gw-resp-declared-001"
63
+
64
+ # Generation chain (declared)
65
+ GEN_DECLARED = "gen-declared-001"
66
+
67
+ # Participants
68
+ PART_AGENT = "part-agent-001"
69
+ PART_USER = "part-user-002"
70
+
71
+ # Trace + window
72
+ TRACE_ID = "8b820e85aaaaaaaabbbbbbbbcccccccc"
73
+ SESSION_START = "2026-04-22T10:00:00.000Z"
74
+ SESSION_END = "2026-04-22T10:01:30.000Z"
75
+ TURN_START = "2026-04-22T10:00:05.000Z"
76
+ TURN_END = "2026-04-22T10:01:00.000Z"
77
+ GW_DECLARED_TS = "2026-04-22T10:00:30.000Z" # inside step-action window
78
+ GW_WINDOW_TS = "2026-04-22T10:00:45.000Z" # inside the TURN window only
79
+
80
+
81
+ IDS = _IDs
82
+
83
+
84
+ # -----------------------------------------------------------------------------
85
+ # Per-DMO row builders
86
+ # -----------------------------------------------------------------------------
87
+
88
+
89
+ def _sessions() -> List[dict]:
90
+ return [{
91
+ "ssot__Id__c": IDS.SID,
92
+ "ssot__InternalOrganizationId__c": IDS.ORG_ID_18,
93
+ "ssot__StartTimestamp__c": IDS.SESSION_START,
94
+ "ssot__EndTimestamp__c": IDS.SESSION_END,
95
+ "ssot__AiAgentChannelType__c": "SCRT2 - EmbeddedMessaging",
96
+ "ssot__AiAgentSessionEndType__c": "USER_ENDED",
97
+ "ssot__RelatedMessagingSessionId__c": "0MwTESTMSG12345AAA",
98
+ }]
99
+
100
+
101
+ def _interactions() -> List[dict]:
102
+ """Three interactions: SESSION_START, TURN, SESSION_END.
103
+
104
+ `AttributeText__c` carries the real internalTraceId in HTML-escaped
105
+ JSON form on the TURN row (matches live DC shape).
106
+ """
107
+ # No spaces in separators — production logger emits compact JSON, and
108
+ # the trace_id regex (`"internalTraceId":"([a-f0-9]+)"`) requires no
109
+ # whitespace around the colon.
110
+ raw_attr_text = json.dumps(
111
+ {"internalTraceId": IDS.TRACE_ID, "label": "react-loop"},
112
+ separators=(",", ":"),
113
+ )
114
+ return [
115
+ {
116
+ "ssot__Id__c": IDS.IXN_START,
117
+ "ssot__AiAgentSessionId__c": IDS.SID,
118
+ "ssot__AiAgentInteractionType__c": "SESSION_START",
119
+ "ssot__StartTimestamp__c": IDS.SESSION_START,
120
+ "ssot__EndTimestamp__c": IDS.SESSION_START,
121
+ "ssot__TelemetryTraceId__c": "",
122
+ "ssot__AttributeText__c": "",
123
+ },
124
+ {
125
+ "ssot__Id__c": IDS.IXN_TURN,
126
+ "ssot__AiAgentSessionId__c": IDS.SID,
127
+ "ssot__AiAgentInteractionType__c": "TURN",
128
+ "ssot__StartTimestamp__c": IDS.TURN_START,
129
+ "ssot__EndTimestamp__c": IDS.TURN_END,
130
+ "ssot__TelemetryTraceId__c": "",
131
+ # HTML-escaped JSON triggers the AttributeText fallback path.
132
+ "ssot__AttributeText__c": html.escape(raw_attr_text, quote=True),
133
+ },
134
+ {
135
+ "ssot__Id__c": IDS.IXN_END,
136
+ "ssot__AiAgentSessionId__c": IDS.SID,
137
+ "ssot__AiAgentInteractionType__c": "SESSION_END",
138
+ "ssot__StartTimestamp__c": IDS.SESSION_END,
139
+ "ssot__EndTimestamp__c": IDS.SESSION_END,
140
+ "ssot__TelemetryTraceId__c": "NOT_SET",
141
+ "ssot__AttributeText__c": "",
142
+ },
143
+ ]
144
+
145
+
146
+ def _steps() -> List[dict]:
147
+ """Three steps inside the TURN. Step times nest inside the turn window
148
+ so the timestamp-window pass binds gateway_requests by containment."""
149
+ return [
150
+ {
151
+ "ssot__Id__c": IDS.STEP_TOPIC,
152
+ "ssot__AiAgentInteractionId__c": IDS.IXN_TURN,
153
+ "ssot__AiAgentInteractionStepType__c": "TOPIC_STEP",
154
+ "ssot__StartTimestamp__c": "2026-04-22T10:00:10.000Z",
155
+ "ssot__EndTimestamp__c": "2026-04-22T10:00:20.000Z",
156
+ "ssot__GenerationId__c": "NOT_SET",
157
+ "ssot__Name__c": "TopicSelection",
158
+ },
159
+ {
160
+ "ssot__Id__c": IDS.STEP_ACTION,
161
+ "ssot__AiAgentInteractionId__c": IDS.IXN_TURN,
162
+ "ssot__AiAgentInteractionStepType__c": "ACTION_STEP",
163
+ "ssot__StartTimestamp__c": "2026-04-22T10:00:25.000Z",
164
+ "ssot__EndTimestamp__c": "2026-04-22T10:00:40.000Z",
165
+ "ssot__GenerationId__c": IDS.GEN_DECLARED,
166
+ "ssot__Name__c": "PrimaryAction",
167
+ },
168
+ {
169
+ "ssot__Id__c": IDS.STEP_GUARDRAIL,
170
+ "ssot__AiAgentInteractionId__c": IDS.IXN_TURN,
171
+ "ssot__AiAgentInteractionStepType__c": "TRUST_GUARDRAILS_STEP",
172
+ "ssot__StartTimestamp__c": "2026-04-22T10:00:55.000Z",
173
+ "ssot__EndTimestamp__c": "2026-04-22T10:01:00.000Z",
174
+ "ssot__GenerationId__c": "NOT_SET",
175
+ "ssot__Name__c": "FinalGuard",
176
+ },
177
+ ]
178
+
179
+
180
+ def _messages() -> List[dict]:
181
+ return [
182
+ {
183
+ "ssot__Id__c": "msg-001",
184
+ "ssot__AiAgentInteractionId__c": IDS.IXN_TURN,
185
+ "ssot__AiAgentInteractionMessageType__c": "USER",
186
+ "ssot__ContentText__c": "How do I refund my order?",
187
+ "ssot__StartTimestamp__c": IDS.TURN_START,
188
+ },
189
+ {
190
+ "ssot__Id__c": "msg-002",
191
+ "ssot__AiAgentInteractionId__c": IDS.IXN_TURN,
192
+ "ssot__AiAgentInteractionMessageType__c": "AGENT",
193
+ "ssot__ContentText__c": "I'll help you with the refund process.",
194
+ "ssot__StartTimestamp__c": IDS.TURN_END,
195
+ },
196
+ ]
197
+
198
+
199
+ def _participants() -> List[dict]:
200
+ return [
201
+ {
202
+ "ssot__Id__c": IDS.PART_AGENT,
203
+ "ssot__AiAgentSessionId__c": IDS.SID,
204
+ "ssot__AiAgentSessionParticipantRole__c": "AGENT",
205
+ "ssot__AiAgentApiName__c": IDS.AGENT_API,
206
+ "ssot__AiAgentVersionApiName__c": IDS.AGENT_VERSION,
207
+ },
208
+ {
209
+ "ssot__Id__c": IDS.PART_USER,
210
+ "ssot__AiAgentSessionId__c": IDS.SID,
211
+ "ssot__AiAgentSessionParticipantRole__c": "USER",
212
+ "ssot__AiAgentApiName__c": "",
213
+ "ssot__AiAgentVersionApiName__c": "",
214
+ },
215
+ ]
216
+
217
+
218
+ def _gateway_requests() -> List[dict]:
219
+ """Two gateway requests:
220
+
221
+ - GW_REQ_DECLARED: chained from Step → Generation → Response → Request.
222
+ Timestamp also falls within step-action window so either binding
223
+ method can resolve it. Declared chain wins.
224
+
225
+ - GW_REQ_WINDOW: NOT in the declared chain. Timestamp falls inside
226
+ the TURN window → exercise timestamp-window fallback.
227
+ """
228
+ return [
229
+ {
230
+ "gatewayRequestId__c": IDS.GW_REQ_DECLARED,
231
+ "sf__Id": "sf-" + IDS.GW_REQ_DECLARED,
232
+ "sessionId__c": f'"{IDS.SID}"',
233
+ "timestamp__c": IDS.GW_DECLARED_TS,
234
+ "model__c": "gpt-4o",
235
+ "provider__c": "openai",
236
+ "promptTemplateDevName__c": "AiCopilot__ReactInitialPrompt",
237
+ "feature__c": "plannerservice",
238
+ "promptTokens__c": 1200,
239
+ "completionTokens__c": 50,
240
+ "totalTokens__c": 1250,
241
+ "prompt__c": "Declared-bound prompt body.",
242
+ },
243
+ {
244
+ "gatewayRequestId__c": IDS.GW_REQ_WINDOW,
245
+ "sf__Id": "sf-" + IDS.GW_REQ_WINDOW,
246
+ "sessionId__c": f'"{IDS.SID}"',
247
+ "timestamp__c": IDS.GW_WINDOW_TS,
248
+ "model__c": "gpt-4o-mini",
249
+ "provider__c": "openai",
250
+ "promptTemplateDevName__c": "AiCopilot__PromptTemplateGenerationsInvocable",
251
+ "feature__c": "plannerservice",
252
+ "promptTokens__c": 200,
253
+ "completionTokens__c": 20,
254
+ "totalTokens__c": 220,
255
+ "prompt__c": "Window-bound prompt body.",
256
+ },
257
+ ]
258
+
259
+
260
+ def _gateway_responses() -> List[dict]:
261
+ raw = '{"finish_reason":"\\"stop\\""}'
262
+ escaped = raw.replace('"', """)
263
+ return [{
264
+ "generationResponseId__c": IDS.GW_RESP_DECLARED,
265
+ "generationRequestId__c": IDS.GW_REQ_DECLARED,
266
+ "parameters__c": escaped,
267
+ "timestamp__c": IDS.GW_DECLARED_TS,
268
+ }]
269
+
270
+
271
+ def _generations() -> List[dict]:
272
+ return [{
273
+ "generationId__c": IDS.GEN_DECLARED,
274
+ "generationResponseId__c": IDS.GW_RESP_DECLARED,
275
+ "responseText__c": "I'll help you with the refund process.",
276
+ "timestamp__c": IDS.GW_DECLARED_TS,
277
+ }]
278
+
279
+
280
+ def _content_quality() -> List[dict]:
281
+ return [{
282
+ "generationId__c": IDS.GEN_DECLARED,
283
+ "trustScore__c": 0.92,
284
+ "qualityType__c": "NORMAL",
285
+ }]
286
+
287
+
288
+ def _gateway_records() -> List[dict]:
289
+ return [{
290
+ "id__c": "gw-rec-001",
291
+ "parent__c": IDS.GW_REQ_DECLARED,
292
+ "sessionId__c": IDS.SID,
293
+ "recordType__c": "RAG",
294
+ }]
295
+
296
+
297
+ def _gateway_request_tags() -> List[dict]:
298
+ return [
299
+ {"id__c": "tag-001", "parent__c": IDS.GW_REQ_DECLARED,
300
+ "tag__c": "promptTemplateDevName", "tagValue__c": "AiCopilot__ReactInitialPrompt"},
301
+ {"id__c": "tag-002", "parent__c": IDS.GW_REQ_DECLARED,
302
+ "tag__c": "feature", "tagValue__c": "plannerservice"},
303
+ ]
304
+
305
+
306
+ # -----------------------------------------------------------------------------
307
+ # Public: rows + manifest
308
+ # -----------------------------------------------------------------------------
309
+
310
+
311
+ _ALL_TEMPLATES = (
312
+ "sessions", "interactions", "messages", "moments", "participants",
313
+ "tag_associations", "gateway_requests",
314
+ "steps", "moment_interactions",
315
+ "telemetry_spans", "generations", "app_generation",
316
+ "gateway_request_tags", "gateway_responses", "gateway_records",
317
+ "gateway_request_metadata", "gateway_request_llm",
318
+ "feedback",
319
+ "content_quality", "content_category", "feedback_details",
320
+ "tag_definitions", "tag_definition_associations", "tags",
321
+ )
322
+
323
+
324
+ def make_rows() -> Dict[str, List[dict]]:
325
+ """Return ``{dmo_name: [row, ...]}`` for all 24 DMOs.
326
+
327
+ Empty lists for DMOs the synthetic session doesn't exercise — the
328
+ code under test reads them by ``.get(name, [])`` and tolerates
329
+ missing entries.
330
+ """
331
+ populated = {
332
+ "sessions": _sessions(),
333
+ "interactions": _interactions(),
334
+ "steps": _steps(),
335
+ "messages": _messages(),
336
+ "participants": _participants(),
337
+ "gateway_requests": _gateway_requests(),
338
+ "gateway_responses": _gateway_responses(),
339
+ "generations": _generations(),
340
+ "content_quality": _content_quality(),
341
+ "gateway_records": _gateway_records(),
342
+ "gateway_request_tags": _gateway_request_tags(),
343
+ }
344
+ rows: Dict[str, List[dict]] = {name: [] for name in _ALL_TEMPLATES}
345
+ rows.update(populated)
346
+ return deepcopy(rows)
347
+
348
+
349
+ def make_manifest() -> dict:
350
+ """Manifest shape matching what `fetch_dc.py` writes."""
351
+ rows = make_rows()
352
+ queries = [
353
+ {
354
+ "name": name,
355
+ "row_count": len(rows[name]),
356
+ "elapsed_ms": 50,
357
+ "where_clause": f"ssot__AiAgentSessionId__c = '{IDS.SID}'",
358
+ }
359
+ for name in _ALL_TEMPLATES
360
+ ]
361
+ return {
362
+ "_doc": "Per-query summary of this DC fetch run.",
363
+ "session_id": IDS.SID,
364
+ "org_alias": "my-org",
365
+ "instance_url": "https://example.my.salesforce.com",
366
+ "org_id_15": IDS.ORG_ID_15,
367
+ "agent_api_name": IDS.AGENT_API,
368
+ "agent_version": IDS.AGENT_VERSION,
369
+ "session_shape": "ok",
370
+ "started_at_utc": "2026-04-22T10:01:30.000Z",
371
+ "finished_at_utc": "2026-04-22T10:01:32.000Z",
372
+ "elapsed_ms": 2000,
373
+ "queries": queries,
374
+ "harvested_ids": {
375
+ "interactions": [IDS.IXN_START, IDS.IXN_TURN, IDS.IXN_END],
376
+ },
377
+ }
378
+
379
+
380
+ # -----------------------------------------------------------------------------
381
+ # Disk materialization
382
+ # -----------------------------------------------------------------------------
383
+
384
+
385
+ def session_dir_for(data_root: Path) -> Path:
386
+ """Compute the canonical session dir under a tmp DATA_ROOT."""
387
+ return (
388
+ data_root
389
+ / IDS.ORG_ID_15
390
+ / f"{IDS.AGENT_API}__{IDS.AGENT_VERSION}"
391
+ / IDS.SID
392
+ )
393
+
394
+
395
+ def write_to_disk(data_root: Path) -> Path:
396
+ """Materialize the synthetic session under ``<data_root>/<org>/<agent>__<ver>/<sid>/``.
397
+
398
+ Writes:
399
+ - dc._session_manifest.json
400
+ - dc.<name>.json for every populated DMO
401
+ - The per-org breadcrumb at <org>/_sessions/<sid>.link
402
+
403
+ Returns the session dir absolute path.
404
+ """
405
+ sdir = session_dir_for(data_root)
406
+ sdir.mkdir(parents=True, exist_ok=True)
407
+
408
+ # DC manifest + rows
409
+ (sdir / "dc._session_manifest.json").write_text(
410
+ json.dumps(make_manifest(), indent=2) + "\n"
411
+ )
412
+ rows = make_rows()
413
+ for name, rs in rows.items():
414
+ if rs:
415
+ (sdir / f"dc.{name}.json").write_text(json.dumps(rs, indent=2) + "\n")
416
+
417
+ # Breadcrumb so _find_session_dir's primary path resolves
418
+ link_dir = data_root / IDS.ORG_ID_15 / "_sessions"
419
+ link_dir.mkdir(parents=True, exist_ok=True)
420
+ (link_dir / f"{IDS.SID}.link").write_text(
421
+ f"../{IDS.AGENT_API}__{IDS.AGENT_VERSION}/{IDS.SID}\n"
422
+ )
423
+
424
+ return sdir
@@ -0,0 +1,115 @@
1
+ """Tests for the bootstrap-variable parser + channel-mode deriver in assemble_dc.py.
2
+
3
+ Coverage:
4
+ - `_parse_bootstrap_variables`
5
+ - returns None for missing/NOT_SET/UNSET_VALUE
6
+ - parses well-formed JSON object
7
+ - parses HTML-entity-encoded JSON
8
+ - returns _parse_error dict for malformed JSON
9
+ - returns _parse_error dict for non-object JSON (array, scalar)
10
+
11
+ - `_derive_mode`
12
+ - voice → when RelatedVoiceCallId set
13
+ - production_messaging → when RelatedMessagingSessionId set
14
+ - builder_previewer → when bootstrap has indicator keys
15
+ - unknown → when nothing matches
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import unittest
20
+
21
+ from . import _bootstrap # noqa: F401 — sys.path setup
22
+
23
+ from assemble_dc import _parse_bootstrap_variables, _derive_mode # type: ignore
24
+
25
+
26
+ class ParseBootstrapVariablesTests(unittest.TestCase):
27
+
28
+ def test_none_input_returns_none(self):
29
+ self.assertIsNone(_parse_bootstrap_variables(None))
30
+
31
+ def test_empty_string_returns_none(self):
32
+ self.assertIsNone(_parse_bootstrap_variables(""))
33
+
34
+ def test_not_set_sentinel_returns_none(self):
35
+ self.assertIsNone(_parse_bootstrap_variables("NOT_SET"))
36
+
37
+ def test_unset_value_sentinel_returns_none(self):
38
+ self.assertIsNone(_parse_bootstrap_variables("UNSET_VALUE"))
39
+
40
+ def test_well_formed_json_object_returns_dict(self):
41
+ out = _parse_bootstrap_variables('{"__resolved_locale__":"en_US","x":1}')
42
+ self.assertEqual(out, {"__resolved_locale__": "en_US", "x": 1})
43
+
44
+ def test_html_entity_encoded_json_unescaped_then_parsed(self):
45
+ """Some surfaces emit `&quot;`-encoded JSON. The parser unescapes
46
+ first, then json.loads."""
47
+ encoded = "{&quot;__resolved_locale__&quot;:&quot;en_US&quot;}"
48
+ out = _parse_bootstrap_variables(encoded)
49
+ self.assertEqual(out, {"__resolved_locale__": "en_US"})
50
+
51
+ def test_malformed_json_returns_parse_error_dict(self):
52
+ out = _parse_bootstrap_variables("{not-valid-json")
53
+ self.assertIsNotNone(out)
54
+ self.assertTrue(out.get("_parse_error"))
55
+ self.assertIn("_raw", out)
56
+
57
+ def test_json_array_returns_parse_error_dict(self):
58
+ """VariableText__c is documented as an object; arrays/scalars are
59
+ defensive cases that surface as _parse_error rather than crash."""
60
+ out = _parse_bootstrap_variables('[1, 2, 3]')
61
+ self.assertTrue(out.get("_parse_error"))
62
+
63
+ def test_json_scalar_returns_parse_error_dict(self):
64
+ out = _parse_bootstrap_variables('"just a string"')
65
+ self.assertTrue(out.get("_parse_error"))
66
+
67
+
68
+ class DeriveModeTests(unittest.TestCase):
69
+
70
+ def test_voice_call_id_set_returns_voice(self):
71
+ out = _derive_mode(
72
+ messaging_session_id="msg-1", # ignored when voice present
73
+ voice_call_id="voice-1",
74
+ bootstrap_variables=None,
75
+ )
76
+ self.assertEqual(out, "voice")
77
+
78
+ def test_messaging_session_id_set_returns_production_messaging(self):
79
+ out = _derive_mode(
80
+ messaging_session_id="0MwTESTMSG00000",
81
+ voice_call_id=None,
82
+ bootstrap_variables=None,
83
+ )
84
+ self.assertEqual(out, "production_messaging")
85
+
86
+ def test_builder_previewer_keys_in_bootstrap_returns_builder_previewer(self):
87
+ bootstrap = {"__resolved_locale__": "en_US", "OpenAgent": "x"}
88
+ out = _derive_mode(
89
+ messaging_session_id=None,
90
+ voice_call_id=None,
91
+ bootstrap_variables=bootstrap,
92
+ )
93
+ self.assertEqual(out, "builder_previewer")
94
+
95
+ def test_no_signals_returns_unknown(self):
96
+ out = _derive_mode(
97
+ messaging_session_id=None,
98
+ voice_call_id=None,
99
+ bootstrap_variables={"OpenAgent": "x"}, # no indicator keys
100
+ )
101
+ self.assertEqual(out, "unknown")
102
+
103
+ def test_voice_takes_priority_over_messaging(self):
104
+ """Defensive: if both messaging_session_id and voice_call_id are
105
+ set, voice wins (per priority order documented in the function)."""
106
+ out = _derive_mode(
107
+ messaging_session_id="msg-1",
108
+ voice_call_id="voice-1",
109
+ bootstrap_variables=None,
110
+ )
111
+ self.assertEqual(out, "voice")
112
+
113
+
114
+ if __name__ == "__main__":
115
+ unittest.main()