@sanity/cli 4.21.0-next.24 → 4.21.0-next.26

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.
@@ -3771,7 +3771,7 @@ const BlueprintsAddExampleUsed = telemetry.defineEvent({
3771
3771
  version: 1,
3772
3772
  name: "Blueprints Add Example Used",
3773
3773
  description: "User used --example flag with blueprints add command"
3774
- }), helpText$s = `
3774
+ }), helpText$t = `
3775
3775
  Arguments
3776
3776
  <type> Type of Resource to add (currently only 'function' is supported)
3777
3777
 
@@ -3813,7 +3813,7 @@ Examples:
3813
3813
  }, addBlueprintsCommand = {
3814
3814
  name: "add",
3815
3815
  group: "blueprints",
3816
- helpText: helpText$s,
3816
+ helpText: helpText$t,
3817
3817
  signature: "<type> [--name <name>] [--fn-type <document-create|document-delete|document-update|document-publish>] [--fn-lang <ts|js>] [--javascript]",
3818
3818
  description: "Add a Resource to a Blueprint",
3819
3819
  async action(args, context) {
@@ -3876,7 +3876,7 @@ Examples:
3876
3876
  signature: "[COMMAND]",
3877
3877
  isGroupRoot: !0,
3878
3878
  description: "Deploy and manage Sanity Blueprints and Stacks (IaC)"
3879
- }, helpText$r = `
3879
+ }, helpText$s = `
3880
3880
  Options
3881
3881
  --edit, -e Modify the configuration interactively, or directly when combined with ID flags.
3882
3882
  --project-id <id> Directly set the Project ID in the configuration. Requires --edit flag
@@ -3894,7 +3894,7 @@ Examples:
3894
3894
  }, configBlueprintsCommand = {
3895
3895
  name: "config",
3896
3896
  group: "blueprints",
3897
- helpText: helpText$r,
3897
+ helpText: helpText$s,
3898
3898
  signature: "[--edit] [--project-id <id>] [--stack-id <id>] [--verbose]",
3899
3899
  description: "View or edit local Blueprints configuration",
3900
3900
  async action(args, context) {
@@ -3921,7 +3921,7 @@ Examples:
3921
3921
  });
3922
3922
  if (!success) throw new Error(error2);
3923
3923
  }
3924
- }, helpText$q = `
3924
+ }, helpText$r = `
3925
3925
  Options
3926
3926
  --no-wait Do not wait for Stack deployment to complete
3927
3927
 
@@ -3936,7 +3936,7 @@ Examples:
3936
3936
  }, deployBlueprintsCommand = {
3937
3937
  name: "deploy",
3938
3938
  group: "blueprints",
3939
- helpText: helpText$q,
3939
+ helpText: helpText$r,
3940
3940
  signature: "[--no-wait]",
3941
3941
  description: "Deploy a Blueprint",
3942
3942
  async action(args, context) {
@@ -3959,7 +3959,7 @@ Examples:
3959
3959
  });
3960
3960
  if (!success) throw new Error(error2);
3961
3961
  }
3962
- }, helpText$p = `
3962
+ }, helpText$q = `
3963
3963
  Options
3964
3964
  --project-id Project associated with the Stack
3965
3965
  --stack-id Stack ID to destroy (defaults to current Stack)
@@ -3980,7 +3980,7 @@ Examples:
3980
3980
  }, destroyBlueprintsCommand = {
3981
3981
  name: "destroy",
3982
3982
  group: "blueprints",
3983
- helpText: helpText$p,
3983
+ helpText: helpText$q,
3984
3984
  signature: "[--project-id <value> --stack-id <value> --force] [--no-wait]",
3985
3985
  description: "Destroy a Blueprint Stack deployment and its resources (will not delete local files)",
3986
3986
  async action(args, context) {
@@ -4006,7 +4006,7 @@ Examples:
4006
4006
  });
4007
4007
  if (!success) throw new Error(error2);
4008
4008
  }
4009
- }, helpText$o = `
4009
+ }, helpText$p = `
4010
4010
  Options
4011
4011
  --verbose Provide detailed information about issues
4012
4012
 
@@ -4018,7 +4018,7 @@ Examples:
4018
4018
  }, doctorBlueprintsCommand = {
4019
4019
  name: "doctor",
4020
4020
  group: "blueprints",
4021
- helpText: helpText$o,
4021
+ helpText: helpText$p,
4022
4022
  signature: "[--verbose]",
4023
4023
  description: "Diagnose potential issues with Blueprint configuration",
4024
4024
  async action(args, context) {
@@ -4039,7 +4039,7 @@ Examples:
4039
4039
  });
