@sanity/cli 7.4.2 → 7.6.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 (74) hide show
  1. package/dist/actions/build/buildApp.js +7 -183
  2. package/dist/actions/build/buildApp.js.map +1 -1
  3. package/dist/actions/build/buildStudio.js +6 -213
  4. package/dist/actions/build/buildStudio.js.map +1 -1
  5. package/dist/actions/build/shouldAutoUpdate.js +100 -22
  6. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  7. package/dist/actions/deploy/{createStudioUserApplication.js → createUserApplication.js} +56 -5
  8. package/dist/actions/deploy/createUserApplication.js.map +1 -0
  9. package/dist/actions/deploy/deployApp.js +232 -185
  10. package/dist/actions/deploy/deployApp.js.map +1 -1
  11. package/dist/actions/deploy/deployChecks.js +263 -0
  12. package/dist/actions/deploy/deployChecks.js.map +1 -0
  13. package/dist/actions/deploy/deployRunner.js +57 -0
  14. package/dist/actions/deploy/deployRunner.js.map +1 -0
  15. package/dist/actions/deploy/deployStudio.js +189 -198
  16. package/dist/actions/deploy/deployStudio.js.map +1 -1
  17. package/dist/actions/deploy/deploymentPlan.js +89 -0
  18. package/dist/actions/deploy/deploymentPlan.js.map +1 -0
  19. package/dist/actions/deploy/findUserApplication.js +209 -0
  20. package/dist/actions/deploy/findUserApplication.js.map +1 -0
  21. package/dist/actions/deploy/resolveDeployTarget.js +185 -0
  22. package/dist/actions/deploy/resolveDeployTarget.js.map +1 -0
  23. package/dist/actions/dev/devAction.js +1 -1
  24. package/dist/actions/dev/devAction.js.map +1 -1
  25. package/dist/actions/dev/servers/getDevServerConfig.js +18 -6
  26. package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
  27. package/dist/actions/dev/servers/startAppDevServer.js +1 -1
  28. package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
  29. package/dist/actions/dev/servers/startStudioDevServer.js +2 -1
  30. package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
  31. package/dist/actions/manifest/extractCoreAppManifest.js +14 -0
  32. package/dist/actions/manifest/extractCoreAppManifest.js.map +1 -1
  33. package/dist/actions/mcp/editorConfigs.js +11 -5
  34. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  35. package/dist/commands/deploy.js +27 -11
  36. package/dist/commands/deploy.js.map +1 -1
  37. package/dist/commands/dev.js +2 -1
  38. package/dist/commands/dev.js.map +1 -1
  39. package/dist/commands/init.js +2 -1
  40. package/dist/commands/init.js.map +1 -1
  41. package/dist/exports/index.d.ts +9 -0
  42. package/dist/exports/index.js +1 -8
  43. package/dist/exports/index.js.map +1 -1
  44. package/dist/server/devServer.js +27 -3
  45. package/dist/server/devServer.js.map +1 -1
  46. package/dist/util/appId.js +13 -5
  47. package/dist/util/appId.js.map +1 -1
  48. package/dist/util/compareDependencyVersions.js.map +1 -1
  49. package/dist/util/determineIsApp.js +1 -1
  50. package/dist/util/determineIsApp.js.map +1 -1
  51. package/dist/util/errorMessages.js +2 -0
  52. package/dist/util/errorMessages.js.map +1 -1
  53. package/oclif.manifest.json +14 -1
  54. package/package.json +8 -8
  55. package/templates/app-quickstart/.claude/skills/sanity-app-sdk/SKILL.md +56 -0
  56. package/templates/app-quickstart/AGENTS.md +40 -0
  57. package/templates/app-quickstart/README.md +22 -0
  58. package/templates/app-quickstart/src/ExampleComponent.css +6 -0
  59. package/templates/app-quickstart/src/ExampleComponent.tsx +30 -9
  60. package/templates/app-sanity-ui/.claude/skills/sanity-app-sdk/SKILL.md +60 -0
  61. package/templates/app-sanity-ui/AGENTS.md +44 -0
  62. package/templates/app-sanity-ui/README.md +23 -0
  63. package/templates/app-sanity-ui/src/ExampleComponent.tsx +8 -5
  64. package/dist/actions/build/handlePrereleaseVersions.js +0 -44
  65. package/dist/actions/build/handlePrereleaseVersions.js.map +0 -1
  66. package/dist/actions/deploy/createStudioUserApplication.js.map +0 -1
  67. package/dist/actions/deploy/createUserApplicationForApp.js +0 -56
  68. package/dist/actions/deploy/createUserApplicationForApp.js.map +0 -1
  69. package/dist/actions/deploy/findUserApplicationForApp.js +0 -111
  70. package/dist/actions/deploy/findUserApplicationForApp.js.map +0 -1
  71. package/dist/actions/deploy/findUserApplicationForStudio.js +0 -172
  72. package/dist/actions/deploy/findUserApplicationForStudio.js.map +0 -1
  73. package/dist/actions/deploy/viewDeployment.js +0 -32
  74. package/dist/actions/deploy/viewDeployment.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive, isWorkbenchApp} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {compareDependencyVersions} from '../../../util/compareDependencyVersions.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies(options)\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = `http://${httpHost || 'localhost'}:${port}${config.basePath}`\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","getLocalPackageVersion","isInteractive","isWorkbenchApp","confirm","logSymbols","spinner","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","compareDependencyVersions","getPackageManagerChoice","upgradePackages","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","basePath","appType","viteVersion","Math","ceil","started"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {compareDependencyVersions} from '../../../util/compareDependencyVersions.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies(options)\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = `http://${httpHost || 'localhost'}:${port}${config.basePath}`\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","getLocalPackageVersion","isInteractive","confirm","logSymbols","spinner","isWorkbenchApp","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","compareDependencyVersions","getPackageManagerChoice","upgradePackages","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","basePath","appType","viteVersion","Math","ceil","started"],"mappings":"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"}
@@ -4,6 +4,20 @@ import { doImport, getCliConfigUncached } from '@sanity/cli-core';
4
4
  import { spinner } from '@sanity/cli-core/ux';
5
5
  import { getErrorMessage } from '../../util/getErrorMessage.js';
6
6
  import { coreAppManifestSchema } from './types.js';
7
+ /**
8
+ * The title change a deploy would sync from the manifest to the user
9
+ * application, or null when the titles already match (or none is set).
10
+ *
11
+ * @internal
12
+ */ export function resolveTitleUpdate(manifest, application) {
13
+ if (manifest?.title === undefined || manifest.title === application.title) {
14
+ return null;
15
+ }
16
+ return {
17
+ from: application.title,
18
+ to: manifest.title
19
+ };
20
+ }
7
21
  const sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href;
