@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,98 @@
1
+ """Shared CLI override helper for d360 entry scripts.
2
+
3
+ D360 has 5 independent entry scripts (``fetch_dc.py``, ``assemble_dc.py``,
4
+ ``render_dc.py``, ``resolve_session.py``, ``discover_sessions.py``) — each
5
+ needs the same ``--data-dir`` / ``--cache-dir`` flags and the same
6
+ 3-level namespace rebind. This module factors that duplication into one
7
+ helper.
8
+
9
+ Usage in each entry script::
10
+
11
+ from _shared.cli_override import add_cli_flags, apply_overrides
12
+
13
+ parser = argparse.ArgumentParser(...)
14
+ parser.add_argument(...)
15
+ add_cli_flags(parser)
16
+ args = parser.parse_args()
17
+ apply_overrides(args, caller_globals=globals())
18
+
19
+ The ``caller_globals=globals()`` parameter is the magic that lets us
20
+ rebind the entry script's own ``DATA_ROOT`` / ``CACHE_ROOT`` snapshot —
21
+ without it, only ``paths.X`` and ``config.X`` would update, and the
22
+ entry script's local ``DATA_ROOT`` would still point at the default.
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import argparse
27
+ from pathlib import Path
28
+
29
+ _SKILL_NAME = "investigating-agentforce-d360"
30
+
31
+
32
+ def add_cli_flags(parser: argparse.ArgumentParser) -> None:
33
+ """Add --data-dir / --cache-dir flags to the given parser.
34
+
35
+ Defaults are runtime-agnostic (``~/.vibe/...``); other
36
+ runtimes (AFV OOTB, Codex, Cursor, OpenCode) override at invocation
37
+ time.
38
+ """
39
+ parser.add_argument(
40
+ "--data-dir",
41
+ type=Path,
42
+ default=None,
43
+ help=(
44
+ "Override data root (default: "
45
+ "~/.vibe/data/investigating-agentforce-d360)."
46
+ ),
47
+ )
48
+ parser.add_argument(
49
+ "--cache-dir",
50
+ type=Path,
51
+ default=None,
52
+ help=(
53
+ "Override cache root (default: "
54
+ "~/.vibe/cache/investigating-agentforce-d360)."
55
+ ),
56
+ )
57
+
58
+
59
+ def apply_overrides(args: argparse.Namespace, caller_globals: dict) -> None:
60
+ """Apply --data-dir / --cache-dir overrides across all 3 namespace levels.
61
+
62
+ Must be called BEFORE any pipeline code reads ``DATA_ROOT`` or
63
+ ``CACHE_ROOT``.
64
+
65
+ Levels rebound:
66
+ 1. ``paths.DATA_ROOT`` (the source of truth)
67
+ 2. ``config.DATA_ROOT`` (the re-export)
68
+ 3. The caller's own local ``DATA_ROOT`` (via ``caller_globals``)
69
+
70
+ Why 3 levels? Python's ``from X import Y`` snapshots ``Y`` into the
71
+ caller's local namespace at import time. Mutating ``X.Y`` later does
72
+ NOT update the caller's local binding. Without the 3rd-level rebind,
73
+ any function in the caller that references ``DATA_ROOT`` still sees
74
+ the default path even after ``paths.DATA_ROOT`` was overridden.
75
+ """
76
+ if not (args.data_dir or args.cache_dir):
77
+ return
78
+
79
+ from _shared import runtime, paths
80
+ import config
81
+
82
+ if args.data_dir:
83
+ runtime.set_data_root_override(args.data_dir)
84
+ new_data = runtime.resolve_data_root(_SKILL_NAME)
85
+ paths.DATA_ROOT = new_data
86
+ config.DATA_ROOT = new_data
87
+ # Rebind caller's local snapshot, if it captured DATA_ROOT.
88
+ if "DATA_ROOT" in caller_globals:
89
+ caller_globals["DATA_ROOT"] = new_data
90
+
91
+ if args.cache_dir:
92
+ runtime.set_cache_root_override(args.cache_dir)
93
+ new_cache = runtime.resolve_cache_root(_SKILL_NAME)
94
+ paths.CACHE_ROOT = new_cache
95
+ if hasattr(config, "CACHE_ROOT"):
96
+ config.CACHE_ROOT = new_cache
97
+ if "CACHE_ROOT" in caller_globals:
98
+ caller_globals["CACHE_ROOT"] = new_cache
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env python3
2
+ r"""Filesystem-safety and input-validation guard.
3
+
4
+ One script, six check types. Emits a STATUS=INVALID_INPUT RESULT block on
5
+ failure + tees to $ERROR_TEE on disk + exits 1.
6
+
7
+ Guiding principle: the agent MUST suffix every call with `|| exit 1` — Python
8
+ `sys.exit(1)` only terminates this subprocess, not the parent bash. A bare
9
+ call without `|| exit 1` silently continues past a failed guard, which is
10
+ the worst possible failure mode for a security check.
11
+
12
+ Check types:
13
+ symlink — path must NOT be a symlink (rejects pre-planted attacker bait)
14
+ owned — path must be owned by current UID (rejects foreign-owned dirs)
15
+ uuid — value must match ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
16
+ org_id_15 — value must match ^[A-Za-z0-9]{15}$ (Salesforce org ID slice)
17
+ api_name — value must match ^[A-Za-z0-9_]+$ (Salesforce API identifier)
18
+ api_version — value must match ^v[0-9]+\.[0-9]+$ (e.g. v60.0)
19
+ agent_version — value must match ^v[0-9]+$ (e.g. v5 — Agentforce agent version, no dot-minor)
20
+ not_empty — value must be non-empty string
21
+
22
+ Python-importable API:
23
+ validate_api_name(value, label="...") — raises ValidationError on bad input
24
+ validate_api_version(value, label="...") — raises ValidationError on bad input
25
+ validate_agent_version(value, label="...") — raises ValidationError on bad input
26
+ validate_org_id_15(value, label="...") — raises ValidationError on bad input
27
+ ValidationError — carries (label, reason)
28
+
29
+ The Python API is used by in-process callers (SOQL loader, path builders in
30
+ config.py) that need a raise-based boundary rather than the process-exit
31
+ CLI behavior. Regex is shared — do NOT duplicate API_NAME_RE / API_VERSION_RE.
32
+
33
+ Usage:
34
+ python3 fs_guard.py <value> <label> <check> || exit 1
35
+
36
+ # Input validation
37
+ python3 fs_guard.py "$AGENT_API_NAME" agent_api_name api_name || exit 1
38
+ python3 fs_guard.py "$ORG_ALIAS" org_alias not_empty || exit 1
39
+
40
+ # Filesystem safety
41
+ python3 fs_guard.py "$WORK_DIR" WORK_DIR symlink || exit 1
42
+ python3 fs_guard.py "$WORK_DIR" WORK_DIR owned || exit 1
43
+ python3 fs_guard.py "$ORG_ID_15" ORG_ID_15 org_id_15 || exit 1
44
+
45
+ Inputs:
46
+ argv[1] value or path to check
47
+ argv[2] label (appears in ERROR_DETAIL; used to identify which guard tripped)
48
+ argv[3] check type (one of the 6 above)
49
+ env $ERROR_TEE (optional): path to disk-tee file. Defaults to
50
+ $HOME/.vibe/data/investigating-agentforce-d360/_last_error_result.txt.
51
+ Also reads $AGENT_API_NAME / $ORG_ID_18 / $ORG_ID_15 for
52
+ RESULT-block context if set.
53
+
54
+ Outputs:
55
+ on failure: STATUS=INVALID_INPUT RESULT block on stdout + tee to disk, exit 1
56
+ on success: silent, exit 0
57
+ on bad argv: exit 1 with a minimal ERROR_DETAIL ("fs_guard internal: ...")
58
+ """
59
+ import os
60
+ import pathlib
61
+ import re
62
+ import sys
63
+
64
+ # Anchored \A...\Z (not ^...$) — Python's `$` matches before a trailing
65
+ # newline, so "00DTESTORG12345\n" passes ^...$ + .match(). Every call
66
+ # site below MUST use .fullmatch() for the same reason; .match() is
67
+ # unsafe even with \A...\Z anchors. Mirrors the pattern in
68
+ # _shared/paths.py SESSION_ID_RE.
69
+ UUID_RE = re.compile(r"\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
70
+ ORG_ID_15_RE = re.compile(r"\A[A-Za-z0-9]{15}\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
71
+ API_NAME_RE = re.compile(r"\A[A-Za-z0-9_]+\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
72
+ # P0-5: api_version check — matches `v60.0`, `v66.0`, etc. Used before any
73
+ # Path composition that embeds the api_version segment.
74
+ API_VERSION_RE = re.compile(r"\Av[0-9]+\.[0-9]+\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
75
+ # Agent-version check — matches Agentforce version identifiers (`v1`, `v5`,
76
+ # `v12`). Deliberately stricter than api_name (rejects free-form names like
77
+ # `release_1`) and looser than api_version (rejects `v66.0` which is a REST
78
+ # API version, never an agent version). Lives on its own so callers that
79
+ # embed agent_version in a filesystem path get the tight regex, not the
80
+ # permissive api_name fallback.
81
+ AGENT_VERSION_RE = re.compile(r"\Av[0-9]+\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
82
+ VALID_CHECKS = {"symlink", "owned", "uuid", "org_id_15", "api_name", "api_version", "agent_version", "not_empty"}
83
+
84
+
85
+ # -----------------------------------------------------------------------------
86
+ # Python-importable API (P0-1, P0-5)
87
+ # -----------------------------------------------------------------------------
88
+ # In-process callers (soql_loader.load_soql, config.build_*_dir) need a
89
+ # raise-based validation boundary, distinct from the CLI script's exit-1
90
+ # behavior. The regexes are shared with the CLI checks above — do NOT
91
+ # duplicate. If a regex changes, both surfaces update in lockstep.
92
+
93
+
94
+ class ValidationError(ValueError):
95
+ """Raised by the Python-importable validators on bad input.
96
+
97
+ Carries the label (which field failed) + reason. Callers (e.g.
98
+ soql_loader.load_soql) convert this into `_unresolved[]` entries or
99
+ RESULT-level INVALID_INPUT responses as appropriate.
100
+ """
101
+
102
+ def __init__(self, label: str, reason: str) -> None:
103
+ self.label = label
104
+ self.reason = reason
105
+ super().__init__(f"{label}: {reason}")
106
+
107
+
108
+ def validate_api_name(value, label: str = "value") -> None:
109
+ """Validate `value` against ^[A-Za-z0-9_]+$ (Salesforce API identifier).
110
+
111
+ P0-1: used by soql_loader.load_soql at the substitution boundary to catch
112
+ injection attempts in names pulled from Bot XML, Flow.Metadata, ApexClass
113
+ SymbolTable, etc.
114
+
115
+ P0-5: used by config.build_*_dir helpers for path components that must
116
+ not contain `..`, `/`, or other traversal characters.
117
+
118
+ Raises ValidationError on any of: None, non-string, empty, regex miss.
119
+ """
120
+ if value is None:
121
+ raise ValidationError(label, "is None")
122
+ if not isinstance(value, str):
123
+ raise ValidationError(label, f"must be str, got {type(value).__name__}")
124
+ if not value:
125
+ raise ValidationError(label, "must not be empty")
126
+ if not API_NAME_RE.fullmatch(value):
127
+ # Preview first 20 chars so logs/_unresolved entries carry enough
128
+ # context to debug, without dumping an unbounded attacker-controlled
129
+ # string into output.
130
+ preview = value[:20]
131
+ raise ValidationError(
132
+ label,
133
+ f"does not match [A-Za-z0-9_]+ (preview={preview!r})",
134
+ )
135
+
136
+
137
+ def validate_api_version(value, label: str = "api_version") -> None:
138
+ """Validate `value` against ^v[0-9]+\\.[0-9]+$ (Salesforce API version).
139
+
140
+ P0-5: used by config.build_*_dir helpers. api_version is returned by
141
+ `sf org display` and later embedded in cache paths; reject anything that
142
+ could escape the cache subtree.
143
+ """
144
+ if value is None:
145
+ raise ValidationError(label, "is None")
146
+ if not isinstance(value, str):
147
+ raise ValidationError(label, f"must be str, got {type(value).__name__}")
148
+ if not value:
149
+ raise ValidationError(label, "must not be empty")
150
+ if not API_VERSION_RE.fullmatch(value):
151
+ preview = value[:20]
152
+ raise ValidationError(
153
+ label,
154
+ f"does not match v<major>.<minor> (preview={preview!r})",
155
+ )
156
+
157
+
158
+ def validate_agent_version(value, label: str = "agent_version") -> None:
159
+ """Validate `value` against ^v[0-9]+$ (Agentforce agent version).
160
+
161
+ Strictly `v<digits>` with no dot-minor — matches the shape Agentforce
162
+ actually uses (`v1`, `v5`, `v12`). Rejects `release_1`, `v66.0`, `FOO`,
163
+ and anything else that could silently slip past a permissive api_name
164
+ check and land in a filesystem path.
165
+
166
+ P0-5: used by path-builder helpers for the agent_version segment.
167
+ """
168
+ if value is None:
169
+ raise ValidationError(label, "is None")
170
+ if not isinstance(value, str):
171
+ raise ValidationError(label, f"must be str, got {type(value).__name__}")
172
+ if not value:
173
+ raise ValidationError(label, "must not be empty")
174
+ if not AGENT_VERSION_RE.fullmatch(value):
175
+ preview = value[:20]
176
+ raise ValidationError(
177
+ label,
178
+ f"does not match v<digits> (preview={preview!r})",
179
+ )
180
+
181
+
182
+ def validate_org_id_15(value, label: str = "org_id_15") -> None:
183
+ """Validate `value` against ^[A-Za-z0-9]{15}$ (Salesforce 15-char org ID).
184
+
185
+ P0-5: stricter than validate_api_name — enforces exact 15 chars AND
186
+ no underscores. `org_id_15` always comes from a Salesforce-generated
187
+ field, never from free-form input.
188
+ """
189
+ if value is None:
190
+ raise ValidationError(label, "is None")
191
+ if not isinstance(value, str):
192
+ raise ValidationError(label, f"must be str, got {type(value).__name__}")
193
+ if not value:
194
+ raise ValidationError(label, "must not be empty")
195
+ if not ORG_ID_15_RE.fullmatch(value):
196
+ preview = value[:20]
197
+ raise ValidationError(
198
+ label,
199
+ f"must be exactly 15 alphanumeric chars (preview={preview!r})",
200
+ )
201
+
202
+
203
+ def scrub(s: str) -> str:
204
+ # Same rules as sanitize.py; duplicated locally so this script has no
205
+ # intra-skill imports. Keeps the agent-script boundary clean.
206
+ bad = set("`$\"\\\r\t\0\n")
207
+ return "".join(c for c in (s or "") if c not in bad)
208
+
209
+
210
+ def emit_failure(reason: str, label: str) -> None:
211
+ agent_api_name = scrub(os.environ.get("AGENT_API_NAME", ""))
212
+ org_id_18 = scrub(os.environ.get("ORG_ID_18", ""))
213
+ org_id_15 = scrub(os.environ.get("ORG_ID_15", ""))
214
+ label_safe = scrub(label)
215
+ reason_safe = scrub(reason)
216
+
217
+ block = (
218
+ "=== RESULT ===\n"
219
+ "STATUS=INVALID_INPUT\n"
220
+ f"ERROR_DETAIL={label_safe}: {reason_safe}\n"
221
+ f"AGENT_API_NAME={agent_api_name}\n"
222
+ f"ORG_ID_18={org_id_18}\n"
223
+ f"ORG_ID_15={org_id_15}\n"
224
+ )
225
+
226
+ # Default ERROR_TEE lives under the skill-scoped data root. Runtime-agnostic
227
+ # default mirrors runtime.resolve_data_root() in the sibling runtime module
228
+ # (duplicated rather than imported because fs_guard.py is also invoked
229
+ # standalone from SKILL.md bash, where the override hook isn't active).
230
+ tee_default = str(
231
+ pathlib.Path.home()
232
+ / ".vibe"
233
+ / "data"
234
+ / "investigating-agentforce-d360"
235
+ / "_last_error_result.txt"
236
+ )
237
+ tee_path = os.environ.get("ERROR_TEE") or tee_default
238
+ try:
239
+ p = pathlib.Path(tee_path)
240
+ p.parent.mkdir(parents=True, exist_ok=True)
241
+ p.write_text(block)
242
+ except OSError:
243
+ pass
244
+
245
+ sys.stdout.write(block)
246
+ sys.exit(1)
247
+
248
+
249
+ def check_symlink(value: str, label: str) -> None:
250
+ if pathlib.Path(value).is_symlink():
251
+ emit_failure(f"path is a symlink (refusing to follow): {value}", label)
252
+
253
+
254
+ def check_owned(value: str, label: str) -> None:
255
+ p = pathlib.Path(value)
256
+ if not p.exists():
257
+ return
258
+ try:
259
+ st = p.stat()
260
+ except OSError as e:
261
+ emit_failure(f"stat failed: {e}", label)
262
+ return
263
+ if st.st_uid != os.getuid():
264
+ emit_failure(f"foreign-owned (uid {st.st_uid} != current {os.getuid()}): {value}", label)
265
+
266
+
267
+ def check_uuid(value: str, label: str) -> None:
268
+ if not UUID_RE.fullmatch(value):
269
+ emit_failure("does not match UUID pattern (8-4-4-4-12 lowercase hex)", label)
270
+
271
+
272
+ def check_org_id_15(value: str, label: str) -> None:
273
+ if not ORG_ID_15_RE.fullmatch(value):
274
+ emit_failure("must be exactly 15 alphanumeric characters", label)
275
+
276
+
277
+ def check_api_name(value: str, label: str) -> None:
278
+ if not API_NAME_RE.fullmatch(value):
279
+ emit_failure("does not match [A-Za-z0-9_]+ (Salesforce API name rules)", label)
280
+
281
+
282
+ def check_api_version(value: str, label: str) -> None:
283
+ # P0-5: api_version must be `vNN.N` — no slashes, no dots beyond the one,
284
+ # no path-traversal sequences.
285
+ if not API_VERSION_RE.fullmatch(value):
286
+ emit_failure("does not match v<major>.<minor> (e.g. v60.0)", label)
287
+
288
+
289
+ def check_agent_version(value: str, label: str) -> None:
290
+ # Agent version must be `v<digits>` — no dots, no slashes.
291
+ if not AGENT_VERSION_RE.fullmatch(value):
292
+ emit_failure("does not match v<digits> (e.g. v5)", label)
293
+
294
+
295
+ def check_not_empty(value: str, label: str) -> None:
296
+ if not value:
297
+ emit_failure("must not be empty", label)
298
+
299
+
300
+ CHECKS = {
301
+ "symlink": check_symlink,
302
+ "owned": check_owned,
303
+ "uuid": check_uuid,
304
+ "org_id_15": check_org_id_15,
305
+ "api_name": check_api_name,
306
+ "api_version": check_api_version,
307
+ "agent_version": check_agent_version,
308
+ "not_empty": check_not_empty,
309
+ }
310
+
311
+
312
+ def main() -> int:
313
+ if len(sys.argv) != 4:
314
+ sys.stdout.write(
315
+ "=== RESULT ===\n"
316
+ "STATUS=INVALID_INPUT\n"
317
+ "ERROR_DETAIL=fs_guard internal: wrong argv count (need value, label, check)\n"
318
+ )
319
+ return 1
320
+ value, label, check = sys.argv[1], sys.argv[2], sys.argv[3]
321
+
322
+ for arg in (value, label, check):
323
+ if any(c == "\0" or (ord(c) < 0x20 and c not in "\t\n") for c in arg):
324
+ emit_failure("argv contains control characters", label or "argv")
325
+
326
+ if check not in VALID_CHECKS:
327
+ emit_failure(f"unknown check type '{check}' (valid: {', '.join(sorted(VALID_CHECKS))})", label)
328
+
329
+ CHECKS[check](value, label)
330
+ return 0
331
+
332
+
333
+ if __name__ == "__main__":
334
+ sys.exit(main())
@@ -0,0 +1,155 @@
1
+ """Canonical path helpers for investigating-agentforce-d360.
2
+
3
+ Layout:
4
+
5
+ ~/.vibe/data/investigating-agentforce-d360/
6
+ └── <org_id_15>/
7
+ └── <agent_api_name>__<agent_version>/
8
+ └── <session_id>/ ← per-session DC artifacts
9
+ ├── dc.*.json
10
+ ├── dc._session_manifest.json
11
+ ├── dc._session_tree.json
12
+ └── dc._session_summary.md
13
+
14
+ Validation strategy
15
+ -------------------
16
+ The three "agent-identity" segments (org_id_15, agent_api_name, agent_version)
17
+ are validated by the regex helpers in the sibling ``fs_guard`` module. Any
18
+ segment containing ``..``, ``/``, or characters outside its regex charclass
19
+ raises ``PathValidationError`` — direct ``Path`` composition from unvalidated
20
+ input would be a path-traversal vulnerability and is prohibited.
21
+
22
+ ``session_id`` is validated locally via ``SESSION_ID_RE.fullmatch`` because
23
+ fs_guard's ``api_name`` rule is too permissive for it (session IDs can contain
24
+ hyphens, which API names cannot). The regex is fully anchored (``\\A...\\Z``)
25
+ and call sites MUST use ``fullmatch`` — ``match`` would silently accept a
26
+ traversal suffix like ``abc\\n../etc``.
27
+ """
28
+ from __future__ import annotations
29
+
30
+ import re
31
+ from pathlib import Path
32
+
33
+ from . import fs_guard
34
+ from . import runtime
35
+
36
+
37
+ # -----------------------------------------------------------------------------
38
+ # Roots
39
+ # -----------------------------------------------------------------------------
40
+ # Runtime-agnostic defaults, overridable via --data-dir / --cache-dir
41
+ # CLI flags on every entry script (fetch_dc, assemble_dc, render_dc,
42
+ # resolve_session, discover_sessions). See runtime.py for details.
43
+
44
+ DATA_ROOT: Path = runtime.resolve_data_root("investigating-agentforce-d360")
45
+ CACHE_ROOT: Path = runtime.resolve_cache_root("investigating-agentforce-d360")
46
+
47
+
48
+ # -----------------------------------------------------------------------------
49
+ # Session-ID validation
50
+ # -----------------------------------------------------------------------------
51
+
52
+ # Fully anchored — call sites MUST use fullmatch (tested). Characters allowed:
53
+ # alphanumeric + underscore + hyphen, matching both UUIDs and MessagingSession
54
+ # IDs.
55
+ SESSION_ID_RE = re.compile(r"\A[A-Za-z0-9_\-]+\Z") # @rule-suppress starter-sec-002 — re.compile, not eval/exec
56
+
57
+
58
+ class PathValidationError(ValueError):
59
+ """Raised when a path segment fails validation.
60
+
61
+ Wraps fs_guard's ``ValidationError`` as well as local ``session_id``
62
+ rejections so callers have a single exception type to catch.
63
+ """
64
+
65
+ def __init__(self, label: str, reason: str) -> None:
66
+ self.label = label
67
+ self.reason = reason
68
+ super().__init__(f"{label}: {reason}")
69
+
70
+
71
+ # -----------------------------------------------------------------------------
72
+ # Validation helpers
73
+ # -----------------------------------------------------------------------------
74
+
75
+
76
+ def _validate_agent_triple(
77
+ org_id_15: str, agent_api_name: str, agent_version: str
78
+ ) -> None:
79
+ """Validate the three identity segments. Raises PathValidationError on
80
+ failure, wrapping fs_guard's ValidationError so callers don't need to
81
+ know about fs_guard internals."""
82
+ try:
83
+ fs_guard.validate_org_id_15(org_id_15, label="org_id_15")
84
+ fs_guard.validate_api_name(agent_api_name, label="agent_api_name")
85
+ fs_guard.validate_agent_version(agent_version, label="agent_version")
86
+ except fs_guard.ValidationError as e:
87
+ raise PathValidationError(e.label, e.reason) from e
88
+
89
+
90
+ def validate_session_id(session_id: str) -> None:
91
+ """Validate session_id via SESSION_ID_RE.fullmatch.
92
+
93
+ Raises :class:`PathValidationError` on any of: None, non-string, empty,
94
+ regex miss. This is the public validator every caller that composes a
95
+ Path segment from a session-id MUST go through — direct
96
+ ``Path / session_id`` composition bypasses the anchored-regex check.
97
+ """
98
+ if session_id is None:
99
+ raise PathValidationError("session_id", "is None")
100
+ if not isinstance(session_id, str):
101
+ raise PathValidationError(
102
+ "session_id", f"must be str, got {type(session_id).__name__}"
103
+ )
104
+ if not session_id:
105
+ raise PathValidationError("session_id", "must not be empty")
106
+ if not SESSION_ID_RE.fullmatch(session_id):
107
+ preview = session_id[:40]
108
+ raise PathValidationError(
109
+ "session_id",
110
+ f"does not match {SESSION_ID_RE.pattern} (preview={preview!r})",
111
+ )
112
+
113
+
114
+ _validate_session_id = validate_session_id # backward-compat alias
115
+
116
+
117
+ # -----------------------------------------------------------------------------
118
+ # Path builders
119
+ # -----------------------------------------------------------------------------
120
+
121
+
122
+ def agent_dir(
123
+ org_id_15: str, agent_api_name: str, agent_version: str
124
+ ) -> Path:
125
+ """Return ``DATA_ROOT/<org_id_15>/<agent_api_name>__<agent_version>/``.
126
+
127
+ All three segments are regex-validated before being joined. Any segment
128
+ containing ``..``, ``/``, or characters outside its regex charclass
129
+ raises ``PathValidationError``.
130
+ """
131
+ _validate_agent_triple(org_id_15, agent_api_name, agent_version)
132
+ return DATA_ROOT / org_id_15 / f"{agent_api_name}__{agent_version}"
133
+
134
+
135
+ def session_dir(
136
+ org_id_15: str,
137
+ agent_api_name: str,
138
+ agent_version: str,
139
+ session_id: str,
140
+ ) -> Path:
141
+ """Return
142
+ ``DATA_ROOT/<org_id_15>/<agent_api_name>__<agent_version>/<session_id>/``.
143
+
144
+ All four segments are validated. The first three go through fs_guard;
145
+ ``session_id`` goes through ``SESSION_ID_RE.fullmatch``. Any rejection
146
+ raises ``PathValidationError``.
147
+ """
148
+ _validate_agent_triple(org_id_15, agent_api_name, agent_version)
149
+ validate_session_id(session_id)
150
+ return (
151
+ DATA_ROOT
152
+ / org_id_15
153
+ / f"{agent_api_name}__{agent_version}"
154
+ / session_id
155
+ )
@@ -0,0 +1,59 @@
1
+ """Runtime override hook for DATA_ROOT / CACHE_ROOT.
2
+
3
+ Default layout is ``~/.vibe/data/<skill>`` and
4
+ ``~/.vibe/cache/<skill>`` — runtime-agnostic branding that
5
+ follows the repo's "tool-agnostic language" guideline.
6
+
7
+ Other runtimes (AFV OOTB, Codex, Cursor, OpenCode) can override via
8
+ ``--data-dir`` / ``--cache-dir`` CLI flags on entry scripts. Those flags
9
+ call ``set_*_override()`` BEFORE any pipeline module imports ``paths.py``,
10
+ so the resolution helpers below pick up the override.
11
+
12
+ Three-level rebind contract
13
+ ---------------------------
14
+ Python's ``from X import Y`` snapshots ``Y`` into the importer's local
15
+ namespace. Mutating ``X.Y`` later does NOT update the importer's local
16
+ binding. Entry scripts that capture ``DATA_ROOT`` / ``CACHE_ROOT`` at
17
+ module top must therefore rebind in THREE places after override:
18
+
19
+ 1. ``paths.DATA_ROOT`` — the source of truth
20
+ 2. ``config.DATA_ROOT`` — the re-export
21
+ 3. The entry script's own local ``DATA_ROOT`` (via ``global``)
22
+ """
23
+ from __future__ import annotations
24
+
25
+ from pathlib import Path
26
+ from typing import Optional
27
+
28
+ _DATA_OVERRIDE: Optional[Path] = None
29
+ _CACHE_OVERRIDE: Optional[Path] = None
30
+
31
+
32
+ def set_data_root_override(p: Optional[Path]) -> None:
33
+ """Set the data-root override. Pass ``None`` to clear."""
34
+ global _DATA_OVERRIDE
35
+ _DATA_OVERRIDE = p
36
+
37
+
38
+ def set_cache_root_override(p: Optional[Path]) -> None:
39
+ """Set the cache-root override. Pass ``None`` to clear."""
40
+ global _CACHE_OVERRIDE
41
+ _CACHE_OVERRIDE = p
42
+
43
+
44
+ def resolve_data_root(skill_name: str) -> Path:
45
+ """Resolve the data root for ``skill_name``.
46
+
47
+ Returns the override if set, else the runtime-agnostic default
48
+ ``~/.vibe/data/<skill_name>``.
49
+ """
50
+ return _DATA_OVERRIDE or (Path.home() / ".vibe" / "data" / skill_name)
51
+
52
+
53
+ def resolve_cache_root(skill_name: str) -> Path:
54
+ """Resolve the cache root for ``skill_name``.
55
+
56
+ Returns the override if set, else the runtime-agnostic default
57
+ ``~/.vibe/cache/<skill_name>``.
58
+ """
59
+ return _CACHE_OVERRIDE or (Path.home() / ".vibe" / "cache" / skill_name)
@@ -0,0 +1,14 @@
1
+ """Canonical SQL-escaping helpers for investigating-agentforce-d360.
2
+
3
+ Single source of truth for DC-SQL string-literal escaping. Behavioral contract
4
+ is fixed — do not change the escape strategy without updating every caller and
5
+ its tests.
6
+ """
7
+ from __future__ import annotations
8
+
9
+
10
+ def _escape_sql_literal(s: str) -> str:
11
+ """Double single quotes per DC SQL escaping rule. Handles O'Brien →
12
+ O''Brien, `'; DROP --` → `''; DROP --` (still harmless because it's
13
+ wrapped in surrounding single quotes)."""
14
+ return s.replace("'", "''")