4040
4040
  if (!success) throw new Error(error2);
4041
4041
  }
4042
- }, helpText$n = `
4042
+ }, helpText$o = `
4043
4043
  Examples:
4044
4044
  # Retrieve information about the current Stack
4045
4045
  sanity blueprints info
@@ -4048,7 +4048,7 @@ Examples:
4048
4048
  }, infoBlueprintsCommand = {
4049
4049
  name: "info",
4050
4050
  group: "blueprints",
4051
- helpText: helpText$n,
4051
+ helpText: helpText$o,
4052
4052
  signature: "",
4053
4053
  description: "Show information about a Blueprint Stack deployment",
4054
4054
  async action(args, context) {
@@ -4069,7 +4069,7 @@ Examples:
4069
4069
  });
4070
4070
  if (!success) throw new Error(error2);
4071
4071
  }
4072
- }, helpText$m = `
4072
+ }, helpText$n = `
4073
4073
  Arguments
4074
4074
  [dir] Path to initialize the Blueprint in
4075
4075
 
@@ -4094,7 +4094,7 @@ Examples:
4094
4094
  }, initBlueprintsCommand = {
4095
4095
  name: "init",
4096
4096
  group: "blueprints",
4097
- helpText: helpText$m,
4097
+ helpText: helpText$n,
4098
4098
  signature: "[dir] [--blueprint-type <type>] [--project-id <id>]",
4099
4099
  description: "Initialize a new Blueprint",
4100
4100
  async action(args, context) {
@@ -4135,7 +4135,7 @@ Examples:
4135
4135
  });
4136
4136
  if (!success) throw new Error(error2);
4137
4137
  }
4138
- }, helpText$l = `
4138
+ }, helpText$m = `
4139
4139
  Options
4140
4140
  --watch, -w Watch for new Stack logs (streaming mode)
4141
4141
 
@@ -4150,7 +4150,7 @@ Examples:
4150
4150
  }, logsBlueprintsCommand = {
4151
4151
  name: "logs",
4152
4152
  group: "blueprints",
4153
- helpText: helpText$l,
4153
+ helpText: helpText$m,
4154
4154
  signature: "[--watch] [-w]",
4155
4155
  description: "Display logs for a Blueprint Stack deployment",
4156
4156
  async action(args, context) {
@@ -4173,7 +4173,7 @@ Examples:
4173
4173
  });
4174
4174
  if (streaming && await streaming, !success) throw new Error(error2);
4175
4175
  }
4176
- }, helpText$k = `
4176
+ }, helpText$l = `
4177
4177
  Safe to run at any time. Will not modify any Resources.
4178
4178
 
4179
4179
  Options
@@ -4187,7 +4187,7 @@ Examples:
4187
4187
  }, planBlueprintsCommand = {
4188
4188
  name: "plan",
4189
4189
  group: "blueprints",
4190
- helpText: helpText$k,
4190
+ helpText: helpText$l,
4191
4191
  signature: "",
4192
4192
  description: "Enumerate resources to be deployed - will not modify any resources",
4193
4193
  async action(args, context) {
@@ -4210,7 +4210,7 @@ Examples:
4210
4210
  });
4211
4211
  if (!success) throw new Error(error2);
4212
4212
  }
4213
- }, helpText$j = `
4213
+ }, helpText$k = `
4214
4214
  Options
4215
4215
  --project-id <id> Project ID to use
4216
4216
 
@@ -4225,7 +4225,7 @@ Examples:
4225
4225
  }, stacksBlueprintsCommand = {
4226
4226
  name: "stacks",
4227
4227
  group: "blueprints",
4228
- helpText: helpText$j,
4228
+ helpText: helpText$k,
4229
4229
  signature: "[--project-id <value>]",
4230
4230
  description: "List all Blueprint Stacks",
4231
4231
  hideFromHelp: !1,
@@ -4394,7 +4394,7 @@ function ensureNpx() {
4394
4394
  );
4395
4395
  }
4396
4396
  }
4397
- const helpText$i = `
4397
+ const helpText$j = `
4398
4398
  Runs a given code modification script on the current studio folder.
4399
4399
  Running the command without a specified codemod name will list available transformations.
4400
4400
 
@@ -4416,7 +4416,7 @@ Examples
4416
4416
  name: "codemod",
4417
4417
  signature: "[CODEMOD_NAME]",
4418
4418
  description: "Updates Sanity Studio codebase with a code modification script",
