Skip to content

Commit bb28934

Browse files
committed
refactor sfra detect and workspace types
1 parent 2f104f9 commit bb28934

14 files changed

Lines changed: 361 additions & 334 deletions

File tree

packages/b2c-dx-mcp/README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,25 @@ When neither `--toolsets` nor `--tools` are provided, the MCP server automatical
6161
**How it works:**
6262

6363
1. The server analyzes your working directory (from `--working-directory` flag, `SFCC_WORKING_DIRECTORY` env var, or current directory)
64-
2. It checks for project markers like `package.json` dependencies, folder structures, and config files
65-
3. It enables all toolsets that match any detected project type
64+
2. It checks for project markers like `package.json` dependencies and `.project` files
65+
3. It enables all toolsets that match any detected project type, plus the base SCAPI toolset
66+
67+
**Base Toolset:**
68+
69+
The **SCAPI** toolset is always enabled, providing API discovery and custom API scaffolding capabilities.
6670

6771
**Project Types and Toolsets:**
6872

6973
| Project Type | Detection | Toolsets Enabled |
7074
|--------------|-----------|------------------|
7175
| **PWA Kit v3** | `@salesforce/pwa-kit-*`, `@salesforce/retail-react-app`, or `ccExtensibility` | PWAV3, MRT, SCAPI |
7276
| **Storefront Next** | `@salesforce/storefront-next-*` packages in package.json | STOREFRONTNEXT, MRT, SCAPI |
73-
| **SFRA** | `cartridges/` folder with controllers or templates | CARTRIDGES, SCAPI |
74-
| **Custom API** | `rest-apis/*/api.json` or `rest-apis/*/schema.yaml` files | CARTRIDGES, SCAPI |
75-
| **Headless** | `dw.json` file (no specific framework detected) | SCAPI |
76-
| **Unknown** | No B2C project markers found | SCAPI (fallback) |
77+
| **Cartridges** | Any cartridge with `.project` file (detected via `findCartridges`) | CARTRIDGES, SCAPI |
78+
| **No project detected** | No B2C project markers found | SCAPI (base toolset only) |
7779

7880
**Hybrid Projects:**
7981

80-
If multiple project types are detected (e.g., SFRA + Custom API), toolsets from all matched types are combined.
82+
If multiple project types are detected (e.g., cartridges + PWA Kit v3), toolsets from all matched types are combined.
8183

8284
**Example:**
8385

@@ -109,6 +111,8 @@ If multiple project types are detected (e.g., SFRA + Custom API), toolsets from
109111

110112
> **Note:** Cursor supports `${workspaceFolder}` variable expansion, but Claude Desktop does not. For Claude Desktop, use an explicit path or set the `SFCC_WORKING_DIRECTORY` environment variable.
111113
114+
> **Warning:** MCP clients like Cursor and Claude Desktop often spawn servers from the home directory (`~`) rather than the project directory. Always set `--working-directory` or `SFCC_WORKING_DIRECTORY` for reliable auto-discovery and scaffolding operations.
115+
112116
### Configuration Examples
113117

