@salesforce/b2c-dx-mcp 0.3.2 → 0.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 (54) hide show
  1. package/README.md +47 -27
  2. package/content/page-designer.md +4 -4
  3. package/dist/commands/mcp.d.ts +12 -0
  4. package/dist/commands/mcp.js +16 -4
  5. package/dist/registry.d.ts +4 -4
  6. package/dist/registry.js +10 -10
  7. package/dist/services.d.ts +75 -1
  8. package/dist/services.js +124 -1
  9. package/dist/tools/adapter.d.ts +29 -21
  10. package/dist/tools/adapter.js +34 -24
  11. package/dist/tools/cartridges/index.d.ts +5 -3
  12. package/dist/tools/cartridges/index.js +55 -25
  13. package/dist/tools/index.d.ts +1 -0
  14. package/dist/tools/index.js +1 -0
  15. package/dist/tools/mrt/index.d.ts +2 -2
  16. package/dist/tools/mrt/index.js +29 -10
  17. package/dist/tools/page-designer-decorator/analyzer.d.ts +169 -0
  18. package/dist/tools/page-designer-decorator/analyzer.js +535 -0
  19. package/dist/tools/page-designer-decorator/index.d.ts +252 -0
  20. package/dist/tools/page-designer-decorator/index.js +597 -0
  21. package/dist/tools/page-designer-decorator/rules/1-mode-selection.d.ts +8 -0
  22. package/dist/tools/page-designer-decorator/rules/1-mode-selection.js +65 -0
  23. package/dist/tools/page-designer-decorator/rules/2a-auto-mode.d.ts +13 -0
  24. package/dist/tools/page-designer-decorator/rules/2a-auto-mode.js +87 -0
  25. package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.d.ts +4 -0
  26. package/dist/tools/page-designer-decorator/rules/2b-0-interactive-overview.js +55 -0
  27. package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.d.ts +22 -0
  28. package/dist/tools/page-designer-decorator/rules/2b-1-interactive-analyze.js +109 -0
  29. package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.d.ts +21 -0
  30. package/dist/tools/page-designer-decorator/rules/2b-2-interactive-select-props.js +60 -0
  31. package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.d.ts +27 -0
  32. package/dist/tools/page-designer-decorator/rules/2b-3-interactive-configure-attrs.js +68 -0
  33. package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.d.ts +4 -0
  34. package/dist/tools/page-designer-decorator/rules/2b-4-interactive-configure-regions.js +65 -0
  35. package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.d.ts +11 -0
  36. package/dist/tools/page-designer-decorator/rules/2b-5-interactive-confirm-generation.js +92 -0
  37. package/dist/tools/page-designer-decorator/rules.d.ts +51 -0
  38. package/dist/tools/page-designer-decorator/rules.js +70 -0
  39. package/dist/tools/page-designer-decorator/templates/decorator-generator.d.ts +116 -0
  40. package/dist/tools/page-designer-decorator/templates/decorator-generator.js +350 -0
  41. package/dist/tools/pwav3/index.d.ts +2 -2
  42. package/dist/tools/pwav3/index.js +13 -13
  43. package/dist/tools/scapi/index.d.ts +10 -2
  44. package/dist/tools/scapi/index.js +5 -56
  45. package/dist/tools/scapi/scapi-custom-apis-status.d.ts +9 -0
  46. package/dist/tools/scapi/scapi-custom-apis-status.js +152 -0
  47. package/dist/tools/scapi/scapi-schemas-list.d.ts +12 -0
  48. package/dist/tools/scapi/scapi-schemas-list.js +248 -0
  49. package/dist/tools/storefrontnext/developer-guidelines.d.ts +2 -2
  50. package/dist/tools/storefrontnext/developer-guidelines.js +3 -3
  51. package/dist/tools/storefrontnext/index.d.ts +2 -2
  52. package/dist/tools/storefrontnext/index.js +13 -13
  53. package/oclif.manifest.json +13 -2
  54. package/package.json +10 -5
@@ -3,22 +3,22 @@
3
3
  *
4
4
  * This module provides utilities for creating standardized MCP tools that:
5
5
  * - Validate input using Zod schemas
6
- * - Inject pre-resolved B2CInstance for WebDAV/OCAPI operations (requiresInstance)
7
- * - Inject pre-resolved MRT auth for MRT API operations (requiresMrtAuth)
6
+ * - Inject loaded B2CInstance for WebDAV/OCAPI operations (requiresInstance)
7
+ * - Inject loaded MRT auth for MRT API operations (requiresMrtAuth)
8
8
  * - Format output consistently (textResult, jsonResult, errorResult)