4419
- helpText: helpText$i,
4419
+ helpText: helpText$j,
4420
4420
  action: codemodAction
4421
4421
  };
4422
4422
  var lodash_isplainobject, hasRequiredLodash_isplainobject;
@@ -6109,7 +6109,7 @@ function normalizePath(input2) {
6109
6109
  const sanityDocsPrefix = "https://www.sanity.io";
6110
6110
  return input2.startsWith(sanityDocsPrefix) ? input2.replace(sanityDocsPrefix, "") : input2;
6111
6111
  }
6112
- const helpText$h = `
6112
+ const helpText$i = `
6113
6113
  Arguments
6114
6114
  <path> Path or URL to article, found in search results and docs content as links
6115
6115
 
@@ -6127,13 +6127,13 @@ Examples
6127
6127
  `, readCommand = {
6128
6128
  name: "read",
6129
6129
  group: "docs",
6130
- helpText: helpText$h,
6130
+ helpText: helpText$i,
6131
6131
  signature: "<path|url> [-w, --web]",
6132
6132
  description: "Read an article in terminal",
6133
6133
  async action(args, context) {
6134
6134
  const { output } = context, flags = args.extOptions, input2 = args.argsWithoutOptions[0];
6135
6135
  if (!input2 || typeof input2 != "string") {
6136
- output.error("Please provide an article path or URL"), output.print(""), output.print(helpText$h), process.exit(1);
6136
+ output.error("Please provide an article path or URL"), output.print(""), output.print(helpText$i), process.exit(1);
6137
6137
  return;
6138
6138
  }
6139
6139
  const path2 = normalizePath(input2);
@@ -6163,7 +6163,7 @@ async function searchDocs(options2, context) {
6163
6163
  const results = await response.json();
6164
6164
  return Array.isArray(results) ? results.slice(0, limit) : [];
6165
6165
  }
6166
- const isInteractive$1 = process.stdout.isTTY && process.env.TERM !== "dumb" && !("CI" in process.env), helpText$g = `
6166
+ const isInteractive$1 = process.stdout.isTTY && process.env.TERM !== "dumb" && !("CI" in process.env), helpText$h = `
6167
6167
  Arguments
6168
6168
  <query> Search query for documentation
6169
6169
 
@@ -6184,7 +6184,7 @@ Examples
6184
6184
  }, searchCommand = {
6185
6185
  name: "search",
6186
6186
  group: "docs",
6187
- helpText: helpText$g,
6187
+ helpText: helpText$h,
6188
6188
  signature: "<query> [--limit <limit>]",
6189
6189
  description: "Search Sanity docs",
6190
6190
  async action(args, context) {
@@ -6238,7 +6238,7 @@ Found ${results.length} result(s):
6238
6238
  }
6239
6239
  }
6240
6240
  }
6241
- }, helpText$f = `
6241
+ }, helpText$g = `
6242
6242
  Options
6243
6243
  --port <port> Port to start emulator on
6244
6244
  --open Open dev server in a new browser tab
@@ -6262,7 +6262,7 @@ Examples
6262
6262
  }, devFunctionsCommand = {
6263
6263
  name: "dev",
6264
6264
  group: "functions",
6265
- helpText: helpText$f,
6265
+ helpText: helpText$g,
6266
6266
  signature: "[--host <host> --port <port> --open]",
6267
6267
  description: "Start the Sanity Function emulator",
6268
6268
  async action(args, context) {
@@ -6284,7 +6284,7 @@ Examples
6284
6284
  if (!success) throw new Error(error2);
6285
6285
  shouldOpen && await open(`http://${flags.host}:${flags.port}`);
6286
6286
  }
6287
- }, helpText$e = `
6287
+ }, helpText$f = `
6288
6288
  Commands
6289
6289
  add Add or update an environment variable
6290
6290
  list List the environment variables
