@sanity/cli 5.3.0-next.8 → 5.3.0-next.80

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.
@@ -18,7 +18,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
18
18
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
19
19
  mod
20
20
  ));
21
- var os = require("node:os"), chalk = require("chalk"), loadEnv = require("./loadEnv.js"), require$$0$5 = require("path"), require$$1$2 = require("module"), require$$0$4 = require("fs"), semver = require("semver"), telemetry = require("@sanity/telemetry"), childProcess = require("node:child_process"), fs$1 = require("node:fs"), path$3 = require("node:path"), fs = require("node:fs/promises"), util$3 = require("node:util"), require$$0$6 = require("os"), getLatestVersion = require("get-latest-version"), pkgDir = require("pkg-dir"), client$1 = require("@sanity/client"), require$$0$7 = require("constants"), require$$0$8 = require("stream"), require$$0$9 = require("util"), require$$0$a = require("assert"), require$$0$b = require("events"), require$$3$1 = require("crypto"), require$$1$3 = require("child_process"), getCliConfig = require("./getCliConfig.js"), require$$0$c = require("fs/promises"), require$$0$d = require("buffer"), journeyConfig = require("./journeyConfig.js"), Stream = require("node:stream"), promises$1 = require("node:stream/promises"), templateValidator = require("@sanity/template-validator"), require$$2$1 = require("string_decoder"), require$$0$e = require("zlib"), require$$7$1 = require("process"), http = require("node:http"), traverse = require("@babel/traverse"), node_url = require("node:url"), node_events = require("node:events"), node_string_decoder = require("node:string_decoder"), process$2 = require("node:process"), require$$2$2 = require("readline"), require$$0$f = require("tty");
21
+ var os = require("node:os"), chalk = require("chalk"), loadEnv = require("./loadEnv.js"), require$$0$5 = require("path"), require$$1$2 = require("module"), require$$0$4 = require("fs"), semver = require("semver"), telemetry = require("@sanity/telemetry"), childProcess = require("node:child_process"), fs$1 = require("node:fs"), path$3 = require("node:path"), fs = require("node:fs/promises"), util$3 = require("node:util"), require$$0$6 = require("os"), getLatestVersion = require("get-latest-version"), pkgDir = require("pkg-dir"), client$1 = require("@sanity/client"), require$$0$7 = require("constants"), require$$0$8 = require("stream"), require$$0$9 = require("util"), require$$0$a = require("assert"), require$$0$b = require("events"), require$$3$1 = require("crypto"), require$$1$3 = require("child_process"), getCliConfig = require("./getCliConfig.js"), require$$0$c = require("fs/promises"), require$$0$d = require("buffer"), journeyConfig = require("./journeyConfig.js"), Stream = require("node:stream"), promises$1 = require("node:stream/promises"), templateValidator = require("@sanity/template-validator"), require$$2$1 = require("string_decoder"), require$$0$e = require("zlib"), require$$7$1 = require("process"), http = require("node:http"), jsoncParser = require("jsonc-parser"), traverse = require("@babel/traverse"), node_url = require("node:url"), node_events = require("node:events"), node_string_decoder = require("node:string_decoder"), process$2 = require("node:process"), require$$2$2 = require("readline"), require$$0$f = require("tty");
22
22
  function _interopDefaultCompat(e) {
23
23
  return e && typeof e == "object" && "default" in e ? e : { default: e };
24
24
  }
@@ -2411,7 +2411,7 @@ function trimHash(version2) {
2411
2411
  }
2412
2412
  const BASE_URL = "https://www.sanity.io/docs/help/";
2413
2413
  function generateHelpUrl(slug) {
2414
- return BASE_URL + slug;
2414
+ return `${BASE_URL}${slug}`;
2415
2415
  }
2416
2416
  var polyfills, hasRequiredPolyfills;