8
22
  /**
9
23
  * Lazy-load {@link sanitizeIconFn} so `isomorphic-dompurify` (and its jsdom
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/manifest/extractCoreAppManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {relative, resolve} from 'node:path'\n\nimport {doImport, getCliConfigUncached} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\nimport {type sanitizeIcon as sanitizeIconFn} from './sanitizeIcon.js'\nimport {type CoreAppManifest, coreAppManifestSchema} from './types.js'\n\ninterface ExtractCoreAppManifestOptions {\n workDir: string\n}\n\nconst sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href\n\n/**\n * Lazy-load {@link sanitizeIconFn} so `isomorphic-dompurify` (and its jsdom\n * dependency) stays out of the CLI's eager import graph. The studio manifest\n * resolver lazy-loads its icon machinery for the same reason; this path runs in\n * the main process (not the manifest worker), so only an app deploy that\n * actually has an icon pays the cost.\n */\nasync function lazySanitizeIcon(): Promise<typeof sanitizeIconFn> {\n const mod = await doImport(sanitizeIconPath)\n return mod.sanitizeIcon\n}\n\n/**\n * Resolves app.icon from config (a file path) to an SVG string for the manifest.\n * The manifest expects the SVG string inline, not a path.\n *\n * The file is sanitized through the same allowlist as the studio manifest's\n * icon resolver (see {@link lazySanitizeIcon}) so both manifest paths inline the\n * same trusted subset of SVG markup.\n */\nasync function readIconFromPath(workDir: string, iconPath: string): Promise<string> {\n const resolvedPath = resolve(workDir, iconPath)\n const pathRelativeToWorkDir = relative(workDir, resolvedPath)\n if (pathRelativeToWorkDir.startsWith('..')) {\n throw new Error(\n `Icon path \"${iconPath}\" resolves outside the project directory and is not allowed.`,\n )\n }\n\n let content: string\n try {\n content = await readFile(resolvedPath, 'utf8')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(\n `Could not read icon file at \"${iconPath}\" (resolved: ${resolvedPath}): ${message}`,\n {cause: err},\n )\n }\n\n const trimmed = content.trim()\n if (!/<svg[\\s>]/i.test(trimmed)) {\n throw new Error(\n `Icon file at \"${iconPath}\" does not contain an SVG element. App manifest icons must be SVG files.`,\n )\n }\n\n const sanitizeIcon = await lazySanitizeIcon()\n return sanitizeIcon(trimmed)\n}\n\n/**\n * Unlike studio manifest extraction, skips schema/tool parsing. The config's\n * `app.icon` is a file path; its content is read and inlined in the manifest.\n */\nexport async function extractCoreAppManifest(\n options: ExtractCoreAppManifestOptions,\n): Promise<CoreAppManifest | undefined> {\n const {workDir} = options\n const {app} = await getCliConfigUncached(workDir)\n if (!app) {\n return undefined\n }\n\n const spin = spinner('Extracting manifest').start()\n\n try {\n let icon: string | undefined\n if (app.icon) {\n icon = await readIconFromPath(workDir, app.icon)\n }\n\n if (!icon && !app.title) {\n spin.succeed('Manifest creation skipped: no icon or title found in app configuration')\n return undefined\n }\n\n const manifest: CoreAppManifest = coreAppManifestSchema.parse({\n version: '1',\n ...(icon ? {icon} : {}),\n ...(app.title ? {title: app.title} : {}),\n ...(app.group ? {group: app.group} : {}),\n ...(app.priority === undefined ? {} : {priority: app.priority}),\n })\n\n spin.succeed(`Extracted manifest`)\n\n return manifest\n } catch (err) {\n const message = getErrorMessage(err)\n spin.fail(message)\n throw err\n }\n}\n"],"names":["readFile","relative","resolve","doImport","getCliConfigUncached","spinner","getErrorMessage","coreAppManifestSchema","sanitizeIconPath","URL","url","href","lazySanitizeIcon","mod","sanitizeIcon","readIconFromPath","workDir","iconPath","resolvedPath","pathRelativeToWorkDir","startsWith","Error","content","err","message","String","cause","trimmed","trim","test","extractCoreAppManifest","options","app","undefined","spin","start","icon","title","succeed","manifest","parse","version","group","priority","fail"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAE3C,SAAQC,QAAQ,EAAEC,oBAAoB,QAAO,mBAAkB;AAC/D,SAAQC,OAAO,QAAO,sBAAqB;AAE3C,SAAQC,eAAe,QAAO,gCAA+B;AAE7D,SAA8BC,qBAAqB,QAAO,aAAY;AAMtE,MAAMC,mBAAmB,IAAIC,IAAI,mBAAmB,YAAYC,GAAG,EAAEC,IAAI;AAEzE;;;;;;CAMC,GACD,eAAeC;IACb,MAAMC,MAAM,MAAMV,SAASK;IAC3B,OAAOK,IAAIC,YAAY;AACzB;AAEA;;;;;;;CAOC,GACD,eAAeC,iBAAiBC,OAAe,EAAEC,QAAgB;IAC/D,MAAMC,eAAehB,QAAQc,SAASC;IACtC,MAAME,wBAAwBlB,SAASe,SAASE;IAChD,IAAIC,sBAAsBC,UAAU,CAAC,OAAO;QAC1C,MAAM,IAAIC,MACR,CAAC,WAAW,EAAEJ,SAAS,4DAA4D,CAAC;IAExF;IAEA,IAAIK;IACJ,IAAI;QACFA,UAAU,MAAMtB,SAASkB,cAAc;IACzC,EAAE,OAAOK,KAAK;QACZ,MAAMC,UAAUD,eAAeF,QAAQE,IAAIC,OAAO,GAAGC,OAAOF;QAC5D,MAAM,IAAIF,MACR,CAAC,6BAA6B,EAAEJ,SAAS,aAAa,EAAEC,aAAa,GAAG,EAAEM,SAAS,EACnF;YAACE,OAAOH;QAAG;IAEf;IAEA,MAAMI,UAAUL,QAAQM,IAAI;IAC5B,IAAI,CAAC,aAAaC,IAAI,CAACF,UAAU;QAC/B,MAAM,IAAIN,MACR,CAAC,cAAc,EAAEJ,SAAS,wEAAwE,CAAC;IAEvG;IAEA,MAAMH,eAAe,MAAMF;IAC3B,OAAOE,aAAaa;AACtB;AAEA;;;CAGC,GACD,OAAO,eAAeG,uBACpBC,OAAsC;IAEtC,MAAM,EAACf,OAAO,EAAC,GAAGe;IAClB,MAAM,EAACC,GAAG,EAAC,GAAG,MAAM5B,qBAAqBY;IACzC,IAAI,CAACgB,KAAK;QACR,OAAOC;IACT;IAEA,MAAMC,OAAO7B,QAAQ,uBAAuB8B,KAAK;IAEjD,IAAI;QACF,IAAIC;QACJ,IAAIJ,IAAII,IAAI,EAAE;YACZA,OAAO,MAAMrB,iBAAiBC,SAASgB,IAAII,IAAI;QACjD;QAEA,IAAI,CAACA,QAAQ,CAACJ,IAAIK,KAAK,EAAE;YACvBH,KAAKI,OAAO,CAAC;YACb,OAAOL;QACT;QAEA,MAAMM,WAA4BhC,sBAAsBiC,KAAK,CAAC;YAC5DC,SAAS;YACT,GAAIL,OAAO;gBAACA;YAAI,IAAI,CAAC,CAAC;YACtB,GAAIJ,IAAIK,KAAK,GAAG;gBAACA,OAAOL,IAAIK,KAAK;YAAA,IAAI,CAAC,CAAC;YACvC,GAAIL,IAAIU,KAAK,GAAG;gBAACA,OAAOV,IAAIU,KAAK;YAAA,IAAI,CAAC,CAAC;YACvC,GAAIV,IAAIW,QAAQ,KAAKV,YAAY,CAAC,IAAI;gBAACU,UAAUX,IAAIW,QAAQ;YAAA,CAAC;QAChE;QAEAT,KAAKI,OAAO,CAAC,CAAC,kBAAkB,CAAC;QAEjC,OAAOC;IACT,EAAE,OAAOhB,KAAK;QACZ,MAAMC,UAAUlB,gBAAgBiB;QAChCW,KAAKU,IAAI,CAACpB;QACV,MAAMD;IACR;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/manifest/extractCoreAppManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {relative, resolve} from 'node:path'\n\nimport {doImport, getCliConfigUncached} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\nimport {type sanitizeIcon as sanitizeIconFn} from './sanitizeIcon.js'\nimport {type CoreAppManifest, coreAppManifestSchema} from './types.js'\n\ninterface ExtractCoreAppManifestOptions {\n workDir: string\n}\n\n/**\n * The title change a deploy would sync from the manifest to the user\n * application, or null when the titles already match (or none is set).\n *\n * @internal\n */\nexport function resolveTitleUpdate(\n manifest: CoreAppManifest | undefined,\n application: {title: string | null},\n): {from: string | null; to: string} | null {\n if (manifest?.title === undefined || manifest.title === application.title) {\n return null\n }\n return {from: application.title, to: manifest.title}\n}\n\nconst sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href\n\n/**\n * Lazy-load {@link sanitizeIconFn} so `isomorphic-dompurify` (and its jsdom\n * dependency) stays out of the CLI's eager import graph. The studio manifest\n * resolver lazy-loads its icon machinery for the same reason; this path runs in\n * the main process (not the manifest worker), so only an app deploy that\n * actually has an icon pays the cost.\n */\nasync function lazySanitizeIcon(): Promise<typeof sanitizeIconFn> {\n const mod = await doImport(sanitizeIconPath)\n return mod.sanitizeIcon\n}\n\n/**\n * Resolves app.icon from config (a file path) to an SVG string for the manifest.\n * The manifest expects the SVG string inline, not a path.\n *\n * The file is sanitized through the same allowlist as the studio manifest's\n * icon resolver (see {@link lazySanitizeIcon}) so both manifest paths inline the\n * same trusted subset of SVG markup.\n */\nasync function readIconFromPath(workDir: string, iconPath: string): Promise<string> {\n const resolvedPath = resolve(workDir, iconPath)\n const pathRelativeToWorkDir = relative(workDir, resolvedPath)\n if (pathRelativeToWorkDir.startsWith('..')) {\n throw new Error(\n `Icon path \"${iconPath}\" resolves outside the project directory and is not allowed.`,\n )\n }\n\n let content: string\n try {\n content = await readFile(resolvedPath, 'utf8')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(\n `Could not read icon file at \"${iconPath}\" (resolved: ${resolvedPath}): ${message}`,\n {cause: err},\n )\n }\n\n const trimmed = content.trim()\n if (!/<svg[\\s>]/i.test(trimmed)) {\n throw new Error(\n `Icon file at \"${iconPath}\" does not contain an SVG element. App manifest icons must be SVG files.`,\n )\n }\n\n const sanitizeIcon = await lazySanitizeIcon()\n return sanitizeIcon(trimmed)\n}\n\n/**\n * Unlike studio manifest extraction, skips schema/tool parsing. The config's\n * `app.icon` is a file path; its content is read and inlined in the manifest.\n */\nexport async function extractCoreAppManifest(\n options: ExtractCoreAppManifestOptions,\n): Promise<CoreAppManifest | undefined> {\n const {workDir} = options\n const {app} = await getCliConfigUncached(workDir)\n if (!app) {\n return undefined\n }\n\n const spin = spinner('Extracting manifest').start()\n\n try {\n let icon: string | undefined\n if (app.icon) {\n icon = await readIconFromPath(workDir, app.icon)\n }\n\n if (!icon && !app.title) {\n spin.succeed('Manifest creation skipped: no icon or title found in app configuration')\n return undefined\n }\n\n const manifest: CoreAppManifest = coreAppManifestSchema.parse({\n version: '1',\n ...(icon ? {icon} : {}),\n ...(app.title ? {title: app.title} : {}),\n ...(app.group ? {group: app.group} : {}),\n ...(app.priority === undefined ? {} : {priority: app.priority}),\n })\n\n spin.succeed(`Extracted manifest`)\n\n return manifest\n } catch (err) {\n const message = getErrorMessage(err)\n spin.fail(message)\n throw err\n }\n}\n"],"names":["readFile","relative","resolve","doImport","getCliConfigUncached","spinner","getErrorMessage","coreAppManifestSchema","resolveTitleUpdate","manifest","application","title","undefined","from","to","sanitizeIconPath","URL","url","href","lazySanitizeIcon","mod","sanitizeIcon","readIconFromPath","workDir","iconPath","resolvedPath","pathRelativeToWorkDir","startsWith","Error","content","err","message","String","cause","trimmed","trim","test","extractCoreAppManifest","options","app","spin","start","icon","succeed","parse","version","group","priority","fail"],"mappings":"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"}
@@ -212,20 +212,23 @@ function buildGitHubCopilotCliServerConfig(token) {
212
212
  };
213
213
  }
