@salesforce/afv-skills 1.13.0 → 1.15.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 (359) hide show
  1. package/package.json +3 -3
  2. package/skills/applying-slds/SKILL.md +322 -0
  3. package/skills/applying-slds/checklists.md +83 -0
  4. package/skills/applying-slds/examples.md +283 -0
  5. package/skills/applying-slds/guidance/README.md +83 -0
  6. package/skills/applying-slds/guidance/blueprints-index.md +213 -0
  7. package/skills/applying-slds/guidance/icons-guidance.md +186 -0
  8. package/skills/applying-slds/guidance/overviews/borders.md +236 -0
  9. package/skills/applying-slds/guidance/overviews/color.md +266 -0
  10. package/skills/applying-slds/guidance/overviews/display-density.md +366 -0
  11. package/skills/applying-slds/guidance/overviews/icons.md +240 -0
  12. package/skills/applying-slds/guidance/overviews/illustrations.md +235 -0
  13. package/skills/applying-slds/guidance/overviews/shadows.md +176 -0
  14. package/skills/applying-slds/guidance/overviews/spacing.md +216 -0
  15. package/skills/applying-slds/guidance/overviews/typography.md +323 -0
  16. package/skills/applying-slds/guidance/overviews/utilities.md +542 -0
  17. package/skills/applying-slds/guidance/slds-development-guide.md +288 -0
  18. package/skills/applying-slds/guidance/styling-hooks/borders.md +202 -0
  19. package/skills/applying-slds/guidance/styling-hooks/color/expressive-palette-hooks.md +153 -0
  20. package/skills/applying-slds/guidance/styling-hooks/color/index.md +171 -0
  21. package/skills/applying-slds/guidance/styling-hooks/color/semantic/accent-hooks.md +204 -0
  22. package/skills/applying-slds/guidance/styling-hooks/color/semantic/feedback-hooks.md +768 -0
  23. package/skills/applying-slds/guidance/styling-hooks/color/semantic/surface-hooks.md +337 -0
  24. package/skills/applying-slds/guidance/styling-hooks/color/system-hooks.md +132 -0
  25. package/skills/applying-slds/guidance/styling-hooks/index.md +327 -0
  26. package/skills/applying-slds/guidance/styling-hooks/shadows.md +238 -0
  27. package/skills/applying-slds/guidance/styling-hooks/spacing.md +254 -0
  28. package/skills/applying-slds/guidance/styling-hooks/typography.md +448 -0
  29. package/skills/applying-slds/guidance/utilities/alignment.md +119 -0
  30. package/skills/applying-slds/guidance/utilities/borders.md +131 -0
  31. package/skills/applying-slds/guidance/utilities/box.md +125 -0
  32. package/skills/applying-slds/guidance/utilities/color.md +165 -0
  33. package/skills/applying-slds/guidance/utilities/dark-mode.md +111 -0
  34. package/skills/applying-slds/guidance/utilities/description-list.md +168 -0
  35. package/skills/applying-slds/guidance/utilities/floats.md +117 -0
  36. package/skills/applying-slds/guidance/utilities/grid.md +264 -0
  37. package/skills/applying-slds/guidance/utilities/horizontal-list.md +110 -0
  38. package/skills/applying-slds/guidance/utilities/hyphenation.md +84 -0
  39. package/skills/applying-slds/guidance/utilities/index.md +205 -0
  40. package/skills/applying-slds/guidance/utilities/interactions.md +89 -0
  41. package/skills/applying-slds/guidance/utilities/layout.md +109 -0
  42. package/skills/applying-slds/guidance/utilities/line-clamp.md +131 -0
  43. package/skills/applying-slds/guidance/utilities/margin.md +155 -0
  44. package/skills/applying-slds/guidance/utilities/media-object.md +161 -0
  45. package/skills/applying-slds/guidance/utilities/name-value-list.md +152 -0
  46. package/skills/applying-slds/guidance/utilities/padding.md +155 -0
  47. package/skills/applying-slds/guidance/utilities/position.md +177 -0
  48. package/skills/applying-slds/guidance/utilities/print.md +114 -0
  49. package/skills/applying-slds/guidance/utilities/scrollable.md +126 -0
  50. package/skills/applying-slds/guidance/utilities/sizing.md +190 -0
  51. package/skills/applying-slds/guidance/utilities/themes.md +121 -0
  52. package/skills/applying-slds/guidance/utilities/truncate.md +127 -0
  53. package/skills/applying-slds/guidance/utilities/typography.md +166 -0
  54. package/skills/applying-slds/guidance/utilities/vertical-list.md +166 -0
  55. package/skills/applying-slds/guidance/utilities/visibility.md +228 -0
  56. package/skills/applying-slds/metadata/README.md +84 -0
  57. package/skills/applying-slds/metadata/blueprints/components/accordion.yaml +304 -0
  58. package/skills/applying-slds/metadata/blueprints/components/activity-timeline.yaml +92 -0
  59. package/skills/applying-slds/metadata/blueprints/components/alert.yaml +103 -0
  60. package/skills/applying-slds/metadata/blueprints/components/app-launcher.yaml +94 -0
  61. package/skills/applying-slds/metadata/blueprints/components/avatar-group.yaml +81 -0
  62. package/skills/applying-slds/metadata/blueprints/components/avatar.yaml +97 -0
  63. package/skills/applying-slds/metadata/blueprints/components/badges.yaml +102 -0
  64. package/skills/applying-slds/metadata/blueprints/components/brand-band.yaml +198 -0
  65. package/skills/applying-slds/metadata/blueprints/components/breadcrumbs.yaml +95 -0
  66. package/skills/applying-slds/metadata/blueprints/components/builder-header.yaml +192 -0
  67. package/skills/applying-slds/metadata/blueprints/components/button-groups.yaml +82 -0
  68. package/skills/applying-slds/metadata/blueprints/components/button-icons.yaml +295 -0
  69. package/skills/applying-slds/metadata/blueprints/components/buttons.yaml +230 -0
  70. package/skills/applying-slds/metadata/blueprints/components/cards.yaml +124 -0
  71. package/skills/applying-slds/metadata/blueprints/components/carousel.yaml +140 -0
  72. package/skills/applying-slds/metadata/blueprints/components/chat.yaml +179 -0
  73. package/skills/applying-slds/metadata/blueprints/components/checkbox-button-group.yaml +192 -0
  74. package/skills/applying-slds/metadata/blueprints/components/checkbox-button.yaml +204 -0
  75. package/skills/applying-slds/metadata/blueprints/components/checkbox-toggle.yaml +177 -0
  76. package/skills/applying-slds/metadata/blueprints/components/checkbox.yaml +108 -0
  77. package/skills/applying-slds/metadata/blueprints/components/color-picker.yaml +172 -0
  78. package/skills/applying-slds/metadata/blueprints/components/combobox.yaml +136 -0
  79. package/skills/applying-slds/metadata/blueprints/components/counter.yaml +147 -0
  80. package/skills/applying-slds/metadata/blueprints/components/data-tables.yaml +157 -0
  81. package/skills/applying-slds/metadata/blueprints/components/datepickers.yaml +130 -0
  82. package/skills/applying-slds/metadata/blueprints/components/datetime-picker.yaml +155 -0
  83. package/skills/applying-slds/metadata/blueprints/components/docked-composer.yaml +201 -0
  84. package/skills/applying-slds/metadata/blueprints/components/docked-form-footer.yaml +161 -0
  85. package/skills/applying-slds/metadata/blueprints/components/docked-utility-bar.yaml +175 -0
  86. package/skills/applying-slds/metadata/blueprints/components/drop-zone.yaml +115 -0
  87. package/skills/applying-slds/metadata/blueprints/components/dueling-picklist.yaml +196 -0
  88. package/skills/applying-slds/metadata/blueprints/components/dynamic-icons.yaml +128 -0
  89. package/skills/applying-slds/metadata/blueprints/components/dynamic-menu.yaml +141 -0
  90. package/skills/applying-slds/metadata/blueprints/components/expandable-section.yaml +115 -0
  91. package/skills/applying-slds/metadata/blueprints/components/expression.yaml +143 -0
  92. package/skills/applying-slds/metadata/blueprints/components/feeds.yaml +125 -0
  93. package/skills/applying-slds/metadata/blueprints/components/file-selector.yaml +154 -0
  94. package/skills/applying-slds/metadata/blueprints/components/files.yaml +119 -0
  95. package/skills/applying-slds/metadata/blueprints/components/form-element.yaml +145 -0
  96. package/skills/applying-slds/metadata/blueprints/components/global-header.yaml +120 -0
  97. package/skills/applying-slds/metadata/blueprints/components/global-navigation.yaml +100 -0
  98. package/skills/applying-slds/metadata/blueprints/components/icons.yaml +138 -0
  99. package/skills/applying-slds/metadata/blueprints/components/illustration.yaml +205 -0
  100. package/skills/applying-slds/metadata/blueprints/components/input.yaml +151 -0
  101. package/skills/applying-slds/metadata/blueprints/components/list-builder.yaml +127 -0
  102. package/skills/applying-slds/metadata/blueprints/components/lookups.yaml +132 -0
  103. package/skills/applying-slds/metadata/blueprints/components/map.yaml +118 -0
  104. package/skills/applying-slds/metadata/blueprints/components/menus.yaml +134 -0
  105. package/skills/applying-slds/metadata/blueprints/components/modals.yaml +152 -0
  106. package/skills/applying-slds/metadata/blueprints/components/notifications.yaml +88 -0
  107. package/skills/applying-slds/metadata/blueprints/components/page-headers.yaml +135 -0
  108. package/skills/applying-slds/metadata/blueprints/components/panels.yaml +149 -0
  109. package/skills/applying-slds/metadata/blueprints/components/path.yaml +154 -0
  110. package/skills/applying-slds/metadata/blueprints/components/picklist.yaml +125 -0
  111. package/skills/applying-slds/metadata/blueprints/components/pills.yaml +154 -0
  112. package/skills/applying-slds/metadata/blueprints/components/popovers.yaml +120 -0
  113. package/skills/applying-slds/metadata/blueprints/components/progress-bar.yaml +110 -0
  114. package/skills/applying-slds/metadata/blueprints/components/progress-indicator.yaml +133 -0
  115. package/skills/applying-slds/metadata/blueprints/components/progress-ring.yaml +102 -0
  116. package/skills/applying-slds/metadata/blueprints/components/prompt.yaml +126 -0
  117. package/skills/applying-slds/metadata/blueprints/components/publishers.yaml +178 -0
  118. package/skills/applying-slds/metadata/blueprints/components/radio-button-group.yaml +172 -0
  119. package/skills/applying-slds/metadata/blueprints/components/radio-group.yaml +112 -0
  120. package/skills/applying-slds/metadata/blueprints/components/rich-text-editor.yaml +135 -0
  121. package/skills/applying-slds/metadata/blueprints/components/scoped-notifications.yaml +188 -0
  122. package/skills/applying-slds/metadata/blueprints/components/scoped-tabs.yaml +97 -0
  123. package/skills/applying-slds/metadata/blueprints/components/select.yaml +127 -0
  124. package/skills/applying-slds/metadata/blueprints/components/setup-assistant.yaml +152 -0
  125. package/skills/applying-slds/metadata/blueprints/components/slider.yaml +111 -0
  126. package/skills/applying-slds/metadata/blueprints/components/spinners.yaml +135 -0
  127. package/skills/applying-slds/metadata/blueprints/components/split-view.yaml +112 -0
  128. package/skills/applying-slds/metadata/blueprints/components/summary-detail.yaml +103 -0
  129. package/skills/applying-slds/metadata/blueprints/components/tabs.yaml +138 -0
  130. package/skills/applying-slds/metadata/blueprints/components/textarea.yaml +116 -0
  131. package/skills/applying-slds/metadata/blueprints/components/tiles.yaml +108 -0
  132. package/skills/applying-slds/metadata/blueprints/components/timepicker.yaml +111 -0
  133. package/skills/applying-slds/metadata/blueprints/components/toast.yaml +154 -0
  134. package/skills/applying-slds/metadata/blueprints/components/tooltips.yaml +107 -0
  135. package/skills/applying-slds/metadata/blueprints/components/tree-grid.yaml +116 -0
  136. package/skills/applying-slds/metadata/blueprints/components/trees.yaml +116 -0
  137. package/skills/applying-slds/metadata/blueprints/components/trial-bar.yaml +112 -0
  138. package/skills/applying-slds/metadata/blueprints/components/vertical-navigation.yaml +130 -0
  139. package/skills/applying-slds/metadata/blueprints/components/vertical-tabs.yaml +140 -0
  140. package/skills/applying-slds/metadata/blueprints/components/visual-picker.yaml +150 -0
  141. package/skills/applying-slds/metadata/blueprints/components/welcome-mat.yaml +136 -0
  142. package/skills/applying-slds/metadata/hooks-index.json +6272 -0
  143. package/skills/applying-slds/metadata/icon-metadata.json +38466 -0
  144. package/skills/applying-slds/metadata/utilities-index.json +21912 -0
  145. package/skills/applying-slds/references/component-selection.md +112 -0
  146. package/skills/applying-slds/references/icons-decision-guide.md +124 -0
  147. package/skills/applying-slds/references/styling-decision-guide.md +228 -0
  148. package/skills/applying-slds/references/utilities-quick-ref.md +125 -0
  149. package/skills/applying-slds/scripts/search-blueprints.cjs +117 -0
  150. package/skills/applying-slds/scripts/search-hooks.cjs +139 -0
  151. package/skills/applying-slds/scripts/search-icons.cjs +174 -0
  152. package/skills/applying-slds/scripts/search-utilities.cjs +161 -0
  153. package/skills/building-ui-bundle-app/SKILL.md +33 -8
  154. package/skills/generating-custom-application/SKILL.md +1 -1
  155. package/skills/generating-custom-lightning-type/SKILL.md +17 -39
  156. package/skills/generating-custom-lightning-type/assets/primitive-types-and-constraints.md +41 -0
  157. package/skills/generating-custom-lightning-type/references/widget-rendition.md +124 -0
  158. package/skills/generating-ui-bundle-custom-app/SKILL.md +93 -0
  159. package/skills/generating-ui-bundle-custom-app/docs/configure-metadata-custom-application.md +70 -0
  160. package/skills/generating-ui-bundle-metadata/SKILL.md +39 -1
  161. package/skills/investigating-agentforce-architecture/README.md +156 -0
  162. package/skills/investigating-agentforce-architecture/SKILL.md +230 -0
  163. package/skills/investigating-agentforce-architecture/assets/cli/describe_sobject.yaml +16 -0
  164. package/skills/investigating-agentforce-architecture/assets/cli/describe_tooling_sobject.yaml +17 -0
  165. package/skills/investigating-agentforce-architecture/assets/cli/list_metadata_genaiprompttemplate.yaml +17 -0
  166. package/skills/investigating-agentforce-architecture/assets/cli/org_display.yaml +15 -0
  167. package/skills/investigating-agentforce-architecture/assets/cli/retrieve_genai_plugin.yaml +18 -0
  168. package/skills/investigating-agentforce-architecture/assets/cli/show_access_token.yaml +27 -0
  169. package/skills/investigating-agentforce-architecture/assets/mermaid/action_tree.mmd +20 -0
  170. package/skills/investigating-agentforce-architecture/assets/mermaid/data_flow.mmd +19 -0
  171. package/skills/investigating-agentforce-architecture/assets/mermaid/dependency_graph.mmd +19 -0
  172. package/skills/investigating-agentforce-architecture/assets/mermaid/invocation_sequence.mmd +20 -0
  173. package/skills/investigating-agentforce-architecture/assets/mermaid/planner_state.mmd +18 -0
  174. package/skills/investigating-agentforce-architecture/assets/soql/apex_class_bodies_by_ids.soql +3 -0
  175. package/skills/investigating-agentforce-architecture/assets/soql/apex_class_bodies_by_names.soql +3 -0
  176. package/skills/investigating-agentforce-architecture/assets/soql/bot_definition_details.soql +3 -0
  177. package/skills/investigating-agentforce-architecture/assets/soql/bot_version_lookup.soql +4 -0
  178. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_by_ids.soql +3 -0
  179. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_ids_by_names.soql +3 -0
  180. package/skills/investigating-agentforce-architecture/assets/soql/flow_definition_view_by_durable_ids.soql +4 -0
  181. package/skills/investigating-agentforce-architecture/assets/soql/flow_metadata_by_id.soql +3 -0
  182. package/skills/investigating-agentforce-architecture/assets/soql/functions_by_plugins.soql +5 -0
  183. package/skills/investigating-agentforce-architecture/assets/soql/planner_attrs_by_parent_ids.soql +3 -0
  184. package/skills/investigating-agentforce-architecture/assets/soql/planner_bundle_functions.soql +3 -0
  185. package/skills/investigating-agentforce-architecture/assets/soql/planner_definition_by_agent_chain.soql +3 -0
  186. package/skills/investigating-agentforce-architecture/assets/soql/plugin_functions_by_plugin_ids.soql +3 -0
  187. package/skills/investigating-agentforce-architecture/assets/soql/plugin_instructions_by_plugin_ids.soql +3 -0
  188. package/skills/investigating-agentforce-architecture/assets/soql/plugins_by_planner.soql +4 -0
  189. package/skills/investigating-agentforce-architecture/references/architecture_sections.md +243 -0
  190. package/skills/investigating-agentforce-architecture/references/contract.json +244 -0
  191. package/skills/investigating-agentforce-architecture/references/soql_fields.md +512 -0
  192. package/skills/investigating-agentforce-architecture/scripts/_shared/__init__.py +1 -0
  193. package/skills/investigating-agentforce-architecture/scripts/_shared/fs_guard.py +329 -0
  194. package/skills/investigating-agentforce-architecture/scripts/_shared/paths.py +110 -0
  195. package/skills/investigating-agentforce-architecture/scripts/_shared/runtime.py +59 -0
  196. package/skills/investigating-agentforce-architecture/scripts/_shared/sql.py +10 -0
  197. package/skills/investigating-agentforce-architecture/scripts/cache_check.py +234 -0
  198. package/skills/investigating-agentforce-architecture/scripts/config.py +131 -0
  199. package/skills/investigating-agentforce-architecture/scripts/fetch_soql.py +689 -0
  200. package/skills/investigating-agentforce-architecture/scripts/finalize.py +295 -0
  201. package/skills/investigating-agentforce-architecture/scripts/main.py +2835 -0
  202. package/skills/investigating-agentforce-architecture/scripts/metadata_listing.py +265 -0
  203. package/skills/investigating-agentforce-architecture/scripts/parallel_retrieve.py +69 -0
  204. package/skills/investigating-agentforce-architecture/scripts/parse_bundle.py +215 -0
  205. package/skills/investigating-agentforce-architecture/scripts/parse_wave.py +845 -0
  206. package/skills/investigating-agentforce-architecture/scripts/probe_channels.py +302 -0
  207. package/skills/investigating-agentforce-architecture/scripts/render_architecture.py +1043 -0
  208. package/skills/investigating-agentforce-architecture/scripts/resolve_bot.py +255 -0
  209. package/skills/investigating-agentforce-architecture/scripts/resolve_invocation_target.py +130 -0
  210. package/skills/investigating-agentforce-architecture/scripts/rest_client.py +763 -0
  211. package/skills/investigating-agentforce-architecture/scripts/retrieve_planner.py +13 -0
  212. package/skills/investigating-agentforce-architecture/scripts/sf_cli.py +242 -0
  213. package/skills/investigating-agentforce-architecture/scripts/soql_loader.py +253 -0
  214. package/skills/investigating-agentforce-architecture/scripts/summarize_tree.py +143 -0
  215. package/skills/investigating-agentforce-architecture/scripts/tests/__init__.py +0 -0
  216. package/skills/investigating-agentforce-architecture/scripts/tests/_bootstrap.py +23 -0
  217. package/skills/investigating-agentforce-architecture/scripts/tests/fixtures/__init__.py +0 -0
  218. package/skills/investigating-agentforce-architecture/scripts/tests/fixtures/genai_payloads.py +400 -0
  219. package/skills/investigating-agentforce-architecture/scripts/tests/test_cache_check.py +307 -0
  220. package/skills/investigating-agentforce-architecture/scripts/tests/test_cache_check_main.py +283 -0
  221. package/skills/investigating-agentforce-architecture/scripts/tests/test_config.py +115 -0
  222. package/skills/investigating-agentforce-architecture/scripts/tests/test_end_to_end_fixture.py +651 -0
  223. package/skills/investigating-agentforce-architecture/scripts/tests/test_finalize.py +278 -0
  224. package/skills/investigating-agentforce-architecture/scripts/tests/test_flow_children_inflation.py +582 -0
  225. package/skills/investigating-agentforce-architecture/scripts/tests/test_fs_guard.py +113 -0
  226. package/skills/investigating-agentforce-architecture/scripts/tests/test_iterative_wave_b.py +478 -0
  227. package/skills/investigating-agentforce-architecture/scripts/tests/test_main_pipeline.py +3359 -0
  228. package/skills/investigating-agentforce-architecture/scripts/tests/test_parallel_retrieve.py +131 -0
  229. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_bundle.py +400 -0
  230. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave.py +644 -0
  231. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_classifiers.py +224 -0
  232. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_helpers.py +380 -0
  233. package/skills/investigating-agentforce-architecture/scripts/tests/test_parse_wave_main.py +397 -0
  234. package/skills/investigating-agentforce-architecture/scripts/tests/test_per_branch_visited.py +244 -0
  235. package/skills/investigating-agentforce-architecture/scripts/tests/test_probe_channels.py +359 -0
  236. package/skills/investigating-agentforce-architecture/scripts/tests/test_probe_cli_recipes.py +185 -0
  237. package/skills/investigating-agentforce-architecture/scripts/tests/test_render_architecture.py +810 -0
  238. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_bot.py +203 -0
  239. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_creds.py +157 -0
  240. package/skills/investigating-agentforce-architecture/scripts/tests/test_resolve_invocation_target.py +145 -0
  241. package/skills/investigating-agentforce-architecture/scripts/tests/test_rest_client.py +1253 -0
  242. package/skills/investigating-agentforce-architecture/scripts/tests/test_runtime_override.py +100 -0
  243. package/skills/investigating-agentforce-architecture/scripts/tests/test_sf_cli.py +261 -0
  244. package/skills/investigating-agentforce-architecture/scripts/tests/test_signature_stamping.py +466 -0
  245. package/skills/investigating-agentforce-architecture/scripts/tests/test_soql_loader.py +501 -0
  246. package/skills/investigating-agentforce-architecture/scripts/tests/test_summarize_tree.py +241 -0
  247. package/skills/investigating-agentforce-architecture/scripts/tests/test_write_emit_ctx.py +480 -0
  248. package/skills/investigating-agentforce-architecture/tools/emit_env.py +157 -0
  249. package/skills/investigating-agentforce-architecture/tools/emit_result.py +262 -0
  250. package/skills/investigating-agentforce-architecture/tools/sanitize.py +33 -0
  251. package/skills/investigating-agentforce-architecture/tools/write_emit_ctx.py +332 -0
  252. package/skills/investigating-agentforce-d360/README.md +123 -0
  253. package/skills/investigating-agentforce-d360/SKILL.md +163 -0
  254. package/skills/investigating-agentforce-d360/assets/dc/app_generation.sql +51 -0
  255. package/skills/investigating-agentforce-d360/assets/dc/content_category.sql +44 -0
  256. package/skills/investigating-agentforce-d360/assets/dc/content_quality.sql +41 -0
  257. package/skills/investigating-agentforce-d360/assets/dc/discover_sessions.sql +36 -0
  258. package/skills/investigating-agentforce-d360/assets/dc/feedback.sql +47 -0
  259. package/skills/investigating-agentforce-d360/assets/dc/feedback_details.sql +38 -0
  260. package/skills/investigating-agentforce-d360/assets/dc/gateway_records.sql +45 -0
  261. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_llm.sql +50 -0
  262. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_metadata.sql +44 -0
  263. package/skills/investigating-agentforce-d360/assets/dc/gateway_request_tags.sql +42 -0
  264. package/skills/investigating-agentforce-d360/assets/dc/gateway_requests.sql +89 -0
  265. package/skills/investigating-agentforce-d360/assets/dc/gateway_responses.sql +43 -0
  266. package/skills/investigating-agentforce-d360/assets/dc/generations.sql +52 -0
  267. package/skills/investigating-agentforce-d360/assets/dc/interactions.sql +53 -0
  268. package/skills/investigating-agentforce-d360/assets/dc/messages.sql +53 -0
  269. package/skills/investigating-agentforce-d360/assets/dc/messaging_session.sql +37 -0
  270. package/skills/investigating-agentforce-d360/assets/dc/moment_interactions.sql +34 -0
  271. package/skills/investigating-agentforce-d360/assets/dc/moments.sql +39 -0
  272. package/skills/investigating-agentforce-d360/assets/dc/participants.sql +48 -0
  273. package/skills/investigating-agentforce-d360/assets/dc/sessions.sql +78 -0
  274. package/skills/investigating-agentforce-d360/assets/dc/steps.sql +64 -0
  275. package/skills/investigating-agentforce-d360/assets/dc/tag_associations.sql +46 -0
  276. package/skills/investigating-agentforce-d360/assets/dc/tag_definition_associations.sql +37 -0
  277. package/skills/investigating-agentforce-d360/assets/dc/tag_definitions.sql +50 -0
  278. package/skills/investigating-agentforce-d360/assets/dc/tags.sql +37 -0
  279. package/skills/investigating-agentforce-d360/assets/dc/telemetry_spans.sql +55 -0
  280. package/skills/investigating-agentforce-d360/references/artifacts.md +50 -0
  281. package/skills/investigating-agentforce-d360/references/dc_dmo_fields.md +823 -0
  282. package/skills/investigating-agentforce-d360/references/dc_pipeline_contract.md +608 -0
  283. package/skills/investigating-agentforce-d360/scripts/_shared/__init__.py +2 -0
  284. package/skills/investigating-agentforce-d360/scripts/_shared/cli_override.py +98 -0
  285. package/skills/investigating-agentforce-d360/scripts/_shared/fs_guard.py +334 -0
  286. package/skills/investigating-agentforce-d360/scripts/_shared/paths.py +155 -0
  287. package/skills/investigating-agentforce-d360/scripts/_shared/runtime.py +59 -0
  288. package/skills/investigating-agentforce-d360/scripts/_shared/sql.py +14 -0
  289. package/skills/investigating-agentforce-d360/scripts/assemble_dc.py +1624 -0
  290. package/skills/investigating-agentforce-d360/scripts/config.py +45 -0
  291. package/skills/investigating-agentforce-d360/scripts/dc.py +188 -0
  292. package/skills/investigating-agentforce-d360/scripts/discover_sessions.py +556 -0
  293. package/skills/investigating-agentforce-d360/scripts/fetch_dc.py +1045 -0
  294. package/skills/investigating-agentforce-d360/scripts/render_dc.py +1750 -0
  295. package/skills/investigating-agentforce-d360/scripts/resolve_session.py +264 -0
  296. package/skills/investigating-agentforce-d360/scripts/storage.py +92 -0
  297. package/skills/investigating-agentforce-d360/scripts/tests/__init__.py +0 -0
  298. package/skills/investigating-agentforce-d360/scripts/tests/_bootstrap.py +15 -0
  299. package/skills/investigating-agentforce-d360/scripts/tests/fixtures/__init__.py +0 -0
  300. package/skills/investigating-agentforce-d360/scripts/tests/fixtures/synthetic_session.py +424 -0
  301. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_bootstrap_and_mode.py +115 -0
  302. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_gateway_direct.py +220 -0
  303. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_gateway_direct_integration.py +158 -0
  304. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_helpers.py +287 -0
  305. package/skills/investigating-agentforce-d360/scripts/tests/test_assemble_dc_integration.py +247 -0
  306. package/skills/investigating-agentforce-d360/scripts/tests/test_dc_and_resolve_session.py +433 -0
  307. package/skills/investigating-agentforce-d360/scripts/tests/test_discover_sessions.py +458 -0
  308. package/skills/investigating-agentforce-d360/scripts/tests/test_discover_sessions_grep_ci.py +193 -0
  309. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_helpers.py +266 -0
  310. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_identity.py +528 -0
  311. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_main.py +251 -0
  312. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_waterfall.py +229 -0
  313. package/skills/investigating-agentforce-d360/scripts/tests/test_fetch_dc_waterfall_full.py +283 -0
  314. package/skills/investigating-agentforce-d360/scripts/tests/test_identity_coherence.py +327 -0
  315. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_branches.py +256 -0
  316. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_gateway_direct.py +130 -0
  317. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_helpers.py +291 -0
  318. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_integration.py +220 -0
  319. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_planner_llm_calls.py +284 -0
  320. package/skills/investigating-agentforce-d360/scripts/tests/test_render_dc_show_prompts_gating.py +215 -0
  321. package/skills/investigating-agentforce-d360/scripts/tests/test_resolve_from_disk.py +100 -0
  322. package/skills/investigating-agentforce-d360/scripts/tests/test_resolve_session_main.py +149 -0
  323. package/skills/investigating-agentforce-d360/scripts/tests/test_runtime_override.py +104 -0
  324. package/skills/investigating-agentforce-d360/scripts/tests/test_session_shape.py +95 -0
  325. package/skills/investigating-agentforce-d360/scripts/tests/test_session_shape_dropped_by_stdm.py +85 -0
  326. package/skills/managing-managed-event-subscription/SKILL.md +152 -0
  327. package/skills/managing-managed-event-subscription/assets/managed-event-subscription-template.xml +20 -0
  328. package/skills/managing-managed-event-subscription/references/delete-guide.md +57 -0
  329. package/skills/managing-managed-event-subscription/references/topic-name-formats.md +26 -0
  330. package/skills/managing-managed-event-subscription/references/update-constraints.md +30 -0
  331. package/skills/reviewing-lwc-mobile-offline/SKILL.md +168 -0
  332. package/skills/reviewing-lwc-mobile-offline/references/grounding.md +7 -0
  333. package/skills/reviewing-lwc-mobile-offline/references/inline-graphql.md +43 -0
  334. package/skills/reviewing-lwc-mobile-offline/references/komaci-eslint.md +125 -0
  335. package/skills/reviewing-lwc-mobile-offline/references/lwc-if.md +78 -0
  336. package/skills/reviewing-lwc-mobile-offline/scripts/komaci.config.mjs +18 -0
  337. package/skills/reviewing-lwc-mobile-offline/scripts/package.json +10 -0
  338. package/skills/reviewing-lwc-mobile-offline/scripts/run-komaci.sh +69 -0
  339. package/skills/uplifting-components-to-slds2/SKILL.md +3 -2
  340. package/skills/uplifting-components-to-slds2/references/color-hooks-decision-guide.md +30 -9
  341. package/skills/uplifting-components-to-slds2/references/examples.md +24 -6
  342. package/skills/using-mobile-native-capabilities/SKILL.md +182 -0
  343. package/skills/using-mobile-native-capabilities/references/app-review.md +68 -0
  344. package/skills/using-mobile-native-capabilities/references/ar-space-capture.md +125 -0
  345. package/skills/using-mobile-native-capabilities/references/barcode-scanner.md +219 -0
  346. package/skills/using-mobile-native-capabilities/references/base-capability.md +22 -0
  347. package/skills/using-mobile-native-capabilities/references/biometrics.md +90 -0
  348. package/skills/using-mobile-native-capabilities/references/calendar.md +213 -0
  349. package/skills/using-mobile-native-capabilities/references/contacts.md +232 -0
  350. package/skills/using-mobile-native-capabilities/references/document-scanner.md +342 -0
  351. package/skills/using-mobile-native-capabilities/references/geofencing.md +123 -0
  352. package/skills/using-mobile-native-capabilities/references/location.md +158 -0
  353. package/skills/using-mobile-native-capabilities/references/mobile-capabilities.md +30 -0
  354. package/skills/using-mobile-native-capabilities/references/nfc.md +181 -0
  355. package/skills/using-mobile-native-capabilities/references/payments.md +95 -0
  356. package/skills/validating-slds/SKILL.md +262 -0
  357. package/skills/validating-slds/references/quality-checks.md +308 -0
  358. package/skills/validating-slds/references/report-format.md +302 -0
  359. package/skills/validating-slds/scripts/analyze-quality.cjs +521 -0