@@ -6307,7 +6307,7 @@ Examples
6307
6307
  `, envFunctionsCommand = {
6308
6308
  name: "env",
6309
6309
  group: "functions",
6310
- helpText: helpText$e,
6310
+ helpText: helpText$f,
6311
6311
  signature: "<add|list|remove> <name> [key] [value]",
6312
6312
  description: "Add or remove an environment variable or list environment variables for a Sanity function",
6313
6313
  async action(args, context) {
@@ -6363,7 +6363,7 @@ Examples
6363
6363
  signature: "[COMMAND]",
6364
6364
  isGroupRoot: !0,
6365
6365
  description: "Manage, test, and observe Sanity Functions"
6366
- }, helpText$d = `
6366
+ }, helpText$e = `
6367
6367
  Arguments
6368
6368
  <name> The name of the Function to retrieve logs for
6369
6369
 
@@ -6400,7 +6400,7 @@ Examples
6400
6400
  }, logsFunctionsCommand = {
6401
6401
  name: "logs",
6402
6402
  group: "functions",
6403
- helpText: helpText$d,
6403
+ helpText: helpText$e,
6404
6404
  signature: "<name> [--limit <number>] [--json] [--utc] [--delete [--force]] [--watch]",
6405
6405
  description: "Retrieve or delete logs for a Sanity Function",
6406
6406
  async action(args, context) {
@@ -6425,7 +6425,7 @@ Examples
6425
6425
  });
6426
6426
  if (!success) throw new Error(error2);
6427
6427
  }
6428
- }, helpText$c = `
6428
+ }, helpText$d = `
6429
6429
  Arguments
6430
6430
  <name> The name of the Sanity Function
6431
6431
 
@@ -6467,7 +6467,7 @@ Examples
6467
6467
  }, testFunctionsCommand = {
6468
6468
  name: "test",
6469
6469
  group: "functions",
6470
- helpText: helpText$c,
6470
+ helpText: helpText$d,
6471
6471
  signature: "<name> [--event create|update|delete] [--data <json>] [--data-before <json>] [--data-after <json>] [--file <filename>] [--file-before <filename>] [--file-after <filename>] [--document-id <id>] [--document-id-before <id>] [--document-id-before <id>] [--timeout <seconds>] [--api <version>] [--dataset <name>] [--project-id <id>] [--media-library-id <id>] [--with-user-token]",
6472
6472
  description: "Invoke a local Sanity Function",
6473
6473
  async action(args, context) {
@@ -6574,11 +6574,11 @@ const commonMistakes = { get: "list" }, levenThreshold = 3, coreCommands = [
6574
6574
  "undeploy",
6575
6575
  "uninstall",
6576
6576
  "users"
6577
- ], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$b = `
6577
+ ], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$c = `
6578
6578
  Run the command again within a Sanity project directory, where "sanity"
6579
6579
  is installed as a dependency.`;
6580
6580
  function getNoSuchCommandText(cmdName, parentGroupName, groups) {
6581
- return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$b}` : suggestCommand(cmdName, groups ? groups.default : []);
6581
+ return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$c}` : suggestCommand(cmdName, groups ? groups.default : []);
6582
6582
  }