9
9
  *
10
10
  * ## Configuration Resolution
11
11
  *
12
- * Both B2C instance and MRT auth are resolved once at server startup via
13
- * {@link Services.fromResolvedConfig} and reused for all tool calls:
12
+ * Both B2C instance and MRT auth are loaded before each tool call via
13
+ * a loader function that calls {@link Services.fromResolvedConfig}:
14
14
  *
15
- * - **B2CInstance**: Resolved from flags + dw.json. Available when `requiresInstance: true`.
16
- * - **MRT Auth**: Resolved from --api-key → SFCC_MRT_API_KEY → ~/.mobify. Available when `requiresMrtAuth: true`.
15
+ * - **B2CInstance**: Loaded from flags + dw.json on each call. Available when `requiresInstance: true`.
16
+ * - **MRT Auth**: Loaded from --api-key → SFCC_MRT_API_KEY → ~/.mobify on each call. Available when `requiresMrtAuth: true`.
17
17
  *
18
- * This "resolve eagerly at startup" pattern provides:
19
- * - Fail-fast behavior (configuration errors surface at startup)
20
- * - Consistent mental model (both resolved the same way)
21
- * - Better performance (no resolution on each tool call)
18
+ * This "load on each call" pattern provides:
19
+ * - Fresh configuration on each tool invocation (picks up changes to config files)
20
+ * - Consistent mental model (both loaded the same way)
21
+ * - Tools can respond to configuration changes without server restart
22
22
  *
23
23
  * @module tools/adapter
24
24
  *
@@ -42,8 +42,11 @@
42
42
  *
43
43
  * @example MRT tool (MRT API)
44
44
  * ```typescript
45
- * // Services created from already-resolved config at startup
46
- * const services = Services.fromResolvedConfig(this.resolvedConfig);
45
+ * // Loader function that loads config and creates Services on each tool call
46
+ * const loadServices = () => {
47
+ * const config = this.loadConfiguration();
48
+ * return Services.fromResolvedConfig(config);
49
+ * };
47
50
  *
48
51
  * const mrtTool = createToolAdapter({
49
52
  * name: 'mrt_bundle_push',
@@ -53,12 +56,12 @@
53
56
  * inputSchema: {
54
57
  * projectSlug: z.string().describe('MRT project slug'),
55
58
  * },
56
- * execute: async (args, { mrtAuth }) => {
57
- * const result = await pushBundle({ projectSlug: args.projectSlug }, mrtAuth);
59
+ * execute: async (args, { mrtConfig }) => {
60
+ * const result = await pushBundle({ projectSlug: args.projectSlug }, mrtConfig.auth);
58
61
  * return result;
59
62
  * },
60
63
  * formatOutput: (output) => jsonResult(output),
61
- * }, services);
64
+ * }, loadServices);
62
65
  * ```
63
66
  */
64
67
  import { type ZodRawShape } from 'zod';
