@salesforce/b2c-dx-mcp 2.0.0 → 2.1.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 (108) hide show
  1. package/README.md +15 -62
  2. package/dist/commands/mcp.d.ts +1 -0
  3. package/dist/commands/mcp.js +47 -9
  4. package/dist/registry.d.ts +3 -4
  5. package/dist/registry.js +7 -14
  6. package/dist/services.d.ts +21 -1
  7. package/dist/services.js +38 -1
  8. package/dist/tools/adapter.d.ts +19 -2
  9. package/dist/tools/adapter.js +49 -10
  10. package/dist/tools/cartridges/index.js +11 -3
  11. package/dist/tools/diagnostics/config-inspect.js +2 -2
  12. package/dist/tools/diagnostics/debug-list-sessions.js +1 -0
  13. package/dist/tools/diagnostics/debug-start-session.js +13 -2
  14. package/dist/tools/diagnostics/log-watch-registry.d.ts +3 -0
  15. package/dist/tools/diagnostics/log-watch-registry.js +1 -0
  16. package/dist/tools/diagnostics/logs-watch-list.js +1 -0
  17. package/dist/tools/diagnostics/logs-watch-start.js +6 -1
  18. package/dist/tools/diagnostics/mrt-log-watch-registry.d.ts +3 -0
  19. package/dist/tools/diagnostics/mrt-log-watch-registry.js +0 -0
  20. package/dist/tools/diagnostics/mrt-logs-watch-list.js +1 -0
  21. package/dist/tools/diagnostics/mrt-logs-watch-start.js +7 -1
  22. package/dist/tools/diagnostics/session-registry.d.ts +3 -0
  23. package/dist/tools/diagnostics/session-registry.js +2 -1
  24. package/dist/tools/index.d.ts +0 -1
  25. package/dist/tools/index.js +0 -1
  26. package/dist/tools/mrt/index.js +4 -0
  27. package/dist/tools/project-context.d.ts +42 -11
  28. package/dist/tools/project-context.js +48 -15
  29. package/dist/tools/scapi/metrics-get.js +1 -1
  30. package/dist/tools/scapi/scapi-custom-api-generate-scaffold.d.ts +4 -0
  31. package/dist/tools/scapi/scapi-custom-api-generate-scaffold.js +27 -7
  32. package/dist/tools/scapi/scapi-custom-apis-get-status.js +1 -1
  33. package/dist/tools/scapi/scapi-schemas-list.js +1 -0
  34. package/dist/utils/constants.d.ts +2 -13
  35. package/dist/utils/constants.js +1 -20
  36. package/oclif.manifest.json +2 -2
  37. package/package.json +3 -3
  38. package/content/sfnext/auth.md +0 -62
  39. package/content/sfnext/components.md +0 -123
  40. package/content/sfnext/config.md +0 -180
  41. package/content/sfnext/data-fetching.md +0 -323
  42. package/content/sfnext/extensions.md +0 -80
  43. package/content/sfnext/i18n.md +0 -121
  44. package/content/sfnext/page-designer.md +0 -78
  45. package/content/sfnext/performance.md +0 -80
  46. package/content/sfnext/pitfalls.md +0 -141
  47. package/content/sfnext/quick-reference.md +0 -226
  48. package/content/sfnext/state-management.md +0 -75
  49. package/content/sfnext/styling.md +0 -51
  50. package/content/sfnext/testing.md +0 -232
  51. package/dist/tools/storefrontnext/figma/figma-to-component/figma-url-parser.d.ts +0 -24
  52. package/dist/tools/storefrontnext/figma/figma-to-component/figma-url-parser.js +0 -53
  53. package/dist/tools/storefrontnext/figma/figma-to-component/index.d.ts +0 -45
  54. package/dist/tools/storefrontnext/figma/figma-to-component/index.js +0 -332
  55. package/dist/tools/storefrontnext/figma/generate-component/decision.d.ts +0 -40
  56. package/dist/tools/storefrontnext/figma/generate-component/decision.js +0 -312
  57. package/dist/tools/storefrontnext/figma/generate-component/formatter.d.ts +0 -9
  58. package/dist/tools/storefrontnext/figma/generate-component/formatter.js +0 -92
  59. package/dist/tools/storefrontnext/figma/generate-component/index.d.ts +0 -117
  60. package/dist/tools/storefrontnext/figma/generate-component/index.js +0 -102
  61. package/dist/tools/storefrontnext/figma/map-tokens/css-parser.d.ts +0 -71
  62. package/dist/tools/storefrontnext/figma/map-tokens/css-parser.js +0 -260
  63. package/dist/tools/storefrontnext/figma/map-tokens/index.d.ts +0 -64
  64. package/dist/tools/storefrontnext/figma/map-tokens/index.js +0 -242
  65. package/dist/tools/storefrontnext/figma/map-tokens/token-matcher.d.ts +0 -65
  66. package/dist/tools/storefrontnext/figma/map-tokens/token-matcher.js +0 -268
  67. package/dist/tools/storefrontnext/index.d.ts +0 -30
  68. package/dist/tools/storefrontnext/index.js +0 -28
  69. package/dist/tools/storefrontnext/page-designer-decorator/analyzer.d.ts +0 -169
  70. package/dist/tools/storefrontnext/page-designer-decorator/analyzer.js +0 -567
  71. package/dist/tools/storefrontnext/page-designer-decorator/index.d.ts +0 -259
  72. package/dist/tools/storefrontnext/page-designer-decorator/index.js +0 -622
  73. package/dist/tools/storefrontnext/page-designer-decorator/rules/1-mode-selection.d.ts +0 -8
  74. package/dist/tools/storefrontnext/page-designer-decorator/rules/1-mode-selection.js +0 -65
  75. package/dist/tools/storefrontnext/page-designer-decorator/rules/2a-auto-mode.d.ts +0 -13
  76. package/dist/tools/storefrontnext/page-designer-decorator/rules/2a-auto-mode.js +0 -87
  77. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-0-interactive-overview.d.ts +0 -4
  78. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-0-interactive-overview.js +0 -55
  79. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-1-interactive-analyze.d.ts +0 -22
  80. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-1-interactive-analyze.js +0 -109
  81. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-2-interactive-select-props.d.ts +0 -21
  82. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-2-interactive-select-props.js +0 -60
  83. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-3-interactive-configure-attrs.d.ts +0 -27
  84. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-3-interactive-configure-attrs.js +0 -68
  85. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-4-interactive-configure-regions.d.ts +0 -4
  86. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-4-interactive-configure-regions.js +0 -65
  87. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-5-interactive-confirm-generation.d.ts +0 -11
  88. package/dist/tools/storefrontnext/page-designer-decorator/rules/2b-5-interactive-confirm-generation.js +0 -92
  89. package/dist/tools/storefrontnext/page-designer-decorator/rules.d.ts +0 -51
  90. package/dist/tools/storefrontnext/page-designer-decorator/rules.js +0 -70
  91. package/dist/tools/storefrontnext/page-designer-decorator/templates/decorator-generator.d.ts +0 -116
  92. package/dist/tools/storefrontnext/page-designer-decorator/templates/decorator-generator.js +0 -350
  93. package/dist/tools/storefrontnext/sfnext-development-guidelines.d.ts +0 -9
  94. package/dist/tools/storefrontnext/sfnext-development-guidelines.js +0 -141
  95. package/dist/tools/storefrontnext/site-theming/color-contrast.d.ts +0 -92
  96. package/dist/tools/storefrontnext/site-theming/color-contrast.js +0 -186
  97. package/dist/tools/storefrontnext/site-theming/color-mapping.d.ts +0 -16
  98. package/dist/tools/storefrontnext/site-theming/color-mapping.js +0 -131
  99. package/dist/tools/storefrontnext/site-theming/guidance-merger.d.ts +0 -11
  100. package/dist/tools/storefrontnext/site-theming/guidance-merger.js +0 -78
  101. package/dist/tools/storefrontnext/site-theming/index.d.ts +0 -14
  102. package/dist/tools/storefrontnext/site-theming/index.js +0 -128
  103. package/dist/tools/storefrontnext/site-theming/response-builder.d.ts +0 -16
  104. package/dist/tools/storefrontnext/site-theming/response-builder.js +0 -316
  105. package/dist/tools/storefrontnext/site-theming/theming-store.d.ts +0 -64
  106. package/dist/tools/storefrontnext/site-theming/theming-store.js +0 -417
  107. package/dist/tools/storefrontnext/site-theming/types.d.ts +0 -36
  108. package/dist/tools/storefrontnext/site-theming/types.js +0 -7