@@ -0,0 +1,264 @@
1
+ """Resolve either an AI-agent session UUID or a Messaging session id (0Mw...)
2
+ to the canonical AI-agent session UUID that the rest of the skill uses.
3
+
4
+ ## Why this exists
5
+
6
+ `ssot__AIAgentSession__dlm.ssot__RelatedMessagingSessionId__c` stores the
7
+ Service Cloud `MessagingSession.Id` (18-char Salesforce id, prefix `0Mw`).
8
+ Users often only have that messaging id on hand, not the AI-agent session
9
+ UUID (`019dface-0000-7000-8000-000000000002`). This resolver lets every
10
+ entry point in the skill accept either form — it normalises to the UUID,
11
+ and artifacts continue to land under `DATA_ROOT/<uuid>/` as before.
12
+
13
+ ## Many-to-one is real
14
+
15
+ Live-verified on an internal test org: 7 distinct messaging ids map to
16
+ multiple agent sessions; one id mapped to 5 separate agent sessions.
17
+ "Most recent by start_ts" is NOT a safe default for disambiguation —
18
+ the user could legitimately want any of them. On multi-match we list
19
+ every candidate and exit non-zero; the user re-invokes with the
20
+ specific UUID.
21
+
22
+ ## Two resolution modes
23
+
24
+ 1. **Live** — query DC. Requires `--org`. Used by `fetch_dc.py` at the
25
+ top of the pipeline (before any artifacts exist on disk).
26
+ 2. **Disk-first** — scan `DATA_ROOT/*/dc.sessions.json` for a row whose
27
+ `ssot__RelatedMessagingSessionId__c` matches. No DC call, no `--org`
28
+ needed. Used by `assemble_dc.py` and `render_dc.py`. If the session
29
+ has never been fetched, returns None and the caller errors with a
30
+ pointer to `fetch_dc.py`.
31
+
32
+ ## CLI
33
+
34
+ python3 scripts/resolve_session.py --id <uuid|msg_id> --org <alias>
35
+
36
+ Prints the resolved UUID to stdout on single-match (or pass-through).
37
+ Non-zero exit with diagnostics on zero-match and multi-match.
38
+ """
39
+ from __future__ import annotations
40
+
41
+ import argparse
42
+ import json
43
+ import sys
44
+ from pathlib import Path
45
+ from typing import List, Optional
46
+
47
+ sys.path.insert(0, str(Path(__file__).parent))
48
+
49
+ from config import DATA_ROOT
50
+ from dc import load_sql, post, resolve_org
51
+
52
+
53
+ # NOT_SET sentinel set. Matches fetch_dc.py:41; keep in sync.
54
+ _NOT_SET = {"", "NOT_SET", None}
55
+
56
+
57
+ def is_messaging_id(s: str) -> bool:
58
+ """Shape check for a Salesforce MessagingSession id. The official key
59
+ prefix is `0Mw`; the id is 15 or 18 chars. UUIDs are 36 chars with
60
+ dashes, so they can't accidentally match."""
61
+ if not s:
62
+ return False
63
+ return s.startswith("0Mw") and len(s) in (15, 18)
64
+
65
+
66
+ # ---- live resolution (queries Data Cloud) --------------------------------
67
+
68
+ def _live_lookup(msg_id: str, org: str) -> List[dict]:
69
+ """Query ssot__AIAgentSession__dlm for rows where RelatedMessagingSessionId
70
+ matches `msg_id`. Returns raw row dicts (caller decides how to handle
71
+ N=0, N=1, N>1).
72
+
73
+ SQL comes from `assets/dc/messaging_session.sql` — same templating
74
+ convention as every other DMO query in this skill. The `MSG_ID`
75
+ placeholder is interpolated as a literal string, but the caller
76
+ guarantees (via is_messaging_id) that the value is a Salesforce
77
+ MessagingSession id: exact 15/18 chars, `0Mw` key prefix. No quote,
78
+ no wildcard, no semicolon can pass that shape check.
79
+ """
80
+ if not is_messaging_id(msg_id):
81
+ raise ValueError(
82
+ f"_live_lookup: msg_id {msg_id!r} failed is_messaging_id() shape check"
83
+ )
84
+ instance_url, token = resolve_org(org)
85
+ sql = load_sql("messaging_session", MSG_ID=msg_id)
86
+ return post(sql, instance_url, token, "resolve_session")
87
+
88
+
89
+ def _format_multi_match(msg_id: str, rows: List[dict]) -> str:
90
+ """Human-readable error for the N>1 case. Lists every candidate so
91
+ the user can pick and re-invoke."""
92
+ lines = [
93
+ f"resolve_session: messaging id {msg_id!r} matches {len(rows)} "
94
+ f"ssot__AIAgentSession__dlm rows — pick one and re-invoke with its UUID:",
95
+ "",
96
+ ]
97
+ for r in rows:
98
+ uuid = r.get("ssot__Id__c")
99
+ start = r.get("ssot__StartTimestamp__c") or "—"
100
+ end = r.get("ssot__EndTimestamp__c") or "—"
101
+ end_type = r.get("ssot__AiAgentSessionEndType__c") or "—"
102
+ channel = r.get("ssot__AiAgentChannelType__c") or "—"
103
+ lines.append(
104
+ f" {uuid} start={start} end={end} end_type={end_type} channel={channel}"
105
+ )
106
+ lines.append("")
107
+ lines.append(
108
+ f"Example: python3 scripts/fetch_dc.py --session {rows[0].get('ssot__Id__c')} --org <alias>"
109
+ )
110
+ return "\n".join(lines)
111
+
112
+
113
+ def resolve(sid_or_msg: str, *, org: str) -> str:
114
+ """Resolve an AI-agent session UUID from either form (live DC query).
115
+ Exits the process on zero- and multi-match with a diagnostic message.
116
+ Pass-through for UUID input."""
117
+ if not is_messaging_id(sid_or_msg):
118
+ return sid_or_msg # already a UUID (or unknown form — let caller fail)
119
+ rows = _live_lookup(sid_or_msg, org)
120
+ if len(rows) == 0:
121
+ raise SystemExit(
122
+ f"resolve_session: no ssot__AIAgentSession__dlm row with "
123
+ f"RelatedMessagingSessionId={sid_or_msg!r} in org {org!r}"
124
+ )
125
+ if len(rows) > 1:
126
+ raise SystemExit(_format_multi_match(sid_or_msg, rows))
127
+ return rows[0]["ssot__Id__c"]
128
+
129
+
130
+ # ---- disk-first resolution (no DC call) ----------------------------------
131
+
132
+ def resolve_from_disk(sid_or_msg: str) -> Optional[str]:
133
+ """For scripts that don't have `--org` wired up. Scans every
134
+ ``dc.sessions.json`` under ``DATA_ROOT`` for a row whose
135
+ ``ssot__RelatedMessagingSessionId__c`` matches ``sid_or_msg``. Returns
136
+ the UUID (from the matching row's ``ssot__Id__c``) or None if not found.
137
+
138
+ Layout: the nested scheme is ``DATA_ROOT/<org_id15>/<agent>__<ver>/<uuid>/
139
+ dc.sessions.json``. Historic flat runs (``DATA_ROOT/<uuid>/...``) are
140
+ picked up by the same ``rglob`` walk, so this resolver works across
141
+ both layouts without caller awareness.
142
+
143
+ Archive suffix: user-created duplicate dirs named like
144
+ ``<uuid> - archive 1/`` carry stale copies of the same rows and would
145
+ otherwise trigger spurious multi-match exits. They are skipped at
146
+ scan time.
147
+
148
+ Pass-through if input is already a UUID; returns input unchanged
149
+ regardless of disk presence (caller validates with its own load-
150
+ artifact check).
151
+ """
152
+ if not is_messaging_id(sid_or_msg):
153
+ return sid_or_msg # UUID — pass through (caller validates disk presence)
154
+
155
+ matches: List[str] = [] # uuids
156
+ if not DATA_ROOT.is_dir():
157
+ return None
158
+ # Nested layout is 4-deep (<org>/<agent>/<uuid>/dc.sessions.json), flat
159
+ # is 2-deep (<uuid>/dc.sessions.json). rglob handles both without a
160
+ # hard-coded depth.
161
+ for sessions_p in sorted(DATA_ROOT.rglob("dc.sessions.json")):
162
+ if not sessions_p.is_file():
163
+ continue
164
+ # Skip `<uuid> - archive N/` duplicate dirs — they hold stale copies
165
+ # of the same rows and would produce spurious multi-match exits.
166
+ if " - archive" in sessions_p.parent.name:
167
+ continue
168
+ try:
169
+ data = json.loads(sessions_p.read_text())
170
+ except (json.JSONDecodeError, OSError):
171
+ continue
172
+ # `dc.sessions.json` is a list of rows (the skill saves raw DC rows).
173
+ if not isinstance(data, list):
174
+ continue
175
+ for row in data:
176
+ row_msg = (row.get("ssot__RelatedMessagingSessionId__c") or "").strip()
177
+ if row_msg in _NOT_SET:
178
+ continue
179
+ if row_msg == sid_or_msg:
180
+ uuid = row.get("ssot__Id__c")
181
+ if uuid:
182
+ matches.append(uuid)
183
+ if not matches:
184
+ return None
185
+ # De-duplicate across multiple dc.sessions.json files that happen to
186
+ # contain the same row (possible if a user copies artifacts between
187
+ # agent dirs). Distinct UUIDs remain a multi-match.
188
+ unique = sorted(set(matches))
189
+ if len(unique) > 1:
190
+ raise SystemExit(
191
+ f"resolve_session: messaging id {sid_or_msg!r} matches {len(unique)} "
192
+ f"session directories on disk — pick a UUID and re-invoke:\n "
193
+ + "\n ".join(unique)
194
+ )
195
+ return unique[0]
196
+
197
+
198
+ def resolve_disk_or_live(sid_or_msg: str, org: Optional[str] = None) -> str:
199
+ """Combined path used by entry points that support both. Tries disk
200
+ first (cheap); falls back to live DC only if `org` is supplied.
201
+ Raises with a useful message if disk-miss and no org."""
202
+ if not is_messaging_id(sid_or_msg):
203
+ return sid_or_msg # UUID — no resolution needed
204
+ disk = resolve_from_disk(sid_or_msg)
205
+ if disk is not None:
206
+ return disk
207
+ if org is None:
208
+ raise SystemExit(
209
+ f"resolve_session: cannot resolve messaging id {sid_or_msg!r} from "
210
+ f"disk (no dc.sessions.json under DATA_ROOT has a matching "
211
+ f"RelatedMessagingSessionId). Run `python3 scripts/fetch_dc.py "
212
+ f"--session {sid_or_msg} --org <alias>` first, or re-invoke with "
213
+ f"the AI-agent session UUID directly."
214
+ )
215
+ return resolve(sid_or_msg, org=org)
216
+
217
+
218
+ # ---- CLI -----------------------------------------------------------------
219
+
220
+ def main() -> int:
221
+ ap = argparse.ArgumentParser(
222
+ description="Resolve a Salesforce messaging session id (0Mw...) to the "
223
+ "AI-agent session UUID the skill uses. Passes UUID input through unchanged."
224
+ )
225
+ ap.add_argument("--id", required=True,
226
+ help="Either the AI-agent session UUID or the MessagingSession id (0Mw...)")
227
+ ap.add_argument("--org", help="sf org alias (required for live DC lookup when input is 0Mw...)")
228
+ ap.add_argument("--disk-only", action="store_true",
229
+ help="Only scan DATA_ROOT/*/dc.sessions.json; no DC query")
230
+ # Runtime-agnostic path overrides; default to ~/.vibe/...
231
+ from _shared.cli_override import add_cli_flags, apply_overrides
232
+ add_cli_flags(ap)
233
+ args = ap.parse_args()
234
+ apply_overrides(args, caller_globals=globals())
235
+
236
+ if not is_messaging_id(args.id):
237
+ print(args.id)
238
+ return 0
239
+ if args.disk_only:
240
+ found = resolve_from_disk(args.id)
241
+ if found is None:
242
+ print(f"resolve_session: no local session dir matches {args.id!r}", file=sys.stderr)
243
+ return 1
244
+ print(found)
245
+ return 0
246
+ if not args.org:
247
+ # Try disk first as a convenience; only error if that also misses.
248
+ disk = resolve_from_disk(args.id)
249
+ if disk is not None:
250
+ print(disk)
251
+ return 0
252
+ print(
253
+ f"resolve_session: {args.id!r} not found on disk; --org <alias> required "
254
+ f"for a live DC lookup",
255
+ file=sys.stderr,
256
+ )
257
+ return 2
258
+ uuid = resolve(args.id, org=args.org)
259
+ print(uuid)
260
+ return 0
261
+
262
+
263
+ if __name__ == "__main__":
264
+ raise SystemExit(main())
@@ -0,0 +1,92 @@
1
+ """Shared per-session JSON writer.
2
+
3
+ Every Data Cloud artifact lands under the nested layout:
4
+
5
+ DATA_ROOT/<org_id_15>/<agent_api_name>__<agent_version>/<session_id>/<source>.<name>.json
6
+
7
+ One save, one shape, one directory convention — imported by every caller.
8
+
9
+ **Security contract:**
10
+ All four path segments (``org_id_15``, ``agent_api_name``, ``agent_version``,
11
+ ``session_id``) flow through ``paths.session_dir(...)``, which validates
12
+ each via fs_guard (regex) before the join. A ``..`` or ``/`` in any
13
+ segment raises ``paths.PathValidationError`` — direct
14
+ ``DATA_ROOT / session_id`` composition is unreachable from this module.
15
+
16
+ Source-prefix convention:
17
+ Flat directory, prefix filenames with provenance so an `ls` on the
18
+ per-session dir tells you where each artifact came from:
19
+
20
+ dc.sessions.json — from Data Cloud
21
+ dc.interactions.json
22
+
23
+ Baking the prefix into the API (vs. leaving it to filename discipline)
24
+ makes it impossible to forget — callers pass ``source`` + ``name``,
25
+ never a raw filename.
26
+ """
27
+ from __future__ import annotations
28
+
29
+ import json
30
+ from pathlib import Path
31
+
32
+ from config import paths
33
+
34
+
35
+ def save(
36
+ data: list[dict] | dict,
37
+ org_id_15: str,
38
+ agent_api_name: str,
39
+ agent_version: str,
40
+ session_id: str,
41
+ source: str,
42
+ name: str,
43
+ ) -> Path:
44
+ """Write JSON under the nested session dir. Returns the target path.
45
+
46
+ Signature:
47
+ save(data, org_id_15, agent_api_name, agent_version, session_id,
48
+ source, name) -> Path
49
+
50
+ ``source`` is the leading filename segment for provenance — callers
51
+ pass ``"dc"``. ``name`` is the bare artifact name, no extension —
52
+ ``.json`` is appended.
53
+
54
+ Raises ``paths.PathValidationError`` if any of the four identity
55
+ segments fails validation.
56
+ """
57
+ # paths.session_dir() validates org_id_15, agent_api_name, agent_version
58
+ # (via fs_guard) and session_id (via SESSION_ID_RE.fullmatch). Any bad
59
+ # input raises PathValidationError before we touch the filesystem.
60
+ target = paths.session_dir(
61
+ org_id_15, agent_api_name, agent_version, session_id
62
+ )
63
+ target.mkdir(parents=True, exist_ok=True)
64
+ path = target / f"{source}.{name}.json"
65
+ path.write_text(json.dumps(data, indent=2, default=str) + "\n")
66
+ _write_breadcrumb(org_id_15, agent_api_name, agent_version, session_id)
67
+ return path
68
+
69
+
70
+ def _write_breadcrumb(
71
+ org_id_15: str,
72
+ agent_api_name: str,
73
+ agent_version: str,
74
+ session_id: str,
75
+ ) -> None:
76
+ """Write ``<org>/_sessions/<sid>.link`` pointing at the session dir.
77
+
78
+ Plain text, no symlink (Windows-safe). Content is the relative path
79
+ ``../<agent>__<ver>/<sid>\\n``. Idempotent — overwriting with the
80
+ same content is a no-op semantically. Silent on failure; breadcrumbs
81
+ are best-effort (a missing breadcrumb doesn't break the write,
82
+ only handoff-session discovery).
83
+ """
84
+ try:
85
+ link_dir = paths.DATA_ROOT / org_id_15 / "_sessions"
86
+ link_dir.mkdir(parents=True, exist_ok=True)
87
+ link_path = link_dir / f"{session_id}.link"
88
+ link_path.write_text(
89
+ f"../{agent_api_name}__{agent_version}/{session_id}\n"
90
+ )
91
+ except OSError:
92
+ pass
@@ -0,0 +1,15 @@
1
+ """Test bootstrap — adds sibling ``scripts/`` to sys.path.
2
+
3
+ Every ``test_*.py`` in this directory imports this module first
4
+ (as ``from . import _bootstrap``) so the sibling modules
5
+ (`config`, `storage`, `paths`, etc.) resolve.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import sys
10
+ from pathlib import Path
11
+
12
+ # scripts/tests/_bootstrap.py → scripts/
13
+ _SCRIPTS_DIR = Path(__file__).resolve().parent.parent
14
+ if str(_SCRIPTS_DIR) not in sys.path:
15
+ sys.path.insert(0, str(_SCRIPTS_DIR))