create-mastra 1.22.0 → 1.23.0-alpha.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # create-mastra
2
2
 
3
+ ## 1.23.0-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed prerelease project creation to keep using the running create-mastra release channel when npm dist-tags have not finished updating. ([#20723](https://github.com/mastra-ai/mastra/pull/20723))
8
+
9
+ ## 1.22.1-alpha.0
10
+
3
11
  ## 1.22.0
4
12
 
5
13
  ### Patch Changes
package/dist/index.js CHANGED
@@ -21619,69 +21619,52 @@ async function writeEmptyScaffold({ projectPath, projectName, versionTag, packag
21619
21619
  const MANAGED_PROVIDER_CONFIGS = {
21620
21620
  openai: {
21621
21621
  displayName: "OpenAI",
21622
- sdkPackage: "@ai-sdk/openai",
21623
- providerIdentifier: "openai",
21624
- apiKeyEnv: "OPENAI_API_KEY",
21625
- apiKeyPrerequisite: "An OpenAI API key",
21626
- featureDescription: "OpenAI web search and direct web page fetching"
21622
+ apiKeyEnv: "OPENAI_API_KEY"
21627
21623
  },
21628
21624
  anthropic: {
21629
21625
  displayName: "Anthropic",
21630
- sdkPackage: "@ai-sdk/anthropic",
21631
- sdkVersion: "^3.0.96",
21632
- providerIdentifier: "anthropic",
21633
21626
  primaryModel: "anthropic/claude-sonnet-5",
21634
21627
  observationalModel: "anthropic/claude-haiku-4-5",
21635
- apiKeyEnv: "ANTHROPIC_API_KEY",
21636
- apiKeyPrerequisite: "An Anthropic API key",
21637
- featureDescription: "Anthropic web search and direct web page fetching",
21638
- webSearchEntry: "anthropic.tools.webSearch_20250305()"
21628
+ apiKeyEnv: "ANTHROPIC_API_KEY"
21639
21629
  },
21640
21630
  google: {
21641
21631
  displayName: "Google Gemini",
21642
- sdkPackage: "@ai-sdk/google",
21643
- sdkVersion: "^3.0.91",
21644
- providerIdentifier: "google",
21645
21632
  primaryModel: "google/gemini-3.5-flash",
21646
21633
  observationalModel: "google/gemini-3.5-flash",
21647
- apiKeyEnv: "GOOGLE_GENERATIVE_AI_API_KEY",
21648
- apiKeyPrerequisite: "A Google Gemini API key",
21649
- featureDescription: "Google Gemini web search and direct web page fetching",
21650
- webSearchEntry: "google.tools.googleSearch({})"
21634
+ apiKeyEnv: "GOOGLE_GENERATIVE_AI_API_KEY"
21651
21635
  },
21652
21636
  xai: {
21653
21637
  displayName: "xAI",
21654
- sdkPackage: "@ai-sdk/xai",
21655
- sdkVersion: "^3.0.106",
21656
- providerIdentifier: "xai",
21657
21638
  primaryModel: "xai/grok-4.3",
21658
21639
  observationalModel: "xai/grok-4.3",
21659
- apiKeyEnv: "XAI_API_KEY",
21660
- apiKeyPrerequisite: "An xAI API key",
21661
- featureDescription: "xAI web search and direct web page fetching",
21662
- webSearchEntry: "xai.tools.webSearch()"
21640
+ apiKeyEnv: "XAI_API_KEY"
21663
21641
  }
21664
21642
  };
21665
- const PROVIDER_SDK_PACKAGES = Object.values(MANAGED_PROVIDER_CONFIGS).map((config) => config.sdkPackage);
21666
- const OPENAI_SDK_PACKAGE = "@ai-sdk/openai";
21667
21643
  const OPENAI_API_KEY = "OPENAI_API_KEY";
21668
- const OPENAI_IMPORT = /^import\s*\{\s*openai\s*\}\s*from\s*['"]@ai-sdk\/openai['"];?\s*$/m;
21669
- const OPENAI_MODEL = /(\bmodel\s*:\s*['"])openai\/[^'"]+(['"])/g;
21670
- const WEB_SEARCH_PROPERTY = /^([ \t]*)web_search\s*:\s*([^\n]+?)(?:,)?\s*$/m;
21644
+ const PRIMARY_OPENAI_MODEL = /(\bmodel\s*:\s*['"])openai\/[^'"]+(['"])(?=\s*,?\s*\n\s*defaultOptions\s*:)/g;
21645
+ const OBSERVATIONAL_OPENAI_MODEL = /(observationalMemory\s*:\s*\{[^{}]*?\bmodel\s*:\s*['"])openai\/[^'"]+(['"])/g;
21671
21646
  function findMatches(content, pattern) {
21672
21647
  const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
21673
21648
  return [...content.matchAll(new RegExp(pattern.source, flags))];
21674
21649
  }
21675
- function replaceSingleMatch(content, pattern, replacement, description, fileName) {
21676
- const matches = findMatches(content, pattern);
21677
- if (matches.length !== 1) throw new Error(`Default template compatibility error: expected one ${description} in ${fileName}, found ${matches.length}.`);
21678
- if (typeof replacement === "string") return content.replace(pattern, replacement);
21679
- return content.replace(pattern, replacement);
21650
+ function replaceSingleMatch(content, pattern, replacement) {
21651
+ if (findMatches(content, pattern).length !== 1) return {
21652
+ applied: false,
21653
+ content
21654
+ };
21655
+ if (typeof replacement === "string") return {
21656
+ applied: true,
21657
+ content: content.replace(pattern, replacement)
21658
+ };
21659
+ return {
21660
+ applied: true,
21661
+ content: content.replace(pattern, replacement)
21662
+ };
21680
21663
  }
21681
21664
  function getDependencyMap(manifest, section) {
21682
21665
  const value = manifest[section];
21683
21666
  if (value === void 0 && section === "devDependencies") return void 0;
21684
- if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Default template compatibility error: package.json has invalid ${section}.`);
21667
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
21685
21668
  return value;
21686
21669
  }
21687
21670
  function collectMastraPackages(manifestSource) {
@@ -21700,120 +21683,157 @@ function collectMastraPackages(manifestSource) {
21700
21683
  }
21701
21684
  return [...names];
21702
21685
  }
21703
- function normalizeManagedManifest(content, provider, mastraVersions, fallbackTag) {
21686
+ function normalizeManagedManifest(content, mastraVersions, fallbackTag) {
21704
21687
  let manifest;
21705
21688
  try {
21706
21689
  manifest = JSON.parse(content);
21707
21690
  } catch {
21708
- throw new Error("Default template compatibility error: package.json is not valid JSON.");
21691
+ return {
21692
+ applied: false,
21693
+ content
21694
+ };
21709
21695
  }
21710
- const dependencySections = [getDependencyMap(manifest, "dependencies"), getDependencyMap(manifest, "devDependencies")].filter((section) => section !== void 0);
21711
- const openAiLocations = dependencySections.filter((section) => Object.hasOwn(section, OPENAI_SDK_PACKAGE));
21712
- if (openAiLocations.length !== 1) throw new Error(`Default template compatibility error: package.json must contain ${OPENAI_SDK_PACKAGE} in exactly one dependency section.`);
21713
- const sourceSection = openAiLocations[0];
21714
- const templateOpenAiVersion = sourceSection[OPENAI_SDK_PACKAGE];
21715
- if (typeof templateOpenAiVersion !== "string" || templateOpenAiVersion.trim() === "") throw new Error(`Default template compatibility error: package.json must contain a nonempty ${OPENAI_SDK_PACKAGE} version.`);
21716
- for (const section of dependencySections) for (const packageName of PROVIDER_SDK_PACKAGES) delete section[packageName];
21717
- const sdkVersion = provider.sdkPackage === OPENAI_SDK_PACKAGE ? templateOpenAiVersion : provider.sdkVersion;
21718
- if (!sdkVersion) throw new Error(`Default template compatibility error: no SDK version is configured for ${provider.displayName}.`);
21719
- sourceSection[provider.sdkPackage] = sdkVersion;
21696
+ const dependencies = getDependencyMap(manifest, "dependencies");
21697
+ const devDependencies = getDependencyMap(manifest, "devDependencies");
21698
+ if (!dependencies || manifest.devDependencies !== void 0 && !devDependencies) return {
21699
+ applied: false,
21700
+ content
21701
+ };
21702
+ const dependencySections = [dependencies, devDependencies].filter((section) => section !== void 0);
21720
21703
  for (const section of dependencySections) for (const packageName of Object.keys(section)) if (packageName === "mastra" || packageName.startsWith("@mastra/")) section[packageName] = mastraVersions?.[packageName] ?? fallbackTag;
21721
21704
  return {
21705
+ applied: true,
21722
21706
  content: `${JSON.stringify(manifest, null, 2)}
21723
- `,
21724
- sdkVersion
21707
+ `
21725
21708
  };
21726
21709
  }
21727
21710
  function adaptAgentSource(source, provider, config) {
21728
- if (provider === "openai") return source;
21729
- if (!config.primaryModel || !config.observationalModel) throw new Error(`Default template compatibility error: model configuration is missing for ${config.displayName}.`);
21730
- let next = replaceSingleMatch(source, OPENAI_IMPORT, `import { ${config.providerIdentifier} } from '${config.sdkPackage}';`, "OpenAI provider import", "src/mastra/agents/agent.ts");
21731
- const modelMatches = findMatches(next, OPENAI_MODEL);
21732
- if (modelMatches.length !== 2) throw new Error(`Default template compatibility error: expected two OpenAI model assignments in src/mastra/agents/agent.ts, found ${modelMatches.length}.`);
21733
- const models = [config.primaryModel, config.observationalModel];
21734
- let modelIndex = 0;
21735
- next = next.replace(OPENAI_MODEL, (_match, prefix, suffix) => {
21736
- return `${prefix}${models[modelIndex++]}${suffix}`;
21737
- });
21738
- const webSearchMatches = findMatches(next, WEB_SEARCH_PROPERTY);
21739
- if (webSearchMatches.length > 1) throw new Error(`Default template compatibility error: expected at most one web_search property in src/mastra/agents/agent.ts, found ${webSearchMatches.length}.`);
21740
- if (webSearchMatches.length === 1) {
21741
- const match = webSearchMatches[0];
21742
- if (!match[2]?.includes("openai.")) throw new Error("Default template compatibility error: the existing web_search property is not owned by the OpenAI template.");
21743
- next = next.replace(WEB_SEARCH_PROPERTY, config.webSearchEntry ? `${match[1]}web_search: ${config.webSearchEntry},` : "");
21744
- } else if (config.webSearchEntry) next = replaceSingleMatch(next, /^([ \t]*)web_fetch\s*:\s*[^\n]+$/m, (_line, indentation) => `${indentation}web_fetch: webFetchTool,
21745
- ${indentation}web_search: ${config.webSearchEntry},`, "web_fetch property used to place web_search", "src/mastra/agents/agent.ts");
21746
- return next;
21711
+ if (provider === "openai") return {
21712
+ applied: true,
21713
+ content: source
21714
+ };
21715
+ if (!config.primaryModel || !config.observationalModel) return {
21716
+ applied: false,
21717
+ content: source
21718
+ };
21719
+ if (findMatches(source, PRIMARY_OPENAI_MODEL).length !== 1) return {
21720
+ applied: false,
21721
+ content: source
21722
+ };
21723
+ if (findMatches(source, OBSERVATIONAL_OPENAI_MODEL).length !== 1) return {
21724
+ applied: false,
21725
+ content: source
21726
+ };
21727
+ return {
21728
+ applied: true,
21729
+ content: source.replace(PRIMARY_OPENAI_MODEL, `$1${config.primaryModel}$2`).replace(OBSERVATIONAL_OPENAI_MODEL, `$1${config.observationalModel}$2`)
21730
+ };
21747
21731
  }
21748
21732
  function replaceEnvKey(source, nextKey) {
21749
- return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${OPENAI_API_KEY}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${nextKey}=`, `${OPENAI_API_KEY} assignment`, ".env.example");
21733
+ return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${OPENAI_API_KEY}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${nextKey}=`);
21750
21734
  }
21751
21735
  function setEnvValue(source, key, value) {
21752
- return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${key}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${key}=${value}`, `${key} assignment`, ".env");
21736
+ return replaceSingleMatch(source, new RegExp(`^([ \\t]*)${key}[ \\t]*=.*$`, "m"), (_line, indentation) => `${indentation}${key}=${value}`);
21753
21737
  }
21754
21738
  function adaptReadme(source, provider, config, projectName, packageManager) {
21755
- return source.replace(/^# .+$/m, `# ${projectName}`).replaceAll("npm run dev", `${packageManager} run dev`).replace(/^- .*OpenAI web search.*$/m, `- ${config.featureDescription}`).replace(/^- .*OpenAI API key.*$/m, `- ${config.apiKeyPrerequisite}`).replace(/^([ \t]*)npx create-mastra@\S+.*$/m, `$1npx create-mastra@latest <project-name> --llm ${provider}`).replaceAll(OPENAI_API_KEY, config.apiKeyEnv);
21756
- }
21757
- function assertNoProviderResidue(provider, files) {
21758
- for (const [otherProvider, config] of Object.entries(MANAGED_PROVIDER_CONFIGS)) {
21759
- if (otherProvider === provider) continue;
21760
- const checks = [
21761
- [files.manifest, config.sdkPackage],
21762
- [files.agent, `${config.providerIdentifier}/`],
21763
- [files.agent, `${config.providerIdentifier}.tools`],
21764
- [files.envExample, config.apiKeyEnv]
21765
- ];
21766
- if (files.env !== void 0) checks.push([files.env, config.apiKeyEnv]);
21767
- for (const [content, residue] of checks) if (content.includes(residue)) throw new Error(`Default template compatibility error: generated project still contains ${JSON.stringify(residue)} from ${config.displayName}.`);
21739
+ if (!(source.includes(OPENAI_API_KEY) || /^([ \t]*)npx create-mastra@\S+.*$/m.test(source))) return {
21740
+ applied: false,
21741
+ content: source
21742
+ };
21743
+ return {
21744
+ applied: true,
21745
+ content: source.replace(/^# .+$/m, `# ${projectName}`).replaceAll("npm run dev", `${packageManager} run dev`).replace(/^([ \t]*)npx create-mastra@\S+.*$/m, `$1npx create-mastra@latest <project-name> --llm ${provider}`).replaceAll(OPENAI_API_KEY, config.apiKeyEnv)
21746
+ };
21747
+ }
21748
+ async function writeSecureEnv(envPath, content) {
21749
+ const tempPath = path.join(path.dirname(envPath), `.env.mastra-create-${process.pid}-${randomUUID()}.tmp`);
21750
+ try {
21751
+ await fsPromises__default.writeFile(tempPath, content, {
21752
+ encoding: "utf8",
21753
+ flag: "wx",
21754
+ mode: 384
21755
+ });
21756
+ if (process.platform !== "win32") await fsPromises__default.chmod(tempPath, 384);
21757
+ await fsPromises__default.rename(tempPath, envPath);
21758
+ return true;
21759
+ } catch {
21760
+ try {
21761
+ await fsPromises__default.rm(tempPath, { force: true });
21762
+ } catch {
21763
+ }
21764
+ return false;
21768
21765
  }
21769
21766
  }
21770
21767
  async function adaptDefaultTemplate({ projectPath, projectName, packageManager, provider, apiKey, versionTag }) {
21771
21768
  const config = MANAGED_PROVIDER_CONFIGS[provider];
21769
+ let adaptationFailed = false;
21770
+ const write = async (filePath, content) => {
21771
+ try {
21772
+ await fsPromises__default.writeFile(filePath, content, "utf8");
21773
+ return true;
21774
+ } catch {
21775
+ adaptationFailed = true;
21776
+ return false;
21777
+ }
21778
+ };
21772
21779
  const agentPath = path.join(projectPath, "src/mastra/agents/agent.ts");
21780
+ if (provider !== "openai") try {
21781
+ const result = adaptAgentSource(await fsPromises__default.readFile(agentPath, "utf8"), provider, config);
21782
+ if (!result.applied) adaptationFailed = true;
21783
+ else await write(agentPath, result.content);
21784
+ } catch {
21785
+ adaptationFailed = true;
21786
+ }
21773
21787
  const packageJsonPath = path.join(projectPath, "package.json");
21788
+ try {
21789
+ const source = await fsPromises__default.readFile(packageJsonPath, "utf8");
21790
+ const mastraPackages = collectMastraPackages(source);
21791
+ const resolvedVersions = await resolveMastraPackageVersions(mastraPackages, versionTag);
21792
+ if (resolvedVersions === void 0 && mastraPackages.length > 0) console.warn(`We could not resolve exact Mastra package versions for the "${versionTag}" channel, using the channel tag instead`);
21793
+ const result = normalizeManagedManifest(source, resolvedVersions, versionTag);
21794
+ if (!result.applied) adaptationFailed = true;
21795
+ else await write(packageJsonPath, result.content);
21796
+ } catch {
21797
+ adaptationFailed = true;
21798
+ }
21774
21799
  const envExamplePath = path.join(projectPath, ".env.example");
21775
21800
  const envPath = path.join(projectPath, ".env");
21801
+ let adaptedEnvExample;
21802
+ try {
21803
+ const result = replaceEnvKey(await fsPromises__default.readFile(envExamplePath, "utf8"), config.apiKeyEnv);
21804
+ if (!result.applied) adaptationFailed = true;
21805
+ else if (await write(envExamplePath, result.content)) adaptedEnvExample = result.content;
21806
+ } catch {
21807
+ adaptationFailed = true;
21808
+ }
21809
+ let apiKeyWritten = false;
21810
+ if (adaptedEnvExample === void 0) {
21811
+ if (apiKey) adaptationFailed = true;
21812
+ } else if (apiKey) {
21813
+ const result = setEnvValue(adaptedEnvExample, config.apiKeyEnv, apiKey);
21814
+ if (!result.applied) adaptationFailed = true;
21815
+ else {
21816
+ apiKeyWritten = await writeSecureEnv(envPath, result.content);
21817
+ if (!apiKeyWritten) adaptationFailed = true;
21818
+ }
21819
+ } else try {
21820
+ await fsPromises__default.rm(envPath, { force: true });
21821
+ } catch {
21822
+ adaptationFailed = true;
21823
+ }
21776
21824
  const readmePath = path.join(projectPath, "README.md");
21777
- let agentSource;
21778
- let packageJsonSource;
21779
- let envExampleSource;
21780
21825
  try {
21781
- [agentSource, packageJsonSource, envExampleSource] = await Promise.all([
21782
- fsPromises__default.readFile(agentPath, "utf8"),
21783
- fsPromises__default.readFile(packageJsonPath, "utf8"),
21784
- fsPromises__default.readFile(envExamplePath, "utf8")
21785
- ]);
21786
- } catch (error) {
21787
- throw new Error(`Default template compatibility error: required template file is missing or unreadable: ${error instanceof Error ? error.message : "Unknown error"}`);
21826
+ const result = adaptReadme(await fsPromises__default.readFile(readmePath, "utf8"), provider, config, projectName, packageManager);
21827
+ if (!result.applied) adaptationFailed = true;
21828
+ else await write(readmePath, result.content);
21829
+ } catch {
21830
+ adaptationFailed = true;
21788
21831
  }
21789
- const readmeSource = await fsPromises__default.readFile(readmePath, "utf8").catch(() => void 0);
21790
- const nextAgent = adaptAgentSource(agentSource, provider, config);
21791
- const mastraPackages = collectMastraPackages(packageJsonSource);
21792
- const resolvedVersions = await resolveMastraPackageVersions(mastraPackages, versionTag);
21793
- if (resolvedVersions === void 0 && mastraPackages.length > 0) console.warn(`We could not resolve exact Mastra package versions for the "${versionTag}" channel, using the channel tag instead`);
21794
- const normalizedManifest = normalizeManagedManifest(packageJsonSource, config, resolvedVersions, versionTag);
21795
- const nextEnvExample = replaceEnvKey(envExampleSource, config.apiKeyEnv);
21796
- const nextEnv = apiKey ? setEnvValue(nextEnvExample, config.apiKeyEnv, apiKey) : void 0;
21797
- const nextReadme = readmeSource === void 0 ? void 0 : adaptReadme(readmeSource, provider, config, projectName, packageManager);
21798
- assertNoProviderResidue(provider, {
21799
- agent: nextAgent,
21800
- manifest: normalizedManifest.content,
21801
- envExample: nextEnvExample,
21802
- env: nextEnv
21803
- });
21804
- const writes = [
21805
- fsPromises__default.writeFile(agentPath, nextAgent, "utf8"),
21806
- fsPromises__default.writeFile(packageJsonPath, normalizedManifest.content, "utf8"),
21807
- fsPromises__default.writeFile(envExamplePath, nextEnvExample, "utf8"),
21808
- nextEnv === void 0 ? fsPromises__default.rm(envPath, { force: true }) : fsPromises__default.writeFile(envPath, nextEnv, "utf8")
21809
- ];
21810
- if (nextReadme !== void 0) writes.push(fsPromises__default.writeFile(readmePath, nextReadme, "utf8"));
21811
- if (packageManager === "pnpm") writes.push(fsPromises__default.writeFile(path.join(projectPath, "pnpm-workspace.yaml"), PNPM_WORKSPACE, "utf8"));
21812
- await Promise.all(writes);
21813
- if (nextEnv !== void 0 && process.platform !== "win32") await fsPromises__default.chmod(envPath, 384);
21832
+ if (packageManager === "pnpm") await write(path.join(projectPath, "pnpm-workspace.yaml"), PNPM_WORKSPACE);
21814
21833
  return {
21815
21834
  ...config,
21816
- sdkVersion: normalizedManifest.sdkVersion
21835
+ apiKeyWritten,
21836
+ adaptationFailed
21817
21837
  };
21818
21838
  }
21819
21839
  const DEFAULT_TEMPLATE = {
@@ -21822,7 +21842,7 @@ const DEFAULT_TEMPLATE = {
21822
21842
  slug: "template-agent-harness",
21823
21843
  agents: ["agent"],
21824
21844
  mcp: [],
21825
- tools: ["web-fetch"],
21845
+ tools: [],
21826
21846
  networks: [],
21827
21847
  workflows: []
21828
21848
  };
@@ -22042,6 +22062,7 @@ const create = async (args) => {
22042
22062
  process.on("SIGINT", handleSigint);
22043
22063
  process.on("SIGTERM", handleSigterm);
22044
22064
  let selectedApiKeyEnv;
22065
+ let selectedApiKeyWritten = false;
22045
22066
  let materializationError;
22046
22067
  try {
22047
22068
  if (mode === "empty") {
@@ -22064,14 +22085,17 @@ const create = async (args) => {
22064
22085
  ...observabilityEnabled ? { silent: true } : {}
22065
22086
  });
22066
22087
  if (isManaged) {
22067
- selectedApiKeyEnv = (await adaptDefaultTemplate({
22088
+ const providerConfig = await adaptDefaultTemplate({
22068
22089
  projectPath: staging.projectPath,
22069
22090
  projectName,
22070
22091
  packageManager,
22071
22092
  provider: llmProvider,
22072
22093
  apiKey: llmApiKey,
22073
22094
  versionTag: versionTag ?? "latest"
22074
- })).apiKeyEnv;
22095
+ });
22096
+ selectedApiKeyEnv = providerConfig.apiKeyEnv;
22097
+ selectedApiKeyWritten = providerConfig.apiKeyWritten;
22098
+ if (providerConfig.adaptationFailed) log.warn("Some provider setup could not be applied. Review the generated project before running it.");
22075
22099
  materializationController.signal.throwIfAborted();
22076
22100
  }
22077
22101
  }
@@ -22175,7 +22199,7 @@ ${placeholderSummary}1. Visit ${color.cyan("https://projects.mastra.ai")} to cre
22175
22199
  2. Paste the token into ${color.cyan("MASTRA_PLATFORM_ACCESS_TOKEN")} and the project id into ${color.cyan("MASTRA_PROJECT_ID")}.`;
22176
22200
  }
22177
22201
  if (mode === "managed") {
22178
- const apiKeySummary = llmApiKey ? `Your ${selectedApiKeyEnv} value was written to ${color.cyan(".env")}.` : platformEnvWritten ? `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : `Copy ${color.cyan(".env.example")} to ${color.cyan(".env")} and set ${selectedApiKeyEnv} before starting.`;
22202
+ const apiKeySummary = llmApiKey ? selectedApiKeyWritten ? `Your ${selectedApiKeyEnv} value was written to ${color.cyan(".env")}.` : `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : platformEnvWritten ? `Set ${selectedApiKeyEnv} in ${color.cyan(".env")} before starting.` : `Copy ${color.cyan(".env.example")} to ${color.cyan(".env")} and set ${selectedApiKeyEnv} before starting.`;
22179
22203
  note(`${color.green("Success!")}
22180
22204
 
22181
22205
  ${apiKeySummary}${observabilitySummary ? `
@@ -22395,6 +22419,8 @@ async function getCreateVersionTag(version) {
22395
22419
  if (tag) return tag;
22396
22420
  } catch {
22397
22421
  }
22422
+ const prereleaseChannel = getPrereleaseChannel(version);
22423
+ if (prereleaseChannel) return prereleaseChannel;
22398
22424
  console.error('We could not resolve the create-mastra version tag, falling back to "latest"');
22399
22425
  return "latest";
22400
22426
  }