@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,521 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * SLDS Quality Analyzer
5
+ *
6
+ * Analyzes CSS and HTML files for SLDS quality issues beyond what the linter catches.
7
+ *
8
+ * Usage: node analyze-quality.cjs <component-path> [--hooks-index <path>]
9
+ *
10
+ * Output: JSON with findings categorized by severity
11
+ */
12
+
13
+ const fs = require('fs');
14
+ const path = require('path');
15
+
16
+ function resolveHooksIndexPath(args) {
17
+ const idx = args.indexOf('--hooks-index');
18
+ if (idx !== -1 && idx + 1 < args.length) {
19
+ return path.resolve(args[idx + 1]);
20
+ }
21
+ return null;
22
+ }
23
+
24
+ let HOOKS_INDEX_PATH = null;
25
+
26
+ // Severity levels
27
+ const CRITICAL = 'critical';
28
+ const WARNING = 'warning';
29
+ const INFO = 'info';
30
+
31
+ // Detection patterns
32
+ // NOTE: Checks that the SLDS linter already handles are excluded here to avoid
33
+ // double-counting. The linter covers: slds/class-override (L001),
34
+ // slds/lwc-token-to-slds-hook (L002), slds/no-hardcoded-values (L003).
35
+ // This script focuses on what the linter does NOT catch.
36
+ const PATTERNS = {
37
+ // CSS patterns (linter-complementary only)
38
+ css: {
39
+ missingFallback: {
40
+ pattern: /var\(--slds-g-[^,)]+\)/g,
41
+ severity: CRITICAL,
42
+ id: 'T002',
43
+ message: 'SLDS hook without fallback value',
44
+ recommendation: 'Add fallback: var(--slds-g-color-surface-1, #fff)'
45
+ },
46
+ important: {
47
+ pattern: /!important/g,
48
+ severity: WARNING,
49
+ id: 'Q001',
50
+ message: '!important declaration found',
51
+ recommendation: 'Remove !important, use proper specificity'
52
+ },
53
+ magicPixels: {
54
+ pattern: /\b(?:margin(?:-[a-z-]+)?|padding(?:-[a-z-]+)?|gap|row-gap|column-gap)\s*:\s*(\d+)px\b(?![^;]*var\()/g,
55
+ severity: WARNING,
56
+ id: 'T021',
57
+ message: 'Magic pixel value not using spacing hook',
58
+ recommendation: 'Use var(--slds-g-spacing-*) or utility class'
59
+ },
60
+ highZindex: {
61
+ pattern: /z-index\s*:\s*(\d{3,})/g,
62
+ severity: WARNING,
63
+ id: 'Q021',
64
+ message: 'High z-index value',
65
+ recommendation: 'Use defined z-index scale'
66
+ },
67
+ outlineNone: {
68
+ pattern: /outline\s*:\s*none/g,
69
+ severity: WARNING,
70
+ id: 'A021',
71
+ message: 'Focus outline removed without alternative',
72
+ recommendation: 'Provide alternative focus indicator'
73
+ }
74
+ },
75
+ // JS patterns (inline styles and dynamic class manipulation)
76
+ js: {
77
+ inlineStyleJS: {
78
+ pattern: /\.style\.\w+\s*=/g,
79
+ severity: WARNING,
80
+ id: 'Q025',
81
+ message: 'Inline style manipulation in JavaScript',
82
+ recommendation: 'Use CSS classes instead of direct style property assignment'
83
+ },
84
+ classListManipulation: {
85
+ pattern: /\.classList\.(add|remove|toggle)\(\s*['"]slds-/g,
86
+ severity: WARNING,
87
+ id: 'Q012',
88
+ message: 'Dynamic SLDS class manipulation in JavaScript',
89
+ recommendation: 'Prefer declarative class bindings; avoid manipulating slds-* classes directly'
90
+ }
91
+ },
92
+ // HTML patterns
93
+ html: {
94
+ inlineStyle: {
95
+ pattern: /style\s*=\s*["'][^"']+["']/gi,
96
+ severity: WARNING,
97
+ id: 'Q002',
98
+ message: 'Inline style attribute',
99
+ recommendation: 'Move styles to CSS file'
100
+ },
101
+ lightningInputNoLabel: {
102
+ pattern: /<lightning-input(?![^>]*\blabel\b)[^>]*>/gi,
103
+ severity: CRITICAL,
104
+ id: 'A001',
105
+ message: 'Lightning input without label attribute',
106
+ recommendation: 'Add label attribute to lightning-input'
107
+ },
108
+ iconNoAlt: {
109
+ pattern: /<lightning-icon(?![^>]*alternative-text)[^>]*>/gi,
110
+ severity: CRITICAL,
111
+ id: 'A004',
112
+ message: 'Icon without alternative-text',
113
+ recommendation: 'Add alternative-text (or empty string for decorative)'
114
+ },
115
+ imgNoAlt: {
116
+ pattern: /<img(?![^>]*\balt\b)[^>]*>/gi,
117
+ severity: CRITICAL,
118
+ id: 'A005',
119
+ message: 'Image without alt attribute',
120
+ recommendation: 'Add alt attribute'
121
+ },
122
+ positiveTabindex: {
123
+ pattern: /tabindex\s*=\s*["']([1-9]\d*)["']/gi,
124
+ severity: WARNING,
125
+ id: 'A020',
126
+ message: 'Positive tabindex value',
127
+ recommendation: 'Use tabindex="0" or "-1" only'
128
+ },
129
+ clickableDiv: {
130
+ pattern: /<div[^>]*onclick[^>]*>/gi,
131
+ severity: WARNING,
132
+ id: 'A022',
133
+ message: 'Div with click handler instead of button',
134
+ recommendation: 'Use <button> or <lightning-button> for interactive elements'
135
+ },
136
+ nativeInput: {
137
+ pattern: /<input\s/gi,
138
+ severity: WARNING,
139
+ id: 'C001',
140
+ message: 'Native input element',
141
+ recommendation: 'Consider <lightning-input> for built-in labeling and validation'
142
+ },
143
+ nativeButton: {
144
+ pattern: /<button\s(?![^>]*class\s*=\s*["'][^"']*slds-button)/gi,
145
+ severity: WARNING,
146
+ id: 'C002',
147
+ message: 'Native button element',
148
+ recommendation: 'Consider <lightning-button> for SLDS styling consistency (suppressed if slds-button class present)'
149
+ },
150
+ nativeSelect: {
151
+ pattern: /<select\s/gi,
152
+ severity: WARNING,
153
+ id: 'C004',
154
+ message: 'Native select element',
155
+ recommendation: 'Consider <lightning-combobox> for consistency'
156
+ }
157
+ }
158
+ };
159
+
160
+ /**
161
+ * Find all files with given extensions in directory
162
+ */
163
+ function findFiles(dir, extensions) {
164
+ const files = [];
165
+
166
+ function walk(currentDir) {
167
+ try {
168
+ const items = fs.readdirSync(currentDir);
169
+ for (const item of items) {
170
+ const fullPath = path.join(currentDir, item);
171
+ const stat = fs.statSync(fullPath);
172
+
173
+ if (stat.isDirectory() && !item.startsWith('.') && item !== 'node_modules') {
174
+ walk(fullPath);
175
+ } else if (stat.isFile()) {
176
+ const ext = path.extname(item).toLowerCase();
177
+ if (extensions.includes(ext)) {
178
+ files.push(fullPath);
179
+ }
180
+ }
181
+ }
182
+ } catch (err) {
183
+ // Skip directories we can't read
184
+ }
185
+ }
186
+
187
+ walk(dir);
188
+ return files;
189
+ }
190
+
191
+ /**
192
+ * Analyze a single file
193
+ */
194
+ function analyzeFile(filePath, patterns) {
195
+ const findings = [];
196
+ const content = fs.readFileSync(filePath, 'utf-8');
197
+ const lines = content.split('\n');
198
+
199
+ for (const [name, config] of Object.entries(patterns)) {
200
+ const regex = new RegExp(config.pattern.source, config.pattern.flags);
201
+ let match;
202
+
203
+ while ((match = regex.exec(content)) !== null) {
204
+ // Find line number
205
+ const beforeMatch = content.substring(0, match.index);
206
+ const lineNumber = beforeMatch.split('\n').length;
207
+ const lineContent = lines[lineNumber - 1] || '';
208
+
209
+ findings.push({
210
+ id: config.id,
211
+ severity: config.severity,
212
+ file: filePath,
213
+ line: lineNumber,
214
+ column: match.index - beforeMatch.lastIndexOf('\n'),
215
+ match: match[0].substring(0, 50),
216
+ message: config.message,
217
+ recommendation: config.recommendation,
218
+ context: lineContent.trim().substring(0, 80)
219
+ });
220
+ }
221
+ }
222
+
223
+ return findings;
224
+ }
225
+
226
+ /**
227
+ * Analyze heading hierarchy in HTML
228
+ */
229
+ function analyzeHeadings(filePath) {
230
+ const findings = [];
231
+ const content = fs.readFileSync(filePath, 'utf-8');
232
+ const headingRegex = /<h([1-6])[^>]*>/gi;
233
+ const headings = [];
234
+ let match;
235
+
236
+ while ((match = headingRegex.exec(content)) !== null) {
237
+ headings.push({
238
+ level: parseInt(match[1]),
239
+ index: match.index
240
+ });
241
+ }
242
+
243
+ // Check for skipped levels
244
+ for (let i = 1; i < headings.length; i++) {
245
+ const prev = headings[i - 1].level;
246
+ const curr = headings[i].level;
247
+
248
+ if (curr > prev + 1) {
249
+ const beforeMatch = content.substring(0, headings[i].index);
250
+ const lineNumber = beforeMatch.split('\n').length;
251
+
252
+ findings.push({
253
+ id: 'A010',
254
+ severity: WARNING,
255
+ file: filePath,
256
+ line: lineNumber,
257
+ message: `Skipped heading level: h${prev} to h${curr}`,
258
+ recommendation: `Use h${prev + 1} instead of h${curr}`
259
+ });
260
+ }
261
+ }
262
+
263
+ return findings;
264
+ }
265
+
266
+ /**
267
+ * Load valid hook tokens from hooks-index.json
268
+ */
269
+ let _validHooks = null;
270
+ function loadValidHooks() {
271
+ if (_validHooks) return _validHooks;
272
+ if (!HOOKS_INDEX_PATH) return null;
273
+ try {
274
+ const data = JSON.parse(fs.readFileSync(HOOKS_INDEX_PATH, 'utf-8'));
275
+ _validHooks = new Set(data.hooks.map(h => h.token));
276
+ } catch {
277
+ console.error(`WARNING: Could not load hooks-index.json at ${HOOKS_INDEX_PATH}`);
278
+ console.error('Invented-hook detection (T051) will be skipped.');
279
+ _validHooks = null;
280
+ }
281
+ return _validHooks;
282
+ }
283
+
284
+ /**
285
+ * Check for invented hooks (T051) — hooks referenced in CSS that don't exist in metadata
286
+ */
287
+ function analyzeInventedHooks(filePath) {
288
+ const findings = [];
289
+ const validHooks = loadValidHooks();
290
+ if (!validHooks) return findings; // skip if metadata unavailable
291
+
292
+ const content = fs.readFileSync(filePath, 'utf-8');
293
+ const lines = content.split('\n');
294
+ const hookRef = /var\((--slds-g-[^,)]+)/g;
295
+ let match;
296
+
297
+ while ((match = hookRef.exec(content)) !== null) {
298
+ const hookName = match[1].trim();
299
+ if (!validHooks.has(hookName)) {
300
+ const beforeMatch = content.substring(0, match.index);
301
+ const lineNumber = beforeMatch.split('\n').length;
302
+ const lineContent = lines[lineNumber - 1] || '';
303
+
304
+ findings.push({
305
+ id: 'T051',
306
+ severity: CRITICAL,
307
+ file: filePath,
308
+ line: lineNumber,
309
+ match: hookName,
310
+ message: `Invented hook — "${hookName}" does not exist in hooks-index.json`,
311
+ recommendation: 'Verify the hook exists via: node scripts/search-hooks.cjs --prefix "' + hookName + '"',
312
+ context: lineContent.trim().substring(0, 80)
313
+ });
314
+ }
315
+ }
316
+
317
+ return findings;
318
+ }
319
+
320
+ /**
321
+ * Check for hook pairing issues
322
+ */
323
+ function analyzeHookPairing(filePath) {
324
+ const findings = [];
325
+ const content = fs.readFileSync(filePath, 'utf-8');
326
+
327
+ // Find all background hooks
328
+ const bgHookRegex = /--slds-g-color-(surface|accent|success|warning|error|info)(?:-container)?-\d/g;
329
+ const textHookRegex = /--slds-g-color-on-(surface|accent|success|warning|error|info)(?:-container)?-\d/g;
330
+
331
+ const bgHooks = content.match(bgHookRegex) || [];
332
+ const textHooks = content.match(textHookRegex) || [];
333
+
334
+ // Extract families
335
+ const bgFamilies = new Set(bgHooks.map(h => {
336
+ const match = h.match(/--slds-g-color-(\w+(?:-container)?)-\d/);
337
+ return match ? match[1] : null;
338
+ }).filter(Boolean));
339
+
340
+ const textFamilies = new Set(textHooks.map(h => {
341
+ const match = h.match(/--slds-g-color-on-(\w+(?:-container)?)-\d/);
342
+ return match ? match[1] : null;
343
+ }).filter(Boolean));
344
+
345
+ // Check for mismatches
346
+ for (const bgFamily of bgFamilies) {
347
+ const expectedTextFamily = bgFamily.replace('-container', '');
348
+ if (!textFamilies.has(expectedTextFamily) && !textFamilies.has(bgFamily)) {
349
+ findings.push({
350
+ id: 'T010',
351
+ severity: WARNING,
352
+ file: filePath,
353
+ message: `Background hook family '${bgFamily}' may lack matching text hook`,
354
+ recommendation: `Pair with --slds-g-color-on-${expectedTextFamily}-*`
355
+ });
356
+ }
357
+ }
358
+
359
+ return findings;
360
+ }
361
+
362
+ /**
363
+ * Calculate scores from findings
364
+ */
365
+ function calculateScores(findings) {
366
+ const weights = {
367
+ [CRITICAL]: 10,
368
+ [WARNING]: 3,
369
+ [INFO]: 1
370
+ };
371
+
372
+ // NOTE: Linter findings (L001, L002, L003) come from the SLDS linter output,
373
+ // not from this script. They should be merged in by the calling agent.
374
+ // This script only produces findings for the other categories.
375
+ const categories = {
376
+ theming: { issues: 0, ids: ['T002', 'T010', 'T011', 'T021', 'T051'] },
377
+ accessibility: { issues: 0, ids: ['A001', 'A004', 'A005', 'A010', 'A020', 'A021', 'A022'] },
378
+ codeQuality: { issues: 0, ids: ['Q001', 'Q002', 'Q012', 'Q021', 'Q025'] },
379
+ componentUsage: { issues: 0, ids: ['C001', 'C002', 'C004'] }
380
+ };
381
+
382
+ // Count weighted issues per category
383
+ for (const finding of findings) {
384
+ const weight = weights[finding.severity];
385
+ for (const [category, config] of Object.entries(categories)) {
386
+ if (config.ids.includes(finding.id)) {
387
+ config.issues += weight;
388
+ break;
389
+ }
390
+ }
391
+ }
392
+
393
+ // Calculate scores
394
+ const scores = {};
395
+ for (const [category, config] of Object.entries(categories)) {
396
+ scores[category] = Math.max(0, 100 - config.issues);
397
+ }
398
+
399
+ return scores;
400
+ }
401
+
402
+ /**
403
+ * Get grade from score
404
+ */
405
+ function getGrade(score) {
406
+ if (score >= 90) return 'A';
407
+ if (score >= 80) return 'B';
408
+ if (score >= 70) return 'C';
409
+ if (score >= 60) return 'D';
410
+ return 'F';
411
+ }
412
+
413
+ /**
414
+ * Main analysis function
415
+ */
416
+ function analyze(componentPath) {
417
+ const resolvedPath = path.resolve(componentPath);
418
+
419
+ if (!fs.existsSync(resolvedPath)) {
420
+ console.error(`Error: Path does not exist: ${resolvedPath}`);
421
+ process.exit(1);
422
+ }
423
+
424
+ const findings = [];
425
+
426
+ // Find and analyze CSS files
427
+ const cssFiles = findFiles(resolvedPath, ['.css']);
428
+ for (const file of cssFiles) {
429
+ findings.push(...analyzeFile(file, PATTERNS.css));
430
+ findings.push(...analyzeHookPairing(file));
431
+ findings.push(...analyzeInventedHooks(file));
432
+ }
433
+
434
+ // Find and analyze HTML files
435
+ const htmlFiles = findFiles(resolvedPath, ['.html']);
436
+ for (const file of htmlFiles) {
437
+ findings.push(...analyzeFile(file, PATTERNS.html));
438
+ findings.push(...analyzeHeadings(file));
439
+ }
440
+
441
+ // Find and analyze JS files
442
+ const jsFiles = findFiles(resolvedPath, ['.js']);
443
+ for (const file of jsFiles) {
444
+ findings.push(...analyzeFile(file, PATTERNS.js));
445
+ }
446
+
447
+ // Calculate scores
448
+ const scores = calculateScores(findings);
449
+
450
+ // Organize findings by severity
451
+ const organized = {
452
+ critical: findings.filter(f => f.severity === CRITICAL),
453
+ warning: findings.filter(f => f.severity === WARNING),
454
+ info: findings.filter(f => f.severity === INFO)
455
+ };
456
+
457
+ // Calculate total lines for complexity classification
458
+ let totalLines = 0;
459
+ for (const file of [...cssFiles, ...htmlFiles, ...jsFiles]) {
460
+ totalLines += fs.readFileSync(file, 'utf-8').split('\n').length;
461
+ }
462
+ const totalFiles = cssFiles.length + htmlFiles.length + jsFiles.length;
463
+ let complexity = 'small';
464
+ if (totalFiles >= 7 || totalLines >= 500) complexity = 'large';
465
+ else if (totalFiles >= 3 || totalLines >= 100) complexity = 'medium';
466
+
467
+ // Build result
468
+ const result = {
469
+ component: path.basename(resolvedPath),
470
+ path: resolvedPath,
471
+ timestamp: new Date().toISOString(),
472
+ complexity: {
473
+ classification: complexity,
474
+ totalFiles,
475
+ totalLines
476
+ },
477
+ note: "These are automated category scores only. Combine them with SLDS linter results and the required Step 3 manual review gate in SKILL.md before making a final ship recommendation.",
478
+ scores: {
479
+ theming: { score: scores.theming, grade: getGrade(scores.theming) },
480
+ accessibility: { score: scores.accessibility, grade: getGrade(scores.accessibility) },
481
+ codeQuality: { score: scores.codeQuality, grade: getGrade(scores.codeQuality) },
482
+ componentUsage: { score: scores.componentUsage, grade: getGrade(scores.componentUsage) }
483
+ },
484
+ findings: organized,
485
+ summary: {
486
+ filesAnalyzed: totalFiles,
487
+ cssFiles: cssFiles.length,
488
+ htmlFiles: htmlFiles.length,
489
+ jsFiles: jsFiles.length,
490
+ totalLines,
491
+ critical: organized.critical.length,
492
+ warnings: organized.warning.length,
493
+ info: organized.info.length
494
+ }
495
+ };
496
+
497
+ return result;
498
+ }
499
+
500
+ // CLI entry point
501
+ if (require.main === module) {
502
+ const args = process.argv.slice(2);
503
+ const positionalArgs = args.filter((a, i) => !a.startsWith('--') && (i === 0 || !args[i - 1].startsWith('--')));
504
+
505
+ if (positionalArgs.length === 0) {
506
+ console.log('SLDS Quality Analyzer');
507
+ console.log('Usage: node analyze-quality.cjs <component-path> [--hooks-index <path>]');
508
+ console.log('');
509
+ console.log('Options:');
510
+ console.log(' --hooks-index <path> Path to hooks-index.json (optional; enables T051 invented-hook detection)');
511
+ console.log('');
512
+ console.log('Output: JSON analysis of SLDS quality issues');
513
+ process.exit(0);
514
+ }
515
+
516
+ HOOKS_INDEX_PATH = resolveHooksIndexPath(args);
517
+ const result = analyze(positionalArgs[0]);
518
+ console.log(JSON.stringify(result, null, 2));
519
+ }
520
+
521
+ module.exports = { analyze, PATTERNS };