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