114118
```json

packages/b2c-dx-mcp/src/registry.ts

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,49 +17,45 @@ import {createScapiTools} from './tools/scapi/index.js';
1717
import {createStorefrontNextTools} from './tools/storefrontnext/index.js';
1818

1919
/**
20-
* Maps a single project type to its associated MCP toolsets.
20+
* Base toolset that is always enabled.
21+
* Provides SCAPI discovery and custom API scaffolding tools.
22+
*/
23+
const BASE_TOOLSET: Toolset = 'SCAPI';
24+
25+
/**
26+
* Toolset mapping by project type.
27+
* Each project type enables specific toolsets IN ADDITION to the base toolset.
28+
*/
29+
const PROJECT_TYPE_TOOLSETS: Record<ProjectType, Toolset[]> = {
30+
cartridges: ['CARTRIDGES'],
31+
'pwa-kit-v3': ['PWAV3', 'MRT'],
32+
'storefront-next': ['STOREFRONTNEXT', 'MRT'],
33+
};
34+
35+
/**
36+
* Gets toolsets for a project type, always including the base toolset.
2137
*/
2238
function getToolsetsForProjectType(projectType: ProjectType): Toolset[] {
23-
switch (projectType) {
24-
case 'custom-api': {
25-
return ['CARTRIDGES', 'SCAPI'];
26-
}
27-
case 'headless': {
28-
return ['SCAPI'];
29-
}
30-
case 'pwa-kit-v3': {
31-
return ['PWAV3', 'MRT', 'SCAPI'];
32-
}
33-
case 'sfra': {
34-
return ['CARTRIDGES', 'SCAPI'];
35-
}
36-
case 'storefront-next': {
37-
return ['STOREFRONTNEXT', 'MRT', 'SCAPI'];
38-
}
39-
default: {
40-
// Fallback: provide basic SCAPI tools
41-
return ['SCAPI'];
42-
}
43-
}
39+
const additionalToolsets = PROJECT_TYPE_TOOLSETS[projectType] ?? [];
40+
return [...additionalToolsets, BASE_TOOLSET];
4441
}
4542

4643
/**
4744
* Maps multiple detected project types to a union of MCP toolsets.
4845
*
4946
* Combines toolsets from all matched project types, enabling hybrid
50-
* project support (e.g., SFRA + Custom API gets both CARTRIDGES and SCAPI).
47+
* project support (e.g., cartridges + pwa-kit-v3 gets CARTRIDGES + PWAV3 + MRT + SCAPI).
5148
*
5249
* @param projectTypes - Array of detected project types
53-
* @returns Union of all toolsets for the detected project types
50+
* @returns Union of all toolsets for the detected project types (always includes base toolset)
5451
*/
5552
function getToolsetsForProjectTypes(projectTypes: ProjectType[]): Toolset[] {
56-
// Fallback to SCAPI when no project types detected
57-
if (projectTypes.length === 0) {
58-
return ['SCAPI'];
59-
}
60-
6153
const toolsetSet = new Set<Toolset>();
6254

55+
// Always include base toolset
56+
toolsetSet.add(BASE_TOOLSET);
57+
58+
// Add toolsets for each detected project type
6359
for (const projectType of projectTypes) {
6460
for (const toolset of getToolsetsForProjectType(projectType)) {
6561
toolsetSet.add(toolset);

packages/b2c-tooling-sdk/src/discovery/index.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
*
2424
* ## Project Types
2525
*
26-
* The detector recognizes the following project types:
26+
* The detector recognizes 3 workspace types:
2727
*
28-
* - `pwa-kit-v3` - PWA Kit v3 storefront (template copy or extensible flavor)
28+
* - `cartridges` - Any cartridge-based project (detected via .project files)
29+
* - `pwa-kit-v3` - PWA Kit v3 storefront
2930
* - `storefront-next` - Storefront Next/Odyssey project
30-
* - `sfra` - SFRA/cartridge-based storefront (has cartridges/ directory)
31-
* - `custom-api` - Custom SCAPI project (has api.json files)
32-
* - `headless` - Generic headless project (has dw.json but no specific framework)
31+
*
32+
* ## Toolset Mapping
33+
*
34+
* - base (fallback): SCAPI
35+
* - cartridges: CARTRIDGES + SCAPI
36+
* - pwa-kit-v3: PWAV3 + MRT + SCAPI
37+
* - storefront-next: STOREFRONTNEXT + MRT + SCAPI
3338
*
3439
* ## Custom Patterns
3540
*
@@ -40,7 +45,7 @@
4045
*
4146
* const myPattern: DetectionPattern = {
4247
* name: 'my-framework',
43-
* projectType: 'custom-api',
48+
* projectType: 'cartridges',
4449
* detect: async (path) => {
4550
* // Custom detection logic
4651
* return false;
@@ -66,11 +71,10 @@ export type {ProjectType, DetectionPattern, DetectionResult, DetectOptions} from
6671
// Patterns (for customization)
6772
export {
6873
DEFAULT_PATTERNS,
74+
cartridgesPattern,
6975
pwaKitV3Pattern,
7076
storefrontNextPattern,
7177
sfraPattern,
72-
customApiPattern,
73-
dwJsonPattern,
7478
} from './patterns/index.js';
7579

7680
// Utilities (for building custom patterns)

packages/b2c-tooling-sdk/src/discovery/patterns/base.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2025, Salesforce, Inc.
3+
* SPDX-License-Identifier: Apache-2
4+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5+
*/
6+
/**
7+
* Cartridge project detection pattern.
8+
*
9+
* Detects any project containing cartridges by looking for .project files
10+
* (Eclipse project markers used in SFCC development).
11+
*
12+
* @module discovery/patterns/cartridges
13+
*/
14+
import type {DetectionPattern} from '../types.js';
15+
import {findCartridges} from '../../operations/code/cartridges.js';
16+
17+
/**
18+
* Detection pattern for cartridge-based projects.
19+
*
20+
* Uses the SDK's findCartridges function to detect any cartridges in the workspace.
21+
* This covers SFRA, custom APIs, and any other cartridge-based development.
22+
*/
23+
export const cartridgesPattern: DetectionPattern = {
24+
name: 'cartridges',
25+
projectType: 'cartridges',
26+
detect: async (workspacePath) => {
27+
const cartridges = findCartridges(workspacePath);
28+
return cartridges.length > 0;
29+
},
30+
};

packages/b2c-tooling-sdk/src/discovery/patterns/custom-api.ts

Lines changed: 0 additions & 48 deletions
This file was deleted.

packages/b2c-tooling-sdk/src/discovery/patterns/index.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,29 @@
66
/**
77
* Detection patterns for workspace discovery.
88
*
9+
* Simplified to 3 workspace types:
10+
* - cartridges: Any project with cartridges
11+
* - pwa-kit-v3: PWA Kit v3 storefront
12+
* - storefront-next: Storefront Next (Odyssey)
13+
*
914
* @module discovery/patterns
1015
*/
1116
import type {DetectionPattern} from '../types.js';
17+
import {cartridgesPattern} from './cartridges.js';
1218
import {pwaKitV3Pattern} from './pwa-kit.js';
1319
import {storefrontNextPattern} from './storefront-next.js';
14-
import {sfraPattern} from './sfra.js';
15-
import {customApiPattern} from './custom-api.js';
16-
import {dwJsonPattern} from './base.js';
1720

1821
/**
19-
* Default detection patterns in priority order.
22+
* Default detection patterns.
2023
*
21-
* Patterns are sorted by priority when detection runs, but this
22-
* array provides a logical grouping:
23-
* 1. Framework-specific patterns (PWA Kit v3, Storefront Next, SFRA)
24-
* 2. Project-type patterns (Custom API)
25-
* 3. Fallback patterns (dw.json)
24+
* All patterns are checked - multiple can match for hybrid projects.
2625
*/
27-
export const DEFAULT_PATTERNS: DetectionPattern[] = [
28-
pwaKitV3Pattern,
29-
storefrontNextPattern,
30-
sfraPattern,
31-
customApiPattern,
32-
dwJsonPattern,
33-
];
26+
export const DEFAULT_PATTERNS: DetectionPattern[] = [pwaKitV3Pattern, storefrontNextPattern, cartridgesPattern];
3427

3528
// Individual pattern exports for customization
29+
export {cartridgesPattern} from './cartridges.js';
3630
export {pwaKitV3Pattern} from './pwa-kit.js';
3731
export {storefrontNextPattern} from './storefront-next.js';
32+
33+
// Additional patterns (not in DEFAULT_PATTERNS, available for custom use)
3834
export {sfraPattern} from './sfra.js';
39-
export {customApiPattern} from './custom-api.js';
40-
export {dwJsonPattern} from './base.js';

0 commit comments

Comments
 (0)