Skip to content

Commit 6eba028

Browse files
authored
@W-21435068 Add post action reminder for cartridge deploy mcp tool (#233)
1 parent 6214103 commit 6eba028

3 files changed

Lines changed: 46 additions & 8 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@salesforce/b2c-dx-mcp': patch
3+
---
4+
5+
cartridge_deploy now reminds users to update the site cartridge path in Business Manager (Sites → Manage Sites → [site] → Settings tab → Cartridges) after deploy.

packages/b2c-dx-mcp/src/tools/cartridges/index.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ import type {DeployResult, DeployOptions, CodeVersion} from '@salesforce/b2c-too
2121
import type {B2CInstance} from '@salesforce/b2c-tooling-sdk';
2222
import {getLogger} from '@salesforce/b2c-tooling-sdk/logging';
2323

24+
/** Reminder shown after deploy so users add cartridges to the site cartridge path. */
25+
const CARTRIDGE_PATH_REMINDER =
26+
"If this is a new or updated cartridge, add it to your site's cartridge path in Business Manager: " +
27+
'Sites → Manage Sites → [your site] → Settings tab → Cartridges field.';
28+
2429
/**
2530
* Input type for cartridge_deploy tool.
2631
*/
@@ -35,6 +40,12 @@ interface CartridgeDeployInput {
3540
reload?: boolean;
3641
}
3742

43+
/** Output type: deploy result plus reminder to update site cartridge path. */
44+
interface CartridgeDeployOutput extends DeployResult {
45+
/** Reminder to add deployed cartridges to the site cartridge path in Business Manager. */
46+
postInstructions?: string;
47+
}
48+
3849
/**
3950
* Optional dependency injections for testing.
4051
*/
@@ -61,15 +72,16 @@ interface CartridgeToolInjections {
6172
function createCartridgeDeployTool(loadServices: () => Services, injections?: CartridgeToolInjections): McpTool {
6273
const findAndDeployCartridgesFn = injections?.findAndDeployCartridges || findAndDeployCartridges;
6374
const getActiveCodeVersionFn = injections?.getActiveCodeVersion || getActiveCodeVersion;
64-
return createToolAdapter<CartridgeDeployInput, DeployResult>(
75+
return createToolAdapter<CartridgeDeployInput, CartridgeDeployOutput>(
6576
{
6677
name: 'cartridge_deploy',
6778
description:
6879
'Finds and deploys cartridges to a B2C Commerce instance via WebDAV. ' +
6980
'Searches the directory for cartridges (by .project files), applies include/exclude filters, ' +
7081
'creates a zip archive, uploads via WebDAV, and optionally reloads the code version. ' +
7182
'Use this tool to deploy custom code cartridges for SFRA or other B2C Commerce code. ' +
72-
'Requires the instance to have a code version configured.',
83+
'Requires the instance to have a code version configured. ' +
84+
"After deploy, add new cartridges to your site's cartridge path in Business Manager: Sites → Manage Sites → [site] → Settings tab → Cartridges.",
7385
toolsets: ['CARTRIDGES'],
7486
isGA: false,
7587
requiresInstance: true,
@@ -152,7 +164,10 @@ function createCartridgeDeployTool(loadServices: () => Services, injections?: Ca
152164
// Deploy cartridges
153165
const result = await findAndDeployCartridgesFn(instance, directory, options);
154166

155-
return result;
167+
return {
168+
...result,
169+
postInstructions: CARTRIDGE_PATH_REMINDER,
170+
};
156171
} catch (error) {
157172
// Handle communication and authentication errors
158173
const errorMessage = error instanceof Error ? error.message : String(error);

packages/b2c-dx-mcp/test/tools/cartridges/index.test.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ import type {B2CInstance} from '@salesforce/b2c-tooling-sdk';
1515
import type {DeployResult, DeployOptions, CodeVersion} from '@salesforce/b2c-tooling-sdk/operations/code';
1616
import type {WebDavClient, OcapiClient} from '@salesforce/b2c-tooling-sdk/clients';
1717

18+
/** Tool output: DeployResult plus postInstructions reminder. */
19+
interface CartridgeDeployOutput extends DeployResult {
20+
postInstructions?: string;
21+
}
22+
1823
/**
1924
* Helper to extract text from a ToolResult.
2025
* Throws if the first content item is not a text type.
@@ -117,6 +122,9 @@ describe('tools/cartridges', () => {
117122
expect(desc).to.include('Finds and deploys cartridges');
118123
expect(desc).to.include('B2C Commerce');
119124
expect(desc).to.include('WebDAV');
125+
expect(desc).to.include('Sites → Manage Sites');
126+
expect(desc).to.include('Settings tab');
127+
expect(desc).to.include('Cartridges');
120128
});
121129

122130
it('should be in CARTRIDGES toolset', () => {
@@ -166,9 +174,12 @@ describe('tools/cartridges', () => {
166174
expect(options.include).to.be.undefined;
167175
expect(options.exclude).to.be.undefined;
168176
expect(options.reload).to.be.undefined;
169-
const jsonResult = getResultJson<DeployResult>(result);
177+
const jsonResult = getResultJson<CartridgeDeployOutput>(result);
170178
expect(jsonResult.codeVersion).to.equal('v1');
171179
expect(jsonResult.cartridges).to.have.lengthOf(1);
180+
expect(jsonResult.postInstructions).to.be.a('string');
181+
expect(jsonResult.postInstructions).to.include('Sites → Manage Sites');
182+
expect(jsonResult.postInstructions).to.include('Cartridges field');
172183
});
173184

174185
it('should call findAndDeployCartridges with custom directory', async () => {
@@ -196,8 +207,9 @@ describe('tools/cartridges', () => {
196207
expect(findAndDeployCartridgesStub.calledOnce).to.be.true;
197208
const [, dir] = findAndDeployCartridgesStub.firstCall.args as [B2CInstance, string, DeployOptions];
198209
expect(dir).to.equal(expectedResolvedPath);
199-
const jsonResult = getResultJson<DeployResult>(result);
210+
const jsonResult = getResultJson<CartridgeDeployOutput>(result);
200211
expect(jsonResult.codeVersion).to.equal('v2');
212+
expect(jsonResult.postInstructions).to.include("site's cartridge path");
201213
});
202214

203215
it('should pass cartridges array as include option', async () => {
@@ -313,7 +325,7 @@ describe('tools/cartridges', () => {
313325
expect(options.reload).to.equal(reload);
314326
});
315327

316-
it('should return DeployResult as JSON', async () => {
328+
it('should return DeployResult with postInstructions as JSON', async () => {
317329
const mockResult: DeployResult = {
318330
cartridges: [
319331
{name: 'app_storefront_base', src: '/path/to/app', dest: 'app_storefront_base'},
@@ -334,12 +346,17 @@ describe('tools/cartridges', () => {
334346
const result = await tool.handler({});
335347

336348
expect(result.isError).to.be.undefined;
337-
const jsonResult = getResultJson<DeployResult>(result);
349+
const jsonResult = getResultJson<CartridgeDeployOutput>(result);
338350
expect(jsonResult.codeVersion).to.equal('v1.2.3');
339351
expect(jsonResult.cartridges).to.have.lengthOf(2);
340352
expect(jsonResult.reloaded).to.be.true;
341353
expect(jsonResult.cartridges[0].name).to.equal('app_storefront_base');
342354
expect(jsonResult.cartridges[1].name).to.equal('app_core');
355+
expect(jsonResult.postInstructions).to.be.a('string');
356+
expect(jsonResult.postInstructions).to.include('Business Manager');
357+
expect(jsonResult.postInstructions).to.include('Sites → Manage Sites');
358+
expect(jsonResult.postInstructions).to.include('Settings tab');
359+
expect(jsonResult.postInstructions).to.include('Cartridges field');
343360
});
344361

345362
it('should resolve relative directory paths relative to project directory', async () => {
@@ -485,8 +502,9 @@ describe('tools/cartridges', () => {
485502
expect(getActiveCodeVersionStub.calledWith(mockInstance)).to.be.true;
486503
expect(mockInstance.config.codeVersion).to.equal('v2');
487504
expect(findAndDeployCartridgesStub.calledOnce).to.be.true;
488-
const jsonResult = getResultJson<DeployResult>(result);
505+
const jsonResult = getResultJson<CartridgeDeployOutput>(result);
489506
expect(jsonResult.codeVersion).to.equal('v2');
507+
expect(jsonResult.postInstructions).to.be.a('string');
490508
});
491509

492510
it('should use existing codeVersion when already specified', async () => {

0 commit comments

Comments
 (0)