@sanity/cli 6.3.0 → 6.3.2

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 (131) hide show
  1. package/README.md +295 -442
  2. package/dist/actions/build/decorateIndexWithStagingScript.js +16 -0
  3. package/dist/actions/build/decorateIndexWithStagingScript.js.map +1 -0
  4. package/dist/actions/build/writeSanityRuntime.js +3 -2
  5. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  6. package/dist/actions/dataset/create.js +4 -0
  7. package/dist/actions/dataset/create.js.map +1 -1
  8. package/dist/actions/deploy/findUserApplicationForApp.js +1 -0
  9. package/dist/actions/deploy/findUserApplicationForApp.js.map +1 -1
  10. package/dist/actions/deploy/types.js +1 -1
  11. package/dist/actions/deploy/types.js.map +1 -1
  12. package/dist/actions/init/templates/nextjs/index.js +1 -2
  13. package/dist/actions/init/templates/nextjs/index.js.map +1 -1
  14. package/dist/actions/manifest/types.js +1 -1
  15. package/dist/actions/manifest/types.js.map +1 -1
  16. package/dist/actions/schema/types.js +3 -3
  17. package/dist/actions/schema/types.js.map +1 -1
  18. package/dist/actions/users/validateEmail.js +2 -2
  19. package/dist/actions/users/validateEmail.js.map +1 -1
  20. package/dist/commands/backups/disable.js +1 -1
  21. package/dist/commands/backups/disable.js.map +1 -1
  22. package/dist/commands/backups/download.js +1 -1
  23. package/dist/commands/backups/download.js.map +1 -1
  24. package/dist/commands/backups/enable.js +1 -1
  25. package/dist/commands/backups/enable.js.map +1 -1
  26. package/dist/commands/backups/list.js +1 -1
  27. package/dist/commands/backups/list.js.map +1 -1
  28. package/dist/commands/build.js +1 -1
  29. package/dist/commands/build.js.map +1 -1
  30. package/dist/commands/cors/add.js +1 -1
  31. package/dist/commands/cors/add.js.map +1 -1
  32. package/dist/commands/cors/delete.js +1 -1
  33. package/dist/commands/cors/delete.js.map +1 -1
  34. package/dist/commands/cors/list.js +2 -2
  35. package/dist/commands/cors/list.js.map +1 -1
  36. package/dist/commands/datasets/alias/create.js +1 -1
  37. package/dist/commands/datasets/alias/create.js.map +1 -1
  38. package/dist/commands/datasets/alias/delete.js +1 -1
  39. package/dist/commands/datasets/alias/delete.js.map +1 -1
  40. package/dist/commands/datasets/alias/link.js +1 -1
  41. package/dist/commands/datasets/alias/link.js.map +1 -1
  42. package/dist/commands/datasets/alias/unlink.js +1 -1
  43. package/dist/commands/datasets/alias/unlink.js.map +1 -1
  44. package/dist/commands/datasets/copy.js +1 -1
  45. package/dist/commands/datasets/copy.js.map +1 -1
  46. package/dist/commands/datasets/create.js +1 -1
  47. package/dist/commands/datasets/create.js.map +1 -1
  48. package/dist/commands/datasets/delete.js +1 -1
  49. package/dist/commands/datasets/delete.js.map +1 -1
  50. package/dist/commands/datasets/embeddings/enable.js +11 -0
  51. package/dist/commands/datasets/embeddings/enable.js.map +1 -1
  52. package/dist/commands/datasets/export.js +2 -2
  53. package/dist/commands/datasets/export.js.map +1 -1
  54. package/dist/commands/datasets/list.js +2 -2
  55. package/dist/commands/datasets/list.js.map +1 -1
  56. package/dist/commands/debug.js +1 -1
  57. package/dist/commands/debug.js.map +1 -1
  58. package/dist/commands/deploy.js +3 -3
  59. package/dist/commands/deploy.js.map +1 -1
  60. package/dist/commands/dev.js +5 -5
  61. package/dist/commands/dev.js.map +1 -1
  62. package/dist/commands/docs/browse.js +1 -1
  63. package/dist/commands/docs/browse.js.map +1 -1
  64. package/dist/commands/documents/delete.js +1 -1
  65. package/dist/commands/documents/delete.js.map +1 -1
  66. package/dist/commands/exec.js +2 -2
  67. package/dist/commands/exec.js.map +1 -1
  68. package/dist/commands/graphql/deploy.js +2 -2
  69. package/dist/commands/graphql/deploy.js.map +1 -1
  70. package/dist/commands/graphql/list.js +2 -2
  71. package/dist/commands/graphql/list.js.map +1 -1
  72. package/dist/commands/hooks/create.js +2 -2
  73. package/dist/commands/hooks/create.js.map +1 -1
  74. package/dist/commands/hooks/delete.js +5 -5
  75. package/dist/commands/hooks/delete.js.map +1 -1
  76. package/dist/commands/hooks/list.js +3 -3
  77. package/dist/commands/hooks/list.js.map +1 -1
  78. package/dist/commands/hooks/logs.js +5 -5
  79. package/dist/commands/hooks/logs.js.map +1 -1
  80. package/dist/commands/init.js +30 -12
  81. package/dist/commands/init.js.map +1 -1
  82. package/dist/commands/install.js +1 -1
  83. package/dist/commands/install.js.map +1 -1
  84. package/dist/commands/learn.js +1 -1
  85. package/dist/commands/learn.js.map +1 -1
  86. package/dist/commands/login.js +1 -1
  87. package/dist/commands/login.js.map +1 -1
  88. package/dist/commands/logout.js +1 -1
  89. package/dist/commands/logout.js.map +1 -1
  90. package/dist/commands/manage.js +1 -1
  91. package/dist/commands/manage.js.map +1 -1
  92. package/dist/commands/manifest/extract.js +2 -2
  93. package/dist/commands/manifest/extract.js.map +1 -1
  94. package/dist/commands/media/delete-aspect.js +1 -1
  95. package/dist/commands/media/delete-aspect.js.map +1 -1
  96. package/dist/commands/media/export.js +1 -1
  97. package/dist/commands/media/export.js.map +1 -1
  98. package/dist/commands/preview.js +3 -3
  99. package/dist/commands/preview.js.map +1 -1
  100. package/dist/commands/projects/list.js +4 -2
  101. package/dist/commands/projects/list.js.map +1 -1
  102. package/dist/commands/schemas/deploy.js +3 -4
  103. package/dist/commands/schemas/deploy.js.map +1 -1
  104. package/dist/commands/schemas/extract.js +3 -3
  105. package/dist/commands/schemas/extract.js.map +1 -1
  106. package/dist/commands/schemas/list.js +4 -5
  107. package/dist/commands/schemas/list.js.map +1 -1
  108. package/dist/commands/telemetry/disable.js +2 -2
  109. package/dist/commands/telemetry/disable.js.map +1 -1
  110. package/dist/commands/telemetry/enable.js +2 -2
  111. package/dist/commands/telemetry/enable.js.map +1 -1
  112. package/dist/commands/telemetry/status.js +2 -2
  113. package/dist/commands/telemetry/status.js.map +1 -1
  114. package/dist/commands/tokens/add.js +1 -1
  115. package/dist/commands/tokens/add.js.map +1 -1
  116. package/dist/commands/tokens/delete.js +1 -1
  117. package/dist/commands/tokens/delete.js.map +1 -1
  118. package/dist/commands/tokens/list.js +2 -2
  119. package/dist/commands/tokens/list.js.map +1 -1
  120. package/dist/commands/users/list.js +1 -1
  121. package/dist/commands/users/list.js.map +1 -1
  122. package/dist/commands/versions.js +1 -1
  123. package/dist/commands/versions.js.map +1 -1
  124. package/dist/server/vite/plugin-sanity-build-entries.js +3 -2
  125. package/dist/server/vite/plugin-sanity-build-entries.js.map +1 -1
  126. package/dist/util/telemetry/createTelemetryStore.js +27 -12
  127. package/dist/util/telemetry/createTelemetryStore.js.map +1 -1
  128. package/dist/util/validateProjection.js +121 -0
  129. package/dist/util/validateProjection.js.map +1 -0
  130. package/oclif.manifest.json +317 -315
  131. package/package.json +27 -26