214
214
  function buildOpenCodeServerConfig(token) {
215
- return {
216
- headers: {
217
- Authorization: `Bearer ${token}`
218
- },
215
+ const config = {
219
216
  type: 'remote',
220
217
  url: MCP_SERVER_URL
221
218
  };
219
+ if (token) {
220
+ config.headers = {
221
+ Authorization: `Bearer ${token}`
222
+ };
223
+ }
224
+ return config;
222
225
  }
223
226
  function buildZedServerConfig(token) {
224
227
  return {
228
+ enabled: true,
225
229
  headers: {
226
230
  Authorization: `Bearer ${token}`
227
231
  },
228
- settings: {},
229
232
  url: MCP_SERVER_URL
230
233
  };
231
234
  }
@@ -317,6 +320,7 @@ function buildZedServerConfig(token) {
317
320
  buildServerConfig: buildOpenCodeServerConfig,
318
321
  configKey: 'mcp',
319
322
  detect: detectOpenCode,
323
+ oauthOnly: true,
320
324
  skillsCliAgent: 'opencode'
321
325
  },
322
326
  // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
@@ -327,6 +331,7 @@ function buildZedServerConfig(token) {
327
331
  ...EDITOR_DEFAULTS,
328
332
  configKey: 'servers',
329
333
  detect: detectVSCode,
334
+ oauthOnly: true,
330
335
  skillsCliAgent: 'github-copilot'
331
336
  },
332
337
  // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers
@@ -335,6 +340,7 @@ function buildZedServerConfig(token) {
335
340
  ...EDITOR_DEFAULTS,
336
341
  configKey: 'servers',
337
342
  detect: detectVSCodeInsiders,
343
+ oauthOnly: true,
338
344
  skillsCliAgent: 'github-copilot'
339
345
  },
340
346
  // Doc: https://zed.dev/docs/assistant/model-context-protocol
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/mcp/editorConfigs.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport {execa} from 'execa'\n\nimport {MCP_SERVER_URL} from '../../services/mcp.js'\n\n/**\n * Environment abstraction for editor detection.\n *\n * Detect functions receive this instead of using module-level imports, making\n * each function independently testable without global mocks.\n */\nexport interface DetectionEnv {\n env: Record<string, string | undefined>\n /** Run a CLI command to check if a tool is installed. Rejects on failure. */\n execCommand: (cmd: string, args: string[]) => Promise<void>\n existsSync: (p: string) => boolean\n homedir: string\n platform: NodeJS.Platform\n}\n\n/** Create the real detection environment backed by process/OS globals. */\nexport function createDetectionEnv(): DetectionEnv {\n return {\n env: process.env,\n execCommand: (cmd, args) => execa(cmd, args, {stdio: 'pipe', timeout: 5000}).then(() => {}),\n existsSync,\n homedir: os.homedir(),\n platform: process.platform,\n }\n}\n\ninterface EditorConfig {\n /** Builds the server config with API token. If oauthOnly is true, the token is not used */\n buildServerConfig: (token: string) => Record<string, unknown>\n configKey: string\n /** Returns the config file path if editor is detected, null otherwise */\n detect: (env: DetectionEnv) => Promise<string | null>\n format: 'jsonc' | 'toml'\n /** Extracts the auth token from a parsed Sanity server config block */\n readToken: (serverConfig: Record<string, unknown>) => string | undefined\n\n /** If true, this editor uses OAuth natively and does not need an embedded API token */\n oauthOnly?: boolean\n /**\n * Corresponding `--agent` value for the `skills` CLI (https://github.com/vercel-labs/skills).\n * Omit when the editor has no skills CLI equivalent.\n */\n skillsCliAgent?: string\n /**\n * The directory to install skills to.\n */\n skillsDir?: string\n}\n\n/**\n * The Sanity MCP server uses OAuth by default\n * If a token is provided, the server will not use OAuth instead tool calls will use the API token\n */\nconst defaultHttpConfig = (token?: string) => {\n const defaultConfig: Record<string, unknown> = {\n type: 'http',\n url: MCP_SERVER_URL,\n }\n\n if (token) {\n defaultConfig.headers = {Authorization: `Bearer ${token}`}\n }\n\n return defaultConfig\n}\n\n// -- Detect functions --\n\nasync function detectClaudeCode(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('claude', ['--version'])\n return path.join(ctx.homedir, '.claude.json')\n } catch {\n return null\n }\n}\n\nasync function detectAntigravity(ctx: DetectionEnv): Promise<string | null> {\n const antigravityDir = path.join(ctx.homedir, '.gemini/antigravity')\n return ctx.existsSync(antigravityDir) ? path.join(antigravityDir, 'mcp_config.json') : null\n}\n\nexport function getVSCodeUserDir(\n ctx: DetectionEnv,\n variant: 'insiders' | 'stable' = 'stable',\n): string | null {\n switch (ctx.platform) {\n case 'darwin': {\n return path.join(\n ctx.homedir,\n variant === 'insiders'\n ? 'Library/Application Support/Code - Insiders/User'\n : 'Library/Application Support/Code/User',\n )\n }\n case 'win32': {\n if (!ctx.env.APPDATA) return null\n return path.join(\n ctx.env.APPDATA,\n variant === 'insiders' ? 'Code - Insiders/User' : 'Code/User',\n )\n }\n default: {\n return path.join(\n ctx.homedir,\n variant === 'insiders' ? '.config/Code - Insiders/User' : '.config/Code/User',\n )\n }\n }\n}\n\nasync function detectCline(ctx: DetectionEnv): Promise<string | null> {\n const vscodeUserDir = getVSCodeUserDir(ctx)\n if (!vscodeUserDir) return null\n const clineConfigDir = path.join(vscodeUserDir, 'globalStorage/saoudrizwan.claude-dev/settings')\n return ctx.existsSync(clineConfigDir)\n ? path.join(clineConfigDir, 'cline_mcp_settings.json')\n : null\n}\n\nasync function detectClineCli(ctx: DetectionEnv): Promise<string | null> {\n const clineHome = ctx.env.CLINE_DIR || path.join(ctx.homedir, '.cline')\n if (!ctx.existsSync(clineHome)) return null\n return path.join(clineHome, 'data/settings/cline_mcp_settings.json')\n}\n\nasync function detectCodexCli(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('codex', ['--version'])\n const codexHome = ctx.env.CODEX_HOME || path.join(ctx.homedir, '.codex')\n return path.join(codexHome, 'config.toml')\n } catch {\n return null\n }\n}\n\nasync function detectCursor(ctx: DetectionEnv): Promise<string | null> {\n const cursorDir = path.join(ctx.homedir, '.cursor')\n return ctx.existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null\n}\n\nasync function detectGeminiCli(ctx: DetectionEnv): Promise<string | null> {\n // Antigravity stores its config under ~/.gemini/antigravity, so checking\n // only the parent ~/.gemini directory causes false Gemini CLI detection.\n const settingsPath = path.join(ctx.homedir, '.gemini/settings.json')\n return ctx.existsSync(settingsPath) ? settingsPath : null\n}\n\nasync function detectGitHubCopilotCli(ctx: DetectionEnv): Promise<string | null> {\n const copilotDir =\n ctx.platform === 'linux' && ctx.env.XDG_CONFIG_HOME\n ? path.join(ctx.env.XDG_CONFIG_HOME, 'copilot')\n : path.join(ctx.homedir, '.copilot')\n return ctx.existsSync(copilotDir) ? path.join(copilotDir, 'mcp-config.json') : null\n}\n\nasync function detectOpenCode(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('opencode', ['--version'])\n return path.join(ctx.homedir, '.config/opencode/opencode.json')\n } catch {\n return null\n }\n}\n\nasync function detectVSCode(ctx: DetectionEnv): Promise<string | null> {\n const configDir = getVSCodeUserDir(ctx)\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectVSCodeInsiders(ctx: DetectionEnv): Promise<string | null> {\n const configDir = getVSCodeUserDir(ctx, 'insiders')\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectZed(ctx: DetectionEnv): Promise<string | null> {\n let configDir: string | null = null\n switch (ctx.platform) {\n case 'win32': {\n if (ctx.env.APPDATA) {\n configDir = path.join(ctx.env.APPDATA, 'Zed')\n }\n break\n }\n default: {\n configDir = path.join(ctx.homedir, '.config/zed')\n }\n }\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'settings.json') : null\n}\n\nasync function detectMCPorter(ctx: DetectionEnv): Promise<string | null> {\n const mcporterDir = path.join(ctx.homedir, '.mcporter')\n if (!ctx.existsSync(mcporterDir)) return null\n\n const jsonPath = path.join(mcporterDir, 'mcporter.json')\n const jsoncPath = path.join(mcporterDir, 'mcporter.jsonc')\n if (ctx.existsSync(jsonPath)) return jsonPath\n if (ctx.existsSync(jsoncPath)) return jsoncPath\n return jsonPath\n}\n\n// -- Read token helpers --\n\n/**\n * Extract a Bearer token from a headers-like object.\n * Looks for `Authorization: \"Bearer <token>\"` and returns the token portion.\n */\nfunction extractBearerToken(headers: unknown): string | undefined {\n if (typeof headers !== 'object' || headers === null) return undefined\n const auth = (headers as Record<string, unknown>).Authorization\n if (typeof auth !== 'string') return undefined\n const match = auth.match(/^Bearer\\s+(.+)$/)\n return match?.[1]\n}\n\nfunction readTokenFromHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.headers)\n}\n\nfunction readTokenFromHttpHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.http_headers)\n}\n\n// -- Defaults & build server config functions --\n\nexport const UNIVERSAL_SKILLS_DIR = '.agents/skills'\n/** Most editors share these values — entries only need to declare `detect` + any overrides. */\nconst EDITOR_DEFAULTS = {\n buildServerConfig: defaultHttpConfig,\n configKey: 'mcpServers',\n format: 'jsonc' as const,\n oauthOnly: false,\n readToken: readTokenFromHeaders,\n skillsDir: UNIVERSAL_SKILLS_DIR,\n}\n\nfunction buildAntigravityServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n serverUrl: MCP_SERVER_URL,\n }\n}\n\nfunction buildClineServerConfig(token: string): Record<string, unknown> {\n return {\n disabled: false,\n headers: {Authorization: `Bearer ${token}`},\n type: 'streamableHttp',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildCodexCliServerConfig(token?: string): Record<string, unknown> {\n const config: Record<string, unknown> = {\n type: 'http',\n url: MCP_SERVER_URL,\n }\n\n if (token) {\n config.http_headers = {Authorization: `Bearer ${token}`}\n }\n\n return config\n}\n\nfunction buildGitHubCopilotCliServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n tools: ['*'],\n type: 'http',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildOpenCodeServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n type: 'remote',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildZedServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n settings: {},\n url: MCP_SERVER_URL,\n }\n}\n\n/**\n * Centralized editor configuration including detection logic.\n * To add a new editor: add an entry here — EditorName type is derived automatically.\n *\n * Each entry includes a doc URL pointing to the source of truth for its\n * config path and format. When updating a path, verify against the linked\n * documentation first.\n */\nexport const EDITOR_CONFIGS = {\n // Doc: https://support.google.com/gemini/answer/16255176 (Antigravity / Project Mariner)\n Antigravity: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildAntigravityServerConfig,\n detect: detectAntigravity,\n skillsCliAgent: 'antigravity',\n },\n // Doc: https://docs.anthropic.com/en/docs/claude-code/mcp\n // Path: ~/.claude.json Key: mcpServers\n 'Claude Code': {\n ...EDITOR_DEFAULTS,\n detect: detectClaudeCode,\n oauthOnly: true,\n skillsCliAgent: 'claude-code',\n skillsDir: '.claude/skills',\n },\n // Doc: https://github.com/cline/cline — VS Code extension (saoudrizwan.claude-dev)\n // Path: <VS Code User>/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json\n Cline: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildClineServerConfig,\n detect: detectCline,\n skillsCliAgent: 'cline',\n },\n // Doc: https://github.com/cline/cline — standalone CLI mode\n // Path: $CLINE_DIR || ~/.cline/data/settings/cline_mcp_settings.json\n 'Cline CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildClineServerConfig,\n detect: detectClineCli,\n skillsCliAgent: 'cline',\n },\n // Doc: https://platform.openai.com/docs/guides/tools-remote-mcp#codex-cli\n // Path: $CODEX_HOME || ~/.codex/config.toml Key: mcp_servers Format: TOML\n 'Codex CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildCodexCliServerConfig,\n configKey: 'mcp_servers',\n detect: detectCodexCli,\n format: 'toml' as const,\n oauthOnly: true,\n readToken: readTokenFromHttpHeaders,\n skillsCliAgent: 'codex',\n },\n // Doc: https://docs.cursor.com/context/model-context-protocol\n // Path: ~/.cursor/mcp.json Key: mcpServers\n Cursor: {\n ...EDITOR_DEFAULTS,\n detect: detectCursor,\n oauthOnly: true,\n skillsCliAgent: 'cursor',\n },\n // Doc: https://googlegemini.wiki/gemini-cli/mcp-servers\n // Path: ~/.gemini/settings.json Key: mcpServers\n 'Gemini CLI': {...EDITOR_DEFAULTS, detect: detectGeminiCli, skillsCliAgent: 'gemini-cli'},\n // Doc: https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-coding-agent-with-mcp\n // Path: ~/.copilot/mcp-config.json (or $XDG_CONFIG_HOME/copilot on Linux) Key: mcpServers\n 'GitHub Copilot CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildGitHubCopilotCliServerConfig,\n detect: detectGitHubCopilotCli,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://github.com/nicobailon/mcporter\n // Path: ~/.mcporter/mcporter.{json,jsonc} Key: mcpServers\n MCPorter: {...EDITOR_DEFAULTS, detect: detectMCPorter},\n // Doc: https://opencode.ai/docs/config\n // Path: ~/.config/opencode/opencode.json Key: mcp\n OpenCode: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildOpenCodeServerConfig,\n configKey: 'mcp',\n detect: detectOpenCode,\n skillsCliAgent: 'opencode',\n },\n // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers\n // Path: <VS Code User dir>/mcp.json Key: servers\n // VS Code uses GitHub Copilot for AI features; skills are installed via the\n // `github-copilot` agent (see https://code.visualstudio.com/docs/copilot/customization/agent-skills).\n 'VS Code': {\n ...EDITOR_DEFAULTS,\n configKey: 'servers',\n detect: detectVSCode,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers\n // Path: <VS Code Insiders User dir>/mcp.json Key: servers\n 'VS Code Insiders': {\n ...EDITOR_DEFAULTS,\n configKey: 'servers',\n detect: detectVSCodeInsiders,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://zed.dev/docs/assistant/model-context-protocol\n // Path: ~/.config/zed/settings.json (or $APPDATA/Zed on Windows) Key: context_servers\n // Zed doesn't support agent skills - https://github.com/zed-industries/zed/issues/49057\n Zed: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildZedServerConfig,\n configKey: 'context_servers',\n detect: detectZed,\n },\n} satisfies Record<string, EditorConfig>\n\n/** Derived from EDITOR_CONFIGS keys - add a new editor there and this updates automatically */\nexport type EditorName = keyof typeof EDITOR_CONFIGS\n\nexport function getSkillsCliAgent(editorName: EditorName): string | undefined {\n if (editorName in EDITOR_CONFIGS) {\n const config = EDITOR_CONFIGS[editorName]\n return 'skillsCliAgent' in config ? config.skillsCliAgent : undefined\n }\n}\n\n/**\n * Skills-CLI agent ID → display name. Mirrors `displayName` from\n * `~/git/skills/src/agents.ts` for the subset of agents we install for. Used\n * to match `skills list --json` output (which keys by display name) against\n * our editors.\n */\nconst SKILLS_CLI_AGENT_DISPLAY_NAMES: Record<string, string> = {\n antigravity: 'Antigravity',\n 'claude-code': 'Claude Code',\n cline: 'Cline',\n codex: 'Codex',\n cursor: 'Cursor',\n 'gemini-cli': 'Gemini CLI',\n 'github-copilot': 'GitHub Copilot',\n opencode: 'OpenCode',\n}\n\nexport function isUniversalSkillsCliAgentByEditorName(editorName: EditorName): boolean {\n return EDITOR_CONFIGS[editorName]?.skillsDir === UNIVERSAL_SKILLS_DIR\n}\n\n/** Display name used by the skills CLI for the given editor, if it has a mapping. */\nexport function getSkillsCliAgentDisplayName(editorName: EditorName): string | undefined {\n const agent = getSkillsCliAgent(editorName)\n return agent ? SKILLS_CLI_AGENT_DISPLAY_NAMES[agent] : undefined\n}\n\n/** Display name for a skills-CLI agent ID (e.g. `'cursor'` → `'Cursor'`). */\nexport function getSkillsCliAgentDisplayNameById(agentId: string): string | undefined {\n return SKILLS_CLI_AGENT_DISPLAY_NAMES[agentId]\n}\n\n/**\n * The relative, home-anchored directory the `skills` CLI installs into for a\n * given agent ID (e.g. `'cursor'` → `'.agents/skills'`, `'claude-code'` →\n * `'.claude/skills'`). Derived from `EDITOR_CONFIGS` so it stays a single\n * source of truth.\n */\nexport function getSkillsCliAgentSkillsDir(agentName: string): string | undefined {\n for (const name of Object.keys(EDITOR_CONFIGS) as EditorName[]) {\n const config = EDITOR_CONFIGS[name]\n const agent = getSkillsCliAgent(name)\n if (agent === agentName) {\n return config.skillsDir\n }\n }\n return undefined\n}\n"],"names":["existsSync","os","path","execa","MCP_SERVER_URL","createDetectionEnv","env","process","execCommand","cmd","args","stdio","timeout","then","homedir","platform","defaultHttpConfig","token","defaultConfig","type","url","headers","Authorization","detectClaudeCode","ctx","join","detectAntigravity","antigravityDir","getVSCodeUserDir","variant","APPDATA","detectCline","vscodeUserDir","clineConfigDir","detectClineCli","clineHome","CLINE_DIR","detectCodexCli","codexHome","CODEX_HOME","detectCursor","cursorDir","detectGeminiCli","settingsPath","detectGitHubCopilotCli","copilotDir","XDG_CONFIG_HOME","detectOpenCode","detectVSCode","configDir","detectVSCodeInsiders","detectZed","detectMCPorter","mcporterDir","jsonPath","jsoncPath","extractBearerToken","undefined","auth","match","readTokenFromHeaders","serverConfig","readTokenFromHttpHeaders","http_headers","UNIVERSAL_SKILLS_DIR","EDITOR_DEFAULTS","buildServerConfig","configKey","format","oauthOnly","readToken","skillsDir","buildAntigravityServerConfig","serverUrl","buildClineServerConfig","disabled","buildCodexCliServerConfig","config","buildGitHubCopilotCliServerConfig","tools","buildOpenCodeServerConfig","buildZedServerConfig","settings","EDITOR_CONFIGS","Antigravity","detect","skillsCliAgent","Cline","Cursor","MCPorter","OpenCode","Zed","getSkillsCliAgent","editorName","SKILLS_CLI_AGENT_DISPLAY_NAMES","antigravity","cline","codex","cursor","opencode","isUniversalSkillsCliAgentByEditorName","getSkillsCliAgentDisplayName","agent","getSkillsCliAgentDisplayNameById","agentId","getSkillsCliAgentSkillsDir","agentName","name","Object","keys"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/mcp/editorConfigs.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport {execa} from 'execa'\n\nimport {MCP_SERVER_URL} from '../../services/mcp.js'\n\n/**\n * Environment abstraction for editor detection.\n *\n * Detect functions receive this instead of using module-level imports, making\n * each function independently testable without global mocks.\n */\nexport interface DetectionEnv {\n env: Record<string, string | undefined>\n /** Run a CLI command to check if a tool is installed. Rejects on failure. */\n execCommand: (cmd: string, args: string[]) => Promise<void>\n existsSync: (p: string) => boolean\n homedir: string\n platform: NodeJS.Platform\n}\n\n/** Create the real detection environment backed by process/OS globals. */\nexport function createDetectionEnv(): DetectionEnv {\n return {\n env: process.env,\n execCommand: (cmd, args) => execa(cmd, args, {stdio: 'pipe', timeout: 5000}).then(() => {}),\n existsSync,\n homedir: os.homedir(),\n platform: process.platform,\n }\n}\n\ninterface EditorConfig {\n /** Builds the server config with API token. If oauthOnly is true, the token is not used */\n buildServerConfig: (token: string) => Record<string, unknown>\n configKey: string\n /** Returns the config file path if editor is detected, null otherwise */\n detect: (env: DetectionEnv) => Promise<string | null>\n format: 'jsonc' | 'toml'\n /** Extracts the auth token from a parsed Sanity server config block */\n readToken: (serverConfig: Record<string, unknown>) => string | undefined\n\n /** If true, this editor uses OAuth natively and does not need an embedded API token */\n oauthOnly?: boolean\n /**\n * Corresponding `--agent` value for the `skills` CLI (https://github.com/vercel-labs/skills).\n * Omit when the editor has no skills CLI equivalent.\n */\n skillsCliAgent?: string\n /**\n * The directory to install skills to.\n */\n skillsDir?: string\n}\n\n/**\n * The Sanity MCP server uses OAuth by default\n * If a token is provided, the server will not use OAuth instead tool calls will use the API token\n */\nconst defaultHttpConfig = (token?: string) => {\n const defaultConfig: Record<string, unknown> = {\n type: 'http',\n url: MCP_SERVER_URL,\n }\n\n if (token) {\n defaultConfig.headers = {Authorization: `Bearer ${token}`}\n }\n\n return defaultConfig\n}\n\n// -- Detect functions --\n\nasync function detectClaudeCode(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('claude', ['--version'])\n return path.join(ctx.homedir, '.claude.json')\n } catch {\n return null\n }\n}\n\nasync function detectAntigravity(ctx: DetectionEnv): Promise<string | null> {\n const antigravityDir = path.join(ctx.homedir, '.gemini/antigravity')\n return ctx.existsSync(antigravityDir) ? path.join(antigravityDir, 'mcp_config.json') : null\n}\n\nexport function getVSCodeUserDir(\n ctx: DetectionEnv,\n variant: 'insiders' | 'stable' = 'stable',\n): string | null {\n switch (ctx.platform) {\n case 'darwin': {\n return path.join(\n ctx.homedir,\n variant === 'insiders'\n ? 'Library/Application Support/Code - Insiders/User'\n : 'Library/Application Support/Code/User',\n )\n }\n case 'win32': {\n if (!ctx.env.APPDATA) return null\n return path.join(\n ctx.env.APPDATA,\n variant === 'insiders' ? 'Code - Insiders/User' : 'Code/User',\n )\n }\n default: {\n return path.join(\n ctx.homedir,\n variant === 'insiders' ? '.config/Code - Insiders/User' : '.config/Code/User',\n )\n }\n }\n}\n\nasync function detectCline(ctx: DetectionEnv): Promise<string | null> {\n const vscodeUserDir = getVSCodeUserDir(ctx)\n if (!vscodeUserDir) return null\n const clineConfigDir = path.join(vscodeUserDir, 'globalStorage/saoudrizwan.claude-dev/settings')\n return ctx.existsSync(clineConfigDir)\n ? path.join(clineConfigDir, 'cline_mcp_settings.json')\n : null\n}\n\nasync function detectClineCli(ctx: DetectionEnv): Promise<string | null> {\n const clineHome = ctx.env.CLINE_DIR || path.join(ctx.homedir, '.cline')\n if (!ctx.existsSync(clineHome)) return null\n return path.join(clineHome, 'data/settings/cline_mcp_settings.json')\n}\n\nasync function detectCodexCli(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('codex', ['--version'])\n const codexHome = ctx.env.CODEX_HOME || path.join(ctx.homedir, '.codex')\n return path.join(codexHome, 'config.toml')\n } catch {\n return null\n }\n}\n\nasync function detectCursor(ctx: DetectionEnv): Promise<string | null> {\n const cursorDir = path.join(ctx.homedir, '.cursor')\n return ctx.existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null\n}\n\nasync function detectGeminiCli(ctx: DetectionEnv): Promise<string | null> {\n // Antigravity stores its config under ~/.gemini/antigravity, so checking\n // only the parent ~/.gemini directory causes false Gemini CLI detection.\n const settingsPath = path.join(ctx.homedir, '.gemini/settings.json')\n return ctx.existsSync(settingsPath) ? settingsPath : null\n}\n\nasync function detectGitHubCopilotCli(ctx: DetectionEnv): Promise<string | null> {\n const copilotDir =\n ctx.platform === 'linux' && ctx.env.XDG_CONFIG_HOME\n ? path.join(ctx.env.XDG_CONFIG_HOME, 'copilot')\n : path.join(ctx.homedir, '.copilot')\n return ctx.existsSync(copilotDir) ? path.join(copilotDir, 'mcp-config.json') : null\n}\n\nasync function detectOpenCode(ctx: DetectionEnv): Promise<string | null> {\n try {\n await ctx.execCommand('opencode', ['--version'])\n return path.join(ctx.homedir, '.config/opencode/opencode.json')\n } catch {\n return null\n }\n}\n\nasync function detectVSCode(ctx: DetectionEnv): Promise<string | null> {\n const configDir = getVSCodeUserDir(ctx)\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectVSCodeInsiders(ctx: DetectionEnv): Promise<string | null> {\n const configDir = getVSCodeUserDir(ctx, 'insiders')\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectZed(ctx: DetectionEnv): Promise<string | null> {\n let configDir: string | null = null\n switch (ctx.platform) {\n case 'win32': {\n if (ctx.env.APPDATA) {\n configDir = path.join(ctx.env.APPDATA, 'Zed')\n }\n break\n }\n default: {\n configDir = path.join(ctx.homedir, '.config/zed')\n }\n }\n return configDir && ctx.existsSync(configDir) ? path.join(configDir, 'settings.json') : null\n}\n\nasync function detectMCPorter(ctx: DetectionEnv): Promise<string | null> {\n const mcporterDir = path.join(ctx.homedir, '.mcporter')\n if (!ctx.existsSync(mcporterDir)) return null\n\n const jsonPath = path.join(mcporterDir, 'mcporter.json')\n const jsoncPath = path.join(mcporterDir, 'mcporter.jsonc')\n if (ctx.existsSync(jsonPath)) return jsonPath\n if (ctx.existsSync(jsoncPath)) return jsoncPath\n return jsonPath\n}\n\n// -- Read token helpers --\n\n/**\n * Extract a Bearer token from a headers-like object.\n * Looks for `Authorization: \"Bearer <token>\"` and returns the token portion.\n */\nfunction extractBearerToken(headers: unknown): string | undefined {\n if (typeof headers !== 'object' || headers === null) return undefined\n const auth = (headers as Record<string, unknown>).Authorization\n if (typeof auth !== 'string') return undefined\n const match = auth.match(/^Bearer\\s+(.+)$/)\n return match?.[1]\n}\n\nfunction readTokenFromHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.headers)\n}\n\nfunction readTokenFromHttpHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.http_headers)\n}\n\n// -- Defaults & build server config functions --\n\nexport const UNIVERSAL_SKILLS_DIR = '.agents/skills'\n/** Most editors share these values — entries only need to declare `detect` + any overrides. */\nconst EDITOR_DEFAULTS = {\n buildServerConfig: defaultHttpConfig,\n configKey: 'mcpServers',\n format: 'jsonc' as const,\n oauthOnly: false,\n readToken: readTokenFromHeaders,\n skillsDir: UNIVERSAL_SKILLS_DIR,\n}\n\nfunction buildAntigravityServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n serverUrl: MCP_SERVER_URL,\n }\n}\n\nfunction buildClineServerConfig(token: string): Record<string, unknown> {\n return {\n disabled: false,\n headers: {Authorization: `Bearer ${token}`},\n type: 'streamableHttp',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildCodexCliServerConfig(token?: string): Record<string, unknown> {\n const config: Record<string, unknown> = {\n type: 'http',\n url: MCP_SERVER_URL,\n }\n\n if (token) {\n config.http_headers = {Authorization: `Bearer ${token}`}\n }\n\n return config\n}\n\nfunction buildGitHubCopilotCliServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n tools: ['*'],\n type: 'http',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildOpenCodeServerConfig(token?: string): Record<string, unknown> {\n const config: Record<string, unknown> = {\n type: 'remote',\n url: MCP_SERVER_URL,\n }\n\n if (token) {\n config.headers = {Authorization: `Bearer ${token}`}\n }\n\n return config\n}\n\nfunction buildZedServerConfig(token: string): Record<string, unknown> {\n return {\n enabled: true,\n headers: {Authorization: `Bearer ${token}`},\n url: MCP_SERVER_URL,\n }\n}\n\n/**\n * Centralized editor configuration including detection logic.\n * To add a new editor: add an entry here — EditorName type is derived automatically.\n *\n * Each entry includes a doc URL pointing to the source of truth for its\n * config path and format. When updating a path, verify against the linked\n * documentation first.\n */\nexport const EDITOR_CONFIGS = {\n // Doc: https://support.google.com/gemini/answer/16255176 (Antigravity / Project Mariner)\n Antigravity: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildAntigravityServerConfig,\n detect: detectAntigravity,\n skillsCliAgent: 'antigravity',\n },\n // Doc: https://docs.anthropic.com/en/docs/claude-code/mcp\n // Path: ~/.claude.json Key: mcpServers\n 'Claude Code': {\n ...EDITOR_DEFAULTS,\n detect: detectClaudeCode,\n oauthOnly: true,\n skillsCliAgent: 'claude-code',\n skillsDir: '.claude/skills',\n },\n // Doc: https://github.com/cline/cline — VS Code extension (saoudrizwan.claude-dev)\n // Path: <VS Code User>/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json\n Cline: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildClineServerConfig,\n detect: detectCline,\n skillsCliAgent: 'cline',\n },\n // Doc: https://github.com/cline/cline — standalone CLI mode\n // Path: $CLINE_DIR || ~/.cline/data/settings/cline_mcp_settings.json\n 'Cline CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildClineServerConfig,\n detect: detectClineCli,\n skillsCliAgent: 'cline',\n },\n // Doc: https://platform.openai.com/docs/guides/tools-remote-mcp#codex-cli\n // Path: $CODEX_HOME || ~/.codex/config.toml Key: mcp_servers Format: TOML\n 'Codex CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildCodexCliServerConfig,\n configKey: 'mcp_servers',\n detect: detectCodexCli,\n format: 'toml' as const,\n oauthOnly: true,\n readToken: readTokenFromHttpHeaders,\n skillsCliAgent: 'codex',\n },\n // Doc: https://docs.cursor.com/context/model-context-protocol\n // Path: ~/.cursor/mcp.json Key: mcpServers\n Cursor: {\n ...EDITOR_DEFAULTS,\n detect: detectCursor,\n oauthOnly: true,\n skillsCliAgent: 'cursor',\n },\n // Doc: https://googlegemini.wiki/gemini-cli/mcp-servers\n // Path: ~/.gemini/settings.json Key: mcpServers\n 'Gemini CLI': {...EDITOR_DEFAULTS, detect: detectGeminiCli, skillsCliAgent: 'gemini-cli'},\n // Doc: https://docs.github.com/en/copilot/customizing-copilot/extending-copilot-coding-agent-with-mcp\n // Path: ~/.copilot/mcp-config.json (or $XDG_CONFIG_HOME/copilot on Linux) Key: mcpServers\n 'GitHub Copilot CLI': {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildGitHubCopilotCliServerConfig,\n detect: detectGitHubCopilotCli,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://github.com/nicobailon/mcporter\n // Path: ~/.mcporter/mcporter.{json,jsonc} Key: mcpServers\n MCPorter: {...EDITOR_DEFAULTS, detect: detectMCPorter},\n // Doc: https://opencode.ai/docs/config\n // Path: ~/.config/opencode/opencode.json Key: mcp\n OpenCode: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildOpenCodeServerConfig,\n configKey: 'mcp',\n detect: detectOpenCode,\n oauthOnly: true,\n skillsCliAgent: 'opencode',\n },\n // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers\n // Path: <VS Code User dir>/mcp.json Key: servers\n // VS Code uses GitHub Copilot for AI features; skills are installed via the\n // `github-copilot` agent (see https://code.visualstudio.com/docs/copilot/customization/agent-skills).\n 'VS Code': {\n ...EDITOR_DEFAULTS,\n configKey: 'servers',\n detect: detectVSCode,\n oauthOnly: true,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://code.visualstudio.com/docs/copilot/chat/mcp-servers\n // Path: <VS Code Insiders User dir>/mcp.json Key: servers\n 'VS Code Insiders': {\n ...EDITOR_DEFAULTS,\n configKey: 'servers',\n detect: detectVSCodeInsiders,\n oauthOnly: true,\n skillsCliAgent: 'github-copilot',\n },\n // Doc: https://zed.dev/docs/assistant/model-context-protocol\n // Path: ~/.config/zed/settings.json (or $APPDATA/Zed on Windows) Key: context_servers\n // Zed doesn't support agent skills - https://github.com/zed-industries/zed/issues/49057\n Zed: {\n ...EDITOR_DEFAULTS,\n buildServerConfig: buildZedServerConfig,\n configKey: 'context_servers',\n detect: detectZed,\n },\n} satisfies Record<string, EditorConfig>\n\n/** Derived from EDITOR_CONFIGS keys - add a new editor there and this updates automatically */\nexport type EditorName = keyof typeof EDITOR_CONFIGS\n\nexport function getSkillsCliAgent(editorName: EditorName): string | undefined {\n if (editorName in EDITOR_CONFIGS) {\n const config = EDITOR_CONFIGS[editorName]\n return 'skillsCliAgent' in config ? config.skillsCliAgent : undefined\n }\n}\n\n/**\n * Skills-CLI agent ID → display name. Mirrors `displayName` from\n * `~/git/skills/src/agents.ts` for the subset of agents we install for. Used\n * to match `skills list --json` output (which keys by display name) against\n * our editors.\n */\nconst SKILLS_CLI_AGENT_DISPLAY_NAMES: Record<string, string> = {\n antigravity: 'Antigravity',\n 'claude-code': 'Claude Code',\n cline: 'Cline',\n codex: 'Codex',\n cursor: 'Cursor',\n 'gemini-cli': 'Gemini CLI',\n 'github-copilot': 'GitHub Copilot',\n opencode: 'OpenCode',\n}\n\nexport function isUniversalSkillsCliAgentByEditorName(editorName: EditorName): boolean {\n return EDITOR_CONFIGS[editorName]?.skillsDir === UNIVERSAL_SKILLS_DIR\n}\n\n/** Display name used by the skills CLI for the given editor, if it has a mapping. */\nexport function getSkillsCliAgentDisplayName(editorName: EditorName): string | undefined {\n const agent = getSkillsCliAgent(editorName)\n return agent ? SKILLS_CLI_AGENT_DISPLAY_NAMES[agent] : undefined\n}\n\n/** Display name for a skills-CLI agent ID (e.g. `'cursor'` → `'Cursor'`). */\nexport function getSkillsCliAgentDisplayNameById(agentId: string): string | undefined {\n return SKILLS_CLI_AGENT_DISPLAY_NAMES[agentId]\n}\n\n/**\n * The relative, home-anchored directory the `skills` CLI installs into for a\n * given agent ID (e.g. `'cursor'` → `'.agents/skills'`, `'claude-code'` →\n * `'.claude/skills'`). Derived from `EDITOR_CONFIGS` so it stays a single\n * source of truth.\n */\nexport function getSkillsCliAgentSkillsDir(agentName: string): string | undefined {\n for (const name of Object.keys(EDITOR_CONFIGS) as EditorName[]) {\n const config = EDITOR_CONFIGS[name]\n const agent = getSkillsCliAgent(name)\n if (agent === agentName) {\n return config.skillsDir\n }\n }\n return undefined\n}\n"],"names":["existsSync","os","path","execa","MCP_SERVER_URL","createDetectionEnv","env","process","execCommand","cmd","args","stdio","timeout","then","homedir","platform","defaultHttpConfig","token","defaultConfig","type","url","headers","Authorization","detectClaudeCode","ctx","join","detectAntigravity","antigravityDir","getVSCodeUserDir","variant","APPDATA","detectCline","vscodeUserDir","clineConfigDir","detectClineCli","clineHome","CLINE_DIR","detectCodexCli","codexHome","CODEX_HOME","detectCursor","cursorDir","detectGeminiCli","settingsPath","detectGitHubCopilotCli","copilotDir","XDG_CONFIG_HOME","detectOpenCode","detectVSCode","configDir","detectVSCodeInsiders","detectZed","detectMCPorter","mcporterDir","jsonPath","jsoncPath","extractBearerToken","undefined","auth","match","readTokenFromHeaders","serverConfig","readTokenFromHttpHeaders","http_headers","UNIVERSAL_SKILLS_DIR","EDITOR_DEFAULTS","buildServerConfig","configKey","format","oauthOnly","readToken","skillsDir","buildAntigravityServerConfig","serverUrl","buildClineServerConfig","disabled","buildCodexCliServerConfig","config","buildGitHubCopilotCliServerConfig","tools","buildOpenCodeServerConfig","buildZedServerConfig","enabled","EDITOR_CONFIGS","Antigravity","detect","skillsCliAgent","Cline","Cursor","MCPorter","OpenCode","Zed","getSkillsCliAgent","editorName","SKILLS_CLI_AGENT_DISPLAY_NAMES","antigravity","cline","codex","cursor","opencode","isUniversalSkillsCliAgentByEditorName","getSkillsCliAgentDisplayName","agent","getSkillsCliAgentDisplayNameById","agentId","getSkillsCliAgentSkillsDir","agentName","name","Object","keys"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,OAAOC,QAAQ,UAAS;AACxB,OAAOC,UAAU,YAAW;AAE5B,SAAQC,KAAK,QAAO,QAAO;AAE3B,SAAQC,cAAc,QAAO,wBAAuB;AAiBpD,wEAAwE,GACxE,OAAO,SAASC;IACd,OAAO;QACLC,KAAKC,QAAQD,GAAG;QAChBE,aAAa,CAACC,KAAKC,OAASP,MAAMM,KAAKC,MAAM;gBAACC,OAAO;gBAAQC,SAAS;YAAI,GAAGC,IAAI,CAAC,KAAO;QACzFb;QACAc,SAASb,GAAGa,OAAO;QACnBC,UAAUR,QAAQQ,QAAQ;IAC5B;AACF;AAyBA;;;CAGC,GACD,MAAMC,oBAAoB,CAACC;IACzB,MAAMC,gBAAyC;QAC7CC,MAAM;QACNC,KAAKhB;IACP;IAEA,IAAIa,OAAO;QACTC,cAAcG,OAAO,GAAG;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;IAC3D;IAEA,OAAOC;AACT;AAEA,yBAAyB;AAEzB,eAAeK,iBAAiBC,GAAiB;IAC/C,IAAI;QACF,MAAMA,IAAIhB,WAAW,CAAC,UAAU;YAAC;SAAY;QAC7C,OAAON,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAChC,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAeY,kBAAkBF,GAAiB;IAChD,MAAMG,iBAAiBzB,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAC9C,OAAOU,IAAIxB,UAAU,CAAC2B,kBAAkBzB,KAAKuB,IAAI,CAACE,gBAAgB,qBAAqB;AACzF;AAEA,OAAO,SAASC,iBACdJ,GAAiB,EACjBK,UAAiC,QAAQ;IAEzC,OAAQL,IAAIT,QAAQ;QAClB,KAAK;YAAU;gBACb,OAAOb,KAAKuB,IAAI,CACdD,IAAIV,OAAO,EACXe,YAAY,aACR,qDACA;YAER;QACA,KAAK;YAAS;gBACZ,IAAI,CAACL,IAAIlB,GAAG,CAACwB,OAAO,EAAE,OAAO;gBAC7B,OAAO5B,KAAKuB,IAAI,CACdD,IAAIlB,GAAG,CAACwB,OAAO,EACfD,YAAY,aAAa,yBAAyB;YAEtD;QACA;YAAS;gBACP,OAAO3B,KAAKuB,IAAI,CACdD,IAAIV,OAAO,EACXe,YAAY,aAAa,iCAAiC;YAE9D;IACF;AACF;AAEA,eAAeE,YAAYP,GAAiB;IAC1C,MAAMQ,gBAAgBJ,iBAAiBJ;IACvC,IAAI,CAACQ,eAAe,OAAO;IAC3B,MAAMC,iBAAiB/B,KAAKuB,IAAI,CAACO,eAAe;IAChD,OAAOR,IAAIxB,UAAU,CAACiC,kBAClB/B,KAAKuB,IAAI,CAACQ,gBAAgB,6BAC1B;AACN;AAEA,eAAeC,eAAeV,GAAiB;IAC7C,MAAMW,YAAYX,IAAIlB,GAAG,CAAC8B,SAAS,IAAIlC,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAC9D,IAAI,CAACU,IAAIxB,UAAU,CAACmC,YAAY,OAAO;IACvC,OAAOjC,KAAKuB,IAAI,CAACU,WAAW;AAC9B;AAEA,eAAeE,eAAeb,GAAiB;IAC7C,IAAI;QACF,MAAMA,IAAIhB,WAAW,CAAC,SAAS;YAAC;SAAY;QAC5C,MAAM8B,YAAYd,IAAIlB,GAAG,CAACiC,UAAU,IAAIrC,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;QAC/D,OAAOZ,KAAKuB,IAAI,CAACa,WAAW;IAC9B,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAeE,aAAahB,GAAiB;IAC3C,MAAMiB,YAAYvC,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IACzC,OAAOU,IAAIxB,UAAU,CAACyC,aAAavC,KAAKuB,IAAI,CAACgB,WAAW,cAAc;AACxE;AAEA,eAAeC,gBAAgBlB,GAAiB;IAC9C,yEAAyE;IACzE,yEAAyE;IACzE,MAAMmB,eAAezC,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAC5C,OAAOU,IAAIxB,UAAU,CAAC2C,gBAAgBA,eAAe;AACvD;AAEA,eAAeC,uBAAuBpB,GAAiB;IACrD,MAAMqB,aACJrB,IAAIT,QAAQ,KAAK,WAAWS,IAAIlB,GAAG,CAACwC,eAAe,GAC/C5C,KAAKuB,IAAI,CAACD,IAAIlB,GAAG,CAACwC,eAAe,EAAE,aACnC5C,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAC7B,OAAOU,IAAIxB,UAAU,CAAC6C,cAAc3C,KAAKuB,IAAI,CAACoB,YAAY,qBAAqB;AACjF;AAEA,eAAeE,eAAevB,GAAiB;IAC7C,IAAI;QACF,MAAMA,IAAIhB,WAAW,CAAC,YAAY;YAAC;SAAY;QAC/C,OAAON,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAChC,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,eAAekC,aAAaxB,GAAiB;IAC3C,MAAMyB,YAAYrB,iBAAiBJ;IACnC,OAAOyB,aAAazB,IAAIxB,UAAU,CAACiD,aAAa/C,KAAKuB,IAAI,CAACwB,WAAW,cAAc;AACrF;AAEA,eAAeC,qBAAqB1B,GAAiB;IACnD,MAAMyB,YAAYrB,iBAAiBJ,KAAK;IACxC,OAAOyB,aAAazB,IAAIxB,UAAU,CAACiD,aAAa/C,KAAKuB,IAAI,CAACwB,WAAW,cAAc;AACrF;AAEA,eAAeE,UAAU3B,GAAiB;IACxC,IAAIyB,YAA2B;IAC/B,OAAQzB,IAAIT,QAAQ;QAClB,KAAK;YAAS;gBACZ,IAAIS,IAAIlB,GAAG,CAACwB,OAAO,EAAE;oBACnBmB,YAAY/C,KAAKuB,IAAI,CAACD,IAAIlB,GAAG,CAACwB,OAAO,EAAE;gBACzC;gBACA;YACF;QACA;YAAS;gBACPmB,YAAY/C,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;YACrC;IACF;IACA,OAAOmC,aAAazB,IAAIxB,UAAU,CAACiD,aAAa/C,KAAKuB,IAAI,CAACwB,WAAW,mBAAmB;AAC1F;AAEA,eAAeG,eAAe5B,GAAiB;IAC7C,MAAM6B,cAAcnD,KAAKuB,IAAI,CAACD,IAAIV,OAAO,EAAE;IAC3C,IAAI,CAACU,IAAIxB,UAAU,CAACqD,cAAc,OAAO;IAEzC,MAAMC,WAAWpD,KAAKuB,IAAI,CAAC4B,aAAa;IACxC,MAAME,YAAYrD,KAAKuB,IAAI,CAAC4B,aAAa;IACzC,IAAI7B,IAAIxB,UAAU,CAACsD,WAAW,OAAOA;IACrC,IAAI9B,IAAIxB,UAAU,CAACuD,YAAY,OAAOA;IACtC,OAAOD;AACT;AAEA,2BAA2B;AAE3B;;;CAGC,GACD,SAASE,mBAAmBnC,OAAgB;IAC1C,IAAI,OAAOA,YAAY,YAAYA,YAAY,MAAM,OAAOoC;IAC5D,MAAMC,OAAO,AAACrC,QAAoCC,aAAa;IAC/D,IAAI,OAAOoC,SAAS,UAAU,OAAOD;IACrC,MAAME,QAAQD,KAAKC,KAAK,CAAC;IACzB,OAAOA,OAAO,CAAC,EAAE;AACnB;AAEA,SAASC,qBAAqBC,YAAqC;IACjE,OAAOL,mBAAmBK,aAAaxC,OAAO;AAChD;AAEA,SAASyC,yBAAyBD,YAAqC;IACrE,OAAOL,mBAAmBK,aAAaE,YAAY;AACrD;AAEA,iDAAiD;AAEjD,OAAO,MAAMC,uBAAuB,iBAAgB;AACpD,6FAA6F,GAC7F,MAAMC,kBAAkB;IACtBC,mBAAmBlD;IACnBmD,WAAW;IACXC,QAAQ;IACRC,WAAW;IACXC,WAAWV;IACXW,WAAWP;AACb;AAEA,SAASQ,6BAA6BvD,KAAa;IACjD,OAAO;QACLI,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;QAC1CwD,WAAWrE;IACb;AACF;AAEA,SAASsE,uBAAuBzD,KAAa;IAC3C,OAAO;QACL0D,UAAU;QACVtD,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;QAC1CE,MAAM;QACNC,KAAKhB;IACP;AACF;AAEA,SAASwE,0BAA0B3D,KAAc;IAC/C,MAAM4D,SAAkC;QACtC1D,MAAM;QACNC,KAAKhB;IACP;IAEA,IAAIa,OAAO;QACT4D,OAAOd,YAAY,GAAG;YAACzC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;IACzD;IAEA,OAAO4D;AACT;AAEA,SAASC,kCAAkC7D,KAAa;IACtD,OAAO;QACLI,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;QAC1C8D,OAAO;YAAC;SAAI;QACZ5D,MAAM;QACNC,KAAKhB;IACP;AACF;AAEA,SAAS4E,0BAA0B/D,KAAc;IAC/C,MAAM4D,SAAkC;QACtC1D,MAAM;QACNC,KAAKhB;IACP;IAEA,IAAIa,OAAO;QACT4D,OAAOxD,OAAO,GAAG;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;IACpD;IAEA,OAAO4D;AACT;AAEA,SAASI,qBAAqBhE,KAAa;IACzC,OAAO;QACLiE,SAAS;QACT7D,SAAS;YAACC,eAAe,CAAC,OAAO,EAAEL,OAAO;QAAA;QAC1CG,KAAKhB;IACP;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,MAAM+E,iBAAiB;IAC5B,yFAAyF;IACzFC,aAAa;QACX,GAAGnB,eAAe;QAClBC,mBAAmBM;QACnBa,QAAQ3D;QACR4D,gBAAgB;IAClB;IACA,0DAA0D;IAC1D,wCAAwC;IACxC,eAAe;QACb,GAAGrB,eAAe;QAClBoB,QAAQ9D;QACR8C,WAAW;QACXiB,gBAAgB;QAChBf,WAAW;IACb;IACA,mFAAmF;IACnF,6FAA6F;IAC7FgB,OAAO;QACL,GAAGtB,eAAe;QAClBC,mBAAmBQ;QACnBW,QAAQtD;QACRuD,gBAAgB;IAClB;IACA,4DAA4D;IAC5D,qEAAqE;IACrE,aAAa;QACX,GAAGrB,eAAe;QAClBC,mBAAmBQ;QACnBW,QAAQnD;QACRoD,gBAAgB;IAClB;IACA,0EAA0E;IAC1E,4EAA4E;IAC5E,aAAa;QACX,GAAGrB,eAAe;QAClBC,mBAAmBU;QACnBT,WAAW;QACXkB,QAAQhD;QACR+B,QAAQ;QACRC,WAAW;QACXC,WAAWR;QACXwB,gBAAgB;IAClB;IACA,8DAA8D;IAC9D,4CAA4C;IAC5CE,QAAQ;QACN,GAAGvB,eAAe;QAClBoB,QAAQ7C;QACR6B,WAAW;QACXiB,gBAAgB;IAClB;IACA,wDAAwD;IACxD,iDAAiD;IACjD,cAAc;QAAC,GAAGrB,eAAe;QAAEoB,QAAQ3C;QAAiB4C,gBAAgB;IAAY;IACxF,sGAAsG;IACtG,2FAA2F;IAC3F,sBAAsB;QACpB,GAAGrB,eAAe;QAClBC,mBAAmBY;QACnBO,QAAQzC;QACR0C,gBAAgB;IAClB;IACA,8CAA8C;IAC9C,2DAA2D;IAC3DG,UAAU;QAAC,GAAGxB,eAAe;QAAEoB,QAAQjC;IAAc;IACrD,uCAAuC;IACvC,mDAAmD;IACnDsC,UAAU;QACR,GAAGzB,eAAe;QAClBC,mBAAmBc;QACnBb,WAAW;QACXkB,QAAQtC;QACRsB,WAAW;QACXiB,gBAAgB;IAClB;IACA,mEAAmE;IACnE,kDAAkD;IAClD,4EAA4E;IAC5E,sGAAsG;IACtG,WAAW;QACT,GAAGrB,eAAe;QAClBE,WAAW;QACXkB,QAAQrC;QACRqB,WAAW;QACXiB,gBAAgB;IAClB;IACA,mEAAmE;IACnE,2DAA2D;IAC3D,oBAAoB;QAClB,GAAGrB,eAAe;QAClBE,WAAW;QACXkB,QAAQnC;QACRmB,WAAW;QACXiB,gBAAgB;IAClB;IACA,6DAA6D;IAC7D,uFAAuF;IACvF,wFAAwF;IACxFK,KAAK;QACH,GAAG1B,eAAe;QAClBC,mBAAmBe;QACnBd,WAAW;QACXkB,QAAQlC;IACV;AACF,EAAwC;AAKxC,OAAO,SAASyC,kBAAkBC,UAAsB;IACtD,IAAIA,cAAcV,gBAAgB;QAChC,MAAMN,SAASM,cAAc,CAACU,WAAW;QACzC,OAAO,oBAAoBhB,SAASA,OAAOS,cAAc,GAAG7B;IAC9D;AACF;AAEA;;;;;CAKC,GACD,MAAMqC,iCAAyD;IAC7DC,aAAa;IACb,eAAe;IACfC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACR,cAAc;IACd,kBAAkB;IAClBC,UAAU;AACZ;AAEA,OAAO,SAASC,sCAAsCP,UAAsB;IAC1E,OAAOV,cAAc,CAACU,WAAW,EAAEtB,cAAcP;AACnD;AAEA,mFAAmF,GACnF,OAAO,SAASqC,6BAA6BR,UAAsB;IACjE,MAAMS,QAAQV,kBAAkBC;IAChC,OAAOS,QAAQR,8BAA8B,CAACQ,MAAM,GAAG7C;AACzD;AAEA,2EAA2E,GAC3E,OAAO,SAAS8C,iCAAiCC,OAAe;IAC9D,OAAOV,8BAA8B,CAACU,QAAQ;AAChD;AAEA;;;;;CAKC,GACD,OAAO,SAASC,2BAA2BC,SAAiB;IAC1D,KAAK,MAAMC,QAAQC,OAAOC,IAAI,CAAC1B,gBAAiC;QAC9D,MAAMN,SAASM,cAAc,CAACwB,KAAK;QACnC,MAAML,QAAQV,kBAAkBe;QAChC,IAAIL,UAAUI,WAAW;YACvB,OAAO7B,OAAON,SAAS;QACzB;IACF;IACA,OAAOd;AACT"}
@@ -43,6 +43,10 @@ export class DeployCommand extends SanityCommand {
43
43
  default: true,
44
44
  description: 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)'
45
45
  }),
