Skip to content

Commit 39bf4a3

Browse files
authored
add page-designer-decorator tool for Storefront Next (#150)
* add page-designer-decorator tool for Storefront Next * Add manual test runner for page-designer-decorator tool- Add automated test runner script (index.test.mjs) with 24 test cases- Support both temporary directory mode (default) and real Storefront Next project mode- Update test documentation with usage instructions for both modes- Update tool README with manual test runner sectionThe test runner covers component discovery, auto mode, interactive mode,error handling, edge cases, and environment variable scenarios. * Remove unused zod-to-json-schema dependency * refactor(b2c-dx-mcp): migrate page-designer-decorator tests from custom runner to Mocha Remove custom test runner (index.test.mjs) and consolidate all test cases into the standard Mocha test suite (index.test.ts) for consistency with the monorepo's test framework. * refactor(mcp): use Services.workingDirectory for component discovery Add workingDirectory property to Services and update page-designer-decorator tool to use it instead of reading process.env.SFCC_WORKING_DIRECTORY directly. This ensures component searches start from the correct project directory when MCP clients spawn servers from the home directory. - Add workingDirectory to Services (resolved from --working-directory flag/env) - Update page-designer-decorator to use services.workingDirectory - Simplify tool description for LLM consumption - Update tests and documentation accordingly * refactor(mcp): rename page designer decorator tool and reorganize docs - Rename tool from to - Remove conflicting placeholder - Reorganize storefrontnext README to scatter tool documentation throughout file - Update all references in code, tests, and documentation This ensures consistent naming with other Storefront Next tools and improves documentation organization by distributing tool details across appropriate sections. * fix(page-designer-decorator): use lazy Services loading and correct API Update createPageDesignerDecoratorTool to accept loadServices function for consistency with other tools. Fix Services API usage to call getWorkingDirectory() method instead of accessing workingDirectory property. Update test mocks to properly construct Services with ResolvedB2CConfig. This fixes build errors and test failures after recent refactoring. * refactor(mcp): add RequestHandlerExtra context parameter to tool handlers Update tool handler signatures to match MCP SDK's expected format by accepting RequestHandlerExtra context parameter. Context is currently unused but available for future protocol-level features. * Updated the lockfile * fix: update test handlers to include context parameter Update all test files to pass the new context parameter to tool.handler() calls. The handler signature was updated to accept a second parameter (RequestHandlerExtra) for MCP context, but tests were still calling handlers with a single argument. Changes: - Add {} as any as second argument to all tool.handler() calls in tests - Add eslint-disable comments for @typescript-eslint/no-explicit-any - Fix prettier formatting issues - Remove duplicate variable declaration in developer-guidelines test - Fix no-await-in-loop lint errors with proper disable comments * Revert the handler signature change * Add missing dependency * Revert build dependencies changes * Additional revert for the workspace file
1 parent e5f59a2 commit 39bf4a3

21 files changed

+4098
-16
lines changed

packages/b2c-dx-mcp/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ Storefront Next development tools for building modern storefronts.
312312
| `storefront_next_figma_to_component_workflow` | Convert Figma designs to Storefront Next components |
313313
| `storefront_next_generate_component` | Generate a new Storefront Next component |
314314
| `storefront_next_map_tokens_to_theme` | Map design tokens to Storefront Next theme configuration |
315-
| `storefront_next_design_decorator` | Apply design decorators to Storefront Next components |
315+
| `storefront_next_page_designer_decorator` | Add Page Designer decorators to Storefront Next components |
316316
| `storefront_next_generate_page_designer_metadata` | Generate Page Designer metadata for Storefront Next components |
317317
| `scapi_schemas_list` | List or fetch SCAPI schemas (standard and custom). Use apiFamily: "custom" for custom APIs. |
318318
| `scapi_custom_apis_status` | Get registration status of custom API endpoints (active/not_registered). Remote only, requires OAuth. |
@@ -415,7 +415,7 @@ npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools --me
415415
# Call a specific tool
416416
npx mcp-inspector --cli node bin/dev.js --toolsets all --allow-non-ga-tools \
417417
--method tools/call \
418-
--tool-name storefront_next_design_decorator
418+
--tool-name storefront_next_page_designer_decorator
419419
```
420420

421421
#### 2. IDE Integration

packages/b2c-dx-mcp/content/page-designer.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ To add a new content page: define a page type and ID in Commerce Cloud, then in
3535

3636
- **Add a metadata class** with `@Component('typeId', { name, description })` and `@AttributeDefinition()` (and optionally `@AttributeDefinition({ type: 'image' })`, `type: 'url'`, etc.) for each prop you want editable in Page Designer. Use `@RegionDefinition([...])` if the component has nested regions (e.g. a grid with slots).
3737
- **Implement the React component** so it accepts those props (and strips Page Designer–only props like `component`, `page`, `componentData`, `designMetadata` before spreading to the DOM). If the component needs server data (e.g. products for a carousel), export a `loader({ componentData, context })` and optionally a `fallback` component; the registry calls the loader during `collectComponentDataPromises` and passes resolved data as the `data` prop.
38-
- **Use the MCP tool `storefront_next_design_decorator`** to generate decorators instead of writing them by hand. Example components: `components/hero/index.tsx`, `components/content-card/index.tsx`, `components/product-carousel/index.tsx`.
38+
- **Use the MCP tool `storefront_next_page_designer_decorator`** to generate decorators instead of writing them by hand. Example components: `components/hero/index.tsx`, `components/content-card/index.tsx`, `components/product-carousel/index.tsx`.
3939

4040
### After changes
4141

@@ -50,7 +50,7 @@ To add a new content page: define a page type and ID in Commerce Cloud, then in
5050

5151
Use the **B2C DX MCP server** for Page Designer work instead of hand-writing decorators and metadata. Configure the B2C DX MCP server in your IDE (e.g. in MCP settings) so these tools are available.
5252

53-
### 1. `storefront_next_design_decorator` (STOREFRONTNEXT toolset)
53+
### 1. `storefront_next_page_designer_decorator` (STOREFRONTNEXT toolset)
5454

5555
Adds Page Designer decorators to an existing React component so it can be used in Business Manager. The tool analyzes the component, picks suitable props, infers types (e.g. `*Url`/`*Link` → url, `*Image` → image, `is*`/`show*` → boolean), and generates `@Component('typeId', { name, description })`, `@AttributeDefinition()` on a metadata class, and optionally `@RegionDefinition([...])` for nested regions. It skips complex or UI-only props (e.g. className, style, callbacks).
5656

@@ -71,7 +71,7 @@ Packages the cartridge, uploads it to Commerce Cloud via WebDAV, and unpacks it
7171

7272
### Typical workflow
7373

74-
1. **`storefront_next_design_decorator`** — Add decorators to the component (use autoMode for a quick first pass).
74+
1. **`storefront_next_page_designer_decorator`** — Add decorators to the component (use autoMode for a quick first pass).
7575
2. **`storefront_next_generate_page_designer_metadata`** — Generate metadata JSON so the component and regions appear in Page Designer.
7676
3. **`cartridge_deploy`** — Deploy to Commerce Cloud so merchants can use the component in Business Manager.
7777

@@ -81,6 +81,6 @@ Packages the cartridge, uploads it to Commerce Cloud via WebDAV, and unpacks it
8181
2. **Use registry for components**: Register all Page Designer components with proper `typeId`
8282
3. **Handle design mode**: Adapt UI when `pageDesignerMode` is `'EDIT'` or `'PREVIEW'`
8383
4. **Rebuild after registry changes**: Static registry is generated at build time
84-
5. **Use MCP tools**: Leverage `storefront_next_design_decorator` and `storefront_next_generate_page_designer_metadata` for faster development
84+
5. **Use MCP tools**: Leverage `storefront_next_page_designer_decorator` and `storefront_next_generate_page_designer_metadata` for faster development
8585

8686
**Reference:** See README.md for complete Page Designer documentation and MCP tool setup.

packages/b2c-dx-mcp/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@
9696
"@modelcontextprotocol/sdk": "1.26.0",
9797
"@oclif/core": "catalog:",
9898
"@salesforce/b2c-tooling-sdk": "workspace:*",
99+
"glob": "catalog:",
100+
"ts-morph": "^27.0.0",
99101
"yaml": "2.8.1",
100102
"zod": "3.25.76"
101103
},
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
# Page Designer Decorator Tool
2+
3+
Tool for adding Page Designer decorators to React components using native TypeScript template literals.
4+
5+
## 🎯 Overview
6+
7+
This tool analyzes React components and generates Page Designer decorators (`@Component`, `@AttributeDefinition`, `@RegionDefinition`) to make components available in Page Designer for Storefront Next.
8+
9+
## ✨ Key Features
10+
11+
- **Name-Based Lookup**: Find components by name (e.g., "ProductCard") without knowing paths
12+
- **Auto-Discovery**: Automatically searches common component directories
13+
- **Type-Safe**: Full TypeScript type inference for all contexts
14+
- **Fast**: Direct function execution, no file I/O or compilation overhead
15+
- **Flexible Input**: Supports component names or file paths
16+
- **Two Modes**: Auto mode for quick setup, Interactive mode for fine-tuned control
17+
18+
## 📁 File Structure
19+
20+
```
21+
page-designer-decorator/
22+
├── analyzer.ts # Component parsing and analysis
23+
├── rules.ts # Rule loader and exports
24+
├── index.ts # Main tool implementation
25+
├── rules/
26+
│ ├── 1-mode-selection.ts # Entry point
27+
│ ├── 2a-auto-mode.ts # Auto mode workflow
28+
│ ├── 2b-0-interactive-overview.ts # Interactive workflow overview
29+
│ ├── 2b-1-interactive-analyze.ts # Step 1: Analysis
30+
│ ├── 2b-2-interactive-select-props.ts # Step 2: Selection
31+
│ ├── 2b-3-interactive-configure-attrs.ts # Step 3: Configuration
32+
│ ├── 2b-4-interactive-configure-regions.ts # Step 4: Regions
33+
│ └── 2b-5-interactive-confirm-generation.ts # Step 5: Generation
34+
└── templates/
35+
└── decorator-generator.ts # Decorator code generation
36+
```
37+
38+
## 🚀 Usage
39+
40+
### Basic Usage (Name-Based - Recommended)
41+
42+
```bash
43+
# By component name (automatically finds the file)
44+
storefront_next_page_designer_decorator({
45+
component: "ProductCard",
46+
autoMode: true
47+
})
48+
49+
# Interactive mode
50+
storefront_next_page_designer_decorator({
51+
component: "Hero",
52+
conversationContext: { step: "analyze" }
53+
})
54+
55+
# With custom search paths (for unusual locations)
56+
storefront_next_page_designer_decorator({
57+
component: "ProductCard",
58+
searchPaths: ["packages/retail/src", "app/features"],
59+
autoMode: true
60+
})
61+
```
62+
63+
### Path-Based Usage
64+
65+
```bash
66+
# If you prefer to specify the exact path
67+
storefront_next_page_designer_decorator({
68+
component: "src/components/ProductCard.tsx",
69+
autoMode: true
70+
})
71+
```
72+
73+
### Workflow
74+
75+
1. **Component Discovery**: Provide name (e.g., "ProductCard") or path
76+
2. **Mode Selection**: Choose Auto or Interactive mode
77+
3. **Analysis** (Interactive only): Review component props
78+
4. **Selection** (Interactive only): Select which props to expose
79+
5. **Configuration** (Interactive only): Configure types and defaults
80+
6. **Regions** (Interactive only): Configure nested content areas
81+
7. **Generation**: Get decorator code
82+
83+
### Component Discovery
84+
85+
The tool automatically searches for components in these locations (in order):
86+
87+
1. `src/components/**` (PascalCase and kebab-case)
88+
2. `app/components/**`
89+
3. `components/**`
90+
4. `src/**` (broader search)
91+
5. Custom paths (if provided via `searchPaths`)
92+
93+
**Working Directory:**
94+
Component discovery uses the working directory resolved from `--working-directory` flag or `SFCC_WORKING_DIRECTORY` environment variable (via Services). This ensures searches start from the correct project directory, especially when MCP clients spawn servers from the home directory.
95+
96+
**Examples:**
97+
98+
- `"ProductCard"` → finds `src/components/product-tile/ProductCard.tsx`
99+
- `"Hero"` → finds `src/components/hero/Hero.tsx` or `app/components/hero.tsx`
100+
- `"product-card"` → finds `src/components/product-card.tsx` or `product-card/index.tsx`
101+
102+
**Tips:**
103+
104+
- Use component name for portability
105+
- Use path for unusual locations
106+
- Add `searchPaths` for monorepos or non-standard structures
107+
- Ensure `--working-directory` flag or `SFCC_WORKING_DIRECTORY` env var is set correctly
108+
109+
## 🏗️ Architecture
110+
111+
### Rule Rendering
112+
113+
Rules are pure TypeScript functions that return strings:
114+
115+
```typescript
116+
${context.hasEditableProps
117+
? context.editableProps.map(prop =>
118+
`- \`${prop.name}\` (${prop.type})`
119+
).join('\n')
120+
: ''
121+
}
122+
```
123+
124+
### Type Safety
125+
126+
Every rule has a strongly-typed context interface:
127+
128+
```typescript
129+
export interface AnalyzeStepContext {
130+
componentName: string;
131+
file: string;
132+
hasEditableProps: boolean;
133+
editableProps: PropInfo[];
134+
// ... more fields
135+
}
136+
137+
export function renderAnalyzeStep(context: AnalyzeStepContext): string {
138+
// TypeScript checks all variable access at compile time
139+
}
140+
```
141+
142+
### Template Generation
143+
144+
Code generation uses pure functions:
145+
146+
```typescript
147+
export function generateDecoratorCode(context: MetadataContext): string {
148+
const imports = generateImports(context);
149+
const decorator = generateComponentDecorator(context);
150+
const attributes = generateAttributes(context);
151+
152+
return `${imports}${decorator}\nexport class ${context.metadataClassName} {\n${attributes}\n}`;
153+
}
154+
```
155+
156+
## 📦 Build Process
157+
158+
All rules and templates are compiled into the JavaScript output:
159+
160+
```json
161+
{
162+
"scripts": {
163+
"build": "tsc"
164+
}
165+
}
166+
```
167+
168+
## 🎯 When to Use This Tool
169+
170+
Use this tool when:
171+
172+
- ✅ You need to add Page Designer support to React components
173+
- ✅ You want automatic component discovery by name
174+
- ✅ You prefer type-safe decorator generation
175+
- ✅ You need both quick auto-mode and detailed interactive workflows
176+
177+
## 🔧 Development
178+
179+
### Adding a New Rule
180+
181+
1. Create a new file in `rules/`:
182+
183+
```typescript
184+
// rules/my-new-rule.ts
185+
export interface MyRuleContext {
186+
message: string;
187+
}
188+
189+
export function renderMyRule(context: MyRuleContext): string {
190+
return `# My Rule\n\n${context.message}`;
191+
}
192+
```
193+
194+
2. Export it from `rules.ts`:
195+
196+
```typescript
197+
import {renderMyRule, type MyRuleContext} from './rules/my-new-rule.js';
198+
199+
export const pageDesignerDecoratorRules = {
200+
// ... existing rules
201+
getMyRule(context: MyRuleContext): string {
202+
return renderMyRule(context);
203+
},
204+
};
205+
```
206+
207+
3. Use it in `index.ts`:
208+
209+
```typescript
210+
const instructions = pageDesignerDecoratorRules.getMyRule({
211+
message: 'Hello World',
212+
});
213+
```
214+
215+
### Modifying Code Generation
216+
217+
Edit `templates/decorator-generator.ts` directly. Changes require recompilation.
218+
219+
## 📊 Performance
220+
221+
The tool uses direct function execution with no file I/O or compilation overhead. Typical tool invocations complete in under 1ms.
222+
223+
## ✅ Testing
224+
225+
### Automated Tests
226+
227+
```bash
228+
pnpm build
229+
pnpm test
230+
```
231+
232+
Comprehensive test suite covers all workflow modes, component discovery, and error handling.
233+
234+
### Running Tests
235+
236+
Run the comprehensive Mocha test suite:
237+
238+
```bash
239+
cd packages/b2c-dx-mcp
240+
pnpm run test:agent -- test/tools/page-designer-decorator/index.test.ts
241+
```
242+
243+
The test suite covers:
244+
- Component discovery (name-based, kebab-case, nested, path-based, custom paths, name collisions)
245+
- Auto mode (basic, type inference, complex props exclusion, UI-only props exclusion, edge cases)
246+
- Interactive mode (all steps: analyze, select_props, configure_attrs, configure_regions, confirm_generation)
247+
- Error handling (invalid input, invalid step name, missing parameters)
248+
- Edge cases (no props, only complex props, optional props, union types, already decorated components)
249+
- Working directory resolution (from --working-directory flag or SFCC_WORKING_DIRECTORY env var via Services)
250+
251+
See [`test/tools/page-designer-decorator/README.md`](../../../test/tools/page-designer-decorator/README.md) for detailed testing instructions.
252+
253+
## 🎓 Learning Resources
254+
255+
- [Template Literals (MDN)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
256+
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
257+
- [MCP Tools Documentation](https://modelcontextprotocol.io/docs)
258+
259+
## 📝 License
260+
261+
Apache-2.0 - Copyright (c) 2025, Salesforce, Inc.

0 commit comments

Comments
 (0)