@@ -11,23 +11,23 @@ const logsHookDebug = subdebug('hook:logs');
11
11
  export class LogsHookCommand extends SanityCommand {
12
12
  static args = {
13
13
  name: Args.string({
14
- description: 'Name of the hook to show logs for',
14
+ description: 'Name of the webhook to show logs for',
15
15
  required: false
16
16
  })
17
17
  };
18
- static description = 'List latest log entries for a given hook';
18
+ static description = 'Show log entries for project webhooks';
19
19
  static examples = [
20
20
  {
21
21
  command: '<%= config.bin %> <%= command.id %>',
22
- description: 'List latest log entries for a given hook'
22
+ description: 'Show log entries for project webhooks'
23
23
  },
24
24
  {
25
25
  command: '<%= config.bin %> <%= command.id %> [NAME]',
26
- description: 'List latest log entries for a specific hook by name'
26
+ description: 'Show log entries for a specific webhook by name'
27
27
  },
28
28
  {
29
29
  command: '<%= config.bin %> <%= command.id %> --project-id abc123',
30
- description: 'List hook logs for a specific project'
30
+ description: 'Show log entries for a specific project'
31
31
  }
32
32
  ];
33
33
  static flags = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/hooks/logs.ts"],"sourcesContent":["import {inspect, styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\nimport groupBy from 'lodash-es/groupBy.js'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt, type Hook, type HookMessage} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n getHookAttemptsForProject,\n getHookMessagesForProject,\n getHooksForProject,\n} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst logsHookDebug = subdebug('hook:logs')\n\nexport class LogsHookCommand extends SanityCommand<typeof LogsHookCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the hook to show logs for',\n required: false,\n }),\n }\n\n static override description = 'List latest log entries for a given hook'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List latest log entries for a given hook',\n },\n {\n command: '<%= config.bin %> <%= command.id %> [NAME]',\n description: 'List latest log entries for a specific hook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'List hook logs for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to view webhook logs for',\n semantics: 'override',\n }),\n detailed: Flags.boolean({\n description: 'Include detailed payload and attempts',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:logs']\n\n public async run() {\n const {args, flags} = await this.parse(LogsHookCommand)\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get hooks for the project\n let hooks: Hook[]\n try {\n hooks = await getHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Hook list retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks currently registered', {exit: 1})\n }\n\n // If hook name is provided, find that specific hook\n let selectedHook: Hook | undefined\n if (args.name) {\n selectedHook = hooks.find((hook) => hook.name.toLowerCase() === args.name?.toLowerCase())\n if (!selectedHook) {\n this.error(`Hook with name \"${args.name}\" not found`, {exit: 1})\n }\n } else if (hooks.length === 1) {\n // If only one hook exists, use that\n selectedHook = hooks[0]\n } else {\n // Otherwise prompt user to select a hook\n selectedHook = await this.selectHook(hooks)\n }\n\n if (!selectedHook) {\n this.error('No hook selected', {exit: 1})\n }\n\n // Fetch messages and attempts for the selected hook\n let messages: HookMessage[]\n let attempts: DeliveryAttempt[] = []\n try {\n ;[messages, attempts] = await Promise.all([\n getHookMessagesForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n getHookAttemptsForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n ])\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching logs for hook ${selectedHook.id}`, err)\n this.error(`Hook logs retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n // Group attempts by message ID\n const groupedAttempts = groupBy(attempts, 'messageId')\n\n // Populate messages with attempts\n const populated = messages.map((msg): HookMessage & {attempts: DeliveryAttempt[]} => ({\n ...msg,\n attempts: groupedAttempts[msg.id] || [],\n }))\n\n const totalMessages = messages.length - 1\n\n for (const [i, message] of populated.entries()) {\n this.printMessage(message, {detailed: flags.detailed})\n this.printSeparator(totalMessages === i)\n }\n }\n\n private formatAttemptDate(dateString: string): string {\n try {\n return new Date(dateString).toISOString().replace(/\\.\\d+Z$/, 'Z')\n } catch {\n return dateString // fallback to original if parsing fails\n }\n }\n\n private printMessage(\n message: HookMessage & {attempts: DeliveryAttempt[]},\n options: {detailed?: boolean},\n ) {\n const {detailed} = options\n\n this.log(`Date: ${message.createdAt}`)\n this.log(`Status: ${message.status}`)\n if (message.resultCode) {\n this.log(`Result code: ${message.resultCode}`)\n }\n\n if (message.failureCount > 0) {\n this.log(`Failures: ${message.failureCount}`)\n }\n\n if (detailed) {\n this.log('Payload:')\n try {\n const payload = JSON.parse(message.payload)\n this.log(inspect(payload, {colors: true}))\n } catch (error) {\n this.log(`Payload (raw): ${message.payload}`)\n logsHookDebug('Failed to parse payload JSON:', error)\n }\n }\n\n if (detailed && message.attempts && message.attempts.length > 0) {\n this.log('Attempts:')\n for (const attempt of message.attempts) {\n const date = this.formatAttemptDate(attempt.createdAt)\n const prefix = ` [${date}]`\n\n if (attempt.inProgress) {\n this.log(`${prefix} ${styleText('yellow', 'Pending')}`)\n } else if (attempt.isFailure) {\n const failure = formatFailure(attempt, {includeHelp: true})\n this.log(`${prefix} ${styleText('yellow', `Failure: ${failure}`)}`)\n } else {\n this.log(`${prefix} Success: HTTP ${attempt.resultCode} (${attempt.duration}ms)`)\n }\n }\n }\n\n // Leave some empty space between messages\n this.log('')\n }\n\n private printSeparator(skip: boolean) {\n if (!skip) {\n this.log('---\\n')\n }\n }\n\n private async selectHook(hooks: Hook[]) {\n const hookId = await select({\n choices: hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n })),\n message: 'Select hook to list logs for',\n })\n\n return hooks.find((hook) => hook.id === hookId)\n }\n}\n"],"names":["inspect","styleText","Args","Flags","SanityCommand","subdebug","select","groupBy","formatFailure","promptForProject","getHookAttemptsForProject","getHookMessagesForProject","getHooksForProject","getProjectIdFlag","logsHookDebug","LogsHookCommand","args","name","string","description","required","examples","command","flags","semantics","detailed","boolean","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hooks","error","err","message","exit","length","selectedHook","find","hook","toLowerCase","selectHook","messages","attempts","Promise","all","hookId","id","groupedAttempts","populated","map","msg","totalMessages","i","entries","printMessage","printSeparator","formatAttemptDate","dateString","Date","toISOString","replace","options","log","createdAt","status","resultCode","failureCount","payload","JSON","colors","attempt","date","prefix","inProgress","isFailure","failure","includeHelp","duration","skip","choices","value"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/hooks/logs.ts"],"sourcesContent":["import {inspect, styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\nimport groupBy from 'lodash-es/groupBy.js'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt, type Hook, type HookMessage} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n getHookAttemptsForProject,\n getHookMessagesForProject,\n getHooksForProject,\n} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst logsHookDebug = subdebug('hook:logs')\n\nexport class LogsHookCommand extends SanityCommand<typeof LogsHookCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the webhook to show logs for',\n required: false,\n }),\n }\n\n static override description = 'Show log entries for project webhooks'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show log entries for project webhooks',\n },\n {\n command: '<%= config.bin %> <%= command.id %> [NAME]',\n description: 'Show log entries for a specific webhook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Show log entries for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to view webhook logs for',\n semantics: 'override',\n }),\n detailed: Flags.boolean({\n description: 'Include detailed payload and attempts',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:logs']\n\n public async run() {\n const {args, flags} = await this.parse(LogsHookCommand)\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get hooks for the project\n let hooks: Hook[]\n try {\n hooks = await getHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Hook list retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks currently registered', {exit: 1})\n }\n\n // If hook name is provided, find that specific hook\n let selectedHook: Hook | undefined\n if (args.name) {\n selectedHook = hooks.find((hook) => hook.name.toLowerCase() === args.name?.toLowerCase())\n if (!selectedHook) {\n this.error(`Hook with name \"${args.name}\" not found`, {exit: 1})\n }\n } else if (hooks.length === 1) {\n // If only one hook exists, use that\n selectedHook = hooks[0]\n } else {\n // Otherwise prompt user to select a hook\n selectedHook = await this.selectHook(hooks)\n }\n\n if (!selectedHook) {\n this.error('No hook selected', {exit: 1})\n }\n\n // Fetch messages and attempts for the selected hook\n let messages: HookMessage[]\n let attempts: DeliveryAttempt[] = []\n try {\n ;[messages, attempts] = await Promise.all([\n getHookMessagesForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n getHookAttemptsForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n ])\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching logs for hook ${selectedHook.id}`, err)\n this.error(`Hook logs retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n // Group attempts by message ID\n const groupedAttempts = groupBy(attempts, 'messageId')\n\n // Populate messages with attempts\n const populated = messages.map((msg): HookMessage & {attempts: DeliveryAttempt[]} => ({\n ...msg,\n attempts: groupedAttempts[msg.id] || [],\n }))\n\n const totalMessages = messages.length - 1\n\n for (const [i, message] of populated.entries()) {\n this.printMessage(message, {detailed: flags.detailed})\n this.printSeparator(totalMessages === i)\n }\n }\n\n private formatAttemptDate(dateString: string): string {\n try {\n return new Date(dateString).toISOString().replace(/\\.\\d+Z$/, 'Z')\n } catch {\n return dateString // fallback to original if parsing fails\n }\n }\n\n private printMessage(\n message: HookMessage & {attempts: DeliveryAttempt[]},\n options: {detailed?: boolean},\n ) {\n const {detailed} = options\n\n this.log(`Date: ${message.createdAt}`)\n this.log(`Status: ${message.status}`)\n if (message.resultCode) {\n this.log(`Result code: ${message.resultCode}`)\n }\n\n if (message.failureCount > 0) {\n this.log(`Failures: ${message.failureCount}`)\n }\n\n if (detailed) {\n this.log('Payload:')\n try {\n const payload = JSON.parse(message.payload)\n this.log(inspect(payload, {colors: true}))\n } catch (error) {\n this.log(`Payload (raw): ${message.payload}`)\n logsHookDebug('Failed to parse payload JSON:', error)\n }\n }\n\n if (detailed && message.attempts && message.attempts.length > 0) {\n this.log('Attempts:')\n for (const attempt of message.attempts) {\n const date = this.formatAttemptDate(attempt.createdAt)\n const prefix = ` [${date}]`\n\n if (attempt.inProgress) {\n this.log(`${prefix} ${styleText('yellow', 'Pending')}`)\n } else if (attempt.isFailure) {\n const failure = formatFailure(attempt, {includeHelp: true})\n this.log(`${prefix} ${styleText('yellow', `Failure: ${failure}`)}`)\n } else {\n this.log(`${prefix} Success: HTTP ${attempt.resultCode} (${attempt.duration}ms)`)\n }\n }\n }\n\n // Leave some empty space between messages\n this.log('')\n }\n\n private printSeparator(skip: boolean) {\n if (!skip) {\n this.log('---\\n')\n }\n }\n\n private async selectHook(hooks: Hook[]) {\n const hookId = await select({\n choices: hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n })),\n message: 'Select hook to list logs for',\n })\n\n return hooks.find((hook) => hook.id === hookId)\n }\n}\n"],"names":["inspect","styleText","Args","Flags","SanityCommand","subdebug","select","groupBy","formatFailure","promptForProject","getHookAttemptsForProject","getHookMessagesForProject","getHooksForProject","getProjectIdFlag","logsHookDebug","LogsHookCommand","args","name","string","description","required","examples","command","flags","semantics","detailed","boolean","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hooks","error","err","message","exit","length","selectedHook","find","hook","toLowerCase","selectHook","messages","attempts","Promise","all","hookId","id","groupedAttempts","populated","map","msg","totalMessages","i","entries","printMessage","printSeparator","formatAttemptDate","dateString","Date","toISOString","replace","options","log","createdAt","status","resultCode","failureCount","payload","JSON","colors","attempt","date","prefix","inProgress","isFailure","failure","includeHelp","duration","skip","choices","value"],"mappings":"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"}
@@ -419,9 +419,9 @@ export class InitCommand extends SanityCommand {
419
419
  sluggedName,
420
420
  workDir
421
421
  });
422
- // Set up MCP integration
422
+ // Set up MCP integration (skip in non-production environments)
423
423
  let mcpMode = 'prompt';
424
- if (!this.flags.mcp || !this.resolveIsInteractive()) {
424
+ if (!this.flags.mcp || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {
425
425
  mcpMode = 'skip';
426
426
  } else if (this.flags.yes) {
427
427
  mcpMode = 'auto';
@@ -552,7 +552,7 @@ export class InitCommand extends SanityCommand {
552
552
  output: this.output,
553
553
  workDir
554
554
  });
555
- const useGit = this.flags.git === undefined || Boolean(this.flags.git);
555
+ const useGit = !this.flags['no-git'] && (this.flags.git === undefined || Boolean(this.flags.git));
556
556
  const commitMessage = this.flags.git;
557
557
  await this.writeStagingEnvIfNeeded(outputPath);
558
558
  // Try initializing a git repository
@@ -574,7 +574,8 @@ export class InitCommand extends SanityCommand {
574
574
  '--dataset',
575
575
  datasetName,
576
576
  '--token',
577
- token
577
+ token,
578
+ '--missing'
578
579
  ], {
579
580
  root: outputPath
580
581
  });
@@ -665,13 +666,8 @@ export class InitCommand extends SanityCommand {
665
666
  }
666
667
  return;
667
668
  }
668
- if (!this.flags['dataset']) {
669
- this.error(`\`--dataset\` must be specified in unattended mode`, {
670
- exit: 1
671
- });
672
- }
673
- // output-path is required in unattended mode when not using nextjs
674
- if (!isNextJs && !this.flags['output-path']) {
669
+ // output-path is required in unattended mode when not using nextjs or bare
670
+ if (!isNextJs && !this.flags.bare && !this.flags['output-path']) {
675
671
  this.error(`\`--output-path\` must be specified in unattended mode`, {
676
672
  exit: 1
677
673
  });
@@ -796,6 +792,28 @@ export class InitCommand extends SanityCommand {
796
792
  userAction: 'none'
797
793
  };
798
794
  }
795
+ // In unattended mode without --dataset, default to "production" with public visibility
796
+ // (same behavior as --dataset-default)
797
+ if (this.isUnattended()) {
798
+ debug('Unattended mode without --dataset, defaulting to "production" dataset');
799
+ const datasetName = 'production';
800
+ const existing = datasets.find((ds)=>ds.name === datasetName);
801
+ if (!existing) {
802
+ await createDataset({
803
+ datasetName,
804
+ forcePublic: visibility === undefined,
805
+ isUnattended: true,
806
+ output: this.output,
807
+ projectFeatures,
808
+ projectId: opts.projectId,
809
+ visibility
810
+ });
811
+ }
812
+ return {
813
+ datasetName,
814
+ userAction: existing ? 'none' : 'create'
815
+ };
816
+ }
799
817
  if (datasets.length === 0) {
800
818
  debug('No datasets found for project, prompting for name');
801
819
  if (opts.showDefaultConfigPrompt) {
@@ -1098,7 +1116,7 @@ export class InitCommand extends SanityCommand {
1098
1116
  // replaces the ":configPath:" placeholder in the template with the correct path to the sanity.config.ts file.
1099
1117
  // we account for the user-defined embeddedStudioPath (default /studio) is accounted for by creating enough "../"
1100
1118
  // relative paths to reach the root level of the project
1101
- await this.writeOrOverwrite(embeddedStudioRouteFilePath, sanityStudioTemplate.replace(':configPath:', `${'../'.repeat(countNestedFolders(embeddedStudioRouteFilePath.slice(workDir.length)))}sanity.config`), workDir);
1119
+ await this.writeOrOverwrite(embeddedStudioRouteFilePath, sanityStudioTemplate.replace(':configPath:', `${'../'.repeat(countNestedFolders(path.dirname(embeddedStudioRouteFilePath.slice(workDir.length))))}sanity.config`), workDir);
1102
1120
  const sanityConfigPath = path.join(workDir, `sanity.config.${fileExtension}`);
1103
1121
  await this.writeOrOverwrite(sanityConfigPath, sanityConfigTemplate(hasSrcFolder).replace(':route:', embeddedStudioRouteFilePath.slice(workDir.length).replace('src/', '')).replace(':basePath:', studioPath), workDir);
1104
1122
  }