@@ -78,7 +81,7 @@ export interface ToolExecutionContext {
78
81
  b2cInstance?: B2CInstance;
79
82
  /**
80
83
  * MRT configuration (auth, project, environment, origin).
81
- * Pre-resolved at server startup.
84
+ * Loaded before each tool call.
82
85
  * Only populated when requiresMrtAuth is true.
83
86
  */
84
87
  mrtConfig?: MrtConfig;
@@ -176,7 +179,7 @@ export declare function jsonResult(data: unknown, indent?: number): ToolResult;
176
179
  * @template TInput - The validated input type (inferred from inputSchema)
177
180
  * @template TOutput - The output type from the execute function
178
181
  * @param options - Tool adapter configuration
179
- * @param services - Services instance for dependency injection
182
+ * @param loadServices - Function that loads configuration and returns Services instance
180
183
  * @returns An McpTool ready for registration
181
184
  *
182
185
  * @example
@@ -184,18 +187,23 @@ export declare function jsonResult(data: unknown, indent?: number): ToolResult;
184
187
  * import { z } from 'zod';
185
188
  * import { createToolAdapter, jsonResult, errorResult } from './adapter.js';
186
189
  *
190
+ * const loadServices = () => {
191
+ * const config = this.loadConfiguration();
192
+ * return Services.fromResolvedConfig(config);
193
+ * };
194
+ *
187
195
  * const listCodeVersionsTool = createToolAdapter({
188
196
  * name: 'code_version_list',
189
197
  * description: 'List all code versions on the instance',
190
198
  * toolsets: ['CARTRIDGES'],
191
199
  * inputSchema: {},
192
- * execute: async (_args, { instance }) => {
193
- * const result = await instance.ocapi.GET('/code_versions', {});
200
+ * execute: async (_args, { b2cInstance }) => {
201
+ * const result = await b2cInstance.ocapi.GET('/code_versions', {});
194
202
  * if (result.error) throw new Error(result.error.message);
195
203
  * return result.data;
196
204
  * },
197
205
  * formatOutput: (data) => jsonResult(data),
198
- * }, services);
206
+ * }, loadServices);
199
207
  * ```
200
208
  */
201
- export declare function createToolAdapter<TInput, TOutput>(options: ToolAdapterOptions<TInput, TOutput>, services: Services): McpTool;
209
+ export declare function createToolAdapter<TInput, TOutput>(options: ToolAdapterOptions<TInput, TOutput>, loadServices: () => Services): McpTool;
@@ -8,22 +8,22 @@
8
8
  *
9
9
  * This module provides utilities for creating standardized MCP tools that:
10
10
  * - Validate input using Zod schemas
11
- * - Inject pre-resolved B2CInstance for WebDAV/OCAPI operations (requiresInstance)
12
- * - Inject pre-resolved MRT auth for MRT API operations (requiresMrtAuth)
11
+ * - Inject loaded B2CInstance for WebDAV/OCAPI operations (requiresInstance)
12
+ * - Inject loaded MRT auth for MRT API operations (requiresMrtAuth)
13
13
  * - Format output consistently (textResult, jsonResult, errorResult)
14
14
  *
15
15
  * ## Configuration Resolution
16
16
  *
17
- * Both B2C instance and MRT auth are resolved once at server startup via
18
- * {@link Services.fromResolvedConfig} and reused for all tool calls:
17
+ * Both B2C instance and MRT auth are loaded before each tool call via
18
+ * a loader function that calls {@link Services.fromResolvedConfig}:
19
19
  *
20
- * - **B2CInstance**: Resolved from flags + dw.json. Available when `requiresInstance: true`.
21
- * - **MRT Auth**: Resolved from --api-key → SFCC_MRT_API_KEY → ~/.mobify. Available when `requiresMrtAuth: true`.
20
+ * - **B2CInstance**: Loaded from flags + dw.json on each call. Available when `requiresInstance: true`.
21
+ * - **MRT Auth**: Loaded from --api-key → SFCC_MRT_API_KEY → ~/.mobify on each call. Available when `requiresMrtAuth: true`.
22
22
  *
23
- * This "resolve eagerly at startup" pattern provides:
24
- * - Fail-fast behavior (configuration errors surface at startup)
25
- * - Consistent mental model (both resolved the same way)
26
- * - Better performance (no resolution on each tool call)
23
+ * This "load on each call" pattern provides:
24
+ * - Fresh configuration on each tool invocation (picks up changes to config files)
25
+ * - Consistent mental model (both loaded the same way)
26
+ * - Tools can respond to configuration changes without server restart
27
27
  *
28
28
  * @module tools/adapter
29
29
  *
@@ -47,8 +47,11 @@
47
47
  *
48
48
  * @example MRT tool (MRT API)
49
49
  * ```typescript
50
- * // Services created from already-resolved config at startup
51
- * const services = Services.fromResolvedConfig(this.resolvedConfig);
50
+ * // Loader function that loads config and creates Services on each tool call
51
+ * const loadServices = () => {
52
+ * const config = this.loadConfiguration();
53
+ * return Services.fromResolvedConfig(config);
54
+ * };
52
55
  *
