@salesforce/b2c-dx-mcp 3.2.1 → 3.4.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/bin/run.js +5 -9
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +4 -4
- package/content/guidance/b2c/b2c-ordering/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +3 -3
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +6 -6
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +54 -25
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +23 -2
- package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +2 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +1 -1
- package/content/guidance/b2c-cli/b2c-job/SKILL.md +9 -3
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +1 -1
- package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +35 -6
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +6 -2
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +2 -2
- package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +13 -8
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +5 -4
- package/content/guidance/index.json +981 -259
- package/content/guidance/mcp/{cip → b2c-mcp-cip}/SKILL.md +10 -8
- package/content/guidance/mcp/{b2c-config → b2c-mcp-config}/SKILL.md +10 -9
- package/content/guidance/mcp/{debugger → b2c-mcp-debugger}/SKILL.md +9 -8
- package/content/guidance/mcp/b2c-mcp-scapi/SKILL.md +98 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/authentication.md +34 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/compose-verify.md +25 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/confirmation.md +30 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/discover.md +94 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/jobs.md +72 -0
- package/content/guidance/mcp/b2c-mcp-scapi/references/workflows.md +28 -0
- package/content/guidance/mcp/{server → b2c-mcp-server}/SKILL.md +52 -25
- package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
- package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +86 -79
- package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/content/guidance/storefront-next/sfnext-components/SKILL.md +98 -136
- package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
- package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +116 -113
- package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +100 -150
- package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +83 -97
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +73 -97
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +96 -131
- package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
- package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
- package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +152 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/content/guidance/storefront-next/sfnext-performance/SKILL.md +75 -105
- package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +103 -116
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
- package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/content/guidance/storefront-next/sfnext-routing/SKILL.md +86 -143
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
- package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
- package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
- package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
- package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +80 -89
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +105 -138
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
- package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/dist/commands/mcp.d.ts +8 -2
- package/dist/commands/mcp.js +54 -20
- package/dist/guidance.d.ts +4 -1
- package/dist/guidance.js +23 -5
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +3 -3
- package/dist/server.d.ts +10 -0
- package/dist/server.js +21 -0
- package/dist/skill-references.js +5 -5
- package/dist/tools/cartridges/index.js +1 -0
- package/dist/tools/cip/index.js +6 -3
- package/dist/tools/diagnostics/debug-capture-at-breakpoint.js +1 -1
- package/dist/tools/diagnostics/debug-set-breakpoints.js +1 -1
- package/dist/tools/diagnostics/debug-start-session.js +1 -1
- package/dist/tools/docs/docs-read.js +4 -2
- package/dist/tools/docs/docs-search.js +10 -8
- package/dist/tools/docs/topics.d.ts +5 -0
- package/dist/tools/docs/topics.js +5 -0
- package/dist/tools/scapi/index.d.ts +4 -1
- package/dist/tools/scapi/index.js +4 -2
- package/dist/tools/scapi/scapi-code.d.ts +2 -2
- package/dist/tools/scapi/scapi-code.js +106 -81
- package/dist/tools/scapi/scapi-schemas-list.js +93 -56
- package/dist/utils/types.d.ts +6 -0
- package/node_modules/@salesforce/b2c-agent-plugins/CHANGELOG.md +32 -0
- package/node_modules/@salesforce/b2c-agent-plugins/README.md +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-onboarding/SKILL.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-ordering/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-querying-data/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/SKILL.md +6 -6
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-config/SKILL.md +54 -25
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-content/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-debug/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-docs/SKILL.md +23 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/SKILL.md +2 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/SKILL.md +9 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/IMPORT.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/RUN-AND-MONITOR.md +35 -6
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-metrics/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-mrt/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-custom/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-schemas/SKILL.md +6 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-site-import-export/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-sites/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-slas/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/.codex-plugin/plugin.json +4 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/README.md +1 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/plugin.json +4 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-checkout-triage/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-edge-traffic-triage/SKILL.md +69 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-job-health/SKILL.md +13 -8
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-production-triage/SKILL.md +5 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/README.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/SKILL.md +76 -73
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/evals/trigger-evals.json +12 -10
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/references/PAGE-DESIGNER-SFN.md +49 -74
- package/node_modules/@salesforce/b2c-agent-plugins/package.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/.codex-plugin/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/README.md +43 -22
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/SKILL.md +103 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/references/checklist.md +64 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/SKILL.md +91 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/SKILL.md +86 -79
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/COOKIES.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/SKILL.md +67 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/SKILL.md +98 -136
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/STORYBOOK.md +54 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/SKILL.md +116 -113
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/SKILL.md +100 -150
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/SKILL.md +83 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/SKILL.md +73 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/SKILL.md +96 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/references/locale-config.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/SKILL.md +101 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/SKILL.md +152 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/SKILL.md +75 -105
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/SKILL.md +103 -116
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/SKILL.md +70 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/SKILL.md +121 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/SKILL.md +86 -143
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/SKILL.md +126 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/SKILL.md +129 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/TURNSTILE.md +43 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/SKILL.md +95 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/SKILL.md +80 -89
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/references/PATTERNS.md +45 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/SKILL.md +105 -138
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/E2E.md +38 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/SKILL.md +104 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next-figma/skills/sfnext-create-figma-kit/SKILL.md +3 -3
- package/oclif.manifest.json +21 -4
- package/package.json +4 -4
- package/content/guidance/mcp/scapi/SKILL.md +0 -203
- package/content/guidance/mcp/scapi/references/jobs.md +0 -30
- package/content/guidance/storefront-next/sfnext-create-component/SKILL.md +0 -195
- package/content/guidance/storefront-next/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-create-vertical/SKILL.md +0 -135
- package/content/guidance/storefront-next/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-custom-apis/SKILL.md +0 -221
- package/content/guidance/storefront-next/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/content/guidance/storefront-next/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/content/guidance/storefront-next/sfnext-scapi-management/SKILL.md +0 -203
- package/content/guidance/storefront-next/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/SKILL.md +0 -195
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/SKILL.md +0 -135
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/SKILL.md +0 -221
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/SKILL.md +0 -203
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-apis.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-properties.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/products.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/promotions.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/saving.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/snippets.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/tokens.md +0 -0
- /package/content/guidance/mcp/{server → b2c-mcp-server}/references/files.md +0 -0
|
@@ -7,15 +7,15 @@ import { TOOLSETS } from '../../utils/constants.js';
|
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { searchDocs } from '@salesforce/b2c-tooling-sdk/docs';
|
|
9
9
|
import { createToolAdapter, jsonResult } from '../adapter.js';
|
|
10
|
-
import { categoryEnumValues, enabledCategoriesNote } from './topics.js';
|
|
10
|
+
import { DOCS_CITATION_NOTE, categoryEnumValues, enabledCategoriesNote } from './topics.js';
|
|
11
11
|
import { workspaceInputSchema, detectedWorkspaceNote, resolveProjectWorkspace, } from './storefront.js';
|
|
12
12
|
/** Default number of results returned when `limit` is not supplied. Kept small to bound payload size for agents. */
|
|
13
13
|
const DEFAULT_LIMIT = 5;
|
|
14
14
|
/**
|
|
15
15
|
* Projects a search hit to the payload returned to an agent. By default we keep
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* the triage-critical fields (id, title, category, summary, score) plus `url`,
|
|
17
|
+
* so an agent can cite the page without exposing the id. `keywords`
|
|
18
|
+
* (index-tuning metadata) and `sourceUrl` (Markdown twin) are verbose-only.
|
|
19
19
|
*/
|
|
20
20
|
function leanResult(entry, score, verbose) {
|
|
21
21
|
const base = {
|
|
@@ -26,11 +26,11 @@ function leanResult(entry, score, verbose) {
|
|
|
26
26
|
};
|
|
27
27
|
if (entry.summary)
|
|
28
28
|
base.summary = entry.summary;
|
|
29
|
+
if (entry.url)
|
|
30
|
+
base.url = entry.url;
|
|
29
31
|
if (verbose) {
|
|
30
32
|
if (entry.keywords && entry.keywords.length > 0)
|
|
31
33
|
base.keywords = entry.keywords;
|
|
32
|
-
if (entry.url)
|
|
33
|
-
base.url = entry.url;
|
|
34
34
|
if (entry.sourceUrl)
|
|
35
35
|
base.sourceUrl = entry.sourceUrl;
|
|
36
36
|
}
|
|
@@ -43,7 +43,8 @@ export function createDocsSearchTool(loadServices, detectedWorkspaces = [], enab
|
|
|
43
43
|
idempotent: true,
|
|
44
44
|
openWorld: false,
|
|
45
45
|
description: 'Search B2C Commerce (SFCC/Demandware) Script API, job steps, developer guides, admin/merchant help, and tooling docs. ' +
|
|
46
|
-
'Use for natural-language queries or unknown IDs; call docs_read with a result ID.' +
|
|
46
|
+
'Use for natural-language queries or unknown IDs; call docs_read with a result ID. ' +
|
|
47
|
+
'Cite by url; never show doc IDs.' +
|
|
47
48
|
enabledCategoriesNote(enabledCategories) +
|
|
48
49
|
detectedWorkspaceNote(detectedWorkspaces),
|
|
49
50
|
toolsets: [...TOOLSETS],
|
|
@@ -66,7 +67,7 @@ export function createDocsSearchTool(loadServices, detectedWorkspaces = [], enab
|
|
|
66
67
|
verbose: z
|
|
67
68
|
.boolean()
|
|
68
69
|
.optional()
|
|
69
|
-
.describe('Include keywords and
|
|
70
|
+
.describe('Include keywords and the Markdown sourceUrl on each result (larger payload). Defaults to false.'),
|
|
70
71
|
},
|
|
71
72
|
async execute(args) {
|
|
72
73
|
const workspace = await resolveProjectWorkspace(args, detectedWorkspaces);
|
|
@@ -89,6 +90,7 @@ export function createDocsSearchTool(loadServices, detectedWorkspaces = [], enab
|
|
|
89
90
|
...(workspace && { workspace }),
|
|
90
91
|
total: ranked.length,
|
|
91
92
|
offset,
|
|
93
|
+
citation: DOCS_CITATION_NOTE,
|
|
92
94
|
results: results.map((r) => leanResult(r.entry, r.score, args.verbose ?? false)),
|
|
93
95
|
...(truncated && { truncated: true, nextOffset: end }),
|
|
94
96
|
};
|
|
@@ -18,4 +18,9 @@ export declare function categoryEnumValues(enabledCategories?: readonly DocCateg
|
|
|
18
18
|
* A sentence for a tool description noting the corpus is restricted to the
|
|
19
19
|
* configured topics, or an empty string when there is no restriction.
|
|
20
20
|
*/
|
|
21
|
+
/**
|
|
22
|
+
* Returned with every docs_search/docs_read result. Doc IDs are lookup keys for docs_read, not user-facing references;
|
|
23
|
+
* the rule sits next to the data because agents cite while reading results, long after reading tool descriptions.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DOCS_CITATION_NOTE = "Cite docs to users by url (sourceUrl for Markdown). Never show doc ids; they are docs_read keys. Show ids only if asked.";
|
|
21
26
|
export declare function enabledCategoriesNote(enabledCategories?: readonly DocCategory[]): string;
|
|
@@ -30,6 +30,11 @@ export function categoryEnumValues(enabledCategories) {
|
|
|
30
30
|
* A sentence for a tool description noting the corpus is restricted to the
|
|
31
31
|
* configured topics, or an empty string when there is no restriction.
|
|
32
32
|
*/
|
|
33
|
+
/**
|
|
34
|
+
* Returned with every docs_search/docs_read result. Doc IDs are lookup keys for docs_read, not user-facing references;
|
|
35
|
+
* the rule sits next to the data because agents cite while reading results, long after reading tool descriptions.
|
|
36
|
+
*/
|
|
37
|
+
export const DOCS_CITATION_NOTE = 'Cite docs to users by url (sourceUrl for Markdown). Never show doc ids; they are docs_read keys. Show ids only if asked.';
|
|
33
38
|
export function enabledCategoriesNote(enabledCategories) {
|
|
34
39
|
if (!enabledCategories || enabledCategories.length === 0)
|
|
35
40
|
return '';
|
|
@@ -8,11 +8,14 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { McpTool } from '../../utils/index.js';
|
|
10
10
|
import type { Services } from '../../services.js';
|
|
11
|
+
import { type ScapiSchemaDocument } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
11
12
|
import type { ScapiExecutionRegistry } from './execution-registry.js';
|
|
12
13
|
/**
|
|
13
14
|
* Creates all tools for the SCAPI toolset.
|
|
14
15
|
*
|
|
15
16
|
* @param loadServices - Function that loads configuration and returns Services instance
|
|
17
|
+
* @param executions - Server-scoped registry for retained code-mode executions
|
|
18
|
+
* @param localSchemas - Startup --scapi-schemas contracts; when omitted, each call reads the project's `scapiSchemas` config
|
|
16
19
|
* @returns Array of MCP tools
|
|
17
20
|
*/
|
|
18
|
-
export declare function createScapiTools(loadServices: () => Promise<Services> | Services, executions?: ScapiExecutionRegistry): McpTool[];
|
|
21
|
+
export declare function createScapiTools(loadServices: () => Promise<Services> | Services, executions?: ScapiExecutionRegistry, localSchemas?: readonly ScapiSchemaDocument[]): McpTool[];
|
|
@@ -12,14 +12,16 @@ import { ScapiLiveSchemaCache, ScapiShopperSessions } from '@salesforce/b2c-tool
|
|
|
12
12
|
* Creates all tools for the SCAPI toolset.
|
|
13
13
|
*
|
|
14
14
|
* @param loadServices - Function that loads configuration and returns Services instance
|
|
15
|
+
* @param executions - Server-scoped registry for retained code-mode executions
|
|
16
|
+
* @param localSchemas - Startup --scapi-schemas contracts; when omitted, each call reads the project's `scapiSchemas` config
|
|
15
17
|
* @returns Array of MCP tools
|
|
16
18
|
*/
|
|
17
|
-
export function createScapiTools(loadServices, executions) {
|
|
19
|
+
export function createScapiTools(loadServices, executions, localSchemas) {
|
|
18
20
|
// Live contracts discovered by search or schema fetches are reused by execution for the same tenant.
|
|
19
21
|
const schemaCache = new ScapiLiveSchemaCache();
|
|
20
22
|
const shopperSessions = new ScapiShopperSessions();
|
|
21
23
|
return [
|
|
22
|
-
...createScapiCodeTools(loadServices, undefined, executions, schemaCache, shopperSessions),
|
|
24
|
+
...createScapiCodeTools(loadServices, undefined, executions, schemaCache, shopperSessions, localSchemas),
|
|
23
25
|
createMetricsGetTool(loadServices),
|
|
24
26
|
createScapiCustomApisStatusTool(loadServices),
|
|
25
27
|
createScapiSchemasListTool(loadServices, schemaCache),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ScapiLiveSchemaCache, ScapiShopperSessions } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
1
|
+
import { ScapiLiveSchemaCache, ScapiShopperSessions, type ScapiSchemaDocument } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
2
2
|
import type { McpTool } from '../../utils/types.js';
|
|
3
3
|
import type { ServicesLoader } from '../adapter.js';
|
|
4
4
|
import { ScapiExecutionRegistry } from './execution-registry.js';
|
|
5
|
-
export declare function createScapiCodeTools(loadServices: ServicesLoader, snippetDirectory?: string, registry?: ScapiExecutionRegistry, schemaCache?: ScapiLiveSchemaCache, shopperSessions?: ScapiShopperSessions): McpTool[];
|
|
5
|
+
export declare function createScapiCodeTools(loadServices: ServicesLoader, snippetDirectory?: string, registry?: ScapiExecutionRegistry, schemaCache?: ScapiLiveSchemaCache, shopperSessions?: ScapiShopperSessions, localSchemas?: readonly ScapiSchemaDocument[]): McpTool[];
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2
|
|
4
4
|
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
5
|
*/
|
|
6
|
+
import path from 'node:path';
|
|
6
7
|
import { z } from 'zod';
|
|
7
|
-
import { loadScapiSchemas, mergeScapiSchemas, scapiTenantKey, ScapiLiveSchemaCache, ScapiShopperSessions, runScapiCode, createScapiRequest, createScapiAuth, loadScapiSnippets, saveScapiSnippet, } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
8
|
+
import { loadScapiSchemas, matchesScapiApi, mergeScapiSchemas, suggestScapiApis, scapiTenantKey, ScapiLiveSchemaCache, ScapiShopperSessions, runScapiCode, createScapiRequest, createScapiAuth, loadScapiSnippets, saveScapiSnippet, isRemoteScapiSchema, loadScapiSchemaOverrides, } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
8
9
|
import { toOrganizationId } from '@salesforce/b2c-tooling-sdk/clients';
|
|
9
10
|
import { getB2CConfigDirectory } from '@salesforce/b2c-tooling-sdk/config';
|
|
10
11
|
import { resolveEffectiveSafetyConfig, loadGlobalSafetyConfig } from '@salesforce/b2c-tooling-sdk/safety';
|
|
@@ -17,64 +18,16 @@ const code = z
|
|
|
17
18
|
.min(1)
|
|
18
19
|
.max(32_768)
|
|
19
20
|
.describe('JavaScript async arrow function. Return concise JSON. No filesystem or shell access.');
|
|
20
|
-
const
|
|
21
|
-
const
|
|
21
|
+
const SCAPI_SKILL_REQUIRED = 'SCAPI_SKILL_REQUIRED: Read skill://mcp/b2c-mcp-scapi/SKILL.md through resources or skills_read, then retry with skillRead: true.';
|
|
22
|
+
const skillRead = z
|
|
23
|
+
.literal(true, { error: SCAPI_SKILL_REQUIRED })
|
|
24
|
+
.describe('Required. Set true only after reading skill://mcp/b2c-mcp-scapi/SKILL.md (MCP resource, or skills_read({uri})).');
|
|
22
25
|
function requireScapiSkill(read) {
|
|
23
26
|
if (read !== true)
|
|
24
|
-
throw new Error(
|
|
27
|
+
throw new Error(SCAPI_SKILL_REQUIRED);
|
|
25
28
|
}
|
|
26
|
-
const searchDescription = `
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
Schemas can be huge. Find operation IDs/paths first; then select required and task fields, not whole trees. Local refs expand; recursive/deep refs remain $ref.
|
|
30
|
-
|
|
31
|
-
Code objects (write JavaScript, not these types):
|
|
32
|
-
interface Operation {
|
|
33
|
-
api: string; operationId: string; summary?: string;
|
|
34
|
-
parameters: Array<{name: string; in: string; required?: boolean; schema?: unknown}>;
|
|
35
|
-
requestBody?: {required?: boolean; content: Record<string, {schema: any}>};
|
|
36
|
-
responses?: Record<string, unknown>;
|
|
37
|
-
security: Array<Record<string, string[]>>;
|
|
38
|
-
auth: {types: string[]; schemes: string[]; executable: boolean}; // runtime support, not access
|
|
39
|
-
}
|
|
40
|
-
declare const spec: {
|
|
41
|
-
apis: Array<{id: string; apiFamily: string; apiName: string; apiVersion: string; authTypes: string[]}>;
|
|
42
|
-
paths: Record<string, Record<string, Operation>>; // full paths, lowercase HTTP methods
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
Examples:
|
|
46
|
-
// Find product operations
|
|
47
|
-
async () => Object.entries(spec.paths)
|
|
48
|
-
.filter(([path]) => path.startsWith('/product/products/'))
|
|
49
|
-
.flatMap(([path, methods]) => Object.entries(methods)
|
|
50
|
-
.map(([method, op]) => ({method, path, operationId: op.operationId})))
|
|
51
|
-
|
|
52
|
-
// Inspect only fields needed for creation
|
|
53
|
-
async () => {
|
|
54
|
-
const op = spec.paths['/product/products/v1/organizations/{organizationId}/products/{productId}'].put;
|
|
55
|
-
const body = op.requestBody.content['application/json'].schema;
|
|
56
|
-
const fields = [...new Set([...(body.required ?? []), 'name', 'owningCatalogId', 'onlineFlag'])];
|
|
57
|
-
return {parameters: op.parameters, required: body.required,
|
|
58
|
-
fields: Object.fromEntries(fields.map(k => [k, body.properties[k]])), auth: op.auth, security: op.security};
|
|
59
|
-
}`;
|
|
60
|
-
const executeDescription = `Read, create, update, or delete Commerce records through SCAPI Admin or Shopper APIs when no dedicated tool fits. Discover endpoints with scapi_search; operations found with schemas:"live" (including custom APIs) are callable here for the same tenant. Otherwise fetch a custom API's live contract through scapi.request() in the same program first. Auth is automatic; Shopper APIs run as a guest whose session (basket) persists per site. JSON only; no binary transfers.
|
|
61
|
-
Read skill://mcp/scapi/SKILL.md first.
|
|
62
|
-
|
|
63
|
-
Reuse workflows with await codemode.run(name, input); describe first. async (input) receives input. Completed executionId enables scapi_snippet_save.
|
|
64
|
-
Safety confirmation uses MCP elicitation. Protocol retries resume retained code; never replay it. Approval has no server deadline. Decline or cancel terminates execution without rollback. action:cancel needs executionId only (plus skillRead).
|
|
65
|
-
|
|
66
|
-
Available in your code:
|
|
67
|
-
declare const organizationId: string | undefined; // resolved tenant
|
|
68
|
-
declare const siteId: string | undefined; // configured site
|
|
69
|
-
declare const scapi: {
|
|
70
|
-
request(options: {method: string; path: string; query?: Record<string, unknown>; body?: unknown}):
|
|
71
|
-
Promise<{status: number; ok: boolean; data: any; diagnostic?: {code: string; message: string}}>;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
Compose dependent requests; await each. Responses can be huge: filter/map/slice; return counts, selected rows and verification. Preserve failures. HTTP failures return ok:false; transport/auth/safety failures throw. SDK safety governs scapi.request. fetch/WebSocket are disabled. Optional auth.accountManager()/auth.slas() export tokens for external clients; see skill. Check writes before retrying.
|
|
75
|
-
|
|
76
|
-
Example: inspect a campaign's promotions
|
|
77
|
-
async () => codemode.run('builtin/campaign-promotions', {campaignId: 'selected-campaign', limit: 4})`;
|
|
29
|
+
const searchDescription = `Requires reading skill://mcp/b2c-mcp-scapi/SKILL.md first. Search SCAPI Admin/Shopper OpenAPI contracts by running JavaScript over \`spec\` (only spec.apis, spec.paths[fullPath][method] and spec.resolve exist), to find the operationId, path, inputs and scopes for a Commerce API task when no dedicated tool fits. Use cip_* for analytics and webdav_* for files. Searches the bundled contracts by default (offline, no credentials); schemas:"live" fetches the current contracts from the configured instance instead, including tenant c_* fields, custom APIs and APIs newer than the bundle (falls back to the bundled contracts with a warning when live access fails). Operations carry summary, description and tags: match on those, not only operationId. Results are capped at 24 KB: operations are an outline by default (no nested descriptions or examples; detail:"full" restores them), and you should still return fields such as operationId, method, path and summary, not whole operations.`;
|
|
30
|
+
const executeDescription = `Requires reading skill://mcp/b2c-mcp-scapi/SKILL.md first. Run any SCAPI Admin or Shopper API operation (reads, writes, searches and actions) through scapi.request() in JavaScript. Covers most developer, merchant and administrator tasks: catalogs, products, pricing, promotions, orders, customers, inventory, sites, jobs, code versions, observability, and storefront flows such as baskets. Use it whenever no more specific tool fits. Find operations with scapi_search first. Auth is automatic; Shopper calls run as a per-site guest whose basket persists. Operations are governed by Safety Mode and may ask the user for confirmation.`;
|
|
78
31
|
function codeResult(data, resolution) {
|
|
79
32
|
const result = resolution ? attachResolution(jsonResult(data, 0), resolution, 0) : jsonResult(data, 0);
|
|
80
33
|
// Code-mode payloads are arbitrary JSON: retain provenance without duplicating the result.
|
|
@@ -93,19 +46,41 @@ function failure(error, resolution) {
|
|
|
93
46
|
isError: true,
|
|
94
47
|
};
|
|
95
48
|
}
|
|
96
|
-
export function createScapiCodeTools(loadServices, snippetDirectory, registry = new ScapiExecutionRegistry(), schemaCache = new ScapiLiveSchemaCache(), shopperSessions = new ScapiShopperSessions()) {
|
|
49
|
+
export function createScapiCodeTools(loadServices, snippetDirectory, registry = new ScapiExecutionRegistry(), schemaCache = new ScapiLiveSchemaCache(), shopperSessions = new ScapiShopperSessions(), localSchemas) {
|
|
50
|
+
// Developer-supplied contracts replace bundled and live ones with the same id. The startup
|
|
51
|
+
// --scapi-schemas flag wins; otherwise each call reads the project's `scapiSchemas` config
|
|
52
|
+
// (dw.json `scapi-schemas` or SFCC_SCAPI_SCHEMAS, including the project .env). Entries may be
|
|
53
|
+
// files, directories or http(s) URLs; fetched contracts are kept until this server ends.
|
|
54
|
+
const remoteSchemas = new Map();
|
|
55
|
+
const projectSchemas = async (services, signal) => {
|
|
56
|
+
if (localSchemas)
|
|
57
|
+
return localSchemas;
|
|
58
|
+
const entries = services?.getResolvedConfig().values.scapiSchemas;
|
|
59
|
+
if (!services || !entries?.length)
|
|
60
|
+
return [];
|
|
61
|
+
const base = services.getResolution().projectDirectory?.path ?? process.cwd();
|
|
62
|
+
return loadScapiSchemaOverrides(entries.map((entry) => (isRemoteScapiSchema(entry) ? entry : path.resolve(base, entry))), { cache: remoteSchemas, signal });
|
|
63
|
+
};
|
|
97
64
|
// Retain only source for the last 50 completed executions, until this server ends.
|
|
98
65
|
const executions = new Map();
|
|
99
66
|
const searchInput = {
|
|
100
67
|
...createProjectContextInputSchema('configuration'),
|
|
101
68
|
code,
|
|
102
69
|
skillRead,
|
|
103
|
-
api: z
|
|
70
|
+
api: z
|
|
71
|
+
.string()
|
|
72
|
+
.regex(/^[a-z0-9-]+(?:\/[a-z0-9-]+){0,2}\/?$/i, 'api must be family, family/name or family/name/version.')
|
|
73
|
+
.optional()
|
|
74
|
+
.describe('Limit schemas to an API family, family/name or family/name/version (cdn, cdn/zones, cdn/zones/v1). Omit for all APIs.'),
|
|
104
75
|
schemas: z
|
|
105
76
|
.enum(['bundled', 'live'])
|
|
106
77
|
.optional()
|
|
107
78
|
.describe('bundled (default, offline) or live tenant contracts from the Schemas API.'),
|
|
108
79
|
refresh: z.boolean().optional().describe('With schemas:"live", refetch instead of using cached contracts.'),
|
|
80
|
+
detail: z
|
|
81
|
+
.enum(['outline', 'full'])
|
|
82
|
+
.optional()
|
|
83
|
+
.describe('outline (default) drops nested descriptions and examples to fit 24 KB; full keeps all prose.'),
|
|
109
84
|
authType: z
|
|
110
85
|
.enum(['admin', 'shopper'])
|
|
111
86
|
.optional()
|
|
@@ -137,7 +112,7 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
|
|
|
137
112
|
{
|
|
138
113
|
name: 'scapi_search',
|
|
139
114
|
title: 'SCAPI Spec Search',
|
|
140
|
-
description: searchDescription
|
|
115
|
+
description: searchDescription,
|
|
141
116
|
inputSchema: searchInput,
|
|
142
117
|
toolsets: ['SCAPI', 'PWAV3', 'STOREFRONTNEXT'],
|
|
143
118
|
effect: 'read',
|
|
@@ -152,35 +127,83 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
|
|
|
152
127
|
throw new Error('SCAPI_SEARCH_ARGUMENT_INVALID: refresh requires schemas:"live".');
|
|
153
128
|
let documents;
|
|
154
129
|
let failures = [];
|
|
130
|
+
let schemaSource = input.schemas === 'live' ? 'live' : 'bundled';
|
|
131
|
+
const warnings = [];
|
|
132
|
+
let services;
|
|
155
133
|
if (input.schemas === 'live') {
|
|
156
|
-
|
|
134
|
+
services = await loadServices(input);
|
|
157
135
|
resolution = services.getResolution();
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
136
|
+
}
|
|
137
|
+
else if (!localSchemas) {
|
|
138
|
+
// Bundled search works without configuration; config is read only for local contracts,
|
|
139
|
+
// and configuration errors surface on tools that need it.
|
|
140
|
+
try {
|
|
141
|
+
services = await loadServices(input);
|
|
142
|
+
resolution = services.getResolution();
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
services = undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const localDocuments = await projectSchemas(services, context?.signal);
|
|
149
|
+
const local = (api) => localDocuments.filter((document) => matchesScapiApi(document.entry.id, api));
|
|
150
|
+
// Name close ids so a near-miss filter (ecdn, zones) can be corrected in one step.
|
|
151
|
+
const unknownApi = (message, known) => {
|
|
152
|
+
const close = suggestScapiApis(known.map((document) => document.entry.id), input.api);
|
|
153
|
+
return new Error(`${message}${close.length > 0 ? ` Close matches: ${close.join(', ')}.` : ''}`);
|
|
154
|
+
};
|
|
155
|
+
const searchBundled = () => {
|
|
156
|
+
const all = mergeScapiSchemas(loadScapiSchemas(), [], local());
|
|
157
|
+
const bundled = all.filter((document) => matchesScapiApi(document.entry.id, input.api));
|
|
158
|
+
if (bundled.length === 0)
|
|
159
|
+
throw unknownApi('Unknown schema ID. Omit api to discover available APIs, or use schemas:"live" for tenant and custom APIs.', all);
|
|
160
|
+
return bundled;
|
|
161
|
+
};
|
|
162
|
+
if (services && input.schemas === 'live') {
|
|
163
|
+
try {
|
|
164
|
+
// Throws with configuration guidance when shortCode, tenantId, or OAuth credentials are missing.
|
|
165
|
+
const client = services.getScapiSchemasClient();
|
|
166
|
+
const organizationId = services.getOrganizationId();
|
|
167
|
+
const tenant = scapiTenantKey(services.getShortCode(), organizationId);
|
|
168
|
+
({ documents, failures } = await schemaCache.load(tenant, client, organizationId, {
|
|
169
|
+
api: input.api,
|
|
170
|
+
refresh: input.refresh,
|
|
171
|
+
signal: context?.signal,
|
|
172
|
+
}));
|
|
173
|
+
documents = mergeScapiSchemas([], documents, local(input.api));
|
|
174
|
+
if (documents.length === 0 && failures.length === 0)
|
|
175
|
+
throw unknownApi('Unknown schema ID for this tenant. Omit api to discover available APIs.', mergeScapiSchemas(loadScapiSchemas(), schemaCache.get(tenant), local()));
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
// Custom APIs exist only on the tenant; an unknown ID is a caller error, not an access problem.
|
|
179
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
180
|
+
if (context?.signal?.aborted ||
|
|
181
|
+
input.api?.split('/')[0].toLowerCase() === 'custom' ||
|
|
182
|
+
message.startsWith('Unknown schema ID'))
|
|
183
|
+
throw error;
|
|
184
|
+
documents = searchBundled();
|
|
185
|
+
schemaSource = 'bundled';
|
|
186
|
+
warnings.push(`Live schemas unavailable (${message.replaceAll(/\s+/g, ' ').trim().slice(0, 300)}). Searching the bundled standard contracts instead: no tenant c_* properties or custom APIs, and they may be older than your tenant.`);
|
|
187
|
+
}
|
|
169
188
|
}
|
|
170
189
|
else {
|
|
171
|
-
documents =
|
|
172
|
-
if (documents.length === 0)
|
|
173
|
-
throw new Error('Unknown schema ID. Omit api to discover available APIs, or use schemas:"live" for tenant and custom APIs.');
|
|
190
|
+
documents = searchBundled();
|
|
174
191
|
}
|
|
175
192
|
const result = await runScapiCode({
|
|
176
193
|
code: input.code,
|
|
177
194
|
documents,
|
|
178
195
|
authType: input.authType,
|
|
196
|
+
detail: input.detail ?? 'outline',
|
|
179
197
|
signal: context?.signal,
|
|
180
198
|
timeoutMs: 10_000,
|
|
181
199
|
snippets: loadScapiSnippets(snippetDirectory),
|
|
182
200
|
});
|
|
183
|
-
return codeResult({
|
|
201
|
+
return codeResult({
|
|
202
|
+
result,
|
|
203
|
+
...(input.schemas === 'live' ? { schemaSource } : {}),
|
|
204
|
+
...(warnings.length > 0 ? { warnings } : {}),
|
|
205
|
+
...(failures.length > 0 ? { schemaFailures: failures } : {}),
|
|
206
|
+
}, resolution);
|
|
184
207
|
}
|
|
185
208
|
catch (error) {
|
|
186
209
|
return failure(error, resolution);
|
|
@@ -190,7 +213,7 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
|
|
|
190
213
|
{
|
|
191
214
|
name: 'scapi_execute',
|
|
192
215
|
title: 'SCAPI Code Executor',
|
|
193
|
-
description: executeDescription
|
|
216
|
+
description: executeDescription,
|
|
194
217
|
inputSchema: executeInput,
|
|
195
218
|
toolsets: ['SCAPI', 'PWAV3', 'STOREFRONTNEXT'],
|
|
196
219
|
effect: 'destructive',
|
|
@@ -218,6 +241,7 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
|
|
|
218
241
|
const services = await loadServices(input);
|
|
219
242
|
resolution = services.getResolution();
|
|
220
243
|
const config = services.getResolvedConfig();
|
|
244
|
+
const localDocuments = await projectSchemas(services, context?.signal);
|
|
221
245
|
const { shortCode, tenantId, siteId } = config.values;
|
|
222
246
|
const tenant = shortCode && tenantId ? scapiTenantKey(shortCode, toOrganizationId(tenantId)) : undefined;
|
|
223
247
|
const safetyEnvironment = Object.fromEntries(['SFCC_SAFETY_LEVEL', 'SFCC_SAFETY_CONFIRM', 'SFCC_SAFETY_CONFIG'].map((name) => [
|
|
@@ -241,11 +265,12 @@ export function createScapiCodeTools(loadServices, snippetDirectory, registry =
|
|
|
241
265
|
slasClientId: config.values.slasClientId,
|
|
242
266
|
slasClientSecret: config.values.slasClientSecret,
|
|
243
267
|
}),
|
|
244
|
-
// Live contracts discovered for this tenant replace bundled ones
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
268
|
+
// Live contracts discovered for this tenant replace bundled ones, and local ones replace both;
|
|
269
|
+
// the user owns their accuracy.
|
|
270
|
+
documents: mergeScapiSchemas(loadScapiSchemas(), tenant ? schemaCache.get(tenant) : [], localDocuments),
|
|
271
|
+
onSchema(document, full) {
|
|
272
|
+
// Keep full tenant contracts (custom properties and prose) from being replaced by lighter fetches.
|
|
273
|
+
if (tenant && (full || document.entry.apiFamily === 'custom'))
|
|
249
274
|
schemaCache.put(tenant, document);
|
|
250
275
|
},
|
|
251
276
|
confirm: (request) => execution.confirm(request),
|
|
@@ -16,7 +16,7 @@ import { z } from 'zod';
|
|
|
16
16
|
import { createToolAdapter, jsonResult } from '../adapter.js';
|
|
17
17
|
import { getApiErrorMessage } from '@salesforce/b2c-tooling-sdk/clients';
|
|
18
18
|
import { collapseOpenApiSchema } from '@salesforce/b2c-tooling-sdk/schemas';
|
|
19
|
-
import { createLiveScapiDocument, scapiTenantKey } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
19
|
+
import { SCAPI_SCHEMA_EXPANSIONS, SCAPI_STANDARD_SCHEMA_EXPAND, createLiveScapiDocument, fetchScapiSchemaWithFallback, isFullScapiExpand, listScapiSchemasWithFallback, normalizeScapiSchemaExpand, scapiSchemaExpandFor, scapiTenantKey, } from '@salesforce/b2c-tooling-sdk/scapi';
|
|
20
20
|
/**
|
|
21
21
|
* Builds the base URL for a SCAPI API endpoint.
|
|
22
22
|
*
|
|
@@ -45,37 +45,67 @@ function getSchemasApiError(error, response) {
|
|
|
45
45
|
}
|
|
46
46
|
return message;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Smallest Schemas API `expand` for the request: collapsed output drops operation bodies, so it never needs
|
|
50
|
+
* prose; expandAll returns the whole contract. An explicit `include` wins.
|
|
51
|
+
*/
|
|
52
|
+
function resolveExpand(args) {
|
|
53
|
+
if (args.include?.length)
|
|
54
|
+
return normalizeScapiSchemaExpand(args.include);
|
|
55
|
+
const customProperties = args.expandCustomProperties !== false;
|
|
56
|
+
if (args.expandAll)
|
|
57
|
+
return customProperties ? scapiSchemaExpandFor({ full: true }) : SCAPI_STANDARD_SCHEMA_EXPAND;
|
|
58
|
+
return scapiSchemaExpandFor({ customProperties });
|
|
59
|
+
}
|
|
48
60
|
/**
|
|
49
61
|
* Fetches a specific schema from the SCAPI Schemas API.
|
|
50
62
|
*
|
|
51
63
|
* @param params - Fetch parameters
|
|
52
|
-
* @param params.
|
|
53
|
-
* @param params.organizationId - Organization ID
|
|
64
|
+
* @param params.svc - Services (client, organization and short code are resolved inside the live fetch)
|
|
54
65
|
* @param params.args - Input arguments with API identifiers
|
|
55
|
-
* @param params.shortCode - Optional short code for building base URL
|
|
56
66
|
* @param params.schemaCache - Optional live contract cache shared with SCAPI code mode
|
|
57
67
|
* @returns Schema fetch output
|
|
58
68
|
*/
|
|
59
69
|
async function fetchSpecificSchema(params) {
|
|
60
|
-
const {
|
|
70
|
+
const { svc, args, schemaCache } = params;
|
|
61
71
|
const { apiFamily, apiName, apiVersion, expandAll, status } = args;
|
|
72
|
+
const expand = resolveExpand(args);
|
|
62
73
|
// Warn if status filter was provided (it's ignored in fetch mode)
|
|
63
|
-
const
|
|
74
|
+
const statusWarning = status
|
|
64
75
|
? `Note: 'status' filter is ignored when fetching a specific schema. The API endpoint for retrieving a specific schema (${apiFamily}/${apiName}/${apiVersion}) does not support status filtering - you're already specifying the exact version. Use discovery mode (omit one or more of apiFamily/apiName/apiVersion) to filter by status.`
|
|
65
76
|
: undefined;
|
|
66
|
-
const {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
const identity = { apiFamily: apiFamily, apiName: apiName, apiVersion: apiVersion };
|
|
78
|
+
// Shared by the live fetch and the cache below; a missing shortCode or credentials throws inside the fetch.
|
|
79
|
+
let live;
|
|
80
|
+
const result = await fetchScapiSchemaWithFallback(identity, async () => {
|
|
81
|
+
const client = svc.getScapiSchemasClient();
|
|
82
|
+
const organizationId = svc.getOrganizationId();
|
|
83
|
+
let shortCode;
|
|
84
|
+
try {
|
|
85
|
+
shortCode = svc.getShortCode();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Continue without shortCode if not available
|
|
89
|
+
}
|
|
90
|
+
const { data, error, response } = await client.GET('/organizations/{organizationId}/schemas/{apiFamily}/{apiName}/{apiVersion}', {
|
|
91
|
+
params: {
|
|
92
|
+
path: { organizationId, ...identity },
|
|
93
|
+
// One comma-joined value: the API rejects a repeated expand parameter.
|
|
94
|
+
query: expand ? { expand } : undefined,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
if (error)
|
|
98
|
+
throw new Error(`Failed to fetch schema for ${identity.apiFamily}/${identity.apiName}/${identity.apiVersion}: ${getSchemasApiError(error, response)}`);
|
|
99
|
+
live = { shortCode, organizationId };
|
|
100
|
+
return data;
|
|
71
101
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
// Contracts carrying custom properties and prose become searchable and executable in SCAPI code mode.
|
|
103
|
+
if (result.source === 'live' &&
|
|
104
|
+
schemaCache &&
|
|
105
|
+
live?.shortCode &&
|
|
106
|
+
(isFullScapiExpand(expand) || apiFamily === 'custom')) {
|
|
77
107
|
try {
|
|
78
|
-
schemaCache.put(scapiTenantKey(shortCode, organizationId), createLiveScapiDocument(
|
|
108
|
+
schemaCache.put(scapiTenantKey(live.shortCode, live.organizationId), createLiveScapiDocument(identity, result.schema));
|
|
79
109
|
}
|
|
80
110
|
catch {
|
|
81
111
|
// Not a usable OpenAPI contract; still return it to the caller.
|
|
@@ -84,20 +114,21 @@ async function fetchSpecificSchema(params) {
|
|
|
84
114
|
// Apply collapsing unless expandAll is requested
|
|
85
115
|
const collapsed = !expandAll;
|
|
86
116
|
const processedSchema = collapsed
|
|
87
|
-
? collapseOpenApiSchema(
|
|
88
|
-
:
|
|
117
|
+
? collapseOpenApiSchema(result.schema)
|
|
118
|
+
: result.schema;
|
|
89
119
|
// Build base URL for the SCAPI API (where to call the API)
|
|
90
|
-
const baseUrl = shortCode
|
|
91
|
-
? buildScapiApiUrl(shortCode, apiFamily, apiName, apiVersion)
|
|
120
|
+
const baseUrl = live?.shortCode
|
|
121
|
+
? buildScapiApiUrl(live.shortCode, identity.apiFamily, identity.apiName, identity.apiVersion)
|
|
92
122
|
: undefined;
|
|
123
|
+
const warning = [statusWarning, result.warning].filter(Boolean).join(' ') || undefined;
|
|
93
124
|
return {
|
|
94
|
-
|
|
95
|
-
apiName: apiName,
|
|
96
|
-
apiVersion: apiVersion,
|
|
125
|
+
...identity,
|
|
97
126
|
schema: processedSchema,
|
|
98
127
|
timestamp: new Date().toISOString(),
|
|
99
128
|
collapsed,
|
|
100
129
|
warning,
|
|
130
|
+
source: result.source,
|
|
131
|
+
...(result.source === 'live' && expand ? { expand } : {}),
|
|
101
132
|
baseUrl,
|
|
102
133
|
};
|
|
103
134
|
}
|
|
@@ -105,39 +136,51 @@ async function fetchSpecificSchema(params) {
|
|
|
105
136
|
* Fetches and filters schemas list from the SCAPI Schemas API.
|
|
106
137
|
*
|
|
107
138
|
* @param params - Fetch parameters
|
|
108
|
-
* @param params.
|
|
109
|
-
* @param params.organizationId - Organization ID
|
|
139
|
+
* @param params.svc - Services (client, organization and short code are resolved inside the live fetch)
|
|
110
140
|
* @param params.args - Input parameters
|
|
111
|
-
* @param params.shortCode - Optional short code for building base URLs
|
|
112
141
|
* @returns Discovery mode output
|
|
113
142
|
*/
|
|
114
143
|
async function fetchSchemasList(params) {
|
|
115
|
-
const {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
const { svc, args } = params;
|
|
145
|
+
let shortCode;
|
|
146
|
+
const result = await listScapiSchemasWithFallback({ apiFamily: args.apiFamily, apiName: args.apiName, apiVersion: args.apiVersion, status: args.status }, async () => {
|
|
147
|
+
const client = svc.getScapiSchemasClient();
|
|
148
|
+
const organizationId = svc.getOrganizationId();
|
|
149
|
+
try {
|
|
150
|
+
shortCode = svc.getShortCode();
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Continue without shortCode if not available
|
|
154
|
+
}
|
|
155
|
+
const { data, error, response } = await client.GET('/organizations/{organizationId}/schemas', {
|
|
156
|
+
params: {
|
|
157
|
+
path: { organizationId },
|
|
158
|
+
query: {
|
|
159
|
+
apiFamily: args.apiFamily,
|
|
160
|
+
apiName: args.apiName,
|
|
161
|
+
apiVersion: args.apiVersion,
|
|
162
|
+
status: args.status,
|
|
163
|
+
},
|
|
124
164
|
},
|
|
125
|
-
}
|
|
165
|
+
});
|
|
166
|
+
if (error)
|
|
167
|
+
throw new Error(`Failed to fetch SCAPI schemas: ${getSchemasApiError(error, response)}`);
|
|
168
|
+
const schemas = data?.data ?? [];
|
|
169
|
+
return { schemas, total: data?.total ?? schemas.length };
|
|
126
170
|
});
|
|
127
|
-
|
|
128
|
-
throw new Error(`Failed to fetch SCAPI schemas: ${getSchemasApiError(error, response)}`);
|
|
129
|
-
}
|
|
130
|
-
const schemas = data?.data ?? [];
|
|
171
|
+
const { schemas } = result;
|
|
131
172
|
const filteredSchemas = prepareSchemaListForConsumer(schemas, shortCode);
|
|
132
173
|
const discoveryMetadata = getAvailableFilters(schemas);
|
|
133
174
|
// Generate helpful message for empty results
|
|
134
175
|
const message = schemas.length === 0 ? generateEmptyResultMessage(args) : undefined;
|
|
135
176
|
return {
|
|
136
177
|
schemas: filteredSchemas,
|
|
137
|
-
total:
|
|
178
|
+
total: result.total,
|
|
138
179
|
timestamp: new Date().toISOString(),
|
|
139
180
|
...discoveryMetadata,
|
|
140
181
|
message,
|
|
182
|
+
source: result.source,
|
|
183
|
+
warning: result.warning,
|
|
141
184
|
};
|
|
142
185
|
}
|
|
143
186
|
/**
|
|
@@ -234,19 +277,12 @@ export function createScapiSchemasListTool(loadServices, schemaCache) {
|
|
|
234
277
|
.boolean()
|
|
235
278
|
.default(true)
|
|
236
279
|
.describe('Include tenant custom property definitions when fetching a schema.'),
|
|
280
|
+
include: z
|
|
281
|
+
.array(z.enum(SCAPI_SCHEMA_EXPANSIONS))
|
|
282
|
+
.optional()
|
|
283
|
+
.describe('Schemas API expand sections (e.g. summaries, examples, all). Overrides expandAll/expandCustomProperties.'),
|
|
237
284
|
},
|
|
238
285
|
async execute(args, { services: svc }) {
|
|
239
|
-
// Get client and organization ID
|
|
240
|
-
const client = svc.getScapiSchemasClient();
|
|
241
|
-
const organizationId = svc.getOrganizationId();
|
|
242
|
-
// Get shortCode for building base URLs (optional)
|
|
243
|
-
let shortCode;
|
|
244
|
-
try {
|
|
245
|
-
shortCode = svc.getShortCode();
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
// Continue without shortCode if not available
|
|
249
|
-
}
|
|
250
286
|
// Determine operation mode
|
|
251
287
|
const hasAllIdentifiers = Boolean(args.apiFamily && args.apiName && args.apiVersion);
|
|
252
288
|
const isFetchMode = hasAllIdentifiers && args.includeSchemas;
|
|
@@ -255,11 +291,12 @@ export function createScapiSchemasListTool(loadServices, schemaCache) {
|
|
|
255
291
|
throw new Error('includeSchemas=true requires all three identifiers: apiFamily, apiName, and apiVersion. ' +
|
|
256
292
|
'Please provide all three to fetch a specific schema, or omit includeSchemas to discover available schemas.');
|
|
257
293
|
}
|
|
258
|
-
// Execute appropriate mode
|
|
294
|
+
// Execute appropriate mode. Live access is attempted inside, so missing configuration, credentials or
|
|
295
|
+
// network falls back to the bundled corpus with a warning.
|
|
259
296
|
if (isFetchMode) {
|
|
260
|
-
return fetchSpecificSchema({
|
|
297
|
+
return fetchSpecificSchema({ svc, args, schemaCache });
|
|
261
298
|
}
|
|
262
|
-
return fetchSchemasList({
|
|
299
|
+
return fetchSchemasList({ svc, args });
|
|
263
300
|
},
|
|
264
301
|
formatOutput: (output) => jsonResult(output),
|
|
265
302
|
}, loadServices);
|