@dropins/mcp 0.1.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 (103) hide show
  1. package/LICENSE.md +127 -0
  2. package/README.md +314 -0
  3. package/dist/common/project-reader.d.ts +55 -0
  4. package/dist/common/project-reader.js +173 -0
  5. package/dist/common/registry-loader.d.ts +101 -0
  6. package/dist/common/registry-loader.js +386 -0
  7. package/dist/common/response-handling.d.ts +12 -0
  8. package/dist/common/response-handling.js +21 -0
  9. package/dist/common/sanitize.d.ts +8 -0
  10. package/dist/common/sanitize.js +45 -0
  11. package/dist/common/synonyms.d.ts +9 -0
  12. package/dist/common/synonyms.js +127 -0
  13. package/dist/common/telemetry.d.ts +14 -0
  14. package/dist/common/telemetry.js +54 -0
  15. package/dist/common/types.d.ts +308 -0
  16. package/dist/common/types.js +1 -0
  17. package/dist/common/version.d.ts +2 -0
  18. package/dist/common/version.js +14 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +136 -0
  21. package/dist/operations/analyze-project.d.ts +13 -0
  22. package/dist/operations/analyze-project.js +125 -0
  23. package/dist/operations/check-block-health.d.ts +19 -0
  24. package/dist/operations/check-block-health.js +1149 -0
  25. package/dist/operations/check-config.d.ts +13 -0
  26. package/dist/operations/check-config.js +228 -0
  27. package/dist/operations/explain-event-flow.d.ts +16 -0
  28. package/dist/operations/explain-event-flow.js +218 -0
  29. package/dist/operations/get-upgrade-diff.d.ts +13 -0
  30. package/dist/operations/get-upgrade-diff.js +144 -0
  31. package/dist/operations/list-api-functions.d.ts +13 -0
  32. package/dist/operations/list-api-functions.js +53 -0
  33. package/dist/operations/list-containers.d.ts +13 -0
  34. package/dist/operations/list-containers.js +44 -0
  35. package/dist/operations/list-design-tokens.d.ts +13 -0
  36. package/dist/operations/list-design-tokens.js +47 -0
  37. package/dist/operations/list-events.d.ts +16 -0
  38. package/dist/operations/list-events.js +39 -0
  39. package/dist/operations/list-graphql-queries.d.ts +19 -0
  40. package/dist/operations/list-graphql-queries.js +84 -0
  41. package/dist/operations/list-i18n-keys.d.ts +19 -0
  42. package/dist/operations/list-i18n-keys.js +105 -0
  43. package/dist/operations/list-models.d.ts +16 -0
  44. package/dist/operations/list-models.js +80 -0
  45. package/dist/operations/list-slots.d.ts +16 -0
  46. package/dist/operations/list-slots.js +81 -0
  47. package/dist/operations/scaffold-block.d.ts +31 -0
  48. package/dist/operations/scaffold-block.js +331 -0
  49. package/dist/operations/scaffold-extension.d.ts +28 -0
  50. package/dist/operations/scaffold-extension.js +346 -0
  51. package/dist/operations/scaffold-slot.d.ts +22 -0
  52. package/dist/operations/scaffold-slot.js +189 -0
  53. package/dist/operations/search-commerce-docs.d.ts +16 -0
  54. package/dist/operations/search-commerce-docs.js +101 -0
  55. package/dist/operations/search-docs.d.ts +23 -0
  56. package/dist/operations/search-docs.js +298 -0
  57. package/dist/operations/suggest-event-handler.d.ts +16 -0
  58. package/dist/operations/suggest-event-handler.js +175 -0
  59. package/dist/operations/suggest-slot-implementation.d.ts +19 -0
  60. package/dist/operations/suggest-slot-implementation.js +183 -0
  61. package/dist/registry/api-functions.json +3045 -0
  62. package/dist/registry/block-patterns.json +78 -0
  63. package/dist/registry/containers.json +2003 -0
  64. package/dist/registry/design-tokens.json +577 -0
  65. package/dist/registry/docs/boilerplate.json +55 -0
  66. package/dist/registry/docs/dropins-all.json +97 -0
  67. package/dist/registry/docs/dropins-b2b.json +607 -0
  68. package/dist/registry/docs/dropins-cart.json +163 -0
  69. package/dist/registry/docs/dropins-checkout.json +193 -0
  70. package/dist/registry/docs/dropins-order.json +139 -0
  71. package/dist/registry/docs/dropins-payment-services.json +73 -0
  72. package/dist/registry/docs/dropins-personalization.json +67 -0
  73. package/dist/registry/docs/dropins-product-details.json +139 -0
  74. package/dist/registry/docs/dropins-product-discovery.json +85 -0
  75. package/dist/registry/docs/dropins-recommendations.json +67 -0
  76. package/dist/registry/docs/dropins-user-account.json +121 -0
  77. package/dist/registry/docs/dropins-user-auth.json +103 -0
  78. package/dist/registry/docs/dropins-wishlist.json +85 -0
  79. package/dist/registry/docs/get-started.json +85 -0
  80. package/dist/registry/docs/how-tos.json +19 -0
  81. package/dist/registry/docs/index.json +139 -0
  82. package/dist/registry/docs/licensing.json +19 -0
  83. package/dist/registry/docs/merchants.json +523 -0
  84. package/dist/registry/docs/resources.json +13 -0
  85. package/dist/registry/docs/sdk.json +139 -0
  86. package/dist/registry/docs/setup.json +145 -0
  87. package/dist/registry/docs/troubleshooting.json +19 -0
  88. package/dist/registry/events.json +2200 -0
  89. package/dist/registry/examples/index.json +19 -0
  90. package/dist/registry/examples/storefront-checkout.json +377 -0
  91. package/dist/registry/examples/storefront-quote-management.json +49 -0
  92. package/dist/registry/extensions.json +272 -0
  93. package/dist/registry/graphql.json +3469 -0
  94. package/dist/registry/i18n.json +1873 -0
  95. package/dist/registry/models.json +1001 -0
  96. package/dist/registry/sdk.json +2357 -0
  97. package/dist/registry/slots.json +2270 -0
  98. package/dist/registry/tools-components.json +595 -0
  99. package/dist/resources/guides.d.ts +7 -0
  100. package/dist/resources/guides.js +625 -0
  101. package/dist/resources/handlers.d.ts +31 -0
  102. package/dist/resources/handlers.js +322 -0
  103. package/package.json +47 -0
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getApiFunctionRegistry, getApiFunctionsByDropin, getAllDropinNames, } from "../common/registry-loader.js";
4
+ export const ListApiFunctionsSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe("Filter by dropin name (e.g. storefront-cart). Omit to list all."),
9
+ });
10
+ export async function listApiFunctions(params) {
11
+ try {
12
+ if (params.dropin) {
13
+ const dropinData = getApiFunctionsByDropin(params.dropin);
14
+ if (!dropinData) {
15
+ const availableDropins = getAllDropinNames();
16
+ return formatSuccessResponse(`Dropin "${params.dropin}" not found`, {
17
+ availableDropins,
18
+ });
19
+ }
20
+ const data = {
21
+ version: dropinData.version,
22
+ importPath: dropinData.importPath,
23
+ functions: dropinData.functions,
24
+ utils: dropinData.utils,
25
+ };
26
+ return formatSuccessResponse(`Found ${dropinData.functions.length} API functions in ${params.dropin}`, data);
27
+ }
28
+ const registry = getApiFunctionRegistry();
29
+ const overview = Object.entries(registry.dropins).map(([dropinName, dropinData]) => {
30
+ const entry = {
31
+ dropin: dropinName,
32
+ version: dropinData.version,
33
+ importPath: dropinData.importPath,
34
+ functionCount: dropinData.functions.length,
35
+ functions: dropinData.functions.map((f) => ({
36
+ name: f.name,
37
+ signature: f.signature,
38
+ description: f.description,
39
+ })),
40
+ utilsImportPath: dropinData.utils?.importPath,
41
+ utilModules: dropinData.utils
42
+ ? Object.keys(dropinData.utils.modules)
43
+ : undefined,
44
+ };
45
+ return entry;
46
+ });
47
+ const totalFunctions = overview.reduce((sum, d) => sum + d.functionCount, 0);
48
+ return formatSuccessResponse(`Found ${totalFunctions} API functions across ${overview.length} dropins`, { sharedFunctions: registry.sharedFunctions, overview });
49
+ }
50
+ catch (error) {
51
+ return formatExceptionResponse(error, "listing API functions");
52
+ }
53
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ export declare const ListContainersSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ }, "strip", z.ZodTypeAny, {
5
+ dropin?: string | undefined;
6
+ }, {
7
+ dropin?: string | undefined;
8
+ }>;
9
+ export declare function listContainers(params: z.infer<typeof ListContainersSchema>): Promise<{
10
+ success: boolean;
11
+ message: string;
12
+ data: unknown;
13
+ }>;
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getContainerRegistry, getContainersByDropin, getAllDropinNames, } from "../common/registry-loader.js";
4
+ export const ListContainersSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe("Filter by dropin name (e.g. storefront-cart). Omit to list all."),
9
+ });
10
+ export async function listContainers(params) {
11
+ try {
12
+ if (params.dropin) {
13
+ const dropinData = getContainersByDropin(params.dropin);
14
+ if (!dropinData) {
15
+ const availableDropins = getAllDropinNames();
16
+ return formatSuccessResponse(`Dropin "${params.dropin}" not found`, {
17
+ availableDropins,
18
+ });
19
+ }
20
+ return formatSuccessResponse(`Found ${dropinData.containers.length} containers in ${params.dropin}`, {
21
+ version: dropinData.version,
22
+ renderImport: dropinData.renderImport,
23
+ apiImport: dropinData.apiImport,
24
+ containers: dropinData.containers,
25
+ });
26
+ }
27
+ const registry = getContainerRegistry();
28
+ const overview = Object.entries(registry.dropins).map(([dropinName, dropinData]) => ({
29
+ dropin: dropinName,
30
+ version: dropinData.version,
31
+ containerCount: dropinData.containers.length,
32
+ containers: dropinData.containers.map((c) => ({
33
+ name: c.name,
34
+ description: c.description,
35
+ slotNames: c.slotNames,
36
+ })),
37
+ }));
38
+ const totalContainers = overview.reduce((sum, d) => sum + d.containerCount, 0);
39
+ return formatSuccessResponse(`Found ${totalContainers} containers across ${overview.length} dropins`, { overview });
40
+ }
41
+ catch (error) {
42
+ return formatExceptionResponse(error, "listing containers");
43
+ }
44
+ }
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ export declare const ListDesignTokensSchema: z.ZodObject<{
3
+ category: z.ZodOptional<z.ZodString>;
4
+ }, "strip", z.ZodTypeAny, {
5
+ category?: string | undefined;
6
+ }, {
7
+ category?: string | undefined;
8
+ }>;
9
+ export declare function listDesignTokens(params: z.infer<typeof ListDesignTokensSchema>): Promise<{
10
+ success: boolean;
11
+ message: string;
12
+ data: unknown;
13
+ }>;
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getDesignTokenRegistry, getDesignTokensByCategory, } from "../common/registry-loader.js";
4
+ export const ListDesignTokensSchema = z.object({
5
+ category: z
6
+ .string()
7
+ .optional()
8
+ .describe("Token category: colors, typography, spacing, shapes, grid. Omit to list all."),
9
+ });
10
+ export async function listDesignTokens(params) {
11
+ try {
12
+ const registry = getDesignTokenRegistry();
13
+ if (params.category) {
14
+ const categoryData = getDesignTokensByCategory(params.category);
15
+ if (!categoryData) {
16
+ const availableCategories = Object.keys(registry.categories);
17
+ return formatSuccessResponse(`Category "${params.category}" not found`, { availableCategories });
18
+ }
19
+ const tokens = categoryData.tokens ?? [];
20
+ return formatSuccessResponse(`Found ${tokens.length} tokens in category "${params.category}"`, {
21
+ category: params.category,
22
+ description: categoryData.description,
23
+ tokens,
24
+ cssScope: registry.cssScope,
25
+ overrideExample: registry.overrideExample,
26
+ });
27
+ }
28
+ const overview = Object.entries(registry.categories).map(([categoryName, categoryData]) => ({
29
+ category: categoryName,
30
+ description: categoryData.description,
31
+ tokenCount: categoryData.tokens?.length ?? 0,
32
+ tokens: categoryData.tokens?.map((t) => ({
33
+ cssVariable: t.cssVariable,
34
+ defaultValue: t.defaultValue,
35
+ })) ?? [],
36
+ }));
37
+ const totalTokens = overview.reduce((sum, c) => sum + c.tokenCount, 0);
38
+ return formatSuccessResponse(`Found ${totalTokens} design tokens across ${overview.length} categories`, {
39
+ cssScope: registry.cssScope,
40
+ overrideExample: registry.overrideExample,
41
+ overview,
42
+ });
43
+ }
44
+ catch (error) {
45
+ return formatExceptionResponse(error, "listing design tokens");
46
+ }
47
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export declare const ListEventsSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ direction: z.ZodOptional<z.ZodEnum<["emitted", "consumed", "all"]>>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ dropin?: string | undefined;
7
+ direction?: "emitted" | "consumed" | "all" | undefined;
8
+ }, {
9
+ dropin?: string | undefined;
10
+ direction?: "emitted" | "consumed" | "all" | undefined;
11
+ }>;
12
+ export declare function listEvents(params: z.infer<typeof ListEventsSchema>): Promise<{
13
+ success: boolean;
14
+ message: string;
15
+ data: unknown;
16
+ }>;
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getEventCatalog, getEventsByDropin, getAllDropinNames, } from "../common/registry-loader.js";
4
+ export const ListEventsSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe("Filter events by dropin name (e.g. storefront-cart)"),
9
+ direction: z
10
+ .enum(["emitted", "consumed", "all"])
11
+ .optional()
12
+ .describe("Filter by direction: emitted, consumed, or all (default: all)"),
13
+ });
14
+ export async function listEvents(params) {
15
+ try {
16
+ if (params.dropin) {
17
+ const direction = params.direction ?? "all";
18
+ const events = getEventsByDropin(params.dropin, direction);
19
+ if (events.length === 0) {
20
+ const availableDropins = getAllDropinNames();
21
+ return formatSuccessResponse(`No events found for dropin "${params.dropin}" (direction: ${direction})`, { availableDropins });
22
+ }
23
+ return formatSuccessResponse(`Found ${events.length} events for ${params.dropin} (direction: ${direction})`, { events });
24
+ }
25
+ const catalog = getEventCatalog();
26
+ const events = catalog.events ?? [];
27
+ const summary = events.map((event) => ({
28
+ name: event.name,
29
+ payloadType: event.payloadType,
30
+ description: event.description,
31
+ emittedBy: event.emittedBy?.map((e) => e.dropin) ?? [],
32
+ consumedBy: event.consumedBy?.map((c) => c.dropin) ?? [],
33
+ }));
34
+ return formatSuccessResponse(`Found ${events.length} events in the catalog`, { events: summary });
35
+ }
36
+ catch (error) {
37
+ return formatExceptionResponse(error, "listing events");
38
+ }
39
+ }
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export declare const ListGraphqlQueriesSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ type: z.ZodOptional<z.ZodEnum<["query", "mutation"]>>;
5
+ name: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ type?: "query" | "mutation" | undefined;
8
+ dropin?: string | undefined;
9
+ name?: string | undefined;
10
+ }, {
11
+ type?: "query" | "mutation" | undefined;
12
+ dropin?: string | undefined;
13
+ name?: string | undefined;
14
+ }>;
15
+ export declare function listGraphqlQueries(params: z.infer<typeof ListGraphqlQueriesSchema>): Promise<{
16
+ success: boolean;
17
+ message: string;
18
+ data: unknown;
19
+ }>;
@@ -0,0 +1,84 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getGraphqlRegistry, getGraphqlByDropin, getAllDropinNames, } from "../common/registry-loader.js";
4
+ function filterOperations(operations, type, name) {
5
+ let result = operations;
6
+ if (type) {
7
+ result = result.filter((op) => op.type === type);
8
+ }
9
+ if (name) {
10
+ const search = name.toLowerCase();
11
+ result = result.filter((op) => op.name?.toLowerCase().includes(search));
12
+ }
13
+ return result;
14
+ }
15
+ function filterFragments(fragments, name) {
16
+ if (!name)
17
+ return fragments;
18
+ const search = name.toLowerCase();
19
+ return fragments.filter((f) => f.name?.toLowerCase().includes(search));
20
+ }
21
+ export const ListGraphqlQueriesSchema = z.object({
22
+ dropin: z
23
+ .string()
24
+ .optional()
25
+ .describe("Filter by dropin name (e.g. storefront-cart). Omit to list all."),
26
+ type: z
27
+ .enum(["query", "mutation"])
28
+ .optional()
29
+ .describe("Filter by operation type: query or mutation."),
30
+ name: z
31
+ .string()
32
+ .optional()
33
+ .describe("Search by operation or fragment name (case-insensitive substring match)."),
34
+ });
35
+ export async function listGraphqlQueries(params) {
36
+ try {
37
+ if (params.dropin) {
38
+ const dropinData = getGraphqlByDropin(params.dropin);
39
+ if (!dropinData) {
40
+ const availableDropins = getAllDropinNames();
41
+ return formatSuccessResponse(`Dropin "${params.dropin}" not found in GraphQL registry`, { availableDropins });
42
+ }
43
+ const operations = filterOperations(dropinData.operations ?? [], params.type, params.name);
44
+ const fragments = filterFragments(dropinData.fragments ?? [], params.name);
45
+ const exportedFragments = fragments.filter((f) => f.exported);
46
+ return formatSuccessResponse(`Found ${operations.length} operation(s) and ${fragments.length} fragment(s) in ${params.dropin}`, {
47
+ version: dropinData.version,
48
+ operations,
49
+ fragments,
50
+ extensibility: {
51
+ exportedFragmentCount: exportedFragments.length,
52
+ hint: exportedFragments.length > 0
53
+ ? "Exported fragments can be extended via overrideGQLOperations in build.mjs"
54
+ : "No exported fragments found for this dropin",
55
+ },
56
+ });
57
+ }
58
+ const registry = getGraphqlRegistry();
59
+ const overview = Object.entries(registry.dropins).map(([dropinName, dropinData]) => {
60
+ const operations = filterOperations(dropinData.operations ?? [], params.type, params.name);
61
+ const allFragments = dropinData.fragments ?? [];
62
+ const filteredFragments = filterFragments(allFragments, params.name);
63
+ const exportedCount = allFragments.filter((f) => f.exported).length;
64
+ return {
65
+ dropin: dropinName,
66
+ version: dropinData.version,
67
+ operationCount: operations.length,
68
+ fragmentCount: filteredFragments.length,
69
+ exportedFragmentCount: exportedCount,
70
+ operations: operations.map(({ source: _, ...rest }) => rest),
71
+ };
72
+ });
73
+ const filtered = overview.filter((d) => d.operationCount > 0 || d.fragmentCount > 0);
74
+ const totalOps = filtered.reduce((sum, d) => sum + d.operationCount, 0);
75
+ const totalFrags = filtered.reduce((sum, d) => sum + d.fragmentCount, 0);
76
+ return formatSuccessResponse(`Found ${totalOps} operation(s) and ${totalFrags} fragment(s) across ${filtered.length} dropin(s)`, {
77
+ hint: "Use dropin parameter to see operation variables, fragment dependencies, and exported fragment source. Fragments marked as 'exported' are extensible via overrideGQLOperations in build.mjs.",
78
+ overview: filtered,
79
+ });
80
+ }
81
+ catch (error) {
82
+ return formatExceptionResponse(error, "listing GraphQL queries");
83
+ }
84
+ }
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ export declare const ListI18nKeysSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ query: z.ZodOptional<z.ZodString>;
5
+ containerName: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ query?: string | undefined;
8
+ dropin?: string | undefined;
9
+ containerName?: string | undefined;
10
+ }, {
11
+ query?: string | undefined;
12
+ dropin?: string | undefined;
13
+ containerName?: string | undefined;
14
+ }>;
15
+ export declare function listI18nKeys(params: z.infer<typeof ListI18nKeysSchema>): Promise<{
16
+ success: boolean;
17
+ message: string;
18
+ data: unknown;
19
+ }>;
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getI18nRegistry, getContainerRegistry, } from "../common/registry-loader.js";
4
+ export const ListI18nKeysSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe('Filter to a specific dropin (e.g. "storefront-checkout"). Omit to search across all dropins.'),
9
+ query: z
10
+ .string()
11
+ .optional()
12
+ .describe('Substring filter applied to both key paths and values (e.g. "email" matches Checkout.LoginForm.invalidEmailError and its value). Case-insensitive.'),
13
+ containerName: z
14
+ .string()
15
+ .optional()
16
+ .describe('Filter to keys used by a specific container (e.g. "MiniCart"). Derived from the second segment of the dot-notation key path.'),
17
+ });
18
+ function inferContainer(key) {
19
+ const parts = key.split(".");
20
+ return parts.length >= 2 ? parts[1] : "(unlinked)";
21
+ }
22
+ export async function listI18nKeys(params) {
23
+ var _a;
24
+ try {
25
+ const registry = getI18nRegistry();
26
+ const allDropins = Object.keys(registry.dropins);
27
+ if (allDropins.length === 0) {
28
+ return formatSuccessResponse("i18n registry is empty", {
29
+ hint: "Run the generate script to populate registry/i18n.json",
30
+ query: null,
31
+ dropinFilter: null,
32
+ containerFilter: null,
33
+ totalMatched: 0,
34
+ dropins: [],
35
+ });
36
+ }
37
+ const searchDropins = params.dropin ? [params.dropin] : allDropins;
38
+ if (params.dropin && !registry.dropins[params.dropin]) {
39
+ return formatSuccessResponse(`Dropin "${params.dropin}" not found in i18n registry`, {
40
+ error: "Dropin not found",
41
+ availableDropins: allDropins,
42
+ });
43
+ }
44
+ const lowerQuery = params.query?.toLowerCase().trim() ?? "";
45
+ const lowerContainer = params.containerName?.toLowerCase().trim() ?? "";
46
+ const containerRegistry = getContainerRegistry();
47
+ const knownContainerNames = new Set(Object.values(containerRegistry.dropins).flatMap((d) => d.containers.map((c) => c.name.toLowerCase())));
48
+ const matches = [];
49
+ for (const dropinName of searchDropins) {
50
+ const dropinData = registry.dropins[dropinName];
51
+ if (!dropinData)
52
+ continue;
53
+ for (const [key, value] of Object.entries(dropinData.keys)) {
54
+ const container = inferContainer(key);
55
+ if (lowerContainer && container.toLowerCase() !== lowerContainer) {
56
+ continue;
57
+ }
58
+ if (!lowerQuery ||
59
+ key.toLowerCase().includes(lowerQuery) ||
60
+ value.toLowerCase().includes(lowerQuery)) {
61
+ matches.push({ dropin: dropinName, container, key, value });
62
+ }
63
+ }
64
+ }
65
+ const grouped = {};
66
+ for (const { dropin, container, key, value } of matches) {
67
+ grouped[dropin] ?? (grouped[dropin] = {});
68
+ (_a = grouped[dropin])[container] ?? (_a[container] = []);
69
+ grouped[dropin][container].push({ key, value });
70
+ }
71
+ const dropinSummary = Object.entries(grouped).map(([dropin, containers]) => {
72
+ const containerEntries = Object.entries(containers).map(([container, keys]) => ({
73
+ container,
74
+ knownContainer: knownContainerNames.has(container.toLowerCase()),
75
+ keys,
76
+ }));
77
+ return {
78
+ dropin,
79
+ version: registry.dropins[dropin]?.version ?? "unknown",
80
+ matchedKeys: containerEntries.reduce((sum, c) => sum + c.keys.length, 0),
81
+ containers: containerEntries,
82
+ };
83
+ });
84
+ const filterParts = [];
85
+ if (params.dropin)
86
+ filterParts.push(params.dropin);
87
+ if (params.containerName)
88
+ filterParts.push(`container "${params.containerName}"`);
89
+ if (params.query)
90
+ filterParts.push(`query "${params.query}"`);
91
+ const filterDesc = filterParts.length
92
+ ? ` in ${filterParts.join(", ")}`
93
+ : " across all dropins";
94
+ return formatSuccessResponse(`Found ${matches.length} key(s)${filterDesc}`, {
95
+ query: params.query ?? null,
96
+ dropinFilter: params.dropin ?? null,
97
+ containerFilter: params.containerName ?? null,
98
+ totalMatched: matches.length,
99
+ dropins: dropinSummary,
100
+ });
101
+ }
102
+ catch (error) {
103
+ return formatExceptionResponse(error, "listing i18n keys");
104
+ }
105
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export declare const ListModelsSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ model: z.ZodOptional<z.ZodString>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ dropin?: string | undefined;
7
+ model?: string | undefined;
8
+ }, {
9
+ dropin?: string | undefined;
10
+ model?: string | undefined;
11
+ }>;
12
+ export declare function listModels(params: z.infer<typeof ListModelsSchema>): Promise<{
13
+ success: boolean;
14
+ message: string;
15
+ data: unknown;
16
+ }>;
@@ -0,0 +1,80 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getModelsRegistry, getModelsByDropin, findModel, getAllDropinNames, } from "../common/registry-loader.js";
4
+ export const ListModelsSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe("Filter models by dropin name (e.g. storefront-cart)"),
9
+ model: z
10
+ .string()
11
+ .optional()
12
+ .describe("Find a specific model by name (e.g. CartModel, Price, Item). Returns full definition."),
13
+ });
14
+ export async function listModels(params) {
15
+ try {
16
+ if (params.model) {
17
+ if (params.dropin) {
18
+ const models = getModelsByDropin(params.dropin);
19
+ const found = models.find((m) => m.name === params.model);
20
+ if (!found) {
21
+ return formatSuccessResponse(`Model "${params.model}" not found in ${params.dropin}`, {
22
+ availableModels: models.map((m) => m.name),
23
+ hint: "The model may exist in a different dropin. Omit the dropin parameter to search globally.",
24
+ });
25
+ }
26
+ return formatSuccessResponse(`Found model "${params.model}" in ${params.dropin}`, {
27
+ name: found.name,
28
+ kind: found.kind,
29
+ dropin: params.dropin,
30
+ definition: found.definition,
31
+ });
32
+ }
33
+ const matches = findModel(params.model);
34
+ if (matches.length === 0) {
35
+ return formatSuccessResponse(`Model "${params.model}" not found in any dropin`, {
36
+ suggestion: "Try searching with a different name or list all models for a dropin",
37
+ });
38
+ }
39
+ if (matches.length === 1) {
40
+ return formatSuccessResponse(`Found model "${params.model}" in ${matches[0].dropin}`, {
41
+ name: matches[0].name,
42
+ kind: matches[0].kind,
43
+ dropin: matches[0].dropin,
44
+ definition: matches[0].definition,
45
+ });
46
+ }
47
+ return formatSuccessResponse(`Model "${params.model}" exists in ${matches.length} dropins — specify a dropin parameter to get the exact definition`, {
48
+ matches: matches.map((m) => ({
49
+ dropin: m.dropin,
50
+ kind: m.kind,
51
+ definition: m.definition,
52
+ })),
53
+ });
54
+ }
55
+ if (params.dropin) {
56
+ const models = getModelsByDropin(params.dropin);
57
+ if (models.length === 0) {
58
+ const availableDropins = getAllDropinNames();
59
+ return formatSuccessResponse(`No models found for dropin "${params.dropin}"`, { availableDropins });
60
+ }
61
+ return formatSuccessResponse(`Found ${models.length} models in ${params.dropin}`, {
62
+ models: models.map((m) => ({
63
+ name: m.name,
64
+ kind: m.kind,
65
+ definition: m.definition,
66
+ })),
67
+ });
68
+ }
69
+ const registry = getModelsRegistry();
70
+ const summary = Object.entries(registry.dropins).map(([dropin, data]) => ({
71
+ dropin,
72
+ modelCount: data.models.length,
73
+ models: data.models.map((m) => m.name),
74
+ }));
75
+ return formatSuccessResponse(`Model registry contains definitions across ${summary.length} dropins`, { dropins: summary });
76
+ }
77
+ catch (error) {
78
+ return formatExceptionResponse(error, "listing models");
79
+ }
80
+ }
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export declare const ListSlotsSchema: z.ZodObject<{
3
+ dropin: z.ZodOptional<z.ZodString>;
4
+ container: z.ZodOptional<z.ZodString>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ dropin?: string | undefined;
7
+ container?: string | undefined;
8
+ }, {
9
+ dropin?: string | undefined;
10
+ container?: string | undefined;
11
+ }>;
12
+ export declare function listSlots(params: z.infer<typeof ListSlotsSchema>): Promise<{
13
+ success: boolean;
14
+ message: string;
15
+ data: unknown;
16
+ }>;
@@ -0,0 +1,81 @@
1
+ import { z } from "zod";
2
+ import { formatSuccessResponse, formatExceptionResponse, } from "../common/response-handling.js";
3
+ import { getSlotRegistry, getSlotsByDropin, getSlotsByContainer, getAllDropinNames, } from "../common/registry-loader.js";
4
+ export const ListSlotsSchema = z.object({
5
+ dropin: z
6
+ .string()
7
+ .optional()
8
+ .describe("Dropin name (e.g. storefront-cart). Omit to list all."),
9
+ container: z
10
+ .string()
11
+ .optional()
12
+ .describe("Container name (e.g. CartSummaryList). Requires dropin to be set."),
13
+ });
14
+ export async function listSlots(params) {
15
+ try {
16
+ const availableDropins = getAllDropinNames();
17
+ if (params.container && !params.dropin) {
18
+ return formatSuccessResponse('The "container" filter requires "dropin" to be specified', {
19
+ hint: 'Provide both dropin and container, e.g. { dropin: "storefront-cart", container: "CartSummaryList" }',
20
+ availableDropins,
21
+ });
22
+ }
23
+ if (params.dropin && params.container) {
24
+ const containerData = getSlotsByContainer(params.dropin, params.container);
25
+ if (!containerData) {
26
+ const dropinData = getSlotsByDropin(params.dropin);
27
+ return formatSuccessResponse(`Container "${params.container}" not found in ${params.dropin}`, {
28
+ availableContainers: dropinData
29
+ ? Object.keys(dropinData.containers)
30
+ : [],
31
+ hint: !dropinData
32
+ ? `Dropin "${params.dropin}" not found. Available: ${availableDropins.join(", ")}`
33
+ : undefined,
34
+ });
35
+ }
36
+ const hasDefaultCtx = (containerData.slots ?? []).some((s) => s.contextType === "DefaultSlotContext");
37
+ const registry = getSlotRegistry();
38
+ return formatSuccessResponse(`Slots for ${params.dropin} > ${params.container}`, {
39
+ ...containerData,
40
+ ...(hasDefaultCtx && registry.defaultSlotContext
41
+ ? { defaultSlotContext: registry.defaultSlotContext }
42
+ : {}),
43
+ });
44
+ }
45
+ if (params.dropin) {
46
+ const dropinData = getSlotsByDropin(params.dropin);
47
+ if (!dropinData) {
48
+ return formatSuccessResponse(`Dropin "${params.dropin}" not found`, {
49
+ availableDropins,
50
+ });
51
+ }
52
+ const summary = Object.entries(dropinData.containers).map(([containerName, containerData]) => ({
53
+ container: containerName,
54
+ slotCount: (containerData.slots ?? []).length,
55
+ slotNames: (containerData.slots ?? []).map((s) => s.name),
56
+ }));
57
+ return formatSuccessResponse(`Slots for ${params.dropin}`, {
58
+ containers: summary,
59
+ raw: dropinData,
60
+ });
61
+ }
62
+ const registry = getSlotRegistry();
63
+ const overview = Object.entries(registry.dropins).map(([dropinName, dropinData]) => {
64
+ const containers = Object.entries(dropinData.containers).map(([containerName, containerData]) => ({
65
+ container: containerName,
66
+ slotCount: (containerData.slots ?? []).length,
67
+ slotNames: (containerData.slots ?? []).map((s) => s.name),
68
+ }));
69
+ return {
70
+ dropin: dropinName,
71
+ totalSlots: containers.reduce((sum, c) => sum + c.slotCount, 0),
72
+ containers,
73
+ };
74
+ });
75
+ const totalSlots = overview.reduce((sum, d) => sum + d.totalSlots, 0);
76
+ return formatSuccessResponse(`Found ${totalSlots} slots across ${overview.length} dropins`, { overview });
77
+ }
78
+ catch (error) {
79
+ return formatExceptionResponse(error, "listing slots");
80
+ }
81
+ }