@sanity/runtime-cli 17.6.2 → 17.7.0-blueprinit.ga49bda6

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 (38) hide show
  1. package/README.md +20 -20
  2. package/dist/actions/blueprinit/manifest.d.ts +15 -0
  3. package/dist/actions/blueprinit/manifest.js +82 -0
  4. package/dist/actions/blueprinit/studio.d.ts +6 -0
  5. package/dist/actions/blueprinit/studio.js +43 -0
  6. package/dist/actions/blueprinit/templates.d.ts +34 -0
  7. package/dist/actions/blueprinit/templates.js +83 -0
  8. package/dist/actions/blueprinit/workspace.d.ts +16 -0
  9. package/dist/actions/blueprinit/workspace.js +143 -0
  10. package/dist/actions/blueprints/wait-for-operation.js +30 -5
  11. package/dist/actions/sanity/datasets.d.ts +15 -0
  12. package/dist/actions/sanity/datasets.js +26 -0
  13. package/dist/commands/init.d.ts +17 -0
  14. package/dist/commands/init.js +59 -0
  15. package/dist/cores/blueprinit/adopt.d.ts +6 -0
  16. package/dist/cores/blueprinit/adopt.js +119 -0
  17. package/dist/cores/blueprinit/finish.d.ts +14 -0
  18. package/dist/cores/blueprinit/finish.js +64 -0
  19. package/dist/cores/blueprinit/fresh.d.ts +3 -0
  20. package/dist/cores/blueprinit/fresh.js +120 -0
  21. package/dist/cores/blueprinit/preview.d.ts +15 -0
  22. package/dist/cores/blueprinit/preview.js +14 -0
  23. package/dist/cores/blueprinit/prompts.d.ts +5 -0
  24. package/dist/cores/blueprinit/prompts.js +22 -0
  25. package/dist/cores/blueprinit/selection.d.ts +15 -0
  26. package/dist/cores/blueprinit/selection.js +90 -0
  27. package/dist/cores/blueprinit/types.d.ts +16 -0
  28. package/dist/cores/blueprinit/types.js +1 -0
  29. package/dist/cores/blueprinit.d.ts +7 -0
  30. package/dist/cores/blueprinit.js +48 -0
  31. package/dist/utils/display/blueprints-formatting.js +18 -7
  32. package/dist/utils/display/resources-formatting.d.ts +3 -2
  33. package/dist/utils/display/resources-formatting.js +27 -12
  34. package/dist/utils/functions/resolve-auth.js +17 -4
  35. package/dist/utils/types.d.ts +3 -0
  36. package/oclif.manifest.json +130 -1
  37. package/package.json +13 -13
  38. package/skills/init.md +155 -0