6583
6583
  function suggestCommand(cmdName, group, parentGroupName = null) {
6584
6584
  const closest = group.filter((command2) => !discouragedCommands.includes(command2.name)).map((command2) => leven(command2.name, cmdName)).reduce(
@@ -42009,6 +42009,106 @@ function readPackageJson(filePath) {
42009
42009
  return;
42010
42010
  }
42011
42011
  }
42012
+ async function detectAvailableEditors() {
42013
+ const editors = [], homeDir = os__default.default.homedir(), cursorDir = path__default.default.join(homeDir, ".cursor");
42014
+ fs$1.existsSync(cursorDir) && editors.push({
42015
+ name: "Cursor",
42016
+ configPath: path__default.default.join(cursorDir, "mcp.json"),
42017
+ configKey: "mcpServers"
42018
+ });
42019
+ let vscodeConfigDir = null;
42020
+ switch (process.platform) {
42021
+ case "darwin":
42022
+ vscodeConfigDir = path__default.default.join(homeDir, "Library/Application Support/Code/User");
42023
+ break;
42024
+ case "win32":
42025
+ process.env.APPDATA && (vscodeConfigDir = path__default.default.join(process.env.APPDATA, "Code/User"));
42026
+ break;
42027
+ default:
42028
+ vscodeConfigDir = path__default.default.join(homeDir, ".config/Code/User");
42029
+ }
42030
+ vscodeConfigDir && fs$1.existsSync(vscodeConfigDir) && editors.push({
42031
+ name: "VS Code",
42032
+ configPath: path__default.default.join(vscodeConfigDir, "mcp.json"),
42033
+ configKey: "servers"
42034
+ });
42035
+ try {
42036
+ await execa("claude", ["--version"], { stdio: "pipe", timeout: 5e3 }), editors.push({
42037
+ name: "Claude Code",
42038
+ configPath: path__default.default.join(homeDir, ".claude.json"),
42039
+ configKey: "mcpServers"
42040
+ });
42041
+ } catch {
42042
+ }
42043
+ return editors;
42044
+ }
42045
+ async function promptForMCPSetup(prompt2, detectedEditors, editorsWithExisting) {
42046
+ const editorChoices = detectedEditors.map((e) => {
42047
+ const isConfigured = editorsWithExisting.some((existing) => existing.name === e.name);
42048
+ return {
42049
+ name: isConfigured ? `${e.name} (already installed)` : e.name,
42050
+ value: e.name,
42051
+ checked: !isConfigured
42052
+ // Only pre-select if NOT already configured
42053
+ };
42054
+ }), selectedNames = (await prompt2([
42055
+ {
42056
+ type: "checkbox",
42057
+ name: "selectedEditors",
42058
+ message: "Configure Sanity MCP server",
42059
+ choices: editorChoices
42060
+ }
42061
+ ])).selectedEditors;
42062
+ return !selectedNames || selectedNames.length === 0 ? null : detectedEditors.filter((e) => selectedNames.includes(e.name));
42063
+ }
42064
+ async function getEditorsWithExistingConfig(editors) {
42065
+ const configured = [];
42066
+ for (const editor2 of editors)
42067
+ if (fs$1.existsSync(editor2.configPath))
42068
+ try {
42069
+ const content = await fs__default.default.readFile(editor2.configPath, "utf-8"), config2 = JSON.parse(content);
42070
+ (config2[editor2.configKey]?.sanity || config2[editor2.configKey]?.Sanity) && configured.push(editor2);
42071
+ } catch (err) {
42072
+ getCliConfig.debug("Could not read MCP config for %s: %s", editor2.name, err);
42073
+ }
42074
+ return configured;
42075
+ }
42076
+ async function writeMCPConfig(editor2) {
42077
+ const configPath = editor2.configPath;
42078
+ let existingConfig = {};
42079
+ if (fs$1.existsSync(configPath))
42080
+ try {
42081
+ const content = await fs__default.default.readFile(configPath, "utf-8");
42082
+ existingConfig = JSON.parse(content);
42083
+ } catch {
42084
+ getCliConfig.debug(`Warning: Could not parse ${configPath}. Creating new config.`);
42085
+ }
42086
+ const serverKey = editor2.configKey;
42087
+ existingConfig[serverKey] || (existingConfig[serverKey] = {});
42088
+ const existingKey = existingConfig[serverKey].Sanity ? "Sanity" : "sanity";
42089
+ existingConfig[serverKey][existingKey] = {
42090
+ command: "npx",
42091
+ args: ["-y", "@sanity/mcp"]
42092
+ }, await fs__default.default.mkdir(path__default.default.dirname(configPath), { recursive: !0 }), await fs__default.default.writeFile(configPath, JSON.stringify(existingConfig, null, 2), "utf-8");
42093
+ }
42094
+ async function setupMCP(context, options2) {
42095
+ const { output, prompt: prompt2 } = context;
42096
+ try {
42097
+ if (options2.mcp === !1)
42098
+ return output.warn("Skipping MCP configuration due to --no-mcp flag"), null;
42099
+ const detected = await detectAvailableEditors();
42100
+ if (detected.length === 0)
42101
+ return output.warn("No supported AI editors detected (Cursor, VS Code, Claude Code)"), null;
42102
+ const editorsWithExisting = await getEditorsWithExistingConfig(detected), selected = await promptForMCPSetup(prompt2, detected, editorsWithExisting);
42103
+ if (!selected || selected.length === 0)
42104
+ return null;
42105
+ for (const editor2 of selected)
42106
+ await writeMCPConfig(editor2), output.success(`MCP configured for ${editor2.name}`);
42107
+ return selected;
42108
+ } catch (error2) {
42109
+ return output.warn(`Could not configure MCP: ${error2 instanceof Error ? error2.message : `${error2}`}`), output.warn("You can set up MCP manually later using https://mcp.sanity.io"), null;
42110
+ }
42111
+ }
42012
42112
  const authorType = `import {UserIcon} from '@sanity/icons'
42013
42113
  import {defineArrayMember, defineField, defineType} from 'sanity'
42014
42114
 
@@ -42574,7 +42674,7 @@ You can find your project on Sanity Manage \u2014 https://www.sanity.io/manage/p
42574
42674
  semver__default.default.coerce(detectedFramework?.detectedVersion)?.major === 15 && isUsingReact19 && (warn("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"), warn("\u2502 \u2502"), warn("\u2502 It looks like you are using Next.js 15 and React 19 \u2502"), warn("\u2502 Please read our compatibility guide. \u2502"), warn("\u2502 https://www.sanity.io/help/react-19 \u2502"), warn("\u2502 \u2502"), warn("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"));
42575
42675
  }
42576
42676
  }
42577
- let useTypeScript = flagOrDefault("typescript", !0);
42677
+ let useTypeScript = flagOrDefault("typescript", !0), mcpConfigured = null;
42578
42678
  if (initNext) {
42579
42679
  shouldPromptFor("typescript") && (useTypeScript = await promptForTypeScript(prompt2)), trace.log({ step: "useTypeScript", selectedOption: useTypeScript ? "yes" : "no" });
42580
42680
  const fileExtension = useTypeScript ? "ts" : "js";
@@ -42649,6 +42749,7 @@ You can find your project on Sanity Manage \u2014 https://www.sanity.io/manage/p
42649
42749
  print(`Failed to add ${nextjsLocalDevOrigin} to CORS origins`, error2);
42650
42750
  });
42651
42751
  }
42752
+ mcpConfigured = await setupMCP(context, { mcp: cliFlags.mcp });
42652
42753
  const chosen = await resolvePackageManager(workDir);
42653
42754
  trace.log({ step: "selectPackageManager", selectedOption: chosen });
42654
42755
  const packages = ["@sanity/vision@4", "sanity@4", "@sanity/image-url@1", "styled-components@6"];
@@ -42668,10 +42769,16 @@ You can find your project on Sanity Manage \u2014 https://www.sanity.io/manage/p
42668
42769
  cwd: workDir,
42669
42770
  stdio: "inherit"
42670
42771
  };
42671
- chosen === "npm" ? await execa("npm", ["install", "--legacy-peer-deps", "next-sanity@11"], execOptions) : chosen === "yarn" ? await execa("npx", ["install-peerdeps", "--yarn", "next-sanity@11"], execOptions) : chosen === "pnpm" && await execa("pnpm", ["install", "next-sanity@11"], execOptions), print(
42772
+ if (chosen === "npm" ? await execa("npm", ["install", "--legacy-peer-deps", "next-sanity@11"], execOptions) : chosen === "yarn" ? await execa("npx", ["install-peerdeps", "--yarn", "next-sanity@11"], execOptions) : chosen === "pnpm" && await execa("pnpm", ["install", "next-sanity@11"], execOptions), print(
42672
42773
  `
42673
42774
  ${chalk2.green("Success!")} Your Sanity configuration files has been added to this project`
42674
- );
42775
+ ), mcpConfigured && mcpConfigured.length > 0) {
42776
+ const editorNames = new Intl.ListFormat("en").format(mcpConfigured.map((e) => e.name));
42777
+ print(
42778
+ `
42779
+ Sanity MCP server has been configured for ${editorNames}. You might need to restart your editor for this to take effect.`
42780
+ ), print(`Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`);
42781
+ }
42675
42782
  return;
42676
42783
  }
42677
42784
  function countNestedFolders(path2) {
@@ -42704,7 +42811,7 @@ ${chalk2.green("Success!")} Your Sanity configuration files has been added to th
42704
42811
  const template = templates[templateName];
42705
42812
  if (!remoteTemplateInfo && !template)
42706
42813
  throw new Error(`Template "${templateName}" not found`);
42707
- !remoteTemplateInfo && template && (template.typescriptOnly === !0 ? useTypeScript = !0 : shouldPromptFor("typescript") && (useTypeScript = await promptForTypeScript(prompt2), trace.log({ step: "useTypeScript", selectedOption: useTypeScript ? "yes" : "no" })));
42814
+ !remoteTemplateInfo && template && (template.typescriptOnly === !0 ? useTypeScript = !0 : shouldPromptFor("typescript") && (useTypeScript = await promptForTypeScript(prompt2), trace.log({ step: "useTypeScript", selectedOption: useTypeScript ? "yes" : "no" }))), mcpConfigured = await setupMCP(context, { mcp: cliFlags.mcp });
42708
42815
  let autoUpdates = !0;
42709
42816
  typeof cliFlags["auto-updates"] == "boolean" && (autoUpdates = cliFlags["auto-updates"]);
42710
42817
  const shouldImport = !unattended && template?.datasetUrl && await promptForDatasetImport(template.importPrompt);
@@ -42735,14 +42842,33 @@ ${chalk2.green("Success!")} Your Sanity configuration files has been added to th
42735
42842
  bun: "bun dev",
42736
42843
  manual: "npm run dev"
42737
42844
  }[pkgManager], isCurrentDir = outputPath === process.cwd(), goToProjectDir = `(${chalk2.cyan(`cd ${outputPath}`)} to navigate to your new project directory)`;
42738
- isAppTemplate ? (print(`\u2705 ${chalk2.green.bold("Success!")} Your custom app has been scaffolded.`), isCurrentDir || print(goToProjectDir), print(
42739
- `
42845
+ if (isAppTemplate) {
42846
+ if (print(`\u2705 ${chalk2.green.bold("Success!")} Your custom app has been scaffolded.`), isCurrentDir || print(goToProjectDir), print(
42847
+ `
42740
42848
  ${chalk2.bold("Next")}, configure the project(s) and dataset(s) your app should work with.`
42741
- ), print("\nGet started in `src/App.tsx`, or refer to our documentation for a walkthrough:"), print(chalk2.blue.underline("https://www.sanity.io/docs/app-sdk/sdk-configuration")), print(`
42742
- `), print("Other helpful commands:"), print("npx sanity docs to open the documentation in a browser"), print("npx sanity dev to start the development server for your app"), print("npx sanity deploy to deploy your app")) : (print(`\u2705 ${chalk2.green.bold("Success!")} Your Studio has been created.`), isCurrentDir || print(goToProjectDir), print(
42743
- `Get started by running ${chalk2.cyan(devCommand)} to launch your Studio\u2019s development server`
42744
- ), print(`
42745
- `), print("Other helpful commands:"), print("npx sanity docs to open the documentation in a browser"), print("npx sanity manage to open the project settings in a browser"), print("npx sanity help to explore the CLI manual")), isFirstProject && (trace.log({ step: "sendCommunityInvite", selectedOption: "yes" }), print(`
42849
+ ), print("\nGet started in `src/App.tsx`, or refer to our documentation for a walkthrough:"), print(chalk2.blue.underline("https://www.sanity.io/docs/app-sdk/sdk-configuration")), mcpConfigured && mcpConfigured.length > 0) {
42850
+ const editorNames = new Intl.ListFormat("en").format(mcpConfigured.map((e) => e.name));
42851
+ print(
42852
+ `
42853
+ Sanity MCP server has been configured for ${editorNames}. You might need to restart your editor for this to take effect.`
42854
+ ), print(`Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`);
42855
+ }
42856
+ print(`
42857
+ `), print("Other helpful commands:"), print("npx sanity docs to open the documentation in a browser"), print("npx sanity dev to start the development server for your app"), print("npx sanity deploy to deploy your app");
42858
+ } else {
42859
+ if (print(`\u2705 ${chalk2.green.bold("Success!")} Your Studio has been created.`), isCurrentDir || print(goToProjectDir), print(
42860
+ `Get started by running ${chalk2.cyan(devCommand)} to launch your Studio\u2019s development server`
42861
+ ), mcpConfigured && mcpConfigured.length > 0) {
42862
+ const editorNames = new Intl.ListFormat("en").format(mcpConfigured.map((e) => e.name));
42863
+ print(
42864
+ `
42865
+ Sanity MCP server has been configured for ${editorNames}. You might need to restart your editor for this to take effect.`
42866
+ ), print(`Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`);
42867
+ }
42868
+ print(`
42869
+ `), print("Other helpful commands:"), print("npx sanity docs to open the documentation in a browser"), print("npx sanity manage to open the project settings in a browser"), print("npx sanity help to explore the CLI manual");
42870
+ }
42871
+ isFirstProject && (trace.log({ step: "sendCommunityInvite", selectedOption: "yes" }), print(`
42746
42872
  Join the Sanity community: ${chalk2.cyan("https://www.sanity.io/community/join")}`), print(`We look forward to seeing you there!
42747
42873
  `)), trace.complete();
42748
42874
  async function getOrCreateUser() {
@@ -43310,7 +43436,7 @@ function getImportCommand(outputPath, studioVersion) {
43310
43436
  );
43311
43437
  }
43312
43438
  }
43313
- const helpText$a = `
43439
+ const helpText$b = `
43314
43440
  Options
43315
43441
  -y, --yes Use unattended mode, accepting defaults and using only flags for choices
43316
43442
  --project, --project-id <projectId> Project ID to use for the studio
@@ -43330,6 +43456,7 @@ Options
43330
43456
  --package-manager <name> Specify which package manager to use [allowed: ${allowedPackageManagersString}]
43331
43457
  --auto-updates Enable/disable auto updates of studio versions (default: true)
43332
43458
  --overwrite-files Overwrite existing files (default: false)
43459
+ --no-mcp Skip AI editor integration (MCP) setup
43333
43460
 
43334
43461
  Some flags are used when initializing a project in a specific framework.
43335
43462
 
@@ -43337,7 +43464,7 @@ Next.js
43337
43464
  --nextjs-add-config-files Add config files to Next.js project (default: true)
43338
43465
  --nextjs-embed-studio Embed the Studio in Next.js application (default: true)
43339
43466
  --nextjs-append-env Append project ID and dataset to .env file (default: true)
43340
-
43467
+
43341
43468
  Examples
43342
43469
  # Initialize a new project, prompt for required information along the way
43343
43470
  sanity init
@@ -43363,7 +43490,7 @@ Examples
43363
43490
  name: "init",
43364
43491
  signature: "",
43365
43492
  description: "Initializes a new Sanity Studio and/or project",
43366
- helpText: helpText$a,
43493
+ helpText: helpText$b,
43367
43494
  action: async (args, context) => {
43368
43495
  const [type2] = args.argsWithoutOptions;
43369
43496
  if (type2)
@@ -43398,7 +43525,7 @@ Examples
43398
43525
  const { output } = context, { print } = output, url = "https://www.sanity.io/learn";
43399
43526
  print(`Opening ${url}`), await open(url);
43400
43527
  }
43401
- }, helpText$9 = `
43528
+ }, helpText$a = `
43402
43529
  Options
43403
43530
  --sso <slug> Log in using Single Sign On, using the given slug
43404
43531
  --provider <providerId> Authenticate against a specific provider
@@ -43416,16 +43543,16 @@ Examples
43416
43543
  `, loginCommand = {
43417
43544
  name: "login",
43418
43545
  signature: "[--sso <slug>] [--provider <providerId>] [--no-open]",
43419
- helpText: helpText$9,
43546
+ helpText: helpText$a,
43420
43547
  description: "Authenticates the CLI for access to Sanity projects",
43421
43548
  action: login
43422
- }, helpText$8 = `
43549
+ }, helpText$9 = `
43423
43550
  Examples
43424
43551
  # Log out of the CLI
43425
43552
  sanity logout
43426
43553
  `, logoutCommand = {
43427
43554
  name: "logout",
43428
- helpText: helpText$8,
43555
+ helpText: helpText$9,
43429
43556
  signature: "logout",
43430
43557
  description: "Logs out the CLI from the current user session",
43431
43558
  async action(args, { output, apiClient }) {
@@ -43455,6 +43582,29 @@ ${err.message}`));
43455
43582
  const { output, cliConfig } = context, { print } = output, projectId = cliConfig?.api?.projectId, url = projectId ? `https://www.sanity.io/manage/project/${projectId}` : "https://www.sanity.io/manage/";
43456
43583
  print(`Opening ${url}`), await open(url);
43457
43584
  }