46
+ 'dry-run': Flags.boolean({
47
+ default: false,
48
+ description: 'Report what would be deployed without uploading or creating anything'
49
+ }),
46
50
  external: Flags.boolean({
47
51
  default: false,
48
52
  description: 'Register an externally hosted studio',
@@ -65,6 +69,9 @@ export class DeployCommand extends SanityCommand {
65
69
  default: false,
66
70
  description: 'Enable source maps for built bundles (increases size of bundle)'
67
71
  }),
72
+ title: Flags.string({
73
+ description: 'Title for a newly created application or studio. For apps it also skips the interactive title prompt, enabling unattended creation'
74
+ }),
68
75
  url: Flags.string({
69
76
  description: 'Studio URL for deployment. For external studios, the full URL. For hosted studios, the hostname (e.g. "my-studio" or "my-studio.sanity.studio")'
70
77
  }),
@@ -91,24 +98,33 @@ export class DeployCommand extends SanityCommand {
91
98
  if (relativeOutput[0] !== '.') {
92
99
  relativeOutput = `./${relativeOutput}`;
93
100
  }
94
- const isEmpty = await dirIsEmptyOrNonExistent(sourceDir);
95
- // Prompt to delete the directory if it's not empty
96
- const shouldProceed = isEmpty || await confirm({
97
- default: false,
98
- message: `"${relativeOutput}" is not empty, do you want to proceed?`
99
- });
100
- if (!shouldProceed) {
101
- this.output.error('Cancelled.', {
102
- exit: 1
101
+ // Unattended runs (--yes or a non-interactive terminal) and dry runs skip the overwrite prompt
102
+ if (!this.isUnattended() && !flags['dry-run']) {
103
+ const isEmpty = await dirIsEmptyOrNonExistent(sourceDir);
104
+ const shouldProceed = isEmpty || await confirm({
105
+ default: false,
106
+ message: `"${relativeOutput}" is not empty, do you want to proceed?`
103
107
  });
108
+ if (!shouldProceed) {
109
+ this.output.error('Cancelled.', {
110
+ exit: 1
111
+ });
112
+ }
104
113
  }
105
114
  this.output.log(`Building to ${relativeOutput}\n`);
106
115
  }
116
+ // Unattended runs (--yes or a non-interactive terminal) and dry runs deploy
117
+ // without any downstream prompts — application resolution and the build
118
+ // (buildApp/buildStudio) otherwise stop for prerelease/version choices.
119
+ const deployFlags = this.isUnattended() || flags['dry-run'] ? {
120
+ ...flags,
121
+ yes: true
122
+ } : flags;
107
123
  if (isApp) {
108
124
  deployDebug('Deploying app');
109
125
  await deployApp({
110
126
  cliConfig,
111
- flags,
127
+ flags: deployFlags,
112
128
  output: this.output,
113
129
  projectRoot,
114
130
  sourceDir
@@ -117,7 +133,7 @@ export class DeployCommand extends SanityCommand {
117
133
  deployDebug('Deploying studio');
118
134
  await deployStudio({
119
135
  cliConfig,
120
- flags,
136
+ flags: deployFlags,
121
137
  output: this.output,
122
138
  projectRoot,
123
139
  sourceDir
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify', 'build'],\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external studios, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n // Prompt to delete the directory if it's not empty\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: 1})\n }\n\n this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","SanityCommand","confirm","deployApp","deployDebug","deployStudio","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","examples","command","flags","boolean","allowNo","deprecated","build","default","external","exclusive","minify","url","string","verbose","yes","char","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isEmpty","shouldProceed","message","output","error","exit","log"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify', 'build'],\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps it also skips the interactive title prompt, enabling unattended creation',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external studios, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n // Unattended runs (--yes or a non-interactive terminal) and dry runs skip the overwrite prompt\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: 1})\n }\n }\n\n this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Unattended runs (--yes or a non-interactive terminal) and dry runs deploy\n // without any downstream prompts — application resolution and the build\n // (buildApp/buildStudio) otherwise stop for prerelease/version choices.\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","SanityCommand","confirm","deployApp","deployDebug","deployStudio","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","examples","command","flags","boolean","allowNo","deprecated","build","default","external","exclusive","minify","title","string","url","verbose","yes","char","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","output","error","exit","log","deployFlags"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { Flags } from '@oclif/core';
3
- import { isWorkbenchApp, SanityCommand } from '@sanity/cli-core';
3
+ import { SanityCommand } from '@sanity/cli-core';
4
+ import { isWorkbenchApp } from '@sanity/workbench-cli';
4
5
  import { devAction } from '../actions/dev/devAction.js';
5
6
  import { devDebug } from '../actions/dev/devDebug.js';
6
7
  import { determineIsApp } from '../util/determineIsApp.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/dev.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {type CliConfig, isWorkbenchApp, SanityCommand} from '@sanity/cli-core'\n\nimport {devAction} from '../actions/dev/devAction.js'\nimport {devDebug} from '../actions/dev/devDebug.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\n\n/**\n * Workbench apps never load in the Sanity dashboard, so `--load-in-dashboard`\n * has no effect for them. The flag is defaulted later in `run`, so an\n * `undefined` value here still means the user never passed it.\n */\nexport function shouldWarnDashboardFlagIgnored(\n cliConfig: CliConfig | undefined,\n loadInDashboard: boolean | undefined,\n): boolean {\n return isWorkbenchApp(cliConfig?.app) && loadInDashboard !== undefined\n}\n\nexport class DevCommand extends SanityCommand<typeof DevCommand> {\n static override description = 'Start a local development server with live reloading'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %> --host=0.0.0.0',\n '<%= config.bin %> <%= command.id %> --port=1942',\n '<%= config.bin %> <%= command.id %> --load-in-dashboard',\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n description: 'Automatically update Sanity Studio dependencies',\n }),\n host: Flags.string({\n description: 'Local network interface to listen on (default: localhost)',\n }),\n 'load-in-dashboard': Flags.boolean({\n allowNo: true,\n description: 'Load the app/studio in the Sanity dashboard',\n }),\n port: Flags.string({\n description: 'TCP port to start server on (default: 3333)',\n }),\n }\n\n public async run(): Promise<{close?: () => Promise<void>}> {\n const {flags} = await this.parse(DevCommand)\n\n const workDir = (await this.getProjectRoot()).directory\n const cliConfig = await this.getCliConfig()\n const isApp = determineIsApp(cliConfig)\n\n if (shouldWarnDashboardFlagIgnored(cliConfig, flags['load-in-dashboard'])) {\n this.output.warn(\n 'Ignoring --load-in-dashboard: workbench apps do not load in the Sanity dashboard',\n )\n }\n\n // load-in-dashboard is defaulted to true for apps.\n if (isApp && flags['load-in-dashboard'] === undefined) {\n flags['load-in-dashboard'] = true\n } else if (flags['load-in-dashboard'] === undefined) {\n // For non-apps, load-in-dashboard is defaulted to false.\n flags['load-in-dashboard'] = false\n }\n\n try {\n const result = await devAction({\n cliConfig,\n flags,\n isApp,\n output: this.output,\n workDir,\n })\n return result\n } catch (error) {\n devDebug(`Failed to start dev server`, error)\n this.output.error(\n styleText(['red', 'bgBlack'], `Failed to start dev server: ${error.message}`),\n {\n exit: 1,\n },\n )\n }\n }\n}\n"],"names":["styleText","Flags","isWorkbenchApp","SanityCommand","devAction","devDebug","determineIsApp","shouldWarnDashboardFlagIgnored","cliConfig","loadInDashboard","app","undefined","DevCommand","description","examples","flags","boolean","allowNo","host","string","port","run","parse","workDir","getProjectRoot","directory","getCliConfig","isApp","output","warn","result","error","message","exit"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAwBC,cAAc,EAAEC,aAAa,QAAO,mBAAkB;AAE9E,SAAQC,SAAS,QAAO,8BAA6B;AACrD,SAAQC,QAAQ,QAAO,6BAA4B;AACnD,SAAQC,cAAc,QAAO,4BAA2B;AAExD;;;;CAIC,GACD,OAAO,SAASC,+BACdC,SAAgC,EAChCC,eAAoC;IAEpC,OAAOP,eAAeM,WAAWE,QAAQD,oBAAoBE;AAC/D;AAEA,OAAO,MAAMC,mBAAmBT;IAC9B,OAAgBU,cAAc,uDAAsD;IAEpF,OAAgBC,WAAW;QACzB;QACA;QACA;KACD,CAAA;IAED,OAAgBC,QAAQ;QACtB,gBAAgBd,MAAMe,OAAO,CAAC;YAC5BC,SAAS;YACTJ,aAAa;QACf;QACAK,MAAMjB,MAAMkB,MAAM,CAAC;YACjBN,aAAa;QACf;QACA,qBAAqBZ,MAAMe,OAAO,CAAC;YACjCC,SAAS;YACTJ,aAAa;QACf;QACAO,MAAMnB,MAAMkB,MAAM,CAAC;YACjBN,aAAa;QACf;IACF,EAAC;IAED,MAAaQ,MAA8C;QACzD,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACV;QAEjC,MAAMW,UAAU,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGC,SAAS;QACvD,MAAMjB,YAAY,MAAM,IAAI,CAACkB,YAAY;QACzC,MAAMC,QAAQrB,eAAeE;QAE7B,IAAID,+BAA+BC,WAAWO,KAAK,CAAC,oBAAoB,GAAG;YACzE,IAAI,CAACa,MAAM,CAACC,IAAI,CACd;QAEJ;QAEA,mDAAmD;QACnD,IAAIF,SAASZ,KAAK,CAAC,oBAAoB,KAAKJ,WAAW;YACrDI,KAAK,CAAC,oBAAoB,GAAG;QAC/B,OAAO,IAAIA,KAAK,CAAC,oBAAoB,KAAKJ,WAAW;YACnD,yDAAyD;YACzDI,KAAK,CAAC,oBAAoB,GAAG;QAC/B;QAEA,IAAI;YACF,MAAMe,SAAS,MAAM1B,UAAU;gBAC7BI;gBACAO;gBACAY;gBACAC,QAAQ,IAAI,CAACA,MAAM;gBACnBL;YACF;YACA,OAAOO;QACT,EAAE,OAAOC,OAAO;YACd1B,SAAS,CAAC,0BAA0B,CAAC,EAAE0B;YACvC,IAAI,CAACH,MAAM,CAACG,KAAK,CACf/B,UAAU;gBAAC;gBAAO;aAAU,EAAE,CAAC,4BAA4B,EAAE+B,MAAMC,OAAO,EAAE,GAC5E;gBACEC,MAAM;YACR;QAEJ;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/commands/dev.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {type CliConfig, SanityCommand} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {devAction} from '../actions/dev/devAction.js'\nimport {devDebug} from '../actions/dev/devDebug.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\n\n/**\n * Workbench apps never load in the Sanity dashboard, so `--load-in-dashboard`\n * has no effect for them. The flag is defaulted later in `run`, so an\n * `undefined` value here still means the user never passed it.\n */\nexport function shouldWarnDashboardFlagIgnored(\n cliConfig: CliConfig | undefined,\n loadInDashboard: boolean | undefined,\n): boolean {\n return isWorkbenchApp(cliConfig?.app) && loadInDashboard !== undefined\n}\n\nexport class DevCommand extends SanityCommand<typeof DevCommand> {\n static override description = 'Start a local development server with live reloading'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %> --host=0.0.0.0',\n '<%= config.bin %> <%= command.id %> --port=1942',\n '<%= config.bin %> <%= command.id %> --load-in-dashboard',\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n description: 'Automatically update Sanity Studio dependencies',\n }),\n host: Flags.string({\n description: 'Local network interface to listen on (default: localhost)',\n }),\n 'load-in-dashboard': Flags.boolean({\n allowNo: true,\n description: 'Load the app/studio in the Sanity dashboard',\n }),\n port: Flags.string({\n description: 'TCP port to start server on (default: 3333)',\n }),\n }\n\n public async run(): Promise<{close?: () => Promise<void>}> {\n const {flags} = await this.parse(DevCommand)\n\n const workDir = (await this.getProjectRoot()).directory\n const cliConfig = await this.getCliConfig()\n const isApp = determineIsApp(cliConfig)\n\n if (shouldWarnDashboardFlagIgnored(cliConfig, flags['load-in-dashboard'])) {\n this.output.warn(\n 'Ignoring --load-in-dashboard: workbench apps do not load in the Sanity dashboard',\n )\n }\n\n // load-in-dashboard is defaulted to true for apps.\n if (isApp && flags['load-in-dashboard'] === undefined) {\n flags['load-in-dashboard'] = true\n } else if (flags['load-in-dashboard'] === undefined) {\n // For non-apps, load-in-dashboard is defaulted to false.\n flags['load-in-dashboard'] = false\n }\n\n try {\n const result = await devAction({\n cliConfig,\n flags,\n isApp,\n output: this.output,\n workDir,\n })\n return result\n } catch (error) {\n devDebug(`Failed to start dev server`, error)\n this.output.error(\n styleText(['red', 'bgBlack'], `Failed to start dev server: ${error.message}`),\n {\n exit: 1,\n },\n )\n }\n }\n}\n"],"names":["styleText","Flags","SanityCommand","isWorkbenchApp","devAction","devDebug","determineIsApp","shouldWarnDashboardFlagIgnored","cliConfig","loadInDashboard","app","undefined","DevCommand","description","examples","flags","boolean","allowNo","host","string","port","run","parse","workDir","getProjectRoot","directory","getCliConfig","isApp","output","warn","result","error","message","exit"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAwBC,aAAa,QAAO,mBAAkB;AAC9D,SAAQC,cAAc,QAAO,wBAAuB;AAEpD,SAAQC,SAAS,QAAO,8BAA6B;AACrD,SAAQC,QAAQ,QAAO,6BAA4B;AACnD,SAAQC,cAAc,QAAO,4BAA2B;AAExD;;;;CAIC,GACD,OAAO,SAASC,+BACdC,SAAgC,EAChCC,eAAoC;IAEpC,OAAON,eAAeK,WAAWE,QAAQD,oBAAoBE;AAC/D;AAEA,OAAO,MAAMC,mBAAmBV;IAC9B,OAAgBW,cAAc,uDAAsD;IAEpF,OAAgBC,WAAW;QACzB;QACA;QACA;KACD,CAAA;IAED,OAAgBC,QAAQ;QACtB,gBAAgBd,MAAMe,OAAO,CAAC;YAC5BC,SAAS;YACTJ,aAAa;QACf;QACAK,MAAMjB,MAAMkB,MAAM,CAAC;YACjBN,aAAa;QACf;QACA,qBAAqBZ,MAAMe,OAAO,CAAC;YACjCC,SAAS;YACTJ,aAAa;QACf;QACAO,MAAMnB,MAAMkB,MAAM,CAAC;YACjBN,aAAa;QACf;IACF,EAAC;IAED,MAAaQ,MAA8C;QACzD,MAAM,EAACN,KAAK,EAAC,GAAG,MAAM,IAAI,CAACO,KAAK,CAACV;QAEjC,MAAMW,UAAU,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGC,SAAS;QACvD,MAAMjB,YAAY,MAAM,IAAI,CAACkB,YAAY;QACzC,MAAMC,QAAQrB,eAAeE;QAE7B,IAAID,+BAA+BC,WAAWO,KAAK,CAAC,oBAAoB,GAAG;YACzE,IAAI,CAACa,MAAM,CAACC,IAAI,CACd;QAEJ;QAEA,mDAAmD;QACnD,IAAIF,SAASZ,KAAK,CAAC,oBAAoB,KAAKJ,WAAW;YACrDI,KAAK,CAAC,oBAAoB,GAAG;QAC/B,OAAO,IAAIA,KAAK,CAAC,oBAAoB,KAAKJ,WAAW;YACnD,yDAAyD;YACzDI,KAAK,CAAC,oBAAoB,GAAG;QAC/B;QAEA,IAAI;YACF,MAAMe,SAAS,MAAM1B,UAAU;gBAC7BI;gBACAO;gBACAY;gBACAC,QAAQ,IAAI,CAACA,MAAM;gBACnBL;YACF;YACA,OAAOO;QACT,EAAE,OAAOC,OAAO;YACd1B,SAAS,CAAC,0BAA0B,CAAC,EAAE0B;YACvC,IAAI,CAACH,MAAM,CAACG,KAAK,CACf/B,UAAU;gBAAC;gBAAO;aAAU,EAAE,CAAC,4BAA4B,EAAE+B,MAAMC,OAAO,EAAE,GAC5E;gBACEC,MAAM;YACR;QAEJ;IACF;AACF"}
@@ -252,7 +252,8 @@ export class InitCommand extends SanityCommand {
252
252
  let mcpMode = 'prompt';
253
253
  if (!this.flags.mcp || !this.resolveIsInteractive()) {
254
254
  mcpMode = 'skip';
255
- } else if (this.flags.yes) {
255
+ } else if (this.isUnattended()) {
256
+ // Any unattended run (e.g. --yes, --json) configures MCP with defaults rather than prompting
256
257
  mcpMode = 'auto';
257
258
  }
258
259
  // Mirror MCP's environment gating: skip install in test environments
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {initAction} from '../actions/init/initAction.js'\nimport {InitError} from '../actions/init/initError.js'\nimport {flagsToInitOptions} from '../actions/init/types.js'\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n skills: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Install Sanity agent skills globally for detected AI editors',\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n 'unstable--workbench': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Opt into workbench: scaffolds the CLI config with unstable_defineApp',\n // Internal-only while workbench is unstable — keep it out of help/docs\n hidden: true,\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive()) {\n mcpMode = 'skip'\n } else if (this.flags.yes) {\n mcpMode = 'auto'\n }\n\n // Mirror MCP's environment gating: skip install in test environments\n // ensure e2e / CI tests don't run the bundled skills CLI.\n let skillsMode: 'auto' | 'prompt' | 'skip' = 'auto'\n if (!this.flags.skills || !this.resolveIsInteractive()) {\n skillsMode = 'skip'\n }\n\n try {\n await initAction(\n flagsToInitOptions(this.flags, this.isUnattended(), this.args, mcpMode, skillsMode),\n {\n output: this.output,\n telemetry: this.telemetry,\n workDir: process.cwd(),\n },\n )\n } catch (error) {\n if (error instanceof InitError) {\n this.error(error.message, {exit: error.exitCode})\n }\n throw error\n }\n }\n}\n"],"names":["Args","Flags","CLIError","SanityCommand","initAction","InitError","flagsToInitOptions","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","input","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","skills","template","typescript","visibility","yes","char","run","mcpMode","resolveIsInteractive","skillsMode","isUnattended","output","telemetry","workDir","process","cwd","error","exit","exitCode"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {initAction} from '../actions/init/initAction.js'\nimport {InitError} from '../actions/init/initError.js'\nimport {flagsToInitOptions} from '../actions/init/types.js'\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n skills: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Install Sanity agent skills globally for detected AI editors',\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n 'unstable--workbench': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Opt into workbench: scaffolds the CLI config with unstable_defineApp',\n // Internal-only while workbench is unstable — keep it out of help/docs\n hidden: true,\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive()) {\n mcpMode = 'skip'\n } else if (this.isUnattended()) {\n // Any unattended run (e.g. --yes, --json) configures MCP with defaults rather than prompting\n mcpMode = 'auto'\n }\n\n // Mirror MCP's environment gating: skip install in test environments\n // ensure e2e / CI tests don't run the bundled skills CLI.\n let skillsMode: 'auto' | 'prompt' | 'skip' = 'auto'\n if (!this.flags.skills || !this.resolveIsInteractive()) {\n skillsMode = 'skip'\n }\n\n try {\n await initAction(\n flagsToInitOptions(this.flags, this.isUnattended(), this.args, mcpMode, skillsMode),\n {\n output: this.output,\n telemetry: this.telemetry,\n workDir: process.cwd(),\n },\n )\n } catch (error) {\n if (error instanceof InitError) {\n this.error(error.message, {exit: error.exitCode})\n }\n throw error\n }\n }\n}\n"],"names":["Args","Flags","CLIError","SanityCommand","initAction","InitError","flagsToInitOptions","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","input","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","skills","template","typescript","visibility","yes","char","run","mcpMode","resolveIsInteractive","isUnattended","skillsMode","output","telemetry","workDir","process","cwd","error","exit","exitCode"],"mappings":"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"}
@@ -1,9 +1,12 @@
1
1
  import { CliConfig } from "@sanity/cli-core";
2
2
  import { ClientConfig } from "@sanity/client";
3
3
  import { DefineAppInput } from "@sanity/workbench-cli";
4
+ import { DefineMediaLibraryInput } from "@sanity/workbench-cli";
4
5
  import { loadEnv } from "vite";
6
+ import { MediaLibraryField } from "@sanity/workbench-cli";
5
7
  import { SanityClient } from "@sanity/client";
6
8
  import { unstable_defineApp } from "@sanity/workbench-cli";
9
+ import { unstable_defineMediaLibrary } from "@sanity/workbench-cli";
7
10
  import { UserViteConfig } from "@sanity/cli-core";
8
11
 
9
12
  /**
@@ -50,6 +53,8 @@ export { DefineAppInput };
50
53
  /** @beta */
51
54
  export declare function defineCliConfig(config: CliConfig): CliConfig;
52
55
 
56
+ export { DefineMediaLibraryInput };
57
+
53
58
  /**
54
59
  * @public
55
60
  *
@@ -112,8 +117,12 @@ export declare interface GraphQLAPIConfig {
112
117
 
113
118
  export { loadEnv };
114
119
 
120
+ export { MediaLibraryField };
121
+
115
122
  export { unstable_defineApp };
116
123
 
124
+ export { unstable_defineMediaLibrary };
125
+
117
126
  export { UserViteConfig };
118
127
 
119
128
  export {};