53
56
  * const mrtTool = createToolAdapter({
54
57
  * name: 'mrt_bundle_push',
@@ -58,12 +61,12 @@
58
61
  * inputSchema: {
59
62
  * projectSlug: z.string().describe('MRT project slug'),
60
63
  * },
61
- * execute: async (args, { mrtAuth }) => {
62
- * const result = await pushBundle({ projectSlug: args.projectSlug }, mrtAuth);
64
+ * execute: async (args, { mrtConfig }) => {
65
+ * const result = await pushBundle({ projectSlug: args.projectSlug }, mrtConfig.auth);
63
66
  * return result;
64
67
  * },
65
68
  * formatOutput: (output) => jsonResult(output),
66
- * }, services);
69
+ * }, loadServices);
67
70
  * ```
68
71
  */
69
72
  import { z } from 'zod';
@@ -138,7 +141,7 @@ function formatZodErrors(error) {
138
141
  * @template TInput - The validated input type (inferred from inputSchema)
139
142
  * @template TOutput - The output type from the execute function
140
143
  * @param options - Tool adapter configuration
141
- * @param services - Services instance for dependency injection
144
+ * @param loadServices - Function that loads configuration and returns Services instance
142
145
  * @returns An McpTool ready for registration
143
146
  *
144
147
  * @example
@@ -146,21 +149,26 @@ function formatZodErrors(error) {
146
149
  * import { z } from 'zod';
147
150
  * import { createToolAdapter, jsonResult, errorResult } from './adapter.js';
148
151
  *
152
+ * const loadServices = () => {
153
+ * const config = this.loadConfiguration();
154
+ * return Services.fromResolvedConfig(config);
155
+ * };
156
+ *
149
157
  * const listCodeVersionsTool = createToolAdapter({
150
158
  * name: 'code_version_list',
151
159
  * description: 'List all code versions on the instance',
152
160
  * toolsets: ['CARTRIDGES'],
153
161
  * inputSchema: {},
154
- * execute: async (_args, { instance }) => {
155
- * const result = await instance.ocapi.GET('/code_versions', {});
162
+ * execute: async (_args, { b2cInstance }) => {
163
+ * const result = await b2cInstance.ocapi.GET('/code_versions', {});
156
164
  * if (result.error) throw new Error(result.error.message);
157
165
  * return result.data;
158
166
  * },
159
167
  * formatOutput: (data) => jsonResult(data),
160
- * }, services);
168
+ * }, loadServices);
161
169
  * ```
162
170
  */
