@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.
Files changed (333) hide show
  1. package/bin/run.js +5 -9
  2. package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
  3. package/content/guidance/b2c/b2c-onboarding/SKILL.md +4 -4
  4. package/content/guidance/b2c/b2c-ordering/SKILL.md +2 -2
  5. package/content/guidance/b2c/b2c-querying-data/SKILL.md +2 -2
  6. package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +3 -3
  7. package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
  8. package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +6 -6
  9. package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
  10. package/content/guidance/b2c-cli/b2c-cip/SKILL.md +3 -3
  11. package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +1 -1
  12. package/content/guidance/b2c-cli/b2c-config/SKILL.md +54 -25
  13. package/content/guidance/b2c-cli/b2c-content/SKILL.md +1 -1
  14. package/content/guidance/b2c-cli/b2c-debug/SKILL.md +1 -1
  15. package/content/guidance/b2c-cli/b2c-docs/SKILL.md +23 -2
  16. package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +2 -0
  17. package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +1 -1
  18. package/content/guidance/b2c-cli/b2c-job/SKILL.md +9 -3
  19. package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +1 -1
  20. package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +35 -6
  21. package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +1 -1
  22. package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +3 -3
  23. package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +1 -1
  24. package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +6 -2
  25. package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +1 -1
  26. package/content/guidance/b2c-cli/b2c-sites/SKILL.md +1 -1
  27. package/content/guidance/b2c-cli/b2c-slas/SKILL.md +1 -1
  28. package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +2 -2
  29. package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
  30. package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +13 -8
  31. package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +1 -1
  32. package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +2 -2
  33. package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +5 -4
  34. package/content/guidance/index.json +981 -259
  35. package/content/guidance/mcp/{cip → b2c-mcp-cip}/SKILL.md +10 -8
  36. package/content/guidance/mcp/{b2c-config → b2c-mcp-config}/SKILL.md +10 -9
  37. package/content/guidance/mcp/{debugger → b2c-mcp-debugger}/SKILL.md +9 -8
  38. package/content/guidance/mcp/b2c-mcp-scapi/SKILL.md +98 -0
  39. package/content/guidance/mcp/b2c-mcp-scapi/references/authentication.md +34 -0
  40. package/content/guidance/mcp/b2c-mcp-scapi/references/compose-verify.md +25 -0
  41. package/content/guidance/mcp/b2c-mcp-scapi/references/confirmation.md +30 -0
  42. package/content/guidance/mcp/b2c-mcp-scapi/references/discover.md +94 -0
  43. package/content/guidance/mcp/b2c-mcp-scapi/references/jobs.md +72 -0
  44. package/content/guidance/mcp/b2c-mcp-scapi/references/workflows.md +28 -0
  45. package/content/guidance/mcp/{server → b2c-mcp-server}/SKILL.md +52 -25
  46. package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
  47. package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
  48. package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
  49. package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
  50. package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +86 -79
  51. package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
  52. package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
  53. package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
  54. package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
  55. package/content/guidance/storefront-next/sfnext-components/SKILL.md +98 -136
  56. package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
  57. package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
  58. package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
  59. package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
  60. package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
  61. package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +116 -113
  62. package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
  63. package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
  64. package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +100 -150
  65. package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
  66. package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
  67. package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
  68. package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
  69. package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +83 -97
  70. package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
  71. package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +73 -97
  72. package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
  73. package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +47 -44
  74. package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
  75. package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
  76. package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +59 -114
  77. package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
  78. package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +96 -131
  79. package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
  80. package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
  81. package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +152 -131
  82. package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
  83. package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
  84. package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
  85. package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
  86. package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
  87. package/content/guidance/storefront-next/sfnext-performance/SKILL.md +75 -105
  88. package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
  89. package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
  90. package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +103 -116
  91. package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
  92. package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
  93. package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
  94. package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
  95. package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
  96. package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
  97. package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
  98. package/content/guidance/storefront-next/sfnext-routing/SKILL.md +86 -143
  99. package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
  100. package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
  101. package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
  102. package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
  103. package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
  104. package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
  105. package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
  106. package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
  107. package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
  108. package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
  109. package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +80 -89
  110. package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
  111. package/content/guidance/storefront-next/sfnext-testing/SKILL.md +105 -138
  112. package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
  113. package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
  114. package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
  115. package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
  116. package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
  117. package/dist/commands/mcp.d.ts +8 -2
  118. package/dist/commands/mcp.js +54 -20
  119. package/dist/guidance.d.ts +4 -1
  120. package/dist/guidance.js +23 -5
  121. package/dist/registry.d.ts +2 -1
  122. package/dist/registry.js +3 -3
  123. package/dist/server.d.ts +10 -0
  124. package/dist/server.js +21 -0
  125. package/dist/skill-references.js +5 -5
  126. package/dist/tools/cartridges/index.js +1 -0
  127. package/dist/tools/cip/index.js +6 -3
  128. package/dist/tools/diagnostics/debug-capture-at-breakpoint.js +1 -1
  129. package/dist/tools/diagnostics/debug-set-breakpoints.js +1 -1
  130. package/dist/tools/diagnostics/debug-start-session.js +1 -1
  131. package/dist/tools/docs/docs-read.js +4 -2
  132. package/dist/tools/docs/docs-search.js +10 -8
  133. package/dist/tools/docs/topics.d.ts +5 -0
  134. package/dist/tools/docs/topics.js +5 -0
  135. package/dist/tools/scapi/index.d.ts +4 -1
  136. package/dist/tools/scapi/index.js +4 -2
  137. package/dist/tools/scapi/scapi-code.d.ts +2 -2
  138. package/dist/tools/scapi/scapi-code.js +106 -81
  139. package/dist/tools/scapi/scapi-schemas-list.js +93 -56
  140. package/dist/utils/types.d.ts +6 -0
  141. package/node_modules/@salesforce/b2c-agent-plugins/CHANGELOG.md +32 -0
  142. package/node_modules/@salesforce/b2c-agent-plugins/README.md +5 -0
  143. package/node_modules/@salesforce/b2c-agent-plugins/b2c/.codex-plugin/plugin.json +1 -1
  144. package/node_modules/@salesforce/b2c-agent-plugins/b2c/plugin.json +1 -1
  145. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
  146. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-onboarding/SKILL.md +4 -4
  147. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-ordering/SKILL.md +2 -2
  148. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-querying-data/SKILL.md +2 -2
  149. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/SKILL.md +3 -3
  150. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
  151. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/SKILL.md +6 -6
  152. package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
  153. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/.codex-plugin/plugin.json +1 -1
  154. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/plugin.json +1 -1
  155. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/SKILL.md +3 -3
  156. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/references/SALES_ANALYSIS.md +1 -1
  157. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-config/SKILL.md +54 -25
  158. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-content/SKILL.md +1 -1
  159. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-debug/SKILL.md +1 -1
  160. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-docs/SKILL.md +23 -2
  161. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/SKILL.md +2 -0
  162. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md +1 -1
  163. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/SKILL.md +9 -3
  164. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/IMPORT.md +1 -1
  165. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/RUN-AND-MONITOR.md +35 -6
  166. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-metrics/SKILL.md +1 -1
  167. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-mrt/SKILL.md +3 -3
  168. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-custom/SKILL.md +1 -1
  169. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-schemas/SKILL.md +6 -2
  170. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-site-import-export/SKILL.md +1 -1
  171. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-sites/SKILL.md +1 -1
  172. package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-slas/SKILL.md +1 -1
  173. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/.codex-plugin/plugin.json +4 -3
  174. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/README.md +1 -0
  175. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/plugin.json +4 -3
  176. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-checkout-triage/SKILL.md +2 -2
  177. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-edge-traffic-triage/SKILL.md +69 -0
  178. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-job-health/SKILL.md +13 -8
  179. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/SKILL.md +1 -1
  180. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/references/order-evidence.md +2 -2
  181. package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-production-triage/SKILL.md +5 -4
  182. package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/README.md +4 -4
  183. package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/SKILL.md +76 -73
  184. package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/evals/trigger-evals.json +12 -10
  185. package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/references/PAGE-DESIGNER-SFN.md +49 -74
  186. package/node_modules/@salesforce/b2c-agent-plugins/package.json +1 -1
  187. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/.codex-plugin/plugin.json +9 -6
  188. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/README.md +43 -22
  189. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/plugin.json +9 -6
  190. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/SKILL.md +103 -0
  191. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/evals/trigger-evals.json +5 -0
  192. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/references/checklist.md +64 -0
  193. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/SKILL.md +91 -0
  194. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/evals/trigger-evals.json +5 -0
  195. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
  196. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/SKILL.md +86 -79
  197. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/evals/trigger-evals.json +5 -0
  198. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/COOKIES.md +39 -0
  199. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
  200. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/SKILL.md +67 -0
  201. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/evals/trigger-evals.json +5 -0
  202. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
  203. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/SKILL.md +98 -136
  204. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/evals/trigger-evals.json +5 -0
  205. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
  206. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/SHAPE-TOKENS.md +51 -0
  207. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/STORYBOOK.md +54 -0
  208. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
  209. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TROUBLESHOOTING.md +19 -0
  210. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/SKILL.md +116 -113
  211. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/evals/trigger-evals.json +5 -0
  212. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
  213. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
  214. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/SKILL.md +100 -150
  215. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/evals/trigger-evals.json +5 -0
  216. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/ACTIONS.md +53 -0
  217. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
  218. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADERS.md +73 -0
  219. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
  220. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/SKILL.md +83 -97
  221. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/evals/trigger-evals.json +5 -0
  222. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
  223. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/SKILL.md +73 -97
  224. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/evals/trigger-evals.json +5 -0
  225. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
  226. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/BASE-AUDIT.md +47 -44
  227. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
  228. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
  229. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/SKILL.md +59 -114
  230. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/evals/trigger-evals.json +5 -0
  231. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
  232. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/SKILL.md +96 -131
  233. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/evals/trigger-evals.json +5 -0
  234. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/references/locale-config.md +35 -0
  235. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/SKILL.md +101 -0
  236. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/evals/trigger-evals.json +5 -0
  237. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/SKILL.md +152 -131
  238. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/evals/trigger-evals.json +5 -0
  239. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
  240. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
  241. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
  242. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
  243. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
  244. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/SKILL.md +75 -105
  245. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/evals/trigger-evals.json +5 -0
  246. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
  247. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
  248. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/SKILL.md +103 -116
  249. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/evals/trigger-evals.json +5 -0
  250. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
  251. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SCRIPTS.md +47 -0
  252. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
  253. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/SKILL.md +70 -0
  254. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/evals/trigger-evals.json +5 -0
  255. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
  256. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/SKILL.md +121 -0
  257. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/evals/trigger-evals.json +5 -0
  258. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
  259. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/SKILL.md +86 -143
  260. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/evals/trigger-evals.json +5 -0
  261. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
  262. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
  263. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/SKILL.md +126 -0
  264. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/evals/trigger-evals.json +5 -0
  265. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
  266. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/SKILL.md +129 -0
  267. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/evals/trigger-evals.json +5 -0
  268. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
  269. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/TURNSTILE.md +43 -0
  270. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/SKILL.md +95 -0
  271. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/evals/trigger-evals.json +5 -0
  272. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
  273. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/SEO-ROUTES.md +31 -0
  274. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/SKILL.md +80 -89
  275. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/evals/trigger-evals.json +5 -0
  276. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/references/PATTERNS.md +45 -0
  277. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/SKILL.md +105 -138
  278. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/evals/trigger-evals.json +5 -0
  279. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/E2E.md +38 -0
  280. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
  281. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
  282. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/SKILL.md +104 -0
  283. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/evals/trigger-evals.json +5 -0
  284. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
  285. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next-figma/skills/sfnext-create-figma-kit/SKILL.md +3 -3
  286. package/oclif.manifest.json +21 -4
  287. package/package.json +4 -4
  288. package/content/guidance/mcp/scapi/SKILL.md +0 -203
  289. package/content/guidance/mcp/scapi/references/jobs.md +0 -30
  290. package/content/guidance/storefront-next/sfnext-create-component/SKILL.md +0 -195
  291. package/content/guidance/storefront-next/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
  292. package/content/guidance/storefront-next/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
  293. package/content/guidance/storefront-next/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
  294. package/content/guidance/storefront-next/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
  295. package/content/guidance/storefront-next/sfnext-create-vertical/SKILL.md +0 -135
  296. package/content/guidance/storefront-next/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
  297. package/content/guidance/storefront-next/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
  298. package/content/guidance/storefront-next/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
  299. package/content/guidance/storefront-next/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
  300. package/content/guidance/storefront-next/sfnext-custom-apis/SKILL.md +0 -221
  301. package/content/guidance/storefront-next/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
  302. package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
  303. package/content/guidance/storefront-next/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
  304. package/content/guidance/storefront-next/sfnext-scapi-management/SKILL.md +0 -203
  305. package/content/guidance/storefront-next/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
  306. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/SKILL.md +0 -195
  307. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/evals/trigger-evals.json +0 -12
  308. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
  309. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
  310. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
  311. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
  312. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/SKILL.md +0 -135
  313. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/evals/trigger-evals.json +0 -12
  314. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
  315. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
  316. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
  317. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
  318. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/SKILL.md +0 -221
  319. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/evals/trigger-evals.json +0 -12
  320. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
  321. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
  322. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
  323. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/SKILL.md +0 -203
  324. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/evals/trigger-evals.json +0 -12
  325. package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
  326. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-apis.md +0 -0
  327. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-properties.md +0 -0
  328. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/products.md +0 -0
  329. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/promotions.md +0 -0
  330. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/saving.md +0 -0
  331. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/snippets.md +0 -0
  332. /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/tokens.md +0 -0
  333. /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