2417
2417
  function requirePolyfills() {
@@ -15818,7 +15818,7 @@ var cleanStack$2, hasRequiredCleanStack$1;
15818
15818
  function requireCleanStack$1() {
15819
15819
  if (hasRequiredCleanStack$1) return cleanStack$2;
15820
15820
  hasRequiredCleanStack$1 = 1;
15821
- const os2 = require$$0__default$2.default, extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/, pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/, homeDir = typeof os2.homedir > "u" ? "" : os2.homedir();
15821
+ const os2 = require$$0__default$2.default, extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/, pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/, homeDir2 = typeof os2.homedir > "u" ? "" : os2.homedir();
15822
15822
  return cleanStack$2 = (stack2, options2) => (options2 = Object.assign({ pretty: !1 }, options2), stack2.replace(/\\/g, "/").split(`
15823
15823
  `).filter((line3) => {
15824
15824
  const pathMatches = line3.match(extractPathRegex);
@@ -15826,7 +15826,7 @@ function requireCleanStack$1() {
15826
15826
  return !0;
15827
15827
  const match2 = pathMatches[1];
15828
15828
  return match2.includes(".app/Contents/Resources/electron.asar") || match2.includes(".app/Contents/Resources/default_app.asar") ? !1 : !pathRegex.test(match2);
15829
- }).filter((line3) => line3.trim() !== "").map((line3) => options2.pretty ? line3.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, "~"))) : line3).join(`
15829
+ }).filter((line3) => line3.trim() !== "").map((line3) => options2.pretty ? line3.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir2, "~"))) : line3).join(`
15830
15830
  `)), cleanStack$2;
15831
15831
  }
15832
15832
  var aggregateError, hasRequiredAggregateError;
@@ -19588,7 +19588,30 @@ const cliPackageManager = {
19588
19588
  getInstallCommand,
19589
19589
  getPackageManagerChoice,
19590
19590
  installNewPackages
19591
- };
19591
+ }, DEFAULT_MESSAGE = 'To set up your project with the MCP server, restart {{editorNames}} and type **"Get started with Sanity"** in the chat.';
19592
+ function applyCyanFormatting(text, chalk2) {
19593
+ return text.replace(/\*\*([^*]+)\*\*/g, (_, content) => chalk2.cyan(content));
19594
+ }
19595
+ function interpolateTemplate(template, editorNames) {
19596
+ return template.replace(/\{\{editorNames\}\}/g, editorNames);
19597
+ }
19598
+ async function fetchPostInitPrompt({
19599
+ client: client2,
19600
+ editorNames,
19601
+ chalk: chalk2
19602
+ }) {
19603
+ try {
19604
+ const template = (await client2.request({
19605
+ method: "GET",
19606
+ uri: "/journey/mcp/post-init-prompt",
19607
+ timeout: 1e3
19608
+ }))?.message || DEFAULT_MESSAGE, interpolated = interpolateTemplate(template, editorNames);
19609
+ return applyCyanFormatting(interpolated, chalk2);
19610
+ } catch {
19611
+ const interpolated = interpolateTemplate(DEFAULT_MESSAGE, editorNames);
19612
+ return applyCyanFormatting(interpolated, chalk2);
19613
+ }
19614
+ }
19592
19615
  var ini = {}, hasRequiredIni;
19593
19616
  function requireIni() {
19594
19617
  if (hasRequiredIni) return ini;
@@ -23447,7 +23470,7 @@ function isGithubRepoShorthand(value) {
23447
23470
  return URL.canParse(value) ? !1 : /^[\w-]+\/[\w-.]+(\/[@\w-.]+)*$/.test(value);
23448
23471
  }
23449
23472
  function isGithubRepoUrl(value) {
23450
- if (URL.canParse(value) === !1)
23473
+ if (!URL.canParse(value))
23451
23474
  return !1;
23452
23475
  const url = new URL(value), pathSegments = url.pathname.slice(1).split("/");
23453
23476
  return url.protocol === "https:" && url.hostname === "github.com" && // The pathname must have at least 2 segments. If it has more than 2, the
@@ -23903,6 +23926,223 @@ function samlProviderToLoginProvider(saml) {
23903
23926
  url: saml.loginUrl
23904
23927
  };
23905
23928
  }
23929
+ const MCP_SERVER_URL = "https://mcp.sanity.io", NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server for your editor. Visit ${MCP_SERVER_URL} for setup instructions.`, defaultHttpConfig = (token2) => ({
23930
+ type: "http",
23931
+ url: MCP_SERVER_URL,
23932
+ headers: { Authorization: `Bearer ${token2}` }
23933
+ }), homeDir = os__default.default.homedir(), EDITOR_CONFIGS = {
23934
+ Cursor: {
23935
+ configKey: "mcpServers",
23936
+ detect: async () => {
23937
+ const cursorDir = path__default.default.join(homeDir, ".cursor");
23938
+ return fs$1.existsSync(cursorDir) ? path__default.default.join(cursorDir, "mcp.json") : null;
23939
+ },
23940
+ buildServerConfig: defaultHttpConfig
23941
+ },
23942
+ "VS Code": {
23943
+ configKey: "servers",
23944
+ detect: async () => {
23945
+ let configDir = null;
23946
+ switch (process.platform) {
23947
+ case "darwin":
23948
+ configDir = path__default.default.join(homeDir, "Library/Application Support/Code/User");
23949
+ break;
23950
+ case "win32":
23951
+ process.env.APPDATA && (configDir = path__default.default.join(process.env.APPDATA, "Code/User"));
23952
+ break;
23953
+ default:
23954
+ configDir = path__default.default.join(homeDir, ".config/Code/User");
23955
+ }
23956
+ return configDir && fs$1.existsSync(configDir) ? path__default.default.join(configDir, "mcp.json") : null;
23957
+ },
23958
+ buildServerConfig: defaultHttpConfig
23959
+ },
23960
+ "VS Code Insiders": {
23961
+ configKey: "servers",
23962
+ detect: async () => {
23963
+ let configDir = null;
23964
+ switch (process.platform) {
23965
+ case "darwin":
23966
+ configDir = path__default.default.join(homeDir, "Library/Application Support/Code - Insiders/User");
23967
+ break;
23968
+ case "win32":
23969
+ process.env.APPDATA && (configDir = path__default.default.join(process.env.APPDATA, "Code - Insiders/User"));
23970
+ break;
23971
+ default:
23972
+ configDir = path__default.default.join(homeDir, ".config/Code - Insiders/User");
23973
+ }
23974
+ return configDir && fs$1.existsSync(configDir) ? path__default.default.join(configDir, "mcp.json") : null;
23975
+ },
23976
+ buildServerConfig: defaultHttpConfig
23977
+ },
23978
+ "Claude Code": {
23979
+ configKey: "mcpServers",
23980
+ detect: async () => {
23981
+ try {
23982
+ return await execa("claude", ["--version"], { stdio: "pipe", timeout: 5e3 }), path__default.default.join(homeDir, ".claude.json");
23983
+ } catch {
23984
+ return null;
23985
+ }
23986
+ },
23987
+ buildServerConfig: defaultHttpConfig
23988
+ },
23989
+ Zed: {
23990
+ configKey: "context_servers",
23991
+ detect: async () => {
23992
+ let configDir = null;
23993
+ return process.platform === "win32" ? process.env.APPDATA && (configDir = path__default.default.join(process.env.APPDATA, "Zed")) : configDir = path__default.default.join(homeDir, ".config/zed"), configDir && fs$1.existsSync(configDir) ? path__default.default.join(configDir, "settings.json") : null;
23994
+ },
23995
+ buildServerConfig: (token2) => ({
23996
+ url: MCP_SERVER_URL,
23997
+ headers: { Authorization: `Bearer ${token2}` },
23998
+ settings: {}
23999
+ })
24000
+ },
24001
+ OpenCode: {
24002
+ configKey: "mcp",
24003
+ detect: async () => {
24004
+ try {
24005
+ return await execa("opencode", ["--version"], { stdio: "pipe", timeout: 5e3 }), path__default.default.join(homeDir, ".config/opencode/opencode.json");
24006
+ } catch {
24007
+ return null;
24008
+ }
24009
+ },
24010
+ buildServerConfig: (token2) => ({
24011
+ type: "remote",
24012
+ url: MCP_SERVER_URL,
24013
+ headers: { Authorization: `Bearer ${token2}` }
24014
+ })
24015
+ }
24016
+ };
24017
+ function parseConfig(content) {
24018
+ if (content.trim() === "")
24019
+ return {};
24020
+ const errors = [], parsed = jsoncParser.parse(content, errors, { allowTrailingComma: !0 });
24021
+ return errors.length > 0 || typeof parsed != "object" || parsed === null || Array.isArray(parsed) ? null : parsed;
24022
+ }
24023
+ async function checkEditorConfig(name, configPath) {
24024
+ const { configKey } = EDITOR_CONFIGS[name];
24025
+ if (!fs$1.existsSync(configPath))
24026
+ return { name, configPath, configured: !1 };
24027
+ try {
24028
+ const content = await fs__default.default.readFile(configPath, "utf-8"), config2 = parseConfig(content);
24029
+ if (config2 === null)
24030
+ return getCliConfig.debug("Skipping %s: could not parse %s", name, configPath), null;
24031
+ const configured = !!config2[configKey]?.Sanity;
24032
+ return { name, configPath, configured };
24033
+ } catch (err) {
24034
+ return getCliConfig.debug("Skipping %s: could not read %s: %s", name, configPath, err), null;
24035
+ }
24036
+ }
24037
+ async function detectAvailableEditors() {
24038
+ const editors = [];
24039
+ for (const [name, config2] of Object.entries(EDITOR_CONFIGS)) {
24040
+ const configPath = await config2.detect();
24041
+ if (configPath) {
24042
+ const editor2 = await checkEditorConfig(name, configPath);
24043
+ editor2 && editors.push(editor2);
24044
+ }
24045
+ }
24046
+ return editors;
24047
+ }
24048
+ async function promptForMCPSetup(prompt2, editors) {
24049
+ const editorChoices = editors.map((e) => ({
24050
+ name: e.configured ? `${e.name} (already installed)` : e.name,
24051
+ value: e.name,
24052
+ checked: !e.configured
24053
+ // Only pre-select if NOT already configured
24054
+ })), selectedNames = (await prompt2([
24055
+ {
24056
+ type: "checkbox",
24057
+ name: "selectedEditors",
24058
+ message: "Configure Sanity MCP server?",
24059
+ choices: editorChoices
24060
+ }
24061
+ ])).selectedEditors;
24062
+ return !selectedNames || selectedNames.length === 0 ? null : editors.filter((e) => selectedNames.includes(e.name));
24063
+ }
24064
+ async function createMCPToken(apiClient) {
24065
+ if (!getCliToken())
24066
+ throw new Error("Not authenticated. Please run `sanity login` first.");
24067
+ const client2 = apiClient({ requireUser: !0, requireProject: !1 }).clone().config({ apiVersion: "2025-12-09" }), sessionResponse = await client2.request({
24068
+ method: "POST",
24069
+ uri: "/auth/session/create",
24070
+ body: {
24071
+ sourceId: "sanity-mcp",
24072
+ withStamp: !1
24073
+ }
24074
+ });
24075
+ return (await client2.request({
24076
+ method: "GET",
24077
+ uri: "/auth/fetch",
24078
+ query: { sid: sessionResponse.sid }
24079
+ })).token;
24080
+ }
24081
+ async function writeMCPConfig(editor2, token2) {
24082
+ const configPath = editor2.configPath, { configKey, buildServerConfig } = EDITOR_CONFIGS[editor2.name];
24083
+ let content = "{}";
24084
+ if (fs$1.existsSync(configPath)) {
24085
+ const fileContent = await fs__default.default.readFile(configPath, "utf-8");
24086
+ fileContent.trim() && (content = fileContent);
24087
+ }
24088
+ const edits = jsoncParser.modify(content, [configKey, "Sanity"], buildServerConfig(token2), {
24089
+ formattingOptions: { tabSize: 2, insertSpaces: !0 }
24090
+ });
24091
+ content = jsoncParser.applyEdits(content, edits), await fs__default.default.mkdir(path__default.default.dirname(configPath), { recursive: !0 }), await fs__default.default.writeFile(configPath, content, "utf-8");
24092
+ }
24093
+ async function setupMCP(context, options2) {
24094
+ const { output, prompt: prompt2 } = context;
24095
+ if (options2.mcp === !1)
24096
+ return output.warn("Skipping MCP configuration due to --no-mcp flag"), {
24097
+ detectedEditors: [],
24098
+ configuredEditors: [],
24099
+ skipped: !0
24100
+ };
24101
+ const editors = await detectAvailableEditors(), detectedEditors = editors.map((e) => e.name);
24102
+ if (editors.length === 0)
24103
+ return output.warn(NO_EDITORS_DETECTED_MESSAGE), {
24104
+ detectedEditors,
24105
+ configuredEditors: [],
24106
+ skipped: !0
24107
+ };
24108
+ const selected = await promptForMCPSetup(prompt2, editors);
24109
+ if (!selected || selected.length === 0)
24110
+ return {
24111
+ detectedEditors,
24112
+ configuredEditors: [],
24113
+ skipped: !0
24114
+ };
24115
+ let token2;
24116
+ try {
24117
+ token2 = await createMCPToken(context.apiClient);
24118
+ } catch (error2) {
24119
+ const err = error2 instanceof Error ? error2 : new Error(String(error2));
24120
+ return output.warn(`Could not configure MCP: ${err.message}`), output.warn("You can set up MCP manually later using https://mcp.sanity.io"), {
24121
+ detectedEditors,
24122
+ configuredEditors: [],
24123
+ skipped: !1,
24124
+ error: err
24125
+ };
24126
+ }
24127
+ try {
24128
+ for (const editor2 of selected)
24129
+ await writeMCPConfig(editor2, token2);
24130
+ } catch (error2) {
24131
+ const err = error2 instanceof Error ? error2 : new Error(String(error2));
24132
+ return output.warn(`Could not configure MCP: ${err.message}`), output.warn("You can set up MCP manually later using https://mcp.sanity.io"), {
24133
+ detectedEditors,
24134
+ configuredEditors: [],
24135
+ skipped: !1,
24136
+ error: err
24137
+ };
24138
+ }
24139
+ const configuredEditors = selected.map((e) => e.name);
24140
+ return output.success(`MCP configured for ${configuredEditors.join(", ")}`), {
24141
+ detectedEditors,
24142
+ configuredEditors,
24143
+ skipped: !1
24144
+ };
24145
+ }
23906
24146
  function createProject(apiClient, options2) {
23907
24147
  return apiClient({
23908
24148
  requireUser: !0,
@@ -34206,7 +34446,7 @@ export default defineCliConfig({
34206
34446
  deployment: {
34207
34447
  /**
34208
34448
  * Enable auto-updates for studios.
34209
- * Learn more at https://www.sanity.io/docs/cli#auto-updates
34449
+ * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56
34210
34450
  */
34211
34451
  autoUpdates: __BOOL__autoUpdates__,
34212
34452
  }
@@ -39625,7 +39865,7 @@ async function bootstrapRemoteTemplate(opts, context) {
39625
39865
  fs: new distExports.LocalFileSystemDetector(packagePath),
39626
39866
  frameworkList: frameworksExports.frameworks
39627
39867
  }), port = getDefaultPortForFramework(packageFramework?.slug);
39628
- corsAdded.includes(port) === !1 && (getCliConfig.debug("Setting CORS origin to http://localhost:%d", port), await setCorsOrigin(`http://localhost:${port}`, variables.projectId, apiClient), corsAdded.push(port)), getCliConfig.debug("Applying environment variables to %s", pkg);
39868
+ corsAdded.includes(port) && (getCliConfig.debug("Setting CORS origin to http://localhost:%d", port), await setCorsOrigin(`http://localhost:${port}`, variables.projectId, apiClient), corsAdded.push(port)), getCliConfig.debug("Applying environment variables to %s", pkg);
39629
39869
  const envName = packageFramework?.slug === "nextjs" ? ".env.local" : ".env";
39630
39870
  await applyEnvVariables(packagePath, { ...variables, readToken, writeToken }, envName);
39631
39871
  }
@@ -39774,160 +40014,6 @@ function readPackageJson(filePath) {
39774
40014
  return;
39775
40015
  }
39776
40016
  }
39777
- const MCP_SERVER_URL = "https://mcp.sanity.io", NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server for your editor. Visit ${MCP_SERVER_URL} for setup instructions.`;
39778
- async function detectAvailableEditors() {
39779
- const editors = [], homeDir = os__default.default.homedir(), cursorDir = path__default.default.join(homeDir, ".cursor");
39780
- fs$1.existsSync(cursorDir) && editors.push({
39781
- name: "Cursor",
39782
- configPath: path__default.default.join(cursorDir, "mcp.json"),
39783
- configKey: "mcpServers"
39784
- });
39785
- let vscodeConfigDir = null;
39786
- switch (process.platform) {
39787
- case "darwin":
39788
- vscodeConfigDir = path__default.default.join(homeDir, "Library/Application Support/Code/User");
39789
- break;
39790
- case "win32":
39791
- process.env.APPDATA && (vscodeConfigDir = path__default.default.join(process.env.APPDATA, "Code/User"));
39792
- break;
39793
- default:
39794
- vscodeConfigDir = path__default.default.join(homeDir, ".config/Code/User");
39795
- }
39796
- vscodeConfigDir && fs$1.existsSync(vscodeConfigDir) && editors.push({
39797
- name: "VS Code",
39798
- configPath: path__default.default.join(vscodeConfigDir, "mcp.json"),
39799
- configKey: "servers"
39800
- });
39801
- try {
39802
- await execa("claude", ["--version"], { stdio: "pipe", timeout: 5e3 }), editors.push({
39803
- name: "Claude Code",
39804
- configPath: path__default.default.join(homeDir, ".claude.json"),
39805
- configKey: "mcpServers"
39806
- });
39807
- } catch {
39808
- }
39809
- return editors;
39810
- }
39811
- async function promptForMCPSetup(prompt2, detectedEditors, editorsWithExisting) {
39812
- const editorChoices = detectedEditors.map((e) => {
39813
- const isConfigured = editorsWithExisting.some((existing) => existing.name === e.name);
39814
- return {
39815
- name: isConfigured ? `${e.name} (already installed)` : e.name,
39816
- value: e.name,
39817
- checked: !isConfigured
39818
- // Only pre-select if NOT already configured
39819
- };
39820
- }), selectedNames = (await prompt2([
39821
- {
39822
- type: "checkbox",
39823
- name: "selectedEditors",
39824
- message: "Configure Sanity MCP server?",
39825
- choices: editorChoices
39826
- }
39827
- ])).selectedEditors;
39828
- return !selectedNames || selectedNames.length === 0 ? null : detectedEditors.filter((e) => selectedNames.includes(e.name));
39829
- }
39830
- async function createMCPToken(apiClient) {
39831
- if (!getCliToken())
39832
- throw new Error("Not authenticated. Please run `sanity login` first.");
39833
- const client2 = apiClient({ requireUser: !0, requireProject: !1 }).clone().config({ apiVersion: "2025-12-09" }), sessionResponse = await client2.request({
39834
- method: "POST",
39835
- uri: "/auth/session/create",
39836
- body: {
39837
- sourceId: "sanity-mcp",
39838
- withStamp: !1
39839
- }
39840
- });
39841
- return (await client2.request({
39842
- method: "GET",
39843
- uri: "/auth/fetch",
39844
- query: { sid: sessionResponse.sid }
39845
- })).token;
39846
- }
39847
- async function getEditorsWithExistingConfig(editors) {
39848
- const configured = [];
39849
- for (const editor2 of editors)
39850
- if (fs$1.existsSync(editor2.configPath))
39851
- try {
39852
- const content = await fs__default.default.readFile(editor2.configPath, "utf-8");
39853
- JSON.parse(content)[editor2.configKey]?.Sanity && configured.push(editor2);
39854
- } catch (err) {
39855
- getCliConfig.debug("Could not read MCP config for %s: %s", editor2.name, err);
39856
- }
39857
- return configured;
39858
- }
39859
- async function writeMCPConfig(editor2, token2) {
39860
- const configPath = editor2.configPath;
39861
- let existingConfig = {};
39862
- if (fs$1.existsSync(configPath))
39863
- try {
39864
- const content = await fs__default.default.readFile(configPath, "utf-8");
39865
- existingConfig = JSON.parse(content);
39866
- } catch {
39867
- getCliConfig.debug(`Warning: Could not parse ${configPath}. Creating new config.`);
39868
- }
39869
- const serverKey = editor2.configKey;
39870
- existingConfig[serverKey] || (existingConfig[serverKey] = {}), existingConfig[serverKey].Sanity = {
39871
- type: "http",
39872
- url: MCP_SERVER_URL,
39873
- headers: {
39874
- Authorization: `Bearer ${token2}`
39875
- }
39876
- }, 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");
39877
- }
39878
- async function setupMCP(context, options2) {
39879
- const { output, prompt: prompt2 } = context;
39880
- if (options2.mcp === !1)
39881
- return output.warn("Skipping MCP configuration due to --no-mcp flag"), {
39882
- detectedEditors: [],
39883
- configuredEditors: [],
39884
- skipped: !0
39885
- };
39886
- const detected = await detectAvailableEditors(), detectedEditors = detected.map((e) => e.name);
39887
- if (detected.length === 0)
39888
- return output.warn(NO_EDITORS_DETECTED_MESSAGE), {
39889
- detectedEditors,
39890
- configuredEditors: [],
39891
- skipped: !0
39892
- };
39893
- const editorsWithExisting = await getEditorsWithExistingConfig(detected), selected = await promptForMCPSetup(prompt2, detected, editorsWithExisting);
39894
- if (!selected || selected.length === 0)
39895
- return {
39896
- detectedEditors,
39897
- configuredEditors: [],
39898
- skipped: !0
39899
- };
39900
- let token2;
39901
- try {
39902
- token2 = await createMCPToken(context.apiClient);
39903
- } catch (error2) {
39904
- const err = error2 instanceof Error ? error2 : new Error(String(error2));
39905
- return output.warn(`Could not configure MCP: ${err.message}`), output.warn("You can set up MCP manually later using https://mcp.sanity.io"), {
39906
- detectedEditors,
39907
- configuredEditors: [],
39908
- skipped: !1,
39909
- error: err
39910
- };
39911
- }
39912
- try {
39913
- for (const editor2 of selected)
39914
- await writeMCPConfig(editor2, token2);
39915
- } catch (error2) {
39916
- const err = error2 instanceof Error ? error2 : new Error(String(error2));
39917
- return output.warn(`Could not configure MCP: ${err.message}`), output.warn("You can set up MCP manually later using https://mcp.sanity.io"), {
39918
- detectedEditors,
39919
- configuredEditors: [],
39920
- skipped: !1,
39921
- error: err
39922
- };
39923
- }
39924
- const configuredEditors = selected.map((e) => e.name);
39925
- return output.success(`MCP configured for ${configuredEditors.join(", ")}`), {
39926
- detectedEditors,
39927
- configuredEditors,
39928
- skipped: !1
39929
- };
39930
- }
39931
40017
  const authorType = `import {UserIcon} from '@sanity/icons'
39932
40018
  import {defineArrayMember, defineField, defineType} from 'sanity'
39933
40019
 
@@ -40597,12 +40683,14 @@ You can find your project on Sanity Manage \u2014 https://www.sanity.io/manage/p
40597
40683
  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(
40598
40684
  `
40599
40685
  ${chalk2.green("Success!")} Your Sanity configuration files has been added to this project`
40600
- ), mcpConfigured.length > 0) {
40601
- const editorNames = new Intl.ListFormat("en").format(mcpConfigured);
40602
- print(
40686
+ ), mcpConfigured && mcpConfigured.length > 0) {
40687
+ const message = await getPostInitMCPPrompt(mcpConfigured);
40688
+ print(`
40689
+ ${message}`), print(`
40690
+ Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`), print(
40603
40691
  `
40604
- Sanity MCP server has been configured for ${editorNames}. You might need to restart your editor for this to take effect.`
40605
- ), print(`Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`);
40692
+ Have feedback? Tell us in the community: ${chalk2.cyan("https://www.sanity.io/community/join")}`
40693
+ );
40606
40694
  }
40607
40695
  return;
40608
40696
  }
@@ -40679,12 +40767,14 @@ Sanity MCP server has been configured for ${editorNames}. You might need to rest
40679
40767
  if (print(`\u2705 ${chalk2.green.bold("Success!")} Your custom app has been scaffolded.`), isCurrentDir || print(goToProjectDir), print(
40680
40768
  `
40681
40769
  ${chalk2.bold("Next")}, configure the project(s) and dataset(s) your app should work with.`
40682
- ), 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.length > 0) {
40683
- const editorNames = new Intl.ListFormat("en").format(mcpConfigured);
40684
- print(
40770
+ ), 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) {
40771
+ const message = await getPostInitMCPPrompt(mcpConfigured);
40772
+ print(`
40773
+ ${message}`), print(`
40774
+ Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`), print(
40685
40775
  `
40686
- Sanity MCP server has been configured for ${editorNames}. You might need to restart your editor for this to take effect.`
40687
- ), print(`Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`);
40776
+ Have feedback? Tell us in the community: ${chalk2.cyan("https://www.sanity.io/community/join")}`
40777
+ );
40688
40778
  }
40689
40779
  print(`
40690
40780
  `), print("Other helpful commands:"), print("npx sanity docs browse 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");
@@ -40692,12 +40782,10 @@ Sanity MCP server has been configured for ${editorNames}. You might need to rest
40692
40782
  if (print(`\u2705 ${chalk2.green.bold("Success!")} Your Studio has been created.`), isCurrentDir || print(goToProjectDir), print(
40693
40783
  `
40694
40784
  Get started by running ${chalk2.cyan(devCommand)} to launch your Studio's development server`
40695
- ), mcpConfigured.length > 0) {
40696
- const editorNames = new Intl.ListFormat("en").format(mcpConfigured);
40697
- print(
40698
- `
40699
- To set up your project with the MCP server, restart ${editorNames} and type ${chalk2.cyan('"Get started with Sanity"')} in the chat`
40700
- ), print(`
40785
+ ), mcpConfigured && mcpConfigured.length > 0) {
40786
+ const message = await getPostInitMCPPrompt(mcpConfigured);
40787
+ print(`
40788
+ ${message}`), print(`
40701
40789
  Learn more: ${chalk2.cyan("https://mcp.sanity.io")}`), print(
40702
40790
  `
40703
40791
  Have feedback? Tell us in the community: ${chalk2.cyan("https://www.sanity.io/community/join")}`
@@ -40760,6 +40848,14 @@ Join the Sanity community: ${chalk2.cyan("https://www.sanity.io/community/join")
40760
40848
  datasetName: dataset.datasetName
40761
40849
  };
40762
40850
  }
40851
+ async function getPostInitMCPPrompt(editorsNames) {
40852
+ const promptClient = apiClient({ requireUser: !1, requireProject: !1 });
40853
+ return fetchPostInitPrompt({
40854
+ client: promptClient,
40855
+ editorNames: new Intl.ListFormat("en").format(editorsNames),
40856
+ chalk: chalk2
40857
+ });
40858
+ }
40763
40859
  async function getOrCreateProject() {
40764
40860
  const client2 = apiClient({ requireUser: !0, requireProject: !1 });
40765
40861
  let projects, organizations;
@@ -41433,7 +41529,7 @@ Examples
41433
41529
  group: "mcp",
41434
41530
  helpText: helpText$8,
41435
41531
  signature: "",
41436
- description: "Configure Sanity MCP server for AI editors (Cursor, VS Code, Claude Code)",
41532
+ description: "Configure Sanity MCP server for AI editors",
41437
41533
  async action(args, context) {
41438
41534
  const { output, telemetry: telemetry2 } = context, trace = telemetry2.trace(MCPConfigureTrace);
41439
41535
  if ((await detectAvailableEditors()).length === 0) {
@@ -70123,7 +70219,7 @@ var cleanStack$1, hasRequiredCleanStack;
70123
70219
  function requireCleanStack() {
70124
70220
  if (hasRequiredCleanStack) return cleanStack$1;
70125
70221
  hasRequiredCleanStack = 1;
70126
- const os2 = require$$0__default$2.default, escapeStringRegexp2 = requireEscapeStringRegexp(), extractPathRegex = /\s+at.*[(\s](.*)\)?/, pathRegex = /^(?:(?:(?:node|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/, homeDir = typeof os2.homedir > "u" ? "" : os2.homedir();
70222
+ const os2 = require$$0__default$2.default, escapeStringRegexp2 = requireEscapeStringRegexp(), extractPathRegex = /\s+at.*[(\s](.*)\)?/, pathRegex = /^(?:(?:(?:node|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/, homeDir2 = typeof os2.homedir > "u" ? "" : os2.homedir();
70127
70223
  return cleanStack$1 = (stack2, { pretty = !1, basePath } = {}) => {
70128
70224
  const basePathRegex = basePath && new RegExp(`(at | \\()${escapeStringRegexp2(basePath)}`, "g");
70129
70225
  return stack2.replace(/\\/g, "/").split(`
@@ -70133,7 +70229,7 @@ function requireCleanStack() {
70133
70229
  return !0;
70134
70230
  const match2 = pathMatches[1];
70135
70231
  return match2.includes(".app/Contents/Resources/electron.asar") || match2.includes(".app/Contents/Resources/default_app.asar") ? !1 : !pathRegex.test(match2);
70136
- }).filter((line3) => line3.trim() !== "").map((line3) => (basePathRegex && (line3 = line3.replace(basePathRegex, "$1")), pretty && (line3 = line3.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, "~")))), line3)).join(`
70232
+ }).filter((line3) => line3.trim() !== "").map((line3) => (basePathRegex && (line3 = line3.replace(basePathRegex, "$1")), pretty && (line3 = line3.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir2, "~")))), line3)).join(`
70137
70233
  `);
70138
70234
  }, cleanStack$1;
70139
70235
  }