163
- export function createToolAdapter(options, services) {
171
+ export function createToolAdapter(options, loadServices) {
164
172
  const { name, description, inputSchema, toolsets, isGA = true, requiresInstance = false, requiresMrtAuth = false, execute, formatOutput, } = options;
165
173
  // Create Zod schema from inputSchema definition
166
174
  const zodSchema = z.object(inputSchema);
@@ -178,7 +186,9 @@ export function createToolAdapter(options, services) {
178
186
  }
179
187
  const args = parseResult.data;
180
188
  try {
181
- // 2. Get B2CInstance if required (pre-resolved at startup)
189
+ // 2. Load Services to get fresh configuration (re-reads config files)
190
+ const services = loadServices();
191
+ // 3. Get B2CInstance if required (loaded on each call)
182
192
  let b2cInstance;
183
193
  if (requiresInstance) {
184
194
  if (!services.b2cInstance) {
@@ -186,7 +196,7 @@ export function createToolAdapter(options, services) {
186
196
  }
187
197
  b2cInstance = services.b2cInstance;
188
198
  }
189
- // 3. Get MRT config if required (pre-resolved at startup)
199
+ // 4. Get MRT config if required (loaded on each call)
190
200
  let mrtConfig;
191
201
  if (requiresMrtAuth) {
192
202
  if (!services.mrtConfig.auth) {
@@ -199,14 +209,14 @@ export function createToolAdapter(options, services) {
199
209
  origin: services.mrtConfig.origin,
200
210
  };
201
211
  }
202
- // 4. Execute the operation
212
+ // 5. Execute the operation
203
213
  const context = {
204
214
  b2cInstance,
205
215
  mrtConfig,
206
216
  services,
207
217
  };
208
218
  const output = await execute(args, context);
209
- // 5. Format output
219
+ // 6. Format output
210
220
  return formatOutput(output);
211
221
  }
212
222
  catch (error) {
@@ -1,6 +1,6 @@
1
1
  import type { McpTool } from '../../utils/index.js';
2
2
  import type { Services } from '../../services.js';
3
- import type { DeployResult, DeployOptions } from '@salesforce/b2c-tooling-sdk/operations/code';
3
+ import type { DeployResult, DeployOptions, CodeVersion } from '@salesforce/b2c-tooling-sdk/operations/code';
4
4
  import type { B2CInstance } from '@salesforce/b2c-tooling-sdk';
5
5
  /**
6
6
  * Optional dependency injections for testing.
@@ -8,13 +8,15 @@ import type { B2CInstance } from '@salesforce/b2c-tooling-sdk';
8
8
  interface CartridgeToolInjections {
9
9
  /** Mock findAndDeployCartridges function for testing */
10
10
  findAndDeployCartridges?: (instance: B2CInstance, directory: string, options: DeployOptions) => Promise<DeployResult>;
11
+ /** Mock getActiveCodeVersion function for testing */
12
+ getActiveCodeVersion?: (instance: B2CInstance) => Promise<CodeVersion | undefined>;
11
13
  }
12
14
  /**
13
15
  * Creates all tools for the CARTRIDGES toolset.
14
16
  *
15
- * @param services - MCP services
17
+ * @param loadServices - Function that loads configuration and returns Services instance
16
18
  * @param injections - Optional dependency injections for testing
17
19
  * @returns Array of MCP tools
18
20
  */
19
- export declare function createCartridgesTools(services: Services, injections?: CartridgeToolInjections): McpTool[];
21
+ export declare function createCartridgesTools(loadServices: () => Services, injections?: CartridgeToolInjections): McpTool[];
20
22
  export {};
@@ -10,9 +10,10 @@
10
10
  *
11
11
  * @module tools/cartridges
12
12
  */
13
+ import path from 'node:path';
13
14
  import { z } from 'zod';
14
15
  import { createToolAdapter, jsonResult } from '../adapter.js';
15
- import { findAndDeployCartridges } from '@salesforce/b2c-tooling-sdk/operations/code';
16
+ import { findAndDeployCartridges, getActiveCodeVersion } from '@salesforce/b2c-tooling-sdk/operations/code';
16
17
  import { getLogger } from '@salesforce/b2c-tooling-sdk/logging';
17
18
  /**
18
19
  * Creates the cartridge_deploy tool.
@@ -23,12 +24,13 @@ import { getLogger } from '@salesforce/b2c-tooling-sdk/logging';
23
24
  * 3. Uploads the zip to WebDAV and triggers server-side unzip
24
25
  * 4. Optionally reloads the code version after deploy
25
26
  *
26
- * @param services - MCP services
27
+ * @param loadServices - Function that loads configuration and returns Services instance
27
28
  * @param injections - Optional dependency injections for testing
28
29
  * @returns The cartridge_deploy tool
29
30
  */
30
- function createCartridgeDeployTool(services, injections) {
31
+ function createCartridgeDeployTool(loadServices, injections) {
31
32
  const findAndDeployCartridgesFn = injections?.findAndDeployCartridges || findAndDeployCartridges;
33
+ const getActiveCodeVersionFn = injections?.getActiveCodeVersion || getActiveCodeVersion;
32
34
  return createToolAdapter({
33
35
  name: 'cartridge_deploy',
34
36
  description: 'Finds and deploys cartridges to a B2C Commerce instance via WebDAV. ' +
@@ -65,37 +67,65 @@ function createCartridgeDeployTool(services, injections) {
65
67
  async execute(args, context) {
66
68
  // Get instance from context (guaranteed by adapter when requiresInstance is true)
67
69
  const instance = context.b2cInstance;
68
- // Default directory to current directory
69
- const directory = args.directory || '.';
70
- // Parse options
71
- const options = {
72
- include: args.cartridges,
73
- exclude: args.exclude,
74
- reload: args.reload,
75
- };
76
- // Log all computed variables before deploying
77
70
  const logger = getLogger();
78
- logger.debug({
79
- directory,
80
- include: options.include,
81
- exclude: options.exclude,
82
- reload: options.reload,
83
- }, '[Cartridges] Deploying cartridges with computed options');
84
- // Deploy cartridges
85
- const result = await findAndDeployCartridgesFn(instance, directory, options);
86
- return result;
71
+ try {
72
+ // If no code version specified, get the active one
73
+ let codeVersion = instance.config.codeVersion;
74
+ if (!codeVersion) {
75
+ logger.debug('No code version specified, getting active version...');
76
+ const active = await getActiveCodeVersionFn(instance);
77
+ if (!active?.id) {
78
+ throw new Error('No code version specified and no active code version found. ' +
79
+ 'Specify a code version using one of: ' +
80
+ '--code-version flag, SFCC_CODE_VERSION environment variable, ' +
81
+ 'or code-version field in dw.json configuration file.');
82
+ }
83
+ codeVersion = active.id;
84
+ instance.config.codeVersion = codeVersion;
85
+ }
86
+ // Resolve directory path: relative paths are resolved relative to working directory, absolute paths are used as-is
87
+ const directory = args.directory
88
+ ? path.isAbsolute(args.directory)
89
+ ? args.directory
90
+ : path.resolve(context.services.getWorkingDirectory(), args.directory)
91
+ : context.services.getWorkingDirectory();
92
+ // Parse options
93
+ const options = {
94
+ include: args.cartridges,
95
+ exclude: args.exclude,
96
+ reload: args.reload,
97
+ };
98
+ // Log all computed variables before deploying
99
+ logger.debug({
100
+ directory,
101
+ codeVersion,
102
+ include: options.include,
103
+ exclude: options.exclude,
104
+ reload: options.reload,
105
+ }, '[Cartridges] Deploying cartridges with computed options');
106
+ // Deploy cartridges
107
+ const result = await findAndDeployCartridgesFn(instance, directory, options);
108
+ return result;
109
+ }
110
+ catch (error) {
111
+ // Handle communication and authentication errors
112
+ const errorMessage = error instanceof Error ? error.message : String(error);
113
+ throw new Error(`Failed to communicate with B2C instance. Check your authentication credentials and network connection. ` +
114
+ `If no code version is specified, ensure the instance is accessible and has an active code version. ` +
115
+ `Original error: ${errorMessage}`);
116
+ }
87
117
  },
88
118
  formatOutput: (output) => jsonResult(output),
89
- }, services);
119
+ }, loadServices);
90
120
  }
91
121
  /**
92
122
  * Creates all tools for the CARTRIDGES toolset.
93
123
  *
94
- * @param services - MCP services
124
+ * @param loadServices - Function that loads configuration and returns Services instance
95
125
  * @param injections - Optional dependency injections for testing
96
126
  * @returns Array of MCP tools
97
127
  */
98
- export function createCartridgesTools(services, injections) {
99
- return [createCartridgeDeployTool(services, injections)];
128
+ export function createCartridgesTools(loadServices, injections) {
129
+ return [createCartridgeDeployTool(loadServices, injections)];
100
130
  }
101
131
  //# sourceMappingURL=index.js.map
@@ -14,4 +14,5 @@ export * from './adapter.js';
14
14
  export * from './cartridges/index.js';
15
15
  export * from './mrt/index.js';
16
16
  export * from './pwav3/index.js';
17
+ export * from './scapi/index.js';
17
18
  export * from './storefrontnext/index.js';
@@ -21,5 +21,6 @@ export * from './adapter.js';
21
21
  export * from './cartridges/index.js';
22
22
  export * from './mrt/index.js';
23
23
  export * from './pwav3/index.js';
24
+ export * from './scapi/index.js';
24
25
  export * from './storefrontnext/index.js';
25
26
  //# sourceMappingURL=index.js.map
@@ -12,9 +12,9 @@ interface MrtToolInjections {
12
12
  /**
13
13
  * Creates all tools for the MRT toolset.
14
14
  *
15
- * @param services - MCP services
15
+ * @param loadServices - Function that loads configuration and returns Services instance
16
16
  * @param injections - Optional dependency injections for testing
17
17
  * @returns Array of MCP tools
18
18
  */
19
- export declare function createMrtTools(services: Services, injections?: MrtToolInjections): McpTool[];
19
+ export declare function createMrtTools(loadServices: () => Services, injections?: MrtToolInjections): McpTool[];
20
20
  export {};
@@ -10,6 +10,7 @@
10
10
  *
11
11
  * @module tools/mrt
12
12
  */
13
+ import path from 'node:path';
13
14
  import { z } from 'zod';
14
15
  import { createToolAdapter, jsonResult } from '../adapter.js';
15
16
  import { pushBundle } from '@salesforce/b2c-tooling-sdk/operations/mrt';
@@ -17,20 +18,20 @@ import { getLogger } from '@salesforce/b2c-tooling-sdk/logging';
17
18
  /**
18
19
  * Creates the mrt_bundle_push tool.
19
20
  *
20
- * Creates a bundle from a pre-built PWA Kit project and pushes it to
21
+ * Creates a bundle from a pre-built PWA Kit or Storefront Next project and pushes it to
21
22
  * Managed Runtime (MRT). Optionally deploys to a target environment after push.
22
23
  * Expects the project to already be built (e.g., `npm run build` completed).
23
24
  * Shared across MRT, PWAV3, and STOREFRONTNEXT toolsets.
24
25
  *
25
- * @param services - MCP services
26
+ * @param loadServices - Function that loads configuration and returns Services instance
26
27
  * @param injections - Optional dependency injections for testing
27
28
  * @returns The mrt_bundle_push tool
28
29
  */
29
- function createMrtBundlePushTool(services, injections) {
30
+ function createMrtBundlePushTool(loadServices, injections) {
30
31
  const pushBundleFn = injections?.pushBundle || pushBundle;
31
32
  return createToolAdapter({
32
33
  name: 'mrt_bundle_push',
33
- description: 'Bundle a pre-built PWA Kit project and push to Managed Runtime. Optionally deploy to a target environment.',
34
+ description: 'Bundle a pre-built PWA Kit or Storefront Next project and push to Managed Runtime. Optionally deploy to a target environment.',
34
35
  toolsets: ['MRT', 'PWAV3', 'STOREFRONTNEXT'],
35
36
  isGA: false,
36
37
  // MRT operations use ApiKeyStrategy from SFCC_MRT_API_KEY or ~/.mobify
@@ -46,6 +47,11 @@ function createMrtBundlePushTool(services, injections) {
46
47
  .string()
47
48
  .optional()
48
49
  .describe('Glob patterns for shared files, comma-separated (default: static/**/*,client/**/*)'),
50
+ deploy: z
51
+ .boolean()
52
+ .optional()
53
+ .default(false)
54
+ .describe('Whether to deploy to an environment after push (default: false)'),
49
55
  },
50
56
  async execute(args, context) {
51
57
  // Get project from --project flag (required)
@@ -54,13 +60,26 @@ function createMrtBundlePushTool(services, injections) {
54
60
  throw new Error('MRT project error: Project is required. Provide --project flag or set SFCC_MRT_PROJECT environment variable.');
55
61
  }
56
62
  // Get environment from --environment flag (optional)
57
- const environment = context.mrtConfig?.environment;
63
+ // When deploy is false, environment is undefined (bundle push only, no deployment)
64
+ // When deploy is true, environment is required
65
+ let environment;
66
+ if (args.deploy) {
67
+ environment = context.mrtConfig?.environment;
68
+ if (!environment) {
69
+ throw new Error('MRT deployment error: Environment is required when deploy=true. ' +
70
+ 'Provide --environment flag, set SFCC_MRT_ENVIRONMENT environment variable, or set mrtEnvironment in dw.json.');
71
+ }
72
+ }
58
73
  // Get origin from --cloud-origin flag or mrtOrigin config (optional)
59
74
  const origin = context.mrtConfig?.origin;
60
75
  // Parse comma-separated glob patterns (same as CLI defaults)
61
76
  const ssrOnly = (args.ssrOnly || 'ssr.js,ssr.mjs,server/**/*').split(',').map((s) => s.trim());
62
77
  const ssrShared = (args.ssrShared || 'static/**/*,client/**/*').split(',').map((s) => s.trim());
63
- const buildDirectory = args.buildDirectory || './build';
78
+ const buildDirectory = args.buildDirectory
79
+ ? path.isAbsolute(args.buildDirectory)
80
+ ? args.buildDirectory
81
+ : path.resolve(context.services.getWorkingDirectory(), args.buildDirectory)
82
+ : path.join(context.services.getWorkingDirectory(), 'build');
64
83
  // Log all computed variables before pushing bundle
65
84
  const logger = getLogger();
66
85
  logger.debug({
@@ -86,16 +105,16 @@ function createMrtBundlePushTool(services, injections) {
86
105
  return result;
87
106
  },
88
107
  formatOutput: (output) => jsonResult(output),
89
- }, services);
108
+ }, loadServices);
90
109
  }
91
110
  /**
92
111
  * Creates all tools for the MRT toolset.
93
112
  *
94
- * @param services - MCP services
113
+ * @param loadServices - Function that loads configuration and returns Services instance
95
114
  * @param injections - Optional dependency injections for testing
96
115
  * @returns Array of MCP tools
97
116
  */
98
- export function createMrtTools(services, injections) {
99
- return [createMrtBundlePushTool(services, injections)];
117
+ export function createMrtTools(loadServices, injections) {
118
+ return [createMrtBundlePushTool(loadServices, injections)];
100
119
  }
101
120
  //# sourceMappingURL=index.js.map