- * only the triage-critical fields (id, title, category, summary, score) and drop
17
- * `keywords` (index-tuning metadata) and `url` (derivable / returned on read),
18
- * which together roughly double the payload. `verbose` restores them.
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 canonical url on each result (larger payload). Defaults to false.'),
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 skillRead = z.boolean().optional().describe('True after reading the linked SCAPI skill.');
21
- const snippetDescription = `\nSnippets: await codemode.search(query) returns up to 10 names/descriptions/effects; await codemode.describe(name) returns source/inputSchema. Prefixes: builtin/, user/.`;
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('SCAPI_SKILL_REQUIRED: Read skill://mcp/scapi/SKILL.md through resources or skills_read, then retry with skillRead: true.');
27
+ throw new Error(SCAPI_SKILL_REQUIRED);
25
28
  }
26
- const searchDescription = `Discover Admin/Shopper SCAPI contracts; prefer dedicated tools. Read skill://mcp/scapi/SKILL.md first.
27
- Default: bundled, offline. schemas:"live": tenant c_*, custom, newer APIs, reused by execute.
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.string().optional().describe('Limit schemas to family/name/version. Omit for all APIs.'),
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 + snippetDescription,
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
- const services = await loadServices(input);
134
+ services = await loadServices(input);
157
135
  resolution = services.getResolution();
158
- // Throws with configuration guidance when shortCode, tenantId, or OAuth credentials are missing.
159
- const client = services.getScapiSchemasClient();
160
- const organizationId = services.getOrganizationId();
161
- const tenant = scapiTenantKey(services.getShortCode(), organizationId);
162
- ({ documents, failures } = await schemaCache.load(tenant, client, organizationId, {
163
- api: input.api,
164
- refresh: input.refresh,
165
- signal: context?.signal,
166
- }));
167
- if (documents.length === 0 && failures.length === 0)
168
- throw new Error('Unknown schema ID for this tenant. Omit api to discover available APIs.');
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 = loadScapiSchemas().filter((document) => !input.api || document.entry.id === input.api);
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({ result, ...(failures.length > 0 ? { schemaFailures: failures } : {}) }, resolution);
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 + snippetDescription,
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; the user owns their accuracy.
245
- documents: mergeScapiSchemas(loadScapiSchemas(), tenant ? schemaCache.get(tenant) : []),
246
- onSchema(document, customProperties) {
247
- // Keep expanded tenant contracts from being replaced by unexpanded fetches.
248
- if (tenant && (customProperties || document.entry.apiFamily === 'custom'))
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.client - SCAPI Schemas client
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 { client, organizationId, args, shortCode, schemaCache } = params;
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 warning = status
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 { data, error, response } = await client.GET('/organizations/{organizationId}/schemas/{apiFamily}/{apiName}/{apiVersion}', {
67
- params: {
68
- path: { organizationId, apiFamily: apiFamily, apiName: apiName, apiVersion: apiVersion },
69
- query: args.expandCustomProperties === false ? undefined : { expand: 'custom_properties' },
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
- if (error) {
73
- throw new Error(`Failed to fetch schema for ${apiFamily}/${apiName}/${apiVersion}: ${getSchemasApiError(error, response)}`);
74
- }
75
- // Expanded tenant contracts become searchable and executable in SCAPI code mode.
76
- if (schemaCache && shortCode && (args.expandCustomProperties !== false || apiFamily === 'custom')) {
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({ apiFamily: apiFamily, apiName: apiName, apiVersion: apiVersion }, data));
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(data)
88
- : data;
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 && apiFamily && apiName && apiVersion
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
- apiFamily: apiFamily,
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.client - SCAPI Schemas client
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 { client, organizationId, args, shortCode } = params;
116
- const { data, error, response } = await client.GET('/organizations/{organizationId}/schemas', {
117
- params: {
118
- path: { organizationId },
119
- query: {
120
- apiFamily: args.apiFamily,
121
- apiName: args.apiName,
122
- apiVersion: args.apiVersion,
123
- status: args.status,
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
- if (error) {
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: data?.total ?? schemas.length,
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({ client, organizationId, args, shortCode, schemaCache });
297
+ return fetchSpecificSchema({ svc, args, schemaCache });
261
298
  }
262
- return fetchSchemasList({ client, organizationId, args, shortCode });
299
+ return fetchSchemasList({ svc, args });
263
300
  },
264
301
  formatOutput: (output) => jsonResult(output),
265
302
  }, loadServices);