@@ -0,0 +1,90 @@
1
+ import { select } from '@inquirer/prompts';
2
+ export async function chooseOrganization(groups, organizationId, interactive) {
3
+ if (groups.length === 0) {
4
+ return failure('No organizations found for this account.');
5
+ }
6
+ if (organizationId) {
7
+ const organization = groups.find((group) => group.organization.id === organizationId);
8
+ return organization
9
+ ? { ok: true, value: organization }
10
+ : failure(`No organization "${organizationId}" found for this account.`);
11
+ }
12
+ if (groups.length === 1)
13
+ return { ok: true, value: groups[0] };
14
+ if (!interactive) {
15
+ return failure('Multiple organizations found.', ['Pass --organization-id <id> to choose one.']);
16
+ }
17
+ const selectedId = await select({
18
+ message: 'Choose a Sanity organization:',
19
+ choices: groups.map(({ organization, projects }) => ({
20
+ name: organization.name,
21
+ value: organization.id,
22
+ description: `${projects?.length ?? 0} projects`,
23
+ })),
24
+ });
25
+ const selected = groups.find(({ organization }) => organization.id === selectedId);
26
+ return selected ? { ok: true, value: selected } : failure('Organization not found.');
27
+ }
28
+ export async function chooseProject(projects, projectId, organizationName, interactive) {
29
+ if (projects.length === 0) {
30
+ return failure(`No projects found in ${organizationName}.`);
31
+ }
32
+ if (projectId) {
33
+ const project = projects.find(({ id }) => id === projectId);
34
+ return project
35
+ ? { ok: true, value: project }
36
+ : failure(`No project "${projectId}" found in ${organizationName}.`);
37
+ }
38
+ if (projects.length === 1)
39
+ return { ok: true, value: projects[0] };
40
+ if (!interactive) {
41
+ return failure('Multiple projects found.', ['Pass --project-id <id> to choose one.']);
42
+ }
43
+ const selectedId = await select({
44
+ message: 'Choose a Sanity project:',
45
+ choices: projects.map((project) => ({ name: project.displayName, value: project.id })),
46
+ });
47
+ const selected = projects.find(({ id }) => id === selectedId);
48
+ return selected ? { ok: true, value: selected } : failure('Project not found.');
49
+ }
50
+ export async function chooseDataset(datasets, datasetName, projectName, interactive) {
51
+ if (datasets.length === 0) {
52
+ return failure(`No datasets found in ${projectName}.`);
53
+ }
54
+ if (datasetName) {
55
+ const dataset = datasets.find(({ name }) => name === datasetName);
56
+ return dataset
57
+ ? { ok: true, value: dataset }
58
+ : failure(`No dataset "${datasetName}" found in ${projectName}.`);
59
+ }
60
+ if (datasets.length === 1)
61
+ return { ok: true, value: datasets[0] };
62
+ if (!interactive) {
63
+ return failure('Multiple datasets found.', ['Pass --dataset <name> to choose one.']);
64
+ }
65
+ const production = datasets.find(({ name }) => name === 'production');
66
+ const orderedDatasets = production
67
+ ? [production, ...datasets.filter(({ name }) => name !== 'production')]
68
+ : datasets;
69
+ const selectedName = await select({
70
+ message: 'Choose a Sanity dataset:',
71
+ choices: orderedDatasets.map((dataset) => ({
72
+ name: dataset.name,
73
+ value: dataset.name,
74
+ description: dataset.aclMode,
75
+ })),
76
+ });
77
+ const selected = datasets.find(({ name }) => name === selectedName);
78
+ return selected ? { ok: true, value: selected } : failure('Dataset not found.');
79
+ }
80
+ export function findProject(groups, projectId) {
81
+ for (const { organization, projects = [] } of groups) {
82
+ const project = projects.find(({ id }) => id === projectId);
83
+ if (project)
84
+ return { organization, project };
85
+ }
86
+ return undefined;
87
+ }
88
+ function failure(message, suggestions) {
89
+ return { ok: false, error: { message, suggestions } };
90
+ }
@@ -0,0 +1,16 @@
1
+ import type { Logger } from '../../utils/logger.js';
2
+ export interface BlueprinitFlags {
3
+ yes?: boolean;
4
+ organizationId?: string;
5
+ projectId?: string;
6
+ datasetName?: string;
7
+ stackName?: string;
8
+ studioName?: string;
9
+ }
10
+ export interface BlueprinitFlowOptions {
11
+ bin: string;
12
+ dir: string;
13
+ flags: BlueprinitFlags;
14
+ log: Logger;
15
+ token: string;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { BlueprinitFlags } from './blueprinit/types.js';
2
+ import type { CoreConfig, CoreResult } from './index.js';
3
+ export interface BlueprinitOptions extends CoreConfig {
4
+ dir?: string;
5
+ flags?: BlueprinitFlags;
6
+ }
7
+ export declare function blueprinitCore(options: BlueprinitOptions): Promise<CoreResult>;
@@ -0,0 +1,48 @@
1
+ import { cwd } from 'node:process';
2
+ import { detectStudio } from '../actions/blueprinit/studio.js';
3
+ import { findBlueprintFile } from '../actions/blueprints/blueprint.js';
4
+ import { readConfigFile } from '../actions/blueprints/config.js';
5
+ import { validTokenOrErrorMessage } from '../utils/validated-token.js';
6
+ import { adoptFlow } from './blueprinit/adopt.js';
7
+ import { freshFlow } from './blueprinit/fresh.js';
8
+ export async function blueprinitCore(options) {
9
+ const { bin, log, flags = {}, dir = cwd() } = options;
10
+ try {
11
+ const existingBlueprint = findBlueprintFile(dir);
12
+ if (existingBlueprint) {
13
+ const blueprintConfig = readConfigFile(existingBlueprint.blueprintFilePath);
14
+ if (!blueprintConfig?.stackId) {
15
+ return {
16
+ success: false,
17
+ error: `A Blueprint exists here (${existingBlueprint.fileName}), but it is not connected to a Stack.`,
18
+ suggestions: [`Finish setup with: npx ${bin} blueprints init`],
19
+ };
20
+ }
21
+ log(`A blueprint already exists here (${existingBlueprint.fileName}).`);
22
+ log('');
23
+ log('Use these instead:');
24
+ log(` npx ${bin} blueprints config --edit`);
25
+ log(` npx ${bin} blueprints doctor`);
26
+ return {
27
+ success: true,
28
+ json: { alreadyInitialized: true, blueprintFile: existingBlueprint.fileName },
29
+ };
30
+ }
31
+ const tokenCheck = await validTokenOrErrorMessage(log);
32
+ if (!tokenCheck.ok) {
33
+ return {
34
+ success: false,
35
+ error: 'No Sanity session found.',
36
+ suggestions: ['Sign in first: npx sanity login', 'Then run init again.'],
37
+ };
38
+ }
39
+ log('Setting up your Sanity workspace.');
40
+ log('');
41
+ const flowOptions = { bin, dir, flags, log, token: tokenCheck.value };
42
+ const studio = detectStudio(dir);
43
+ return studio ? await adoptFlow({ ...flowOptions, studio }) : await freshFlow(flowOptions);
44
+ }
45
+ catch (error) {
46
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
47
+ }
48
+ }
@@ -1,10 +1,10 @@
1
1
  import { treeify } from 'array-treeify';
2
- import { SANITY_ACCESS_ROBOT, SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_DURABLE, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_PUBSUB, SANITY_FUNCTION_SCHEDULED, SANITY_FUNCTION_SYNC_TAG_INVALIDATE, SANITY_PROJECT, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
2
+ import { SANITY_ACCESS_ROBOT, SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_DURABLE, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_PUBSUB, SANITY_FUNCTION_SCHEDULED, SANITY_FUNCTION_SYNC_TAG_INVALIDATE, SANITY_PROJECT, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, SANITY_STUDIO, } from '../../constants.js';
3
3
  import { styleText } from '../style-text.js';
4
- import { isCorsOriginResource, isDatasetResource, isRobotResource, isRoleResource, isWebhookResource, } from '../types.js';
4
+ import { isCorsOriginResource, isDatasetResource, isRobotResource, isRoleResource, isStudioResource, isWebhookResource, } from '../types.js';
5
5
  import { formatDateTime, formatDuration } from './dates.js';
6
6
  import { capitalize, niceId, renderSection } from './presenters.js';
7
- import { arrayifyCors, arrayifyDataset, arrayifyFunction, arrayifyRobot, arrayifyRole, arrayifyWebhook, } from './resources-formatting.js';
7
+ import { arrayifyCors, arrayifyDataset, arrayifyFunction, arrayifyRobot, arrayifyRole, arrayifyStudio, arrayifyWebhook, } from './resources-formatting.js';
8
8
  const functionCategory = {
9
9
  label: 'Functions',
10
10
  displayNameAttribute: 'displayName',
@@ -58,6 +58,13 @@ const RESOURCE_CATEGORIES = {
58
58
  return isWebhookResource(res) ? arrayifyWebhook(res) : [];
59
59
  },
60
60
  },
61
+ [SANITY_STUDIO]: {
62
+ label: 'Studios',
63
+ displayNameAttribute: 'title',
64
+ formatDetails(res) {
65
+ return isStudioResource(res) ? arrayifyStudio(res) : [];
66
+ },
67
+ },
61
68
  };
62
69
  const categoryByLabel = Object.values(RESOURCE_CATEGORIES).reduce((acc, curr) => {
63
70
  acc[curr.label] = curr;
@@ -76,9 +83,11 @@ function resourceName(res, displayNameAttribute) {
76
83
  }
77
84
  function deployedResourceName(res, displayNameAttribute, verbose = false) {
78
85
  const nameParts = [styleText(['bold', 'green'], res.name)];
79
- const displayName = displayNameAttribute &&
80
- typeof res.parameters[displayNameAttribute] === 'string' &&
81
- res.parameters[displayNameAttribute];
86
+ // deployed state: prefer the resolved value, fall back to the authored one
87
+ const nameValue = displayNameAttribute
88
+ ? (res.resolvedParameters?.[displayNameAttribute] ?? res.parameters[displayNameAttribute])
89
+ : undefined;
90
+ const displayName = typeof nameValue === 'string' && nameValue;
82
91
  if (displayName && displayName !== res.name)
83
92
  nameParts.push(styleText('green', `"${displayName}"`));
84
93
  if (verbose)
@@ -151,7 +160,9 @@ function buildOutputTree(resources, createName, mapToResource, verbose = false)
151
160
  export function formatDeployedResourceTree(resources, verbose = false) {
152
161
  if (!resources || resources.length === 0)
153
162
  return ' Zero deployed resources';
154
- const output = buildOutputTree(resources, (category, res, v) => deployedResourceName(res, category.displayNameAttribute, v), (res) => ({ name: res.name, type: res.type, ...res.parameters }), verbose);
163
+ const output = buildOutputTree(resources, (category, res, v) => deployedResourceName(res, category.displayNameAttribute, v),
164
+ // deployed state: prefer resolved values, fall back to authored ones
165
+ (res) => ({ name: res.name, type: res.type, ...(res.resolvedParameters ?? res.parameters) }), verbose);
155
166
  return `${treeify(output)}\n`;
156
167
  }
157
168
  export function formatResourceTree(resources, verbose = false) {
@@ -1,8 +1,9 @@
1
- import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintResource, BlueprintRobotResource, BlueprintRoleResource } from '@sanity/blueprints';
1
+ import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintResource, BlueprintRobotResource, BlueprintRoleResource, BlueprintStudioResource } from '@sanity/blueprints';
2
2
  import type { TreeInput } from 'array-treeify';
3
- export declare function arrayifyFunction(fn: BlueprintResource): TreeInput;
4
3
  export declare function arrayifyCors(resource: BlueprintCorsOriginResource): TreeInput;
5
4
  export declare function arrayifyDataset(resource: BlueprintDatasetResource): TreeInput;
5
+ export declare function arrayifyFunction(fn: BlueprintResource): TreeInput;
6
6
  export declare function arrayifyRobot(resource: BlueprintRobotResource): TreeInput;
7
7
  export declare function arrayifyRole(resource: BlueprintRoleResource): TreeInput;
8
+ export declare function arrayifyStudio(resource: BlueprintStudioResource): TreeInput;
8
9
  export declare function arrayifyWebhook(resource: BlueprintDocumentWebhookResource): TreeInput;
@@ -1,11 +1,27 @@
1
1
  import { hasEventSource, isLocalFunctionResource, isScheduleEvent, } from '../../utils/types.js';
2
2
  import { styleText } from '../style-text.js';
3
+ import { niceId } from './presenters.js';
3
4
  function formatLabel(label) {
4
5
  return styleText('dim', `${label}:`);
5
6
  }
6
7
  function formatLabeledValue(label, value) {
7
8
  return `${styleText('dim', `${label}:`)} ${value}`;
8
9
  }
10
+ export function arrayifyCors(resource) {
11
+ const details = [formatLabeledValue('origin', resource.origin)];
12
+ if (resource.allowCredentials !== undefined) {
13
+ details.push(formatLabeledValue('allowCredentials', resource.allowCredentials));
14
+ }
15
+ return details;
16
+ }
17
+ export function arrayifyDataset(resource) {
18
+ const details = [formatLabeledValue('title', resource.datasetName)];
19
+ if (resource.aclMode)
20
+ details.push(formatLabeledValue('visibility', resource.aclMode));
21
+ if (resource.project)
22
+ details.push(formatLabeledValue('project', niceId(resource.project)));
23
+ return details;
24
+ }
9
25
  function arrayifyEvent(event) {
10
26
  if (!event)
11
27
  return undefined;
@@ -55,19 +71,8 @@ export function arrayifyFunction(fn) {
55
71
  }
56
72
  return details;
57
73
  }
58
- export function arrayifyCors(resource) {
59
- return [formatLabeledValue('origin', resource.origin)];
60
- }
61
- export function arrayifyDataset(resource) {
62
- const details = [formatLabeledValue('title', resource.datasetName)];
63
- if (resource.aclMode)
64
- details.push(formatLabeledValue('visibility', resource.aclMode));
65
- if (resource.project)
66
- details.push(formatLabeledValue('project', resource.project));
67
- return details;
68
- }
69
74
  export function arrayifyRobot(resource) {
70
- const details = [formatLabeledValue('label', resource.label)];
75
+ const details = [];
71
76
  if (resource.memberships.length > 0) {
72
77
  details.push(formatLabel('memberships'));
73
78
  const memberships = [];
@@ -115,8 +120,16 @@ export function arrayifyRole(resource) {
115
120
  }
116
121
  return details;
117
122
  }
123
+ export function arrayifyStudio(resource) {
124
+ const details = [formatLabeledValue('appHost', resource.slug)];
125
+ if (resource.project)
126
+ details.push(formatLabeledValue('project', niceId(resource.project)));
127
+ return details;
128
+ }
118
129
  export function arrayifyWebhook(resource) {
119
130
  const details = [];
131
+ if (resource.displayName)
132
+ details.push(formatLabeledValue('displayName', resource.displayName));
120
133
  if (resource.description)
121
134
  details.push(formatLabeledValue('description', resource.description));
122
135
  details.push(formatLabeledValue('url', resource.url));
@@ -131,6 +144,8 @@ export function arrayifyWebhook(resource) {
131
144
  details.push(formatLabeledValue('httpMethod', resource.httpMethod));
132
145
  if (resource.dataset)
133
146
  details.push(formatLabeledValue('dataset', resource.dataset));
147
+ if (resource.project)
148
+ details.push(formatLabeledValue('project', niceId(resource.project)));
134
149
  // not included: headers, includeDrafts, includeAllVersions, secret, apiVersion
135
150
  return details;
136
151
  }
@@ -1,4 +1,15 @@
1
1
  import { ORGANIZATION_SCOPED_FUNCTION_TYPES, PROJECT_SCOPED_FUNCTION_TYPES } from '../../constants.js';
2
+ const REFERENCE_PREFIX = '$.resources.';
3
+ /**
4
+ * A scope ID the API can use: a literal, never an unresolved Blueprint reference.
5
+ * Overly defensive and checks resource.parameters as fallback.
6
+ */
7
+ function literalScopeId(resource, key) {
8
+ const value = resource.resolvedParameters?.[key] ?? resource.parameters[key];
9
+ if (typeof value !== 'string' || value.startsWith(REFERENCE_PREFIX))
10
+ return undefined;
11
+ return value;
12
+ }
2
13
  /**
3
14
  * Resolves the correct auth scope for a function API request.
4
15
  *
@@ -8,11 +19,13 @@ import { ORGANIZATION_SCOPED_FUNCTION_TYPES, PROJECT_SCOPED_FUNCTION_TYPES } fro
8
19
  */
9
20
  export function resolveFunctionAuth(auth, deployedStack, resource) {
10
21
  // 1. explicit resource-level scope takes highest priority
11
- if (typeof resource.parameters.project === 'string') {
12
- return { ...auth, scopeType: 'project', scopeId: resource.parameters.project };
22
+ const project = literalScopeId(resource, 'project');
23
+ if (project) {
24
+ return { ...auth, scopeType: 'project', scopeId: project };
13
25
  }
14
- if (typeof resource.parameters.organization === 'string') {
15
- return { ...auth, scopeType: 'organization', scopeId: resource.parameters.organization };
26
+ const organization = literalScopeId(resource, 'organization');
27
+ if (organization) {
28
+ return { ...auth, scopeType: 'organization', scopeId: organization };
16
29
  }
17
30
  // 2. project-scoped function types: resolve a project ID or fail
18
31
  if (PROJECT_SCOPED_FUNCTION_TYPES.has(resource.type)) {
@@ -33,7 +33,10 @@ export interface AuthParams {
33
33
  export interface BlueprintResourceRecord extends BlueprintResource {
34
34
  id: string;
35
35
  externalId?: string | null;
36
+ /** Authored values; a value can be an unresolved `$.resources.<name>` reference */
36
37
  parameters: Record<string, unknown>;
38
+ /** Values deployment used, with references resolved */
39
+ resolvedParameters?: Record<string, unknown>;
37
40
  }
38
41
  /** The deployed resource; complete with external ID */
39
42
  export interface DeployedResource extends BlueprintResourceRecord {
@@ -1,5 +1,134 @@
1
1
  {
2
2
  "commands": {
3
+ "init": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Scaffolds a Blueprint, Studio, and starter function around an existing Sanity project.\n\nThis hidden command is an experiment; its interface and generated files are not stable.",
7
+ "examples": [
8
+ "<%= config.bin %> <%= command.id %>",
9
+ "<%= config.bin %> <%= command.id %> --yes",
10
+ "<%= config.bin %> <%= command.id %> --project-id <id> --dataset <name> --yes"
11
+ ],
12
+ "flags": {
13
+ "json": {
14
+ "description": "Format output as json",
15
+ "name": "json",
16
+ "allowNo": false,
17
+ "type": "boolean"
18
+ },
19
+ "path": {
20
+ "aliases": [
21
+ "blueprint-path"
22
+ ],
23
+ "char": "p",
24
+ "description": "Path to a Blueprint file or directory containing one",
25
+ "env": "SANITY_BLUEPRINT_PATH",
26
+ "hidden": true,
27
+ "name": "path",
28
+ "hasDynamicHelp": false,
29
+ "multiple": false,
30
+ "type": "option"
31
+ },
32
+ "trace": {
33
+ "description": "Trace output",
34
+ "hidden": true,
35
+ "name": "trace",
36
+ "allowNo": false,
37
+ "type": "boolean"
38
+ },
39
+ "validate-resources": {
40
+ "description": "Validate resources",
41
+ "hidden": true,
42
+ "name": "validate-resources",
43
+ "allowNo": true,
44
+ "type": "boolean"
45
+ },
46
+ "verbose": {
47
+ "description": "Verbose output",
48
+ "hidden": true,
49
+ "name": "verbose",
50
+ "allowNo": false,
51
+ "type": "boolean"
52
+ },
53
+ "llms": {
54
+ "aliases": [
55
+ "skill"
56
+ ],
57
+ "description": "Show agent-oriented guidance for this command",
58
+ "hidden": true,
59
+ "name": "llms",
60
+ "allowNo": false,
61
+ "type": "boolean"
62
+ },
63
+ "yes": {
64
+ "char": "y",
65
+ "description": "Skip confirmation prompts",
66
+ "name": "yes",
67
+ "allowNo": false,
68
+ "type": "boolean"
69
+ },
70
+ "organization-id": {
71
+ "aliases": [
72
+ "organization",
73
+ "organizationId",
74
+ "org"
75
+ ],
76
+ "description": "Organization to use when the account has several",
77
+ "name": "organization-id",
78
+ "hasDynamicHelp": false,
79
+ "multiple": false,
80
+ "type": "option"
81
+ },
82
+ "project-id": {
83
+ "aliases": [
84
+ "project",
85
+ "projectId"
86
+ ],
87
+ "description": "Project to use when the organization has several",
88
+ "name": "project-id",
89
+ "hasDynamicHelp": false,
90
+ "multiple": false,
91
+ "type": "option"
92
+ },
93
+ "dataset": {
94
+ "description": "Dataset to attach",
95
+ "name": "dataset",
96
+ "hasDynamicHelp": false,
97
+ "multiple": false,
98
+ "type": "option"
99
+ },
100
+ "stack-name": {
101
+ "description": "Name for the new organization-scoped Stack",
102
+ "name": "stack-name",
103
+ "hasDynamicHelp": false,
104
+ "multiple": false,
105
+ "type": "option"
106
+ },
107
+ "studio-name": {
108
+ "description": "Name and hosted slug for the Studio resource",
109
+ "name": "studio-name",
110
+ "hasDynamicHelp": false,
111
+ "multiple": false,
112
+ "type": "option"
113
+ }
114
+ },
115
+ "hasDynamicHelp": false,
116
+ "hidden": true,
117
+ "hiddenAliases": [],
118
+ "id": "init",
119
+ "pluginAlias": "@sanity/runtime-cli",
120
+ "pluginName": "@sanity/runtime-cli",
121
+ "pluginType": "core",
122
+ "strict": true,
123
+ "summary": "Experimental blueprints-first project init",
124
+ "enableJsonFlag": true,
125
+ "isESM": true,
126
+ "relativePath": [
127
+ "dist",
128
+ "commands",
129
+ "init.js"
130
+ ]
131
+ },
3
132
  "blueprints:add": {
4
133
  "aliases": [],
5
134
  "args": {
@@ -3127,5 +3256,5 @@
3127
3256
  ]
3128
3257
  }
3129
3258
  },
3130
- "version": "17.6.2"
3259
+ "version": "17.7.0-blueprinit.ga49bda6"
3131
3260
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sanity/runtime-cli",
3
3
  "description": "Sanity's Runtime CLI for Blueprints and Functions",
4
- "version": "17.6.2",
4
+ "version": "17.7.0-blueprinit.ga49bda6",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -65,20 +65,20 @@
65
65
  "@architect/hydrate": "~6.0.2",
66
66
  "@architect/inventory": "~6.1.0",
67
67
  "@inquirer/prompts": "^8.5.2",
68
- "@oclif/core": "^4.13.3",
69
- "@oclif/plugin-help": "^6.2.56",
68
+ "@oclif/core": "^4.13.4",
69
+ "@oclif/plugin-help": "^6.2.58",
70
70
  "@sanity-labs/design-tokens": "^0.0.2-alpha.2",
71
71
  "@sanity-labs/oclif-plugin-skills-flag": "^0.2.1",
72
- "@sanity/blueprints": "^0.23.2",
73
- "@sanity/blueprints-parser": "^0.4.0",
74
- "@sanity/cli-build": "^5.1.0",
75
- "@sanity/cli-core": "^2.8.1",
76
- "@sanity/client": "^7.26.2",
72
+ "@sanity/blueprints": "^0.23.6",
73
+ "@sanity/blueprints-parser": "^0.5.0",
74
+ "@sanity/cli-build": "^5.2.0",
75
+ "@sanity/cli-core": "^3.0.0",
76
+ "@sanity/client": "^8.0.0",
77
77
  "adm-zip": "^0.6.0",
78
- "array-treeify": "^0.1.5",
78
+ "array-treeify": "^0.2.0",
79
79
  "cardinal": "^2.1.1",
80
80
  "empathic": "^2.0.1",
81
- "eventsource": "^4.1.1",
81
+ "eventsource": "^5.1.0",
82
82
  "groq-js": "^2.0.0",
83
83
  "jiti": "^2.7.0",
84
84
  "mime-types": "^3.0.2",
@@ -92,15 +92,15 @@
92
92
  "xdg-basedir": "^5.1.0"
93
93
  },
94
94
  "devDependencies": {
95
- "@biomejs/biome": "2.5.7",
95
+ "@biomejs/biome": "2.5.8",
96
96
  "@codemirror/lang-json": "^6.0.2",
97
97
  "@codemirror/state": "^6.7.1",
98
98
  "@enhance/store": "^1.0.2",
99
99
  "@lezer/highlight": "^1.2.3",
100
- "@oclif/test": "^4.1.21",
100
+ "@oclif/test": "^4.1.22",
101
101
  "@playwright/test": "^1.62.1",
102
102
  "@rollup/plugin-node-resolve": "^16.0.3",
103
- "@sanity/functions": "^1.6.0",
103
+ "@sanity/functions": "^1.6.6",
104
104
  "@types/adm-zip": "^0.5.8",
105
105
  "@types/cardinal": "^2.1.1",
106
106
  "@types/mime-types": "^3.0.1",