@@ -20,12 +20,12 @@ export function createConfigInspectTool(loadServices) {
20
20
  name: 'config_inspect',
21
21
  description: 'Inspect the resolved B2C Commerce configuration the MCP server is using — instance hostname, auth, SCAPI, MRT, and other settings — along with which source (dw.json, environment variables, flags) provided each value. ' +
22
22
  'Secrets (passwords, client secrets, API keys) are redacted by default. ' +
23
- 'Pass projectDirectory and/or configPath to inspect the same project and dw.json-format file a CLI command would use. The output includes the effective projectDirectory and source provenance, which is useful for diagnosing why the server targets the wrong instance or cannot find a project. ' +
23
+ 'Pass projectDirectory, configPath, and/or instanceName to inspect the same project, configuration catalog, and named instance another tool would use. The detailed source graph is supplemented by the same compact resolution provenance returned by other configuration-aware tools. ' +
24
24
  'Use this first when configuration seems wrong, auth is failing, or the server appears to be operating in the wrong directory.',
25
25
  toolsets: ['DIAGNOSTICS'],
26
26
  isGA: true,
27
27
  requiresInstance: false,
28
- usesProjectContext: true,
28
+ usesConfigurationContext: true,
29
29
  inputSchema: {
30
30
  unmask: z
31
31
  .boolean()
@@ -30,6 +30,7 @@ export function createDebugListSessionsTool(loadServices, serverContext) {
30
30
  session_cookie: dwsid ? { name: 'dwsid', value: dwsid } : null,
31
31
  created_at: new Date(entry.createdAt).toISOString(),
32
32
  last_activity_at: new Date(entry.lastActivityAt).toISOString(),
33
+ resolution: entry.resolution,
33
34
  };
34
35
  }),
