Skip to content

Commit 241215c

Browse files
committed
Fixed component matching for the page designer decorator tool
1 parent be0106c commit 241215c

File tree

5 files changed

+79
-29
lines changed

5 files changed

+79
-29
lines changed

docs/mcp/tools/storefront-next-page-designer-decorator.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The `storefront_next_page_designer_decorator` tool analyzes React components and
1313
1. **Auto Mode**: Quick setup with sensible defaults-automatically selects suitable props, infers types, and generates decorators immediately.
1414
2. **Interactive Mode**: Multi-step workflow for fine-tuned control over decorator configuration.
1515

16-
The tool uses component discovery to find components by name (e.g., "ProductCard") without requiring exact file paths, making it easy to add Page Designer support to existing components.
16+
The tool uses component discovery to find components by name (e.g., "ProductItem", "ProductTile") without requiring exact file paths, making it easy to add Page Designer support to existing components.
1717

1818
## Authentication
1919

@@ -27,7 +27,7 @@ No authentication required. This tool operates on local files only.
2727

2828
| Parameter | Type | Required | Description |
2929
|-----------|------|----------|-------------|
30-
| `component` | string | Yes | Component name (for example, `"ProductCard"`, `"Hero"`) or file path (for example, `"src/components/ProductCard.tsx"`). When a name is provided, the tool automatically searches common component directories. |
30+
| `component` | string | Yes | Component name (for example, `"ProductItem"`, `"ProductTile"`) or file path (for example, `"src/components/ProductItem.tsx"`). When a name is provided, the tool automatically searches common component directories. |
3131
| `searchPaths` | string[] | No | Additional directories to search for components (for example, `["packages/retail/src", "app/features"]`). Only used when a component is specified by name (not path). |
3232
| `autoMode` | boolean | No | Auto-generate all configurations with sensible defaults (skip interactive workflow). When enabled, automatically selects suitable props, infers types, and generates decorators without user confirmation. |
3333
| `componentId` | string | No | Override component ID (default: auto-generated from component name). |
@@ -60,14 +60,14 @@ Auto mode generates decorators immediately with sensible defaults:
6060
**Usage:**
6161

6262
```
63-
Use the MCP tool to add Page Designer decorators to my ProductCard component with auto mode.
63+
Use the MCP tool to add Page Designer decorators to my ProductItem component with auto mode.
6464
```
6565

6666
**Example:**
6767

6868
```json
6969
{
70-
"component": "ProductCard",
70+
"component": "ProductItem",
7171
"autoMode": true
7272
}
7373
```
@@ -85,14 +85,14 @@ Interactive mode provides a multi-step workflow for fine-tuned control:
8585
**Usage:**
8686

8787
```
88-
Use the MCP tool to add Page Designer decorators to my Hero component interactively.
88+
Use the MCP tool to add Page Designer decorators to my ProductTile component interactively.
8989
```
9090

9191
**Example:**
9292

9393
```json
9494
{
95-
"component": "Hero",
95+
"component": "ProductTile",
9696
"conversationContext": {
9797
"step": "analyze"
9898
}
@@ -110,13 +110,13 @@ The tool automatically searches for components in these locations (in order):
110110
5. Custom paths (if provided via `searchPaths`)
111111

112112
**Project Directory:**
113-
Component discovery uses the project directory resolved from `--project-directory` flag or `SFCC_PROJECT_DIRECTORY` environment variable. This ensures searches start from the correct project directory, especially when MCP clients spawn servers from the home directory.
113+
Component discovery uses the project directory from `--project-directory` flag or `SFCC_PROJECT_DIRECTORY` environment variable. This ensures searches start from the correct project directory, especially when MCP clients spawn servers from the home directory.
114114

115115
**Examples:**
116116

117-
- `"ProductCard"` → finds `src/components/product-tile/ProductCard.tsx`
118-
- `"Hero"` → finds `src/components/hero/Hero.tsx` or `app/components/hero.tsx`
119-
- `"product-card"` → finds `src/components/product-card.tsx` or `product-card/index.tsx`
117+
- `"ProductItem"` → finds `src/components/product-item/index.tsx` or `ProductItem.tsx`
118+
- `"ProductTile"` → finds `src/components/product-tile/ProductTile.tsx` or `product-tile/index.tsx`
119+
- `"product-item"` → finds `src/components/product-item.tsx` or `product-item/index.tsx`
120120

121121
**Tips:**
122122

@@ -132,31 +132,31 @@ Component discovery uses the project directory resolved from `--project-director
132132
Add Page Designer support with auto-generated defaults:
133133

134134
```
135-
Use the MCP tool to add Page Designer decorators to my ProductCard component.
135+
Use the MCP tool to add Page Designer decorators to my ProductItem component.
136136
```
137137

