@pega/sdk 0.0.6 → 0.0.7

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.
package/dist/index.js CHANGED
@@ -1036,6 +1036,35 @@ var SDK_CONFIG_USER_KEYS = [
1036
1036
  "authConfig.mashupUserIdentifier",
1037
1037
  "authConfig.portalClientId"
1038
1038
  ];
1039
+ var MCP_CONFIG_USER_KEYS = ["url", "clientId"];
1040
+ var MCP_CONFIG_FILES = {
1041
+ copilot: { source: "copilot.mcp.json", dest: path2.join(".vscode", "mcp.json") },
1042
+ cursor: { source: "cursor.mcp.json", dest: path2.join(".cursor", "mcp.json") },
1043
+ "claude-code": { source: "claude-code.mcp.json", dest: ".mcp.json" }
1044
+ };
1045
+ function resolveMcpConfig(aiCommonSrc, choices) {
1046
+ const { source, dest } = MCP_CONFIG_FILES[choices.aiTool];
1047
+ const srcPath = path2.join(aiCommonSrc, "mcp", source);
1048
+ if (!fs2.existsSync(srcPath)) {
1049
+ throw new Error(`MCP config template not found at ${srcPath}. Ensure the template source is available.`);
1050
+ }
1051
+ const tokens = {
1052
+ "{InfinityURL}": choices.serverUrl,
1053
+ "{AppAlias}": choices.appAlias,
1054
+ "{ClientId}": choices.clientId
1055
+ };
1056
+ if (choices.mcpRuleName) tokens["{MCPRuleName}"] = choices.mcpRuleName;
1057
+ if (choices.mcpRuleInsKey) tokens["{MCPRuleInsKey}"] = choices.mcpRuleInsKey;
1058
+ const content = applyTokens(fs2.readFileSync(srcPath, "utf-8"), tokens);
1059
+ return { config: JSON.parse(content), destRelPath: dest };
1060
+ }
1061
+ function ensureGitignoreEntry(targetDir, entry) {
1062
+ const gitignorePath = path2.join(targetDir, ".gitignore");
1063
+ const existing = fs2.existsSync(gitignorePath) ? fs2.readFileSync(gitignorePath, "utf-8") : "";
1064
+ if (existing.split(/\r?\n/).some((line) => line.trim() === entry)) return;
1065
+ const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
1066
+ fs2.writeFileSync(gitignorePath, existing + separator + entry + "\n");
1067
+ }
1039
1068
  function buildSdkConfig(choices) {
1040
1069
  return {
1041
1070
  serverConfig: {
@@ -1079,6 +1108,11 @@ function collectEmbeddedConflicts(targetDir, choices) {
1079
1108
  if (isConflict(sdkConfigPath, buildSdkConfig(choices), SDK_CONFIG_USER_KEYS)) {
1080
1109
  conflicts.push(sdkConfigPath);
1081
1110
  }
1111
+ const { config: mcpConfig, destRelPath: mcpDestRelPath } = resolveMcpConfig(aiCommonSrc, choices);
1112
+ const mcpConfigPath = path2.join(targetDir, mcpDestRelPath);
1113
+ if (isConflict(mcpConfigPath, mcpConfig, MCP_CONFIG_USER_KEYS)) {
1114
+ conflicts.push(mcpConfigPath);
1115
+ }
1082
1116
  return conflicts.map((filePath) => path2.relative(targetDir, filePath));
1083
1117
  }
1084
1118
  async function scaffoldEmbedded(choices, targetDir, onProgress) {
@@ -1129,6 +1163,12 @@ async function scaffoldEmbedded(choices, targetDir, onProgress) {
1129
1163
  if (staticDir !== targetDir && fs2.existsSync(path2.join(targetDir, "sdk-config.json"))) {
1130
1164
  report(`\u26A0\uFE0F A sdk-config.json also exists at the project root. The active one is ${sdkConfigPath}.`);
1131
1165
  }
1166
+ report("Creating MCP server configuration\u2026");
1167
+ const { config: mcpConfig, destRelPath: mcpDestRelPath } = resolveMcpConfig(aiCommonSrc, choices);
1168
+ writeManagedJson(path2.join(targetDir, mcpDestRelPath), mcpConfig, policy, MCP_CONFIG_USER_KEYS);
1169
+ if (aiTool === "cursor") {
1170
+ ensureGitignoreEntry(targetDir, mcpDestRelPath);
1171
+ }
1132
1172
  report("Installing dependencies (this may take a minute)\u2026");
1133
1173
  let installSucceeded = true;
1134
1174
  try {
@@ -1247,7 +1287,7 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
1247
1287
  process.exit(0);
1248
1288
  }
1249
1289
  p.log.info(pc.dim("\nNow let's connect to your Pega server."));
1250
- const serverUrl = await p.text({
1290
+ const serverUrlResult = await p.text({
1251
1291
  message: "What is your Pega server URL?",
1252
1292
  placeholder: "https://your-pega-server.com/prweb",
1253
1293
  validate(value) {
@@ -1255,10 +1295,11 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
1255
1295
  if (!value.startsWith("http")) return "Must be a valid URL starting with http:// or https://";
1256
1296
  }
1257
1297
  });
1258
- if (p.isCancel(serverUrl)) {
1298
+ if (p.isCancel(serverUrlResult)) {
1259
1299
  p.cancel("Operation cancelled.");
1260
1300
  process.exit(0);
1261
1301
  }
1302
+ const serverUrl = serverUrlResult.replace(/\/+$/, "");
1262
1303
  const appAlias = await p.text({
1263
1304
  message: "What is your Pega application alias?",
1264
1305
  placeholder: "MyApp",
@@ -1292,6 +1333,25 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
1292
1333
  p.cancel("Operation cancelled.");
1293
1334
  process.exit(0);
1294
1335
  }
1336
+ p.log.info(pc.dim("\nIf you've configured an MCP server for this app, we can wire it up too (optional)."));
1337
+ const mcpRuleNameResult = await p.text({
1338
+ message: "What is your Pega MCP rule name? (press Enter to skip)",
1339
+ placeholder: "SDKMCP"
1340
+ });
1341
+ if (p.isCancel(mcpRuleNameResult)) {
1342
+ p.cancel("Operation cancelled.");
1343
+ process.exit(0);
1344
+ }
1345
+ const mcpRuleInsKeyResult = await p.text({
1346
+ message: "What is your Pega MCP rule instance key? (press Enter to skip)",
1347
+ placeholder: "@baseclass!SDKMCP"
1348
+ });
1349
+ if (p.isCancel(mcpRuleInsKeyResult)) {
1350
+ p.cancel("Operation cancelled.");
1351
+ process.exit(0);
1352
+ }
1353
+ const mcpRuleName = mcpRuleNameResult || void 0;
1354
+ const mcpRuleInsKey = mcpRuleInsKeyResult || void 0;
1295
1355
  const embeddedTargetDir = cwd;
1296
1356
  p.note(
1297
1357
  [
@@ -1301,7 +1361,9 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
1301
1361
  `${pc.bold("Server")}: ${serverUrl}`,
1302
1362
  `${pc.bold("App Alias")}: ${appAlias}`,
1303
1363
  `${pc.bold("Client ID")}: ${clientId}`,
1304
- `${pc.bold("Operator")}: ${userIdentifier}`
1364
+ `${pc.bold("Operator")}: ${userIdentifier}`,
1365
+ `${pc.bold("MCP Rule")}: ${mcpRuleName ?? pc.dim("(not configured \u2014 markers left in generated file)")}`,
1366
+ `${pc.bold("MCP Ins Key")}: ${mcpRuleInsKey ?? pc.dim("(not configured \u2014 markers left in generated file)")}`
1305
1367
  ].join("\n"),
1306
1368
  "Configuration"
1307
1369
  );
@@ -1318,7 +1380,9 @@ Usage: ${pc.cyan("npx @pega/sdk init")}`);
1318
1380
  serverUrl,
1319
1381
  appAlias,
1320
1382
  clientId,
1321
- userIdentifier
1383
+ userIdentifier,
1384
+ mcpRuleName,
1385
+ mcpRuleInsKey
1322
1386
  };
1323
1387
  let conflicts = [];
1324
1388
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pega/sdk",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "Scaffold a Pega SDK application project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "pega-{MCPRuleName}": {
4
+ "type": "http",
5
+ "url": "{InfinityURL}/app/{AppAlias}/api/service/v1/mcp/{MCPRuleInsKey}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "servers": {
3
+ "pega-{MCPRuleName}": {
4
+ "type": "http",
5
+ "url": "{InfinityURL}/app/{AppAlias}/api/service/v1/mcp/{MCPRuleInsKey}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "mcpServers": {
3
+ "pega-{MCPRuleName}": {
4
+ "url": "{InfinityURL}/app/{AppAlias}/api/service/v1/mcp/{MCPRuleInsKey}",
5
+ "auth": {
6
+ "clientId": "{ClientId}",
7
+ "clientSecret": "<YOUR_CLIENT_SECRET>"
8
+ }
9
+ }
10
+ }
11
+ }