43585
+ }, helpText$8 = `
43586
+ Examples
43587
+ # Configure Sanity MCP server for detected AI editors
43588
+ sanity mcp configure
43589
+ `, configureMcpCommand = {
43590
+ name: "configure",
43591
+ group: "mcp",
43592
+ helpText: helpText$8,
43593
+ signature: "",
43594
+ description: "Configure Sanity MCP server for AI editors (Cursor, VS Code, Claude Code)",
43595
+ async action(args, context) {
43596
+ const { output } = context;
43597
+ if ((await detectAvailableEditors()).length === 0) {
43598
+ output.print("No supported AI editors detected (Cursor, VS Code, Claude Code)."), output.print("Visit https://mcp.sanity.io for manual setup instructions.");
43599
+ return;
43600
+ }
43601
+ await setupMCP(context, { mcp: !0 });
43602
+ }
43603
+ }, mcpGroup = {
43604
+ name: "mcp",
43605
+ signature: "[COMMAND]",
43606
+ isGroupRoot: !0,
43607
+ description: "Manages MCP (Model Context Protocol) server configuration for AI editors"
43458
43608
  };
43459
43609
  async function getSpec(options2, context) {
43460
43610
  const { output } = context;
@@ -44098,6 +44248,8 @@ const baseCommands = [
44098
44248
  disableTelemetryCommand,
44099
44249
  enableTelemetryCommand,
44100
44250
  telemetryStatusCommand,
44251
+ mcpGroup,
44252
+ configureMcpCommand,
44101
44253
  generateTypegenCommand,
44102
44254
  typegenGroup,
44103
44255
  functionsGroup,