35
36
  };
@@ -23,7 +23,7 @@ export function createDebugStartSessionTool(loadServices, serverContext) {
23
23
  .optional()
24
24
  .describe('Optional cartridge discovery and debugger source-mapping root. Relative paths resolve from projectDirectory. Defaults to projectDirectory.'),
25
25
  },
26
- usesProjectContext: true,
26
+ usesConfigurationContext: true,
27
27
  async execute(args, context) {
28
28
  const registry = getRegistry(context);
29
29
  const credentials = context.services.getBasicAuthCredentials();
@@ -35,6 +35,10 @@ export function createDebugStartSessionTool(loadServices, serverContext) {
35
35
  const clientId = `b2c-dx-mcp-${randomUUID()}`;
36
36
  const projectDirectory = context.services.resolveProjectDirectory(args.projectDirectory);
37
37
  const cartridgeDir = context.services.resolveWithProjectDirectory(args.cartridgeDirectory, args.projectDirectory);
38
+ context.setResolvedDirectory('cartridgeDirectory', {
39
+ path: cartridgeDir,
40
+ source: args.cartridgeDirectory ? 'argument' : 'projectDirectory',
41
+ });
38
42
  const cartridges = findCartridges(cartridgeDir);
39
43
  const warnings = [];
40
44
  if (cartridges.length === 0) {
@@ -55,7 +59,14 @@ export function createDebugStartSessionTool(loadServices, serverContext) {
55
59
  };
56
60
  const manager = new DebugSessionManager({ hostname, username, password, clientId, cartridgeRoots: cartridges }, callbacks);
57
61
  await manager.connect();
58
- const entry = registry.registerSession({ hostname, clientId, manager, sourceMapper, cartridges });
62
+ const entry = registry.registerSession({
63
+ hostname,
64
+ clientId,
65
+ manager,
66
+ sourceMapper,
67
+ cartridges,
68
+ resolution: structuredClone(context.resolution),
69
+ });
59
70
  const cartridgeMappings = {};
60
71
  for (const c of cartridges)
61
72
  cartridgeMappings[c.name] = c.src;
@@ -1,5 +1,6 @@
1
1
  import type { LogEntry, LogFile, TailLogsResult } from '@salesforce/b2c-tooling-sdk/operations/logs';
2
2
  import type { ToolExecutionContext } from '../adapter.js';
3
+ import type { ToolResolution } from '../project-context.js';
3
4
  /** Maximum number of buffered entries before oldest are evicted. */
4
5
  export declare const DEFAULT_BUFFER_CAP = 5000;
5
6
  /**
@@ -38,6 +39,7 @@ export interface LogWatchEntry {
38
39
  createdAt: number;
39
40
  lastActivityAt: number;
40
41
  stopped: boolean;
42
+ resolution?: ToolResolution;
41
43
  }
42
44
  export interface RegisterWatchOptions {
43
45
  hostname: string;
@@ -45,6 +47,7 @@ export interface RegisterWatchOptions {
45
47
  tailResult: TailLogsResult;
46
48
  bufferCap?: number;
47
49
  bufferBytesCap?: number;
50
+ resolution?: ToolResolution;
48
51
  }
49
52
  export declare class LogWatchRegistry {
50
53
  private cleanupTimer;
@@ -194,6 +194,7 @@ export class LogWatchRegistry {
194
194
  stopped: false,
195
195
  totalEntriesSeen: 0,
196
196
  watchId,
197
+ resolution: opts.resolution,
197
198
  };
198
199
  this.watches.set(watchId, entry);
199
200
  return entry;
@@ -27,6 +27,7 @@ export function createLogsWatchListTool(loadServices, serverContext) {
27
27
  stopped: w.stopped,
28
28
  total_entries_seen: w.totalEntriesSeen,
29
29
  watch_id: w.watchId,
30
+ resolution: w.resolution,
30
31
  })),
31
32
  };
32
33
  },
@@ -97,7 +97,12 @@ export function createLogsWatchStartTool(loadServices, serverContext, injections
97
97
  // it isn't orphaned (it would otherwise poll WebDAV until process exit).
98
98
  let entry;
99
99
  try {
100
- entry = registry.registerWatch({ hostname, prefixes, tailResult });
100
+ entry = registry.registerWatch({
101
+ hostname,
102
+ prefixes,
103
+ tailResult,
104
+ resolution: structuredClone(context.resolution),
105
+ });
101
106
  }
102
107
  catch (error) {
103
108
  await tailResult.stop().catch(() => { });
@@ -1,5 +1,6 @@
1
1
  import type { MrtLogEntry, TailMrtLogsResult } from '@salesforce/b2c-tooling-sdk/operations/mrt';
2
2
  import type { ToolExecutionContext } from '../adapter.js';
3
+ import type { ToolResolution } from '../project-context.js';
3
4
  /** Maximum number of buffered entries before oldest are evicted. */
4
5
  export declare const DEFAULT_BUFFER_CAP = 5000;
5
6
  /**
@@ -42,6 +43,7 @@ export interface MrtLogWatchEntry {
42
43
  * watch keeps its buffered entries until drained or idle-reaped.
43
44
  */
44
45
  stopped: boolean;
46
+ resolution?: ToolResolution;
45
47
  }
46
48
  export interface RegisterMrtWatchOptions {
47
49
  project: string;
@@ -50,6 +52,7 @@ export interface RegisterMrtWatchOptions {
50
52
  tailResult: TailMrtLogsResult;
51
53
  bufferCap?: number;
52
54
  bufferBytesCap?: number;
55
+ resolution?: ToolResolution;
53
56
  }
54
57
  /**
55
58
  * Stable dedup key for an MRT log watch. A developer may tail several
@@ -27,6 +27,7 @@ export function createMrtLogsWatchListTool(loadServices, serverContext) {
27
27
  stopped: w.stopped,
28
28
  total_entries_seen: w.totalEntriesSeen,
29
29
  watch_id: w.watchId,
30
+ resolution: w.resolution,
30
31
  })),
31
32
  };
32
33
  },
@@ -113,7 +113,13 @@ export function createMrtLogsWatchStartTool(loadServices, serverContext, injecti
113
113
  // exit).
114
114
  let entry;
115
115
  try {
116
- entry = registry.registerWatch({ project, environment, origin, tailResult });
116
+ entry = registry.registerWatch({
117
+ project,
118
+ environment,
119
+ origin,
120
+ tailResult,
121
+ resolution: structuredClone(context.resolution),
122
+ });
117
123
  }
118
124
  catch (error) {
119
125
  tailResult.stop();
@@ -1,6 +1,7 @@
1
1
  import type { DebugSessionManager, SourceMapper, SdapiBreakpoint, SdapiScriptThread } from '@salesforce/b2c-tooling-sdk/operations/debug';
2
2
  import type { CartridgeMapping } from '@salesforce/b2c-tooling-sdk/operations/code';
3
3
  import type { ToolExecutionContext } from '../adapter.js';
4
+ import type { ToolResolution } from '../project-context.js';
4
5
  export interface HaltWaiter {
5
6
  resolve: (thread: SdapiScriptThread) => void;
6
7
  reject: (error: Error) => void;
@@ -17,6 +18,7 @@ export interface DebugSessionEntry {
17
18
  haltWaiters: HaltWaiter[];
18
19
  createdAt: number;
19
20
  lastActivityAt: number;
21
+ resolution?: ToolResolution;
20
22
  }
21
23
  export interface RegisterSessionOptions {
22
24
  hostname: string;
@@ -24,6 +26,7 @@ export interface RegisterSessionOptions {
24
26
  manager: DebugSessionManager;
25
27
  sourceMapper: SourceMapper;
26
28
  cartridges: CartridgeMapping[];
29
+ resolution?: ToolResolution;
27
30
  }
28
31
  export declare class DebugSessionRegistry {
29
32
  private cleanupTimer;
@@ -64,7 +64,7 @@ export class DebugSessionRegistry {
64
64
  return [...this.sessions.values()];
65
65
  }
66
66
  registerSession(opts) {
67
- const { hostname, clientId, manager, sourceMapper, cartridges } = opts;
67
+ const { hostname, clientId, manager, sourceMapper, cartridges, resolution } = opts;
68
68
  const existing = this.findByHostAndClientId(hostname, clientId);
69
69
  if (existing) {
70
70
  throw new Error(`A debug session already exists for ${hostname} ` +
@@ -84,6 +84,7 @@ export class DebugSessionRegistry {
84
84
  haltWaiters: [],
85
85
  createdAt: now,
86
86
  lastActivityAt: now,
87
+ resolution,
87
88
  };
88
89
  this.sessions.set(sessionId, entry);
89
90
  return entry;
@@ -14,4 +14,3 @@ export * from './docs/index.js';
14
14
  export * from './mrt/index.js';
15
15
  export * from './pwav3/index.js';
16
16
  export * from './scapi/index.js';
17
- export * from './storefrontnext/index.js';
@@ -21,5 +21,4 @@ export * from './docs/index.js';
21
21
  export * from './mrt/index.js';
22
22
  export * from './pwav3/index.js';
23
23
  export * from './scapi/index.js';
24
- export * from './storefrontnext/index.js';
25
24
  //# sourceMappingURL=index.js.map
@@ -175,6 +175,10 @@ function createMrtBundlePushTool(loadServices, injections) {
175
175
  const ssrOnly = args.ssrOnly ? parseGlobPatterns(args.ssrOnly) : defaults.ssrOnly;
176
176
  const ssrShared = args.ssrShared ? parseGlobPatterns(args.ssrShared) : defaults.ssrShared;
177
177
  const buildDirectory = context.services.resolveWithProjectDirectory(args.buildDirectory ?? defaults.buildDirectory, args.projectDirectory);
178
+ context.setResolvedDirectory('buildDirectory', {
179
+ path: buildDirectory,
180
+ source: args.buildDirectory ? 'argument' : 'projectDirectory',
181
+ });
178
182
  // Log all computed variables before pushing bundle
179
183
  const logger = getLogger();
180
184
  logger.debug({
@@ -1,22 +1,53 @@
1
- import { z } from 'zod';
1
+ import { z, type ZodRawShape } from 'zod';
2
2
  /** Input shared by MCP tools that resolve files or configuration from a project. */
3
3
  export interface ProjectContextInput {
4
4
  /** Per-call project directory override. */
5
5
  projectDirectory?: string;
6
- /** Per-call explicit dw.json-format configuration path. */
6
+ /** Per-call explicit primary dw.json-format configuration path. */
7
7
  configPath?: string;
8
+ /** Per-call named instance selection. */
9
+ instanceName?: string;
8
10
  }
9
11
  /** Effective project directory and the source that selected it. */
10
12
  export interface ProjectDirectoryInfo {
11
13
  path: string;
12
14
  source: 'argument' | 'config' | 'cwd';
13
15
  }
14
- /** Shared schema field injected into every project-aware MCP tool. */
15
- export declare const projectDirectoryInput: z.ZodOptional<z.ZodString>;
16
- /** Shared explicit dw.json path field injected into every project-aware MCP tool. */
17
- export declare const configPathInput: z.ZodOptional<z.ZodString>;
18
- /** Shared schema fields injected into every project-aware MCP tool. */
19
- export declare const projectContextInputSchema: {
20
- projectDirectory: z.ZodOptional<z.ZodString>;
21
- configPath: z.ZodOptional<z.ZodString>;
22
- };
16
+ /** How the selected dw.json file entered the configuration resolver. */
17
+ export type ConfigurationResolutionSource = 'argument' | 'globalDefault' | 'none' | 'projectDirectory' | 'projectEnvironment' | 'server';
18
+ /** Compact selected-configuration provenance returned by project-aware tools. */
19
+ export interface ConfigurationResolutionInfo {
20
+ hostname?: string;
21
+ instanceName?: string;
22
+ path?: string;
23
+ source: ConfigurationResolutionSource;
24
+ }
25
+ /** Provenance for a specialized project-relative directory. */
26
+ export interface DirectoryResolutionInfo {
27
+ path: string;
28
+ source: 'argument' | 'projectDirectory';
29
+ }
30
+ /** Compact, common provenance block returned by project/config-aware tools. */
31
+ export interface ToolResolution {
32
+ configuration?: ConfigurationResolutionInfo;
33
+ directories?: Record<string, DirectoryResolutionInfo>;
34
+ projectDirectory: ProjectDirectoryInfo;
35
+ }
36
+ /** Defaults known when MCP tool schemas are registered. */
37
+ export interface ProjectContextDefaults {
38
+ projectDirectory: ProjectDirectoryInfo;
39
+ }
40
+ /** Whether a tool needs only a project root or full configuration selection. */
41
+ export type ProjectContextKind = 'configuration' | 'project';
42
+ /** Build the canonical project-directory field with the effective fallback embedded in its description. */
43
+ export declare function createProjectDirectoryInput(defaults?: ProjectContextDefaults): z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
44
+ /** Build the canonical explicit primary dw.json field. */
45
+ export declare function createConfigPathInput(): z.ZodOptional<z.ZodString>;
46
+ /** Build the canonical named-instance selection field. */
47
+ export declare function createInstanceNameInput(): z.ZodOptional<z.ZodString>;
48
+ /** Build flat canonical schema fields for a local-project or configuration-aware tool. */
49
+ export declare function createProjectContextInputSchema(kind: ProjectContextKind, defaults?: ProjectContextDefaults): ZodRawShape;
50
+ /** Static field for schemas declared outside the shared adapter. */
51
+ export declare const projectDirectoryInput: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
52
+ /** Static configuration schema for legacy/manual tool definitions. */
53
+ export declare const projectContextInputSchema: z.ZodRawShape;
@@ -3,20 +3,53 @@
3
3
  * SPDX-License-Identifier: Apache-2
4
4
  * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5
5
  */
6
+ import path from 'node:path';
6
7
  import { z } from 'zod';
7
- /** Shared schema field injected into every project-aware MCP tool. */
8
- export const projectDirectoryInput = z
9
- .string()
10
- .optional()
11
- .describe('Absolute project directory for this call. Overrides --project-directory / SFCC_PROJECT_DIRECTORY and the MCP process working directory. Also controls project-local configuration discovery.');
12
- /** Shared explicit dw.json path field injected into every project-aware MCP tool. */
13
- export const configPathInput = z
14
- .string()
15
- .optional()
16
- .describe('Explicit path to a dw.json-format configuration file for this call. Overrides startup --config / SFCC_CONFIG and project .env SFCC_CONFIG. Relative paths resolve from projectDirectory.');
17
- /** Shared schema fields injected into every project-aware MCP tool. */
18
- export const projectContextInputSchema = {
19
- projectDirectory: projectDirectoryInput,
20
- configPath: configPathInput,
21
- };
8
+ function defaultProjectContext() {
9
+ return { projectDirectory: { path: process.cwd(), source: 'cwd' } };
10
+ }
11
+ /** Build the canonical project-directory field with the effective fallback embedded in its description. */
12
+ export function createProjectDirectoryInput(defaults = defaultProjectContext()) {
13
+ const fallback = defaults.projectDirectory;
14
+ const sourceDescription = fallback.source === 'cwd'
15
+ ? 'the MCP process working directory'
16
+ : 'the server-level --project-directory / SFCC_PROJECT_DIRECTORY value';
17
+ return z
18
+ .string()
19
+ .refine((value) => path.isAbsolute(value), 'projectDirectory must be an absolute path')
20
+ .optional()
21
+ .describe(`Optional absolute project root for this call. Overrides the server-level project directory. ` +
22
+ `When omitted, uses ${sourceDescription}: ${fallback.path}`);
23
+ }
24
+ /** Build the canonical explicit primary dw.json field. */
25
+ export function createConfigPathInput() {
26
+ return z
27
+ .string()
28
+ .optional()
29
+ .describe('Optional path to a dw.json-format configuration file. Relative paths resolve from projectDirectory. ' +
30
+ 'Selects the primary file ahead of server and project automatic selection; the shared default dw.json remains available as a fallback and for named-instance lookup.');
31
+ }
32
+ /** Build the canonical named-instance selection field. */
33
+ export function createInstanceNameInput() {
34
+ return z
35
+ .string()
36
+ .min(1)
37
+ .optional()
38
+ .describe('Optional named instance to select from the resolved primary and default dw.json files. The primary file is searched first. When omitted, the active/default instance is used.');
39
+ }
40
+ /** Build flat canonical schema fields for a local-project or configuration-aware tool. */
41
+ export function createProjectContextInputSchema(kind, defaults = defaultProjectContext()) {
42
+ const project = { projectDirectory: createProjectDirectoryInput(defaults) };
43
+ if (kind === 'project')
44
+ return project;
45
+ return {
46
+ ...project,
47
+ configPath: createConfigPathInput(),
48
+ instanceName: createInstanceNameInput(),
49
+ };
50
+ }
51
+ /** Static field for schemas declared outside the shared adapter. */
52
+ export const projectDirectoryInput = createProjectDirectoryInput();
53
+ /** Static configuration schema for legacy/manual tool definitions. */
54
+ export const projectContextInputSchema = createProjectContextInputSchema('configuration');
22
55
  //# sourceMappingURL=project-context.js.map
@@ -63,7 +63,7 @@ Retrieve observability metrics time-series for a B2C Commerce tenant. Returns me
63
63
  toolsets: ['SCAPI'],
64
64
  isGA: false,
65
65
  requiresInstance: false, // SCAPI uses OAuth directly
66
- usesProjectContext: true,
66
+ usesConfigurationContext: true,
67
67
  inputSchema: {
68
68
  category: z
69
69
  .enum(['overall', 'sales', 'ecdn', 'third-party', 'scapi', 'scapi-hooks', 'mrt', 'controller', 'ocapi'])
@@ -23,8 +23,12 @@ interface ScaffoldCustomApiInput extends ProjectContextInput {
23
23
  /** Short description of the API. Default: "A custom B2C Commerce API" */
24
24
  apiDescription?: string;
25
25
  /** Project root for cartridge discovery and output. Default: MCP project directory */
26
+ cartridgeDirectory?: string;
27
+ /** @deprecated Use cartridgeDirectory. */
26
28
  projectRoot?: string;
27
29
  /** Output directory override. Default: scaffold default or project root */
30
+ outputDirectory?: string;
31
+ /** @deprecated Use outputDirectory. */
28
32
  outputDir?: string;
29
33
  }
30
34
  /**
@@ -22,7 +22,7 @@ const CUSTOM_API_SCAFFOLD_ID = 'custom-api';
22
22
  */
23
23
  export async function executeScaffoldCustomApi(args, services, overrides) {
24
24
  const projectDirectory = services.resolveProjectDirectory(args.projectDirectory);
25
- const projectRoot = services.resolveWithProjectDirectory(args.projectRoot, args.projectDirectory);
25
+ const projectRoot = services.resolveWithProjectDirectory(args.cartridgeDirectory ?? args.projectRoot, args.projectDirectory);
26
26
  const getScaffold = overrides?.getScaffold ??
27
27
  (async (id, opts) => {
28
28
  const registry = createScaffoldRegistry();
@@ -96,7 +96,7 @@ export async function executeScaffoldCustomApi(args, services, overrides) {
96
96
  };
97
97
  }
98
98
  const outputDir = resolveOutputDirectory({
99
- outputDir: args.outputDir,
99
+ outputDir: args.outputDirectory ?? args.outputDir,
100
100
  scaffold,
101
101
  projectRoot,
102
102
  });
@@ -149,7 +149,7 @@ export function createScaffoldCustomApiTool(loadServices, executeOverrides) {
149
149
  name: 'scapi_custom_api_generate_scaffold',
150
150
  description: `Generate a new custom SCAPI endpoint (OAS 3.0 schema, api.json, script.js) in an existing cartridge. \
151
151
  Required: apiName (kebab-case). Optional: cartridgeName (defaults to first cartridge found in project), apiType (shopper|admin) default to shopper, \
152
- apiDescription, projectRoot, outputDir.`,
152
+ apiDescription, cartridgeDirectory, outputDirectory.`,
153
153
  toolsets: ['PWAV3', 'SCAPI', 'STOREFRONTNEXT'],
154
154
  isGA: true,
155
155
  requiresInstance: false,
@@ -169,14 +169,34 @@ apiDescription, projectRoot, outputDir.`,
169
169
  .optional()
170
170
  .describe('Admin (no siteId) or shopper (siteId, customer-facing). Default: shopper'),
171
171
  apiDescription: z.string().optional().describe('Short description of the API.'),
172
+ cartridgeDirectory: z
173
+ .string()
174
+ .nullish()
175
+ .describe('Optional cartridge discovery root, resolved relative to projectDirectory. Defaults to projectDirectory.'),
172
176
  projectRoot: z
173
177
  .string()
174
178
  .nullish()
175
- .describe('Optional cartridge discovery/output root, resolved relative to projectDirectory. Defaults to projectDirectory.'),
176
- outputDir: z.string().optional().describe('Output directory override. Default: project root'),
179
+ .describe('Deprecated alias for cartridgeDirectory. cartridgeDirectory takes precedence.'),
180
+ outputDirectory: z
181
+ .string()
182
+ .optional()
183
+ .describe('Optional output directory. Relative paths resolve from cartridgeDirectory.'),
184
+ outputDir: z
185
+ .string()
186
+ .optional()
187
+ .describe('Deprecated alias for outputDirectory. outputDirectory takes precedence.'),
177
188
  },
178
- async execute(args, { services }) {
179
- return executeScaffoldCustomApi(args, services, executeOverrides);
189
+ async execute(args, context) {
190
+ const output = await executeScaffoldCustomApi(args, context.services, executeOverrides);
191
+ context.setResolvedDirectory('cartridgeDirectory', {
192
+ path: output.projectRoot,
193
+ source: args.cartridgeDirectory || args.projectRoot ? 'argument' : 'projectDirectory',
194
+ });
195
+ context.setResolvedDirectory('outputDirectory', {
196
+ path: output.outputDir,
197
+ source: args.outputDirectory || args.outputDir ? 'argument' : 'projectDirectory',
198
+ });
199
+ return output;
180
200
  },
181
201
  formatOutput(output) {
182
202
  if (output.error) {
@@ -94,7 +94,7 @@ CLI: b2c scapi custom status`,
94
94
  toolsets: ['PWAV3', 'SCAPI', 'STOREFRONTNEXT'],
95
95
  isGA: true,
96
96
  requiresInstance: false,
97
- usesProjectContext: true,
97
+ usesConfigurationContext: true,
98
98
  inputSchema: {
99
99
  status: z.enum(['active', 'not_registered']).optional().describe('Filter by status. Omit for all.'),
100
100
  groupBy: z.enum(['site', 'type']).optional().describe('Group by siteId or type (Admin/Shopper).'),
@@ -199,6 +199,7 @@ export function createScapiSchemasListTool(loadServices) {
199
199
  toolsets: ['PWAV3', 'SCAPI', 'STOREFRONTNEXT'],
200
200
  isGA: true,
201
201
  requiresInstance: false, // SCAPI uses OAuth directly, doesn't need B2CInstance (hostname)
202
+ usesConfigurationContext: true,
202
203
  inputSchema: {
203
204
  apiFamily: z.string().optional().describe('API family (e.g., "checkout", "product", "custom").'),
204
205
  apiName: z.string().optional().describe('API name (e.g., "shopper-baskets", "shopper-products").'),
@@ -5,22 +5,11 @@ export declare const ALL_TOOLSETS = "ALL";
5
5
  /**
6
6
  * Available toolsets that can be enabled.
7
7
  */
8
- export declare const TOOLSETS: readonly ["CARTRIDGES", "DIAGNOSTICS", "MRT", "PWAV3", "SCAPI", "STOREFRONTNEXT", "STOREFRONTNEXT_DEPRECATED"];
9
- /**
10
- * Deprecated toolsets. These can only be enabled by explicitly naming them via
11
- * `--toolsets`; they are never auto-activated by project detection and are NOT
12
- * included when `--toolsets ALL` is used.
13
- *
14
- * `STOREFRONTNEXT_DEPRECATED` holds the legacy `sfnext_*` MCP tools. They are
15
- * superseded by the `storefront-next` and `storefront-next-figma` agent-skills
16
- * plugins and are not compatible with the Storefront Next 1.0 GA release. They
17
- * will be removed in a future release.
18
- */
19
- export declare const DEPRECATED_TOOLSETS: readonly ["STOREFRONTNEXT_DEPRECATED"];
8
+ export declare const TOOLSETS: readonly ["CARTRIDGES", "DIAGNOSTICS", "MRT", "PWAV3", "SCAPI", "STOREFRONTNEXT"];
20
9
  /**
21
10
  * Valid toolset names including the special "ALL" value.
22
11
  */
23
- export declare const VALID_TOOLSET_NAMES: readonly ["ALL", "CARTRIDGES", "DIAGNOSTICS", "MRT", "PWAV3", "SCAPI", "STOREFRONTNEXT", "STOREFRONTNEXT_DEPRECATED"];
12
+ export declare const VALID_TOOLSET_NAMES: readonly ["ALL", "CARTRIDGES", "DIAGNOSTICS", "MRT", "PWAV3", "SCAPI", "STOREFRONTNEXT"];
24
13
  /**
25
14
  * Type representing a valid toolset name.
26
15
  */
@@ -10,26 +10,7 @@ export const ALL_TOOLSETS = 'ALL';
10
10
  /**
11
11
  * Available toolsets that can be enabled.
12
12
  */
13
- export const TOOLSETS = [
14
- 'CARTRIDGES',
15
- 'DIAGNOSTICS',
16
- 'MRT',
17
- 'PWAV3',
18
- 'SCAPI',
19
- 'STOREFRONTNEXT',
20
- 'STOREFRONTNEXT_DEPRECATED',
21
- ];
22
- /**
23
- * Deprecated toolsets. These can only be enabled by explicitly naming them via
24
- * `--toolsets`; they are never auto-activated by project detection and are NOT
25
- * included when `--toolsets ALL` is used.
26
- *
27
- * `STOREFRONTNEXT_DEPRECATED` holds the legacy `sfnext_*` MCP tools. They are
28
- * superseded by the `storefront-next` and `storefront-next-figma` agent-skills
29
- * plugins and are not compatible with the Storefront Next 1.0 GA release. They
30
- * will be removed in a future release.
31
- */
32
- export const DEPRECATED_TOOLSETS = ['STOREFRONTNEXT_DEPRECATED'];
13
+ export const TOOLSETS = ['CARTRIDGES', 'DIAGNOSTICS', 'MRT', 'PWAV3', 'SCAPI', 'STOREFRONTNEXT'];
33
14
  /**
34
15
  * Valid toolset names including the special "ALL" value.
35
16
  */
@@ -388,7 +388,7 @@
388
388
  "type": "boolean"
389
389
  },
390
390
  "toolsets": {
391
- "description": "Toolsets to enable (comma-separated). Options: all, CARTRIDGES, DIAGNOSTICS, MRT, PWAV3, SCAPI, STOREFRONTNEXT, STOREFRONTNEXT_DEPRECATED",
391
+ "description": "Toolsets to enable (comma-separated). Options: all, CARTRIDGES, DIAGNOSTICS, MRT, PWAV3, SCAPI, STOREFRONTNEXT",
392
392
  "env": "SFCC_TOOLSETS",
393
393
  "name": "toolsets",
394
394
  "hasDynamicHelp": false,
@@ -429,5 +429,5 @@
429
429
  "enableJsonFlag": false
430
430
  }
431
431
  },
432
- "version": "2.0.0"
432
+ "version": "2.1.0"
433
433
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salesforce/b2c-dx-mcp",
3
3
  "description": "MCP server for B2C Commerce developer experience tools",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "author": "Salesforce",
6
6
  "license": "Apache-2.0",
7
7
  "repository": "SalesforceCommerceCloud/b2c-developer-tooling",
@@ -80,7 +80,7 @@
80
80
  "yaml": "2.9.0",
81
81
  "postcss": "8.5.15",
82
82
  "zod": "3.25.76",
83
- "@salesforce/b2c-tooling-sdk": "1.24.0"
83
+ "@salesforce/b2c-tooling-sdk": "1.24.1"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@eslint/compat": "^1",
@@ -126,7 +126,7 @@
126
126
  "test": "c8 mocha --forbid-only --ignore \"test/e2e/**\" \"test/**/*.test.ts\"",
127
127
  "test:ci": "c8 mocha --forbid-only --reporter json --reporter-option output=test-results.json --ignore \"test/e2e/**\" \"test/**/*.test.ts\"",
128
128
  "test:ci:win": "c8 --check-coverage=false mocha --forbid-only --reporter json --reporter-option output=test-results.json --ignore \"test/e2e/**\" \"test/**/*.test.ts\"",
129
- "test:agent": "mocha --forbid-only --reporter min --ignore \"test/e2e/**\" \"test/**/*.test.ts\"",
129
+ "test:agent": "pnpm run pretest && mocha --forbid-only --reporter min --ignore \"test/e2e/**\" \"test/**/*.test.ts\"",
130
130
  "test:e2e": "mocha --forbid-only \"test/e2e/**/*.test.ts\"",
131
131
  "test:e2e:ci": "mocha --forbid-only --reporter json --reporter-option output=test-results-e2e.json \"test/e2e/**/*.test.ts\"",
132
132
  "coverage": "c8 report",