138138
### Auto Mode with Custom Search Paths
139139

140140
Search in custom directories:
141141

142142
```
143-
Use the MCP tool to add Page Designer decorators to ProductCard, searching in packages/retail/src and app/features.
143+
Use the MCP tool to add Page Designer decorators to ProductItem, searching in packages/retail/src and app/features.
144144
```
145145

146146
### Interactive Mode - Start Analysis
147147

148148
Begin interactive workflow:
149149

150150
```
151-
Use the MCP tool to analyze my Hero component for Page Designer decorators.
151+
Use the MCP tool to analyze my ProductTile component for Page Designer decorators.
152152
```
153153

154154
### Path-Based Usage
155155

156156
Specify exact component path:
157157

158158
```
159-
Use the MCP tool to add Page Designer decorators to src/components/ProductCard.tsx with auto mode.
159+
Use the MCP tool to add Page Designer decorators to src/components/ProductItem.tsx with auto mode.
160160
```
161161

162162
## Output
@@ -174,12 +174,12 @@ The tool returns generated decorator code that includes:
174174
import { Component, AttributeDefinition, RegionDefinition } from '@salesforce/page-designer';
175175

176176
@Component({
177-
id: 'product-card',
178-
name: 'Product Card',
177+
id: 'product-item',
178+
name: 'Product Item',
179179
description: 'Displays product information',
180180
group: 'Commerce'
181181
})
182-
export class ProductCardMetadata {
182+
export class ProductItemMetadata {
183183
@AttributeDefinition({
184184
id: 'product-id',
185185
name: 'Product ID',

packages/b2c-dx-mcp/src/tools/storefrontnext/page-designer-decorator/README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This tool analyzes React components and generates Page Designer decorators (`@Co
88

99
## ✨ Key Features
1010

11-
- **Name-Based Lookup**: Find components by name (e.g., "ProductCard") without knowing paths
11+
- **Name-Based Lookup**: Find components by name (e.g., "ProductItem", "ProductTile") without knowing paths
1212
- **Auto-Discovery**: Automatically searches common component directories
1313
- **Type-Safe**: Full TypeScript type inference for all contexts
1414
- **Fast**: Direct function execution, no file I/O or compilation overhead
@@ -42,19 +42,19 @@ page-designer-decorator/
4242
```bash
4343
# By component name (automatically finds the file)
4444
storefront_next_page_designer_decorator({
45-
component: "ProductCard",
45+
component: "ProductItem",
4646
autoMode: true
4747
})
4848

4949
# Interactive mode
5050
storefront_next_page_designer_decorator({
51-
component: "Hero",
51+
component: "ProductTile",
5252
conversationContext: { step: "analyze" }
5353
})
5454

5555
# With custom search paths (for unusual locations)
5656
storefront_next_page_designer_decorator({
57-
component: "ProductCard",
57+
component: "ProductItem",
5858
searchPaths: ["packages/retail/src", "app/features"],
5959
autoMode: true
6060
})
@@ -65,14 +65,14 @@ storefront_next_page_designer_decorator({
6565
```bash
6666
# If you prefer to specify the exact path
6767
storefront_next_page_designer_decorator({
68-
component: "src/components/ProductCard.tsx",
68+
component: "src/components/ProductItem.tsx",
6969
autoMode: true
7070
})
7171
```
7272

7373
### Workflow
7474

75-
1. **Component Discovery**: Provide name (e.g., "ProductCard") or path
75+
1. **Component Discovery**: Provide name (e.g., "ProductItem") or path
7676
2. **Mode Selection**: Choose Auto or Interactive mode
7777
3. **Analysis** (Interactive only): Review component props
7878
4. **Selection** (Interactive only): Select which props to expose
@@ -91,13 +91,13 @@ The tool automatically searches for components in these locations (in order):
9191
5. Custom paths (if provided via `searchPaths`)
9292

9393
**Project Directory:**
94-
Component discovery uses the project directory resolved from `--project-directory` flag or `SFCC_PROJECT_DIRECTORY` environment variable (via Services). This ensures searches start from the correct project directory, especially when MCP clients spawn servers from the home directory.
94+
Component discovery uses the project directory from `--project-directory` flag or `SFCC_PROJECT_DIRECTORY` environment variable (via Services). This ensures searches start from the correct project directory, especially when MCP clients spawn servers from the home directory.
9595

9696
**Examples:**
9797

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`
98+
- `"ProductItem"` → finds `src/components/product-item/index.tsx` or `ProductItem.tsx`
99+
- `"ProductTile"` → finds `src/components/product-tile/ProductTile.tsx` or `product-tile/index.tsx`
100+
- `"product-item"` → finds `src/components/product-item.tsx` or `product-item/index.tsx`
101101

102102
**Tips:**
103103

packages/b2c-dx-mcp/src/tools/storefrontnext/page-designer-decorator/analyzer.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,29 @@ export function generateTypeSuggestions(propName: string, tsType: string): TypeS
290290

291291
/**
292292
* Extract component name from file content
293+
*
294+
* Priority order:
295+
* 1. export default function X (inline default function)
296+
* 2. export default X (default export of named identifier, e.g. export default ProductItem)
297+
* 3. export function X (first named function export)
298+
* 4. export const X =
299+
* 5. fallback: 'Component'
300+
*
301+
* Note: (2) must be checked before (3) because files may have both "export function Foo"
302+
* and "export default Bar" — the default export is the primary component.
293303
*/
294304
function extractComponentName(content: string): string {
295305
const defaultFunctionMatch = content.match(/export\s+default\s+function\s+(\w+)/);
296306
if (defaultFunctionMatch) {
297307
return defaultFunctionMatch[1];
298308
}
299309

310+
// export default X where X is a named identifier (not "function")
311+
const defaultNamedMatch = content.match(/export\s+default\s+(?!function\s)(\w+)/);
312+
if (defaultNamedMatch) {
313+
return defaultNamedMatch[1];
314+
}
315+
300316
const namedFunctionMatch = content.match(/export\s+function\s+(\w+)/);
301317
if (namedFunctionMatch) {
302318
return namedFunctionMatch[1];

packages/b2c-dx-mcp/src/tools/storefrontnext/page-designer-decorator/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const pageDesignerDecoratorSchema = z
2020
component: z
2121
.string()
2222
.describe(
23-
'Component name (e.g., "ProductCard", "Hero") or file path (e.g., "src/components/ProductCard.tsx"). ' +
23+
'Component name (e.g., "ProductItem", "ProductTile") or file path (e.g., "src/components/ProductItem.tsx"). ' +
2424
'When a name is provided, the tool automatically searches common component directories. ' +
2525
'For backward compatibility, file paths are also supported.',
2626
),
@@ -634,7 +634,7 @@ export function createPageDesignerDecoratorTool(loadServices: () => Services): M
634634
description:
635635
'Adds Page Designer decorators (@Component, @AttributeDefinition, @RegionDefinition) to React components. ' +
636636
'Two modes: autoMode=true for quick setup with defaults, or interactive mode via conversationContext.step. ' +
637-
'Component discovery uses projectDirectory from flags/env. ' +
637+
'Component discovery uses --project-directory flag or SFCC_PROJECT_DIRECTORY env var. ' +
638638
'Auto mode: selects suitable props, infers types, generates code immediately. ' +
639639
'Interactive mode: multi-step workflow (analyze → select_props → configure_attrs → configure_regions → confirm_generation).',
640640

packages/b2c-dx-mcp/test/tools/storefrontnext/page-designer-decorator/index.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,40 @@ export default function CollisionComponent({title}: CollisionComponentProps) { r
12931293
const text = getResultText(result);
12941294
expect(text).to.include('CollisionComponent');
12951295
});
1296+
1297+
it('should pick default export over first named export (export default X pattern)', async () => {
1298+
const tool = createPageDesignerDecoratorTool(getServices);
1299+
// Simulate product-item/index.tsx: has export function X (helper) and export default Y (main)
1300+
const productItemDir = path.join(testDir, 'src', 'components', 'product-item');
1301+
mkdirSync(productItemDir, {recursive: true});
1302+
const indexPath = path.join(productItemDir, 'index.tsx');
1303+
writeFileSync(
1304+
indexPath,
1305+
`export interface ProductItemProps { productId: string; }
1306+
1307+
export function ProductItemVariantImage() { return null; }
1308+
export function ProductItemVariantAttributes() { return null; }
1309+
1310+
function ProductItem({ productId }: ProductItemProps) {
1311+
return <div>{productId}</div>;
1312+
}
1313+
1314+
export default ProductItem;
1315+
`,
1316+
'utf8',
1317+
);
1318+
1319+
const result = await tool.handler({
1320+
component: 'ProductItem',
1321+
autoMode: true,
1322+
});
1323+
1324+
expect(result.isError).to.be.undefined;
1325+
const text = getResultText(result);
1326+
// Must target ProductItem (default export), not ProductItemVariantImage (first named export)
1327+
expect(text).to.include('ProductItem');
1328+
expect(text).not.to.include('ProductItemVariantImage');
1329+
});
12961330
});
12971331

12981332
describe('input validation', () => {

0 commit comments

Comments
 (0)