create-mastra 1.0.0-beta.1 → 1.0.0-beta.10

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/dist/index.js CHANGED
@@ -4,26 +4,26 @@ import { randomUUID } from 'node:crypto';
4
4
  import * as fs3__default from 'node:fs';
5
5
  import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
- import path, { dirname } from 'node:path';
7
+ import path3, { dirname } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { PostHog } from 'posthog-node';
10
+ import fs4 from 'node:fs/promises';
10
11
  import util, { stripVTControlCharacters } from 'node:util';
11
12
  import y$1, { stdout, stdin } from 'node:process';
12
13
  import * as g from 'node:readline';
13
14
  import g__default from 'node:readline';
14
15
  import { Writable } from 'node:stream';
15
- import fs4 from 'node:fs/promises';
16
16
  import child_process from 'node:child_process';
17
17
  import tty from 'node:tty';
18
18
  import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
19
19
  import prettier from 'prettier';
20
20
  import { execa } from 'execa';
21
+ import fsExtra$1 from 'fs-extra';
21
22
  import pino from 'pino';
22
23
  import pretty from 'pino-pretty';
23
- import fsExtra$1 from 'fs-extra';
24
24
 
25
25
  var __filename = fileURLToPath(import.meta.url);
26
- var __dirname = path.dirname(__filename);
26
+ var __dirname = path3.dirname(__filename);
27
27
  var analyticsInstance = null;
28
28
  function getAnalytics() {
29
29
  return analyticsInstance;
@@ -39,7 +39,7 @@ var PosthogAnalytics = class {
39
39
  host = "https://app.posthog.com"
40
40
  }) {
41
41
  this.version = version;
42
- const cliConfigPath = path.join(__dirname, "mastra-cli.json");
42
+ const cliConfigPath = path3.join(__dirname, "mastra-cli.json");
43
43
  if (existsSync(cliConfigPath)) {
44
44
  try {
45
45
  const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
@@ -67,7 +67,7 @@ var PosthogAnalytics = class {
67
67
  }
68
68
  writeCliConfig({ distinctId, sessionId }) {
69
69
  try {
70
- writeFileSync(path.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
70
+ writeFileSync(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
71
71
  } catch {
72
72
  }
73
73
  }
@@ -382,7 +382,7 @@ function DD({onlyFirst:e=false}={}){const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:
382
382
  `).length-1;this.output.write(srcExports.cursor.move(-999,u*-1));}render(){const u=Y$1(this._render(this)??"",process.stdout.columns,{hard:true});if(u!==this._prevFrame){if(this.state==="initial")this.output.write(srcExports.cursor.hide);else {const t=BD(this._prevFrame,u);if(this.restoreCursor(),t&&t?.length===1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.lines(1));const s=u.split(`
383
383
  `);this.output.write(s[F]),this._prevFrame=u,this.output.write(srcExports.cursor.move(0,s.length-F-1));return}if(t&&t?.length>1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.down());const s=u.split(`
384
384
  `).slice(F);this.output.write(s.join(`
385
- `)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
385
+ `)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}class dD extends x{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(u){super(u,false),this.value=!!u.initialValue,this.on("value",()=>{this.value=this._value;}),this.on("confirm",t=>{this.output.write(srcExports.cursor.move(0,-1)),this.value=t,this.state="submit",this.close();}),this.on("cursor",()=>{this.value=!this.value;});}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
386
386
 
387
387
  function ce(){return y$1.platform!=="win32"?y$1.env.TERM!=="linux":!!y$1.env.CI||!!y$1.env.WT_SESSION||!!y$1.env.TERMINUS_SUBLIME||y$1.env.ConEmuTask==="{cmd::Cmder}"||y$1.env.TERM_PROGRAM==="Terminus-Sublime"||y$1.env.TERM_PROGRAM==="vscode"||y$1.env.TERM==="xterm-256color"||y$1.env.TERM==="alacritty"||y$1.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}const V=ce(),u=(t,n)=>V?t:n,le=u("\u25C6","*"),L=u("\u25A0","x"),W=u("\u25B2","x"),C=u("\u25C7","o"),ue=u("\u250C","T"),o=u("\u2502","|"),d=u("\u2514","\u2014"),k=u("\u25CF",">"),P=u("\u25CB"," "),_=u("\u2500","-"),me=u("\u256E","+"),de=u("\u251C","+"),pe=u("\u256F","+"),q=u("\u25CF","\u2022"),D=u("\u25C6","*"),U=u("\u25B2","!"),K=u("\u25A0","x"),b=t=>{switch(t){case "initial":case "active":return color2.cyan(le);case "cancel":return color2.red(L);case "error":return color2.yellow(W);case "submit":return color2.green(C)}},G=t=>{const{cursor:n,options:r,style:i}=t,s=t.maxItems??Number.POSITIVE_INFINITY,c=Math.max(process.stdout.rows-4,0),a=Math.min(c,Math.max(s,5));let l=0;n>=l+a-3?l=Math.max(Math.min(n-a+3,r.length-a),0):n<l+2&&(l=Math.max(n-2,0));const $=a<r.length&&l>0,g=a<r.length&&l+a<r.length;return r.slice(l,l+a).map((p,v,f)=>{const j=v===0&&$,E=v===f.length-1&&g;return j||E?color2.dim("..."):i(p,v+l===n)})},he=t=>new RD({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,render(){const n=`${color2.gray(o)}
388
388
  ${b(this.state)} ${t.message}
@@ -392,7 +392,12 @@ ${color2.yellow(d)} ${color2.yellow(this.error)}
392
392
  `;case "submit":return `${n}${color2.gray(o)} ${color2.dim(this.value||t.placeholder)}`;case "cancel":return `${n}${color2.gray(o)} ${color2.strikethrough(color2.dim(this.value??""))}${this.value?.trim()?`
393
393
  ${color2.gray(o)}`:""}`;default:return `${n}${color2.cyan(o)} ${i}
394
394
  ${color2.cyan(d)}
395
- `}}}).prompt(),ve=t=>{const n=(r,i)=>{const s=r.label??String(r.value);switch(i){case "selected":return `${color2.dim(s)}`;case "active":return `${color2.green(k)} ${s} ${r.hint?color2.dim(`(${r.hint})`):""}`;case "cancelled":return `${color2.strikethrough(color2.dim(s))}`;default:return `${color2.dim(P)} ${color2.dim(s)}`}};return new LD({options:t.options,initialValue:t.initialValue,render(){const r=`${color2.gray(o)}
395
+ `}}}).prompt(),ye=t=>{const n=t.active??"Yes",r=t.inactive??"No";return new dD({active:n,inactive:r,initialValue:t.initialValue??true,render(){const i=`${color2.gray(o)}
396
+ ${b(this.state)} ${t.message}
397
+ `,s=this.value?n:r;switch(this.state){case "submit":return `${i}${color2.gray(o)} ${color2.dim(s)}`;case "cancel":return `${i}${color2.gray(o)} ${color2.strikethrough(color2.dim(s))}
398
+ ${color2.gray(o)}`;default:return `${i}${color2.cyan(o)} ${this.value?`${color2.green(k)} ${n}`:`${color2.dim(P)} ${color2.dim(n)}`} ${color2.dim("/")} ${this.value?`${color2.dim(P)} ${color2.dim(r)}`:`${color2.green(k)} ${r}`}
399
+ ${color2.cyan(d)}
400
+ `}}}).prompt()},ve=t=>{const n=(r,i)=>{const s=r.label??String(r.value);switch(i){case "selected":return `${color2.dim(s)}`;case "active":return `${color2.green(k)} ${s} ${r.hint?color2.dim(`(${r.hint})`):""}`;case "cancelled":return `${color2.strikethrough(color2.dim(s))}`;default:return `${color2.dim(P)} ${color2.dim(s)}`}};return new LD({options:t.options,initialValue:t.initialValue,render(){const r=`${color2.gray(o)}
396
401
  ${b(this.state)} ${t.message}
397
402
  `;switch(this.state){case "submit":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"selected")}`;case "cancel":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"cancelled")}
398
403
  ${color2.gray(o)}`;default:return `${r}${color2.cyan(o)} ${G({cursor:this.cursor,options:this.options,maxItems:t.maxItems,style:(i,s)=>n(i,s?"active":"inactive")}).join(`
@@ -887,6 +892,7 @@ class YoctoSpinner {
887
892
  #exitHandlerBound;
888
893
  #isInteractive;
889
894
  #lastSpinnerFrameTime = 0;
895
+ #isSpinning = false;
890
896
 
891
897
  constructor(options = {}) {
892
898
  const spinner = options.spinner ?? defaultSpinner;
@@ -908,13 +914,17 @@ class YoctoSpinner {
908
914
  return this;
909
915
  }
910
916
 
917
+ this.#isSpinning = true;
911
918
  this.#hideCursor();
912
919
  this.#render();
913
920
  this.#subscribeToProcessEvents();
914
921
 
915
- this.#timer = setInterval(() => {
916
- this.#render();
917
- }, this.#interval);
922
+ // Only start the timer in interactive mode
923
+ if (this.#isInteractive) {
924
+ this.#timer = setInterval(() => {
925
+ this.#render();
926
+ }, this.#interval);
927
+ }
918
928
 
919
929
  return this;
920
930
  }
@@ -924,8 +934,12 @@ class YoctoSpinner {
924
934
  return this;
925
935
  }
926
936
 
927
- clearInterval(this.#timer);
928
- this.#timer = undefined;
937
+ this.#isSpinning = false;
938
+ if (this.#timer) {
939
+ clearInterval(this.#timer);
940
+ this.#timer = undefined;
941
+ }
942
+
929
943
  this.#showCursor();
930
944
  this.clear();
931
945
  this.#unsubscribeFromProcessEvents();
@@ -958,7 +972,7 @@ class YoctoSpinner {
958
972
  }
959
973
 
960
974
  get isSpinning() {
961
- return this.#timer !== undefined;
975
+ return this.#isSpinning;
962
976
  }
963
977
 
964
978
  get text() {
@@ -1130,10 +1144,15 @@ var MastraLogger = class {
1130
1144
  }
1131
1145
  };
1132
1146
 
1133
- var PinoLogger = class extends MastraLogger {
1147
+ var PinoLogger = class _PinoLogger extends MastraLogger {
1134
1148
  logger;
1135
1149
  constructor(options = {}) {
1136
1150
  super(options);
1151
+ const internalOptions = options;
1152
+ if (internalOptions._logger) {
1153
+ this.logger = internalOptions._logger;
1154
+ return;
1155
+ }
1137
1156
  let prettyStream = void 0;
1138
1157
  if (!options.overrideDefaultTransports) {
1139
1158
  prettyStream = pretty({
@@ -1150,7 +1169,8 @@ var PinoLogger = class extends MastraLogger {
1150
1169
  {
1151
1170
  name: options.name || "app",
1152
1171
  level: options.level || LogLevel.INFO,
1153
- formatters: options.formatters
1172
+ formatters: options.formatters,
1173
+ redact: options.redact
1154
1174
  },
1155
1175
  options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
1156
1176
  ...transportsAry.map(([, transport]) => ({
@@ -1164,6 +1184,38 @@ var PinoLogger = class extends MastraLogger {
1164
1184
  ])
1165
1185
  );
1166
1186
  }
1187
+ /**
1188
+ * Creates a child logger with additional bound context.
1189
+ * All logs from the child logger will include the bound context.
1190
+ *
1191
+ * @param bindings - Key-value pairs to include in all logs from this child logger
1192
+ * @returns A new PinoLogger instance with the bound context
1193
+ *
1194
+ * @example
1195
+ * ```typescript
1196
+ * const baseLogger = new PinoLogger({ name: 'MyApp' });
1197
+ *
1198
+ * // Create module-scoped logger
1199
+ * const serviceLogger = baseLogger.child({ module: 'UserService' });
1200
+ * serviceLogger.info('User created', { userId: '123' });
1201
+ * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }
1202
+ *
1203
+ * // Create request-scoped logger
1204
+ * const requestLogger = baseLogger.child({ requestId: req.id });
1205
+ * requestLogger.error('Request failed', { err: error });
1206
+ * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }
1207
+ * ```
1208
+ */
1209
+ child(bindings) {
1210
+ const childPino = this.logger.child(bindings);
1211
+ const childOptions = {
1212
+ name: this.name,
1213
+ level: this.level,
1214
+ transports: Object.fromEntries(this.transports),
1215
+ _logger: childPino
1216
+ };
1217
+ return new _PinoLogger(childOptions);
1218
+ }
1167
1219
  debug(message, args = {}) {
1168
1220
  this.logger.debug(args, message);
1169
1221
  }
@@ -1178,118 +1230,8 @@ var PinoLogger = class extends MastraLogger {
1178
1230
  }
1179
1231
  };
1180
1232
 
1181
- var args = ["-y", "@mastra/mcp-docs-server"];
1182
- var createMcpConfig = (editor) => {
1183
- if (editor === "vscode") {
1184
- return {
1185
- servers: {
1186
- mastra: process.platform === `win32` ? {
1187
- command: "cmd",
1188
- args: ["/c", "npx", ...args],
1189
- type: "stdio"
1190
- } : {
1191
- command: "npx",
1192
- args,
1193
- type: "stdio"
1194
- }
1195
- }
1196
- };
1197
- }
1198
- return {
1199
- mcpServers: {
1200
- mastra: {
1201
- command: "npx",
1202
- args
1203
- }
1204
- }
1205
- };
1206
- };
1207
- function makeConfig(original, editor) {
1208
- if (editor === "vscode") {
1209
- return {
1210
- ...original,
1211
- servers: {
1212
- ...original?.servers || {},
1213
- ...createMcpConfig(editor).servers
1214
- }
1215
- };
1216
- }
1217
- return {
1218
- ...original,
1219
- mcpServers: {
1220
- ...original?.mcpServers || {},
1221
- ...createMcpConfig(editor).mcpServers
1222
- }
1223
- };
1224
- }
1225
- async function writeMergedConfig(configPath, editor) {
1226
- const configExists = existsSync(configPath);
1227
- const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
1228
- await ensureFile(configPath);
1229
- await writeJSON(configPath, config, {
1230
- spaces: 2
1231
- });
1232
- }
1233
- var windsurfGlobalMCPConfigPath = path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1234
- var cursorGlobalMCPConfigPath = path.join(os.homedir(), ".cursor", "mcp.json");
1235
- path.join(process.cwd(), ".vscode", "mcp.json");
1236
- var vscodeGlobalMCPConfigPath = path.join(
1237
- os.homedir(),
1238
- process.platform === "win32" ? path.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path.join("Library", "Application Support", "Code", "User", "settings.json") : path.join(".config", "Code", "User", "settings.json")
1239
- );
1240
- async function installMastraDocsMCPServer({ editor, directory }) {
1241
- if (editor === `cursor`) {
1242
- await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
1243
- }
1244
- if (editor === `vscode`) {
1245
- await writeMergedConfig(path.join(directory, ".vscode", "mcp.json"), "vscode");
1246
- }
1247
- if (editor === `cursor-global`) {
1248
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1249
- if (alreadyInstalled) {
1250
- return;
1251
- }
1252
- await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
1253
- }
1254
- if (editor === `windsurf`) {
1255
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1256
- if (alreadyInstalled) {
1257
- return;
1258
- }
1259
- await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
1260
- }
1261
- }
1262
- async function globalMCPIsAlreadyInstalled(editor) {
1263
- let configPath = ``;
1264
- if (editor === "windsurf") {
1265
- configPath = windsurfGlobalMCPConfigPath;
1266
- } else if (editor === "cursor-global") {
1267
- configPath = cursorGlobalMCPConfigPath;
1268
- } else if (editor === "vscode") {
1269
- configPath = vscodeGlobalMCPConfigPath;
1270
- }
1271
- if (!configPath || !existsSync(configPath)) {
1272
- return false;
1273
- }
1274
- try {
1275
- const configContents = await readJSON(configPath);
1276
- if (!configContents) return false;
1277
- if (editor === "vscode") {
1278
- if (!configContents.servers) return false;
1279
- const hasMastraMCP2 = Object.values(configContents.servers).some(
1280
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1281
- );
1282
- return hasMastraMCP2;
1283
- }
1284
- if (!configContents?.mcpServers) return false;
1285
- const hasMastraMCP = Object.values(configContents.mcpServers).some(
1286
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1287
- );
1288
- return hasMastraMCP;
1289
- } catch {
1290
- return false;
1291
- }
1292
- }
1233
+ var package_default = {
1234
+ version: "1.0.0-beta.10"};
1293
1235
  function getPackageManagerAddCommand(pm) {
1294
1236
  switch (pm) {
1295
1237
  case "npm":
@@ -1312,11 +1254,11 @@ var DepsService = class {
1312
1254
  findLockFile(dir) {
1313
1255
  const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
1314
1256
  for (const file of lockFiles) {
1315
- if (fs3__default__default.existsSync(path.join(dir, file))) {
1257
+ if (fs3__default__default.existsSync(path3.join(dir, file))) {
1316
1258
  return file;
1317
1259
  }
1318
1260
  }
1319
- const parentDir = path.resolve(dir, "..");
1261
+ const parentDir = path3.resolve(dir, "..");
1320
1262
  if (parentDir !== dir) {
1321
1263
  return this.findLockFile(parentDir);
1322
1264
  }
@@ -1349,7 +1291,7 @@ var DepsService = class {
1349
1291
  }
1350
1292
  async checkDependencies(dependencies) {
1351
1293
  try {
1352
- const packageJsonPath = path.join(process.cwd(), "package.json");
1294
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1353
1295
  try {
1354
1296
  await fs4.access(packageJsonPath);
1355
1297
  } catch {
@@ -1369,7 +1311,7 @@ var DepsService = class {
1369
1311
  }
1370
1312
  async getProjectName() {
1371
1313
  try {
1372
- const packageJsonPath = path.join(process.cwd(), "package.json");
1314
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1373
1315
  const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
1374
1316
  const pkg = JSON.parse(packageJson);
1375
1317
  return pkg.name;
@@ -1457,8 +1399,8 @@ var FileService = class {
1457
1399
  */
1458
1400
  async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
1459
1401
  const __filename = fileURLToPath(import.meta.url);
1460
- const __dirname = path.dirname(__filename);
1461
- const filePath = path.resolve(__dirname, "starter-files", inputFile);
1402
+ const __dirname = path3.dirname(__filename);
1403
+ const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1462
1404
  const fileString = fs3__default__default.readFileSync(filePath, "utf8");
1463
1405
  if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1464
1406
  console.info(`${outputFilePath} already exists`);
@@ -1468,7 +1410,7 @@ var FileService = class {
1468
1410
  return true;
1469
1411
  }
1470
1412
  async setupEnvFile({ dbUrl }) {
1471
- const envPath = path.join(process.cwd(), ".env.development");
1413
+ const envPath = path3.join(process.cwd(), ".env.development");
1472
1414
  await fsExtra.ensureFile(envPath);
1473
1415
  const fileEnvService = new FileEnvService(envPath);
1474
1416
  await fileEnvService.setEnvValue("DB_URL", dbUrl);
@@ -1492,21 +1434,142 @@ var FileService = class {
1492
1434
  fs3__default__default.writeFileSync(filePath, fileContent);
1493
1435
  }
1494
1436
  };
1437
+ var createArgs = (versionTag) => {
1438
+ const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1439
+ return ["-y", packageName];
1440
+ };
1441
+ var createMcpConfig = (editor, versionTag) => {
1442
+ const args = createArgs(versionTag);
1443
+ if (editor === "vscode") {
1444
+ return {
1445
+ servers: {
1446
+ mastra: process.platform === `win32` ? {
1447
+ command: "cmd",
1448
+ args: ["/c", "npx", ...args],
1449
+ type: "stdio"
1450
+ } : {
1451
+ command: "npx",
1452
+ args,
1453
+ type: "stdio"
1454
+ }
1455
+ }
1456
+ };
1457
+ }
1458
+ return {
1459
+ mcpServers: {
1460
+ mastra: {
1461
+ command: "npx",
1462
+ args
1463
+ }
1464
+ }
1465
+ };
1466
+ };
1467
+ function makeConfig(original, editor, versionTag) {
1468
+ if (editor === "vscode") {
1469
+ return {
1470
+ ...original,
1471
+ servers: {
1472
+ ...original?.servers || {},
1473
+ ...createMcpConfig(editor, versionTag).servers
1474
+ }
1475
+ };
1476
+ }
1477
+ return {
1478
+ ...original,
1479
+ mcpServers: {
1480
+ ...original?.mcpServers || {},
1481
+ ...createMcpConfig(editor, versionTag).mcpServers
1482
+ }
1483
+ };
1484
+ }
1485
+ async function writeMergedConfig(configPath, editor, versionTag) {
1486
+ const configExists = existsSync(configPath);
1487
+ const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor, versionTag);
1488
+ await ensureFile(configPath);
1489
+ await writeJSON(configPath, config, {
1490
+ spaces: 2
1491
+ });
1492
+ }
1493
+ var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1494
+ var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1495
+ path3.join(process.cwd(), ".vscode", "mcp.json");
1496
+ var vscodeGlobalMCPConfigPath = path3.join(
1497
+ os.homedir(),
1498
+ process.platform === "win32" ? path3.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path3.join("Library", "Application Support", "Code", "User", "settings.json") : path3.join(".config", "Code", "User", "settings.json")
1499
+ );
1500
+ async function installMastraDocsMCPServer({
1501
+ editor,
1502
+ directory,
1503
+ versionTag
1504
+ }) {
1505
+ if (editor === `cursor`) {
1506
+ await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor", versionTag);
1507
+ }
1508
+ if (editor === `vscode`) {
1509
+ await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode", versionTag);
1510
+ }
1511
+ if (editor === `cursor-global`) {
1512
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1513
+ if (alreadyInstalled) {
1514
+ return;
1515
+ }
1516
+ await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global", versionTag);
1517
+ }
1518
+ if (editor === `windsurf`) {
1519
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1520
+ if (alreadyInstalled) {
1521
+ return;
1522
+ }
1523
+ await writeMergedConfig(windsurfGlobalMCPConfigPath, editor, versionTag);
1524
+ }
1525
+ }
1526
+ async function globalMCPIsAlreadyInstalled(editor, versionTag) {
1527
+ let configPath = ``;
1528
+ if (editor === "windsurf") {
1529
+ configPath = windsurfGlobalMCPConfigPath;
1530
+ } else if (editor === "cursor-global") {
1531
+ configPath = cursorGlobalMCPConfigPath;
1532
+ } else if (editor === "vscode") {
1533
+ configPath = vscodeGlobalMCPConfigPath;
1534
+ }
1535
+ if (!configPath || !existsSync(configPath)) {
1536
+ return false;
1537
+ }
1538
+ try {
1539
+ const configContents = await readJSON(configPath);
1540
+ if (!configContents) return false;
1541
+ const expectedPackage = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1542
+ if (editor === "vscode") {
1543
+ if (!configContents.servers) return false;
1544
+ const hasMastraMCP2 = Object.values(configContents.servers).some(
1545
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1546
+ );
1547
+ return hasMastraMCP2;
1548
+ }
1549
+ if (!configContents?.mcpServers) return false;
1550
+ const hasMastraMCP = Object.values(configContents.mcpServers).some(
1551
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1552
+ );
1553
+ return hasMastraMCP;
1554
+ } catch {
1555
+ return false;
1556
+ }
1557
+ }
1495
1558
  var exec = util.promisify(child_process.exec);
1496
1559
  var getModelIdentifier = (llmProvider) => {
1497
- if (llmProvider === "openai") {
1498
- return `'openai/gpt-4o-mini'`;
1499
- } else if (llmProvider === "anthropic") {
1500
- return `'anthropic/claude-sonnet-4-5-20250929'`;
1560
+ let model = "openai/gpt-4o";
1561
+ if (llmProvider === "anthropic") {
1562
+ model = "anthropic/claude-sonnet-4-5";
1501
1563
  } else if (llmProvider === "groq") {
1502
- return `'groq/llama-3.3-70b-versatile'`;
1564
+ model = "groq/llama-3.3-70b-versatile";
1503
1565
  } else if (llmProvider === "google") {
1504
- return `'google/gemini-2.5-pro'`;
1566
+ model = "google/gemini-2.5-pro";
1505
1567
  } else if (llmProvider === "cerebras") {
1506
- return `'cerebras/llama-3.3-70b'`;
1568
+ model = "cerebras/llama-3.3-70b";
1507
1569
  } else if (llmProvider === "mistral") {
1508
- return `'mistral/mistral-medium-2508'`;
1570
+ model = "mistral/mistral-medium-2508";
1509
1571
  }
1572
+ return model;
1510
1573
  };
1511
1574
  async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
1512
1575
  const modelString = getModelIdentifier(llmProvider);
@@ -1535,7 +1598,7 @@ export const weatherAgent = new Agent({
1535
1598
  id: 'weather-agent',
1536
1599
  name: 'Weather Agent',
1537
1600
  instructions: \`${instructions}\`,
1538
- model: ${modelString},
1601
+ model: '${modelString}',
1539
1602
  ${addExampleTool ? "tools: { weatherTool }," : ""}
1540
1603
  ${addScorers ? `scorers: {
1541
1604
  toolCallAppropriateness: {
@@ -1794,7 +1857,7 @@ export const translationScorer = createScorer({
1794
1857
  description: 'Checks that non-English location names are translated and used correctly',
1795
1858
  type: 'agent',
1796
1859
  judge: {
1797
- model: ${modelString},
1860
+ model: '${modelString}',
1798
1861
  instructions:
1799
1862
  'You are an expert evaluator of translation quality for geographic locations. ' +
1800
1863
  'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
@@ -1891,7 +1954,7 @@ var writeIndexFile = async ({
1891
1954
  addScorers
1892
1955
  }) => {
1893
1956
  const indexPath = dirPath + "/index.ts";
1894
- const destPath = path.join(indexPath);
1957
+ const destPath = path3.join(indexPath);
1895
1958
  try {
1896
1959
  await fs4.writeFile(destPath, "");
1897
1960
  const filteredExports = [
@@ -1974,7 +2037,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
1974
2037
  };
1975
2038
  var createMastraDir = async (directory) => {
1976
2039
  let dir = directory.trim().split("/").filter((item) => item !== "");
1977
- const dirPath = path.join(process.cwd(), ...dir, "mastra");
2040
+ const dirPath = path3.join(process.cwd(), ...dir, "mastra");
1978
2041
  try {
1979
2042
  await fs4.access(dirPath);
1980
2043
  return { ok: false };
@@ -1999,8 +2062,8 @@ var LLM_PROVIDERS = [
1999
2062
  { value: "cerebras", label: "Cerebras" },
2000
2063
  { value: "mistral", label: "Mistral" }
2001
2064
  ];
2002
- var interactivePrompt = async (args2 = {}) => {
2003
- const { skip = {}, options: { showBanner = true } = {} } = args2;
2065
+ var interactivePrompt = async (args = {}) => {
2066
+ const { skip = {}, options: { showBanner = true } = {} } = args;
2004
2067
  if (showBanner) {
2005
2068
  Ie(color2.inverse(" Mastra Init "));
2006
2069
  }
@@ -2038,46 +2101,29 @@ var interactivePrompt = async (args2 = {}) => {
2038
2101
  return void 0;
2039
2102
  },
2040
2103
  configureEditorWithDocsMCP: async () => {
2041
- const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
2042
- const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
2043
- const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
2044
2104
  const editor = await ve({
2045
2105
  message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
2046
2106
  options: [
2047
2107
  { value: "skip", label: "Skip for now", hint: "default" },
2048
2108
  {
2049
2109
  value: "cursor",
2050
- label: "Cursor (project only)",
2051
- hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
2110
+ label: "Cursor (project only)"
2052
2111
  },
2053
2112
  {
2054
2113
  value: "cursor-global",
2055
- label: "Cursor (global, all projects)",
2056
- hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
2114
+ label: "Cursor (global, all projects)"
2057
2115
  },
2058
2116
  {
2059
2117
  value: "windsurf",
2060
- label: "Windsurf",
2061
- hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
2118
+ label: "Windsurf"
2062
2119
  },
2063
2120
  {
2064
2121
  value: "vscode",
2065
- label: "VSCode",
2066
- hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
2122
+ label: "VSCode"
2067
2123
  }
2068
2124
  ]
2069
2125
  });
2070
2126
  if (editor === `skip`) return void 0;
2071
- if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
2072
- M.message(`
2073
- Windsurf is already installed, skipping.`);
2074
- return void 0;
2075
- }
2076
- if (editor === `vscode` && vscodeIsAlreadyInstalled) {
2077
- M.message(`
2078
- VSCode is already installed, skipping.`);
2079
- return void 0;
2080
- }
2081
2127
  if (editor === `cursor`) {
2082
2128
  M.message(
2083
2129
  `
@@ -2086,19 +2132,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
2086
2132
  );
2087
2133
  }
2088
2134
  if (editor === `cursor-global`) {
2089
- const confirm = await ve({
2135
+ const confirm3 = await ve({
2090
2136
  message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
2091
2137
  options: [
2092
2138
  { value: "yes", label: "Yes, I understand" },
2093
2139
  { value: "skip", label: "No, skip for now" }
2094
2140
  ]
2095
2141
  });
2096
- if (confirm !== `yes`) {
2142
+ if (confirm3 !== `yes`) {
2097
2143
  return void 0;
2098
2144
  }
2099
2145
  }
2100
2146
  if (editor === `windsurf`) {
2101
- const confirm = await ve({
2147
+ const confirm3 = await ve({
2102
2148
  message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
2103
2149
  This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
2104
2150
  options: [
@@ -2106,11 +2152,17 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2106
2152
  { value: "skip", label: "No, skip for now" }
2107
2153
  ]
2108
2154
  });
2109
- if (confirm !== `yes`) {
2155
+ if (confirm3 !== `yes`) {
2110
2156
  return void 0;
2111
2157
  }
2112
2158
  }
2113
2159
  return editor;
2160
+ },
2161
+ initGit: async () => {
2162
+ return ye({
2163
+ message: "Initialize a new git repository?",
2164
+ initialValue: true
2165
+ });
2114
2166
  }
2115
2167
  },
2116
2168
  {
@@ -2125,6 +2177,9 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2125
2177
  function getPackageManager() {
2126
2178
  const userAgent = process.env.npm_config_user_agent || "";
2127
2179
  const execPath = process.env.npm_execpath || "";
2180
+ if (userAgent.includes("bun")) {
2181
+ return "bun";
2182
+ }
2128
2183
  if (userAgent.includes("yarn")) {
2129
2184
  return "yarn";
2130
2185
  }
@@ -2134,6 +2189,9 @@ function getPackageManager() {
2134
2189
  if (userAgent.includes("npm")) {
2135
2190
  return "npm";
2136
2191
  }
2192
+ if (execPath.includes("bun")) {
2193
+ return "bun";
2194
+ }
2137
2195
  if (execPath.includes("yarn")) {
2138
2196
  return "yarn";
2139
2197
  }
@@ -2145,6 +2203,20 @@ function getPackageManager() {
2145
2203
  }
2146
2204
  return "npm";
2147
2205
  }
2206
+ async function gitInit({ cwd }) {
2207
+ await execa("git", ["init"], { cwd, stdio: "ignore" });
2208
+ await execa("git", ["add", "-A"], { cwd, stdio: "ignore" });
2209
+ await execa(
2210
+ "git",
2211
+ [
2212
+ "commit",
2213
+ "-m",
2214
+ '"Initial commit from Mastra"',
2215
+ '--author="dane-ai-mastra[bot] <dane-ai-mastra[bot]@users.noreply.github.com>"'
2216
+ ],
2217
+ { cwd, stdio: "ignore" }
2218
+ );
2219
+ }
2148
2220
  var logger = createLogger(false);
2149
2221
  function createLogger(debug = false) {
2150
2222
  return new PinoLogger({
@@ -2154,19 +2226,23 @@ function createLogger(debug = false) {
2154
2226
  }
2155
2227
  var exec2 = util.promisify(child_process.exec);
2156
2228
  async function cloneTemplate(options) {
2157
- const { template, projectName, targetDir } = options;
2158
- const projectPath = targetDir ? path.resolve(targetDir, projectName) : path.resolve(projectName);
2229
+ const { template, projectName, targetDir, branch, llmProvider } = options;
2230
+ const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
2159
2231
  const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
2160
2232
  try {
2161
2233
  if (await directoryExists(projectPath)) {
2162
2234
  spinner4.error(`Directory ${projectName} already exists`);
2163
2235
  throw new Error(`Directory ${projectName} already exists`);
2164
2236
  }
2165
- await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
2237
+ await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
2166
2238
  await updatePackageJson(projectPath, projectName);
2167
- const envExamplePath = path.join(projectPath, ".env.example");
2239
+ const envExamplePath = path3.join(projectPath, ".env.example");
2168
2240
  if (await fileExists(envExamplePath)) {
2169
- await fs4.copyFile(envExamplePath, path.join(projectPath, ".env"));
2241
+ const envPath = path3.join(projectPath, ".env");
2242
+ await fs4.copyFile(envExamplePath, envPath);
2243
+ if (llmProvider) {
2244
+ await updateEnvFile(envPath, llmProvider);
2245
+ }
2170
2246
  }
2171
2247
  spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
2172
2248
  return projectPath;
@@ -2191,21 +2267,27 @@ async function fileExists(filePath) {
2191
2267
  return false;
2192
2268
  }
2193
2269
  }
2194
- async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
2270
+ async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
2195
2271
  await fs4.mkdir(targetPath, { recursive: true });
2196
2272
  try {
2197
2273
  const degitRepo = repoUrl.replace("https://github.com/", "");
2198
- const degitCommand = shellQuote2.quote(["npx", "degit", degitRepo, targetPath]);
2274
+ const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
2275
+ const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
2199
2276
  await exec2(degitCommand, {
2200
2277
  cwd: process.cwd()
2201
2278
  });
2202
2279
  } catch {
2203
2280
  try {
2204
- const gitCommand = shellQuote2.quote(["git", "clone", repoUrl, targetPath]);
2281
+ const gitArgs = ["git", "clone"];
2282
+ if (branch) {
2283
+ gitArgs.push("--branch", branch);
2284
+ }
2285
+ gitArgs.push(repoUrl, targetPath);
2286
+ const gitCommand = shellQuote2.quote(gitArgs);
2205
2287
  await exec2(gitCommand, {
2206
2288
  cwd: process.cwd()
2207
2289
  });
2208
- const gitDir = path.join(targetPath, ".git");
2290
+ const gitDir = path3.join(targetPath, ".git");
2209
2291
  if (await directoryExists(gitDir)) {
2210
2292
  await fs4.rm(gitDir, { recursive: true, force: true });
2211
2293
  }
@@ -2215,7 +2297,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
2215
2297
  }
2216
2298
  }
2217
2299
  async function updatePackageJson(projectPath, projectName) {
2218
- const packageJsonPath = path.join(projectPath, "package.json");
2300
+ const packageJsonPath = path3.join(projectPath, "package.json");
2219
2301
  try {
2220
2302
  const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
2221
2303
  const packageJson = JSON.parse(packageJsonContent);
@@ -2225,6 +2307,22 @@ async function updatePackageJson(projectPath, projectName) {
2225
2307
  logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
2226
2308
  }
2227
2309
  }
2310
+ async function updateEnvFile(envPath, llmProvider) {
2311
+ try {
2312
+ const envContent = await fs4.readFile(envPath, "utf-8");
2313
+ const modelString = getModelIdentifier(llmProvider);
2314
+ if (!modelString) {
2315
+ logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
2316
+ return;
2317
+ }
2318
+ const modelValue = modelString.replace(/'/g, "");
2319
+ const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
2320
+ await fs4.writeFile(envPath, updatedContent, "utf-8");
2321
+ logger.info(`Updated MODEL in .env to ${modelValue}`);
2322
+ } catch (error) {
2323
+ logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
2324
+ }
2325
+ }
2228
2326
  async function installDependencies(projectPath, packageManager) {
2229
2327
  const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
2230
2328
  try {
@@ -2310,7 +2408,8 @@ var init = async ({
2310
2408
  llmApiKey,
2311
2409
  addExample = false,
2312
2410
  configureEditorWithDocsMCP,
2313
- versionTag
2411
+ versionTag,
2412
+ initGit = false
2314
2413
  }) => {
2315
2414
  s.start("Initializing Mastra");
2316
2415
  const packageVersionTag = versionTag ? `@${versionTag}` : "";
@@ -2364,10 +2463,21 @@ var init = async ({
2364
2463
  if (configureEditorWithDocsMCP) {
2365
2464
  await installMastraDocsMCPServer({
2366
2465
  editor: configureEditorWithDocsMCP,
2367
- directory: process.cwd()
2466
+ directory: process.cwd(),
2467
+ versionTag
2368
2468
  });
2369
2469
  }
2370
2470
  s.stop();
2471
+ if (initGit) {
2472
+ const s2 = Y();
2473
+ try {
2474
+ s2.start("Initializing git repository");
2475
+ await gitInit({ cwd: process.cwd() });
2476
+ s2.stop("Git repository initialized");
2477
+ } catch {
2478
+ s2.stop();
2479
+ }
2480
+ }
2371
2481
  if (!llmApiKey) {
2372
2482
  Me(`
2373
2483
  ${color2.green("Mastra initialized successfully!")}
@@ -2413,6 +2523,32 @@ var execWithTimeout = async (command, timeoutMs) => {
2413
2523
  throw error;
2414
2524
  }
2415
2525
  };
2526
+ async function getInitCommand(pm) {
2527
+ switch (pm) {
2528
+ case "npm":
2529
+ return "npm init -y";
2530
+ case "pnpm":
2531
+ return "pnpm init";
2532
+ case "yarn":
2533
+ return "yarn init -y";
2534
+ case "bun":
2535
+ return "bun init -y";
2536
+ default:
2537
+ return "npm init -y";
2538
+ }
2539
+ }
2540
+ async function initializePackageJson(pm) {
2541
+ const initCommand = await getInitCommand(pm);
2542
+ await exec3(initCommand);
2543
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
2544
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
2545
+ packageJson.type = "module";
2546
+ packageJson.engines = {
2547
+ ...packageJson.engines,
2548
+ node: ">=22.13.0"
2549
+ };
2550
+ await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2551
+ }
2416
2552
  async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
2417
2553
  let installCommand = getPackageManagerAddCommand(pm);
2418
2554
  if (isDev) {
@@ -2459,7 +2595,7 @@ var createMastraProject = async ({
2459
2595
  xe("Operation cancelled");
2460
2596
  process.exit(0);
2461
2597
  }
2462
- let result;
2598
+ let result = void 0;
2463
2599
  if (needsInteractive) {
2464
2600
  result = await interactivePrompt({
2465
2601
  options: { showBanner: false },
@@ -2467,10 +2603,13 @@ var createMastraProject = async ({
2467
2603
  });
2468
2604
  }
2469
2605
  const s2 = Y();
2606
+ const originalCwd = process.cwd();
2607
+ let projectPath = null;
2470
2608
  try {
2471
2609
  s2.start("Creating project");
2472
2610
  try {
2473
2611
  await fs4.mkdir(projectName);
2612
+ projectPath = path3.resolve(originalCwd, projectName);
2474
2613
  } catch (error) {
2475
2614
  if (error instanceof Error && "code" in error && error.code === "EEXIST") {
2476
2615
  s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
@@ -2485,9 +2624,7 @@ var createMastraProject = async ({
2485
2624
  const installCommand = getPackageManagerAddCommand(pm);
2486
2625
  s2.message("Initializing project structure");
2487
2626
  try {
2488
- await exec3(`npm init -y`);
2489
- await exec3(`npm pkg set type="module"`);
2490
- await exec3(`npm pkg set engines.node=">=20.9.0"`);
2627
+ await initializePackageJson(pm);
2491
2628
  const depsService = new DepsService();
2492
2629
  await depsService.addScriptsToPackageJson({
2493
2630
  dev: "mastra dev",
@@ -2566,44 +2703,61 @@ var createMastraProject = async ({
2566
2703
  s2.stop();
2567
2704
  const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
2568
2705
  xe(`Project creation failed: ${errorMessage}`);
2706
+ if (projectPath && fs3__default__default.existsSync(projectPath)) {
2707
+ try {
2708
+ process.chdir(originalCwd);
2709
+ await fs4.rm(projectPath, { recursive: true, force: true });
2710
+ } catch (cleanupError) {
2711
+ console.error(
2712
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
2713
+ );
2714
+ }
2715
+ }
2569
2716
  process.exit(1);
2570
2717
  }
2571
2718
  };
2572
- var create = async (args2) => {
2573
- if (args2.template !== void 0) {
2574
- await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
2719
+ var version$1 = package_default.version;
2720
+ var create = async (args) => {
2721
+ if (args.template !== void 0) {
2722
+ await createFromTemplate({
2723
+ projectName: args.projectName,
2724
+ template: args.template,
2725
+ timeout: args.timeout,
2726
+ injectedAnalytics: args.analytics,
2727
+ llmProvider: args.llmProvider
2728
+ });
2575
2729
  return;
2576
2730
  }
2577
- const needsInteractive = args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0;
2731
+ const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
2578
2732
  const { projectName, result } = await createMastraProject({
2579
- projectName: args2?.projectName,
2580
- createVersionTag: args2?.createVersionTag,
2581
- timeout: args2?.timeout,
2582
- llmProvider: args2?.llmProvider,
2583
- llmApiKey: args2?.llmApiKey,
2733
+ projectName: args?.projectName,
2734
+ createVersionTag: args?.createVersionTag,
2735
+ timeout: args?.timeout,
2736
+ llmProvider: args?.llmProvider,
2737
+ llmApiKey: args?.llmApiKey,
2584
2738
  needsInteractive
2585
2739
  });
2586
- const directory = args2.directory || "src/";
2740
+ const directory = args.directory || "src/";
2587
2741
  if (needsInteractive && result) {
2588
2742
  await init({
2589
2743
  ...result,
2590
2744
  llmApiKey: result?.llmApiKey,
2591
2745
  components: ["agents", "tools", "workflows", "scorers"],
2592
2746
  addExample: true,
2593
- versionTag: args2.createVersionTag
2747
+ versionTag: args.createVersionTag
2594
2748
  });
2595
2749
  postCreate({ projectName });
2596
2750
  return;
2597
2751
  }
2598
- const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args2;
2752
+ const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
2599
2753
  await init({
2600
2754
  directory,
2601
2755
  components,
2602
2756
  llmProvider,
2603
2757
  addExample,
2604
2758
  llmApiKey,
2605
- configureEditorWithDocsMCP: args2.mcpServer,
2606
- versionTag: args2.createVersionTag
2759
+ configureEditorWithDocsMCP: args.mcpServer,
2760
+ versionTag: args.createVersionTag
2607
2761
  });
2608
2762
  postCreate({ projectName });
2609
2763
  };
@@ -2694,9 +2848,9 @@ async function createFromGitHubUrl(url) {
2694
2848
  workflows: []
2695
2849
  };
2696
2850
  }
2697
- async function createFromTemplate(args2) {
2851
+ async function createFromTemplate(args) {
2698
2852
  let selectedTemplate;
2699
- if (args2.template === true) {
2853
+ if (args.template === true) {
2700
2854
  const templates = await loadTemplates();
2701
2855
  const selected = await selectTemplate(templates);
2702
2856
  if (!selected) {
@@ -2704,11 +2858,11 @@ async function createFromTemplate(args2) {
2704
2858
  return;
2705
2859
  }
2706
2860
  selectedTemplate = selected;
2707
- } else if (args2.template && typeof args2.template === "string") {
2708
- if (isGitHubUrl(args2.template)) {
2861
+ } else if (args.template && typeof args.template === "string") {
2862
+ if (isGitHubUrl(args.template)) {
2709
2863
  const spinner4 = Y();
2710
2864
  spinner4.start("Validating GitHub repository...");
2711
- const validation = await validateGitHubProject(args2.template);
2865
+ const validation = await validateGitHubProject(args.template);
2712
2866
  if (!validation.isValid) {
2713
2867
  spinner4.stop("Validation failed");
2714
2868
  M.error("This does not appear to be a valid Mastra project:");
@@ -2716,14 +2870,14 @@ async function createFromTemplate(args2) {
2716
2870
  throw new Error("Invalid Mastra project");
2717
2871
  }
2718
2872
  spinner4.stop("Valid Mastra project \u2713");
2719
- selectedTemplate = await createFromGitHubUrl(args2.template);
2873
+ selectedTemplate = await createFromGitHubUrl(args.template);
2720
2874
  } else {
2721
2875
  const templates = await loadTemplates();
2722
- const found = findTemplateByName(templates, args2.template);
2876
+ const found = findTemplateByName(templates, args.template);
2723
2877
  if (!found) {
2724
- M.error(`Template "${args2.template}" not found. Available templates:`);
2878
+ M.error(`Template "${args.template}" not found. Available templates:`);
2725
2879
  templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2726
- throw new Error(`Template "${args2.template}" not found`);
2880
+ throw new Error(`Template "${args.template}" not found`);
2727
2881
  }
2728
2882
  selectedTemplate = found;
2729
2883
  }
@@ -2731,7 +2885,7 @@ async function createFromTemplate(args2) {
2731
2885
  if (!selectedTemplate) {
2732
2886
  throw new Error("No template selected");
2733
2887
  }
2734
- let projectName = args2.projectName;
2888
+ let projectName = args.projectName;
2735
2889
  if (!projectName) {
2736
2890
  const defaultName = getDefaultProjectName(selectedTemplate);
2737
2891
  const response = await he({
@@ -2745,19 +2899,61 @@ async function createFromTemplate(args2) {
2745
2899
  }
2746
2900
  projectName = response;
2747
2901
  }
2902
+ let llmProvider = args.llmProvider;
2903
+ if (!llmProvider) {
2904
+ const providerResponse = await ve({
2905
+ message: "Select a default provider:",
2906
+ options: LLM_PROVIDERS
2907
+ });
2908
+ if (pD(providerResponse)) {
2909
+ M.info("Project creation cancelled.");
2910
+ return;
2911
+ }
2912
+ llmProvider = providerResponse;
2913
+ }
2914
+ let initGit = false;
2915
+ const gitConfirmResult = await ye({
2916
+ message: "Initialize a new git repository?",
2917
+ initialValue: true
2918
+ });
2919
+ if (!pD(gitConfirmResult)) {
2920
+ initGit = gitConfirmResult;
2921
+ }
2922
+ let projectPath = null;
2748
2923
  try {
2749
- const analytics = args2.injectedAnalytics || getAnalytics();
2924
+ const analytics = args.injectedAnalytics || getAnalytics();
2750
2925
  if (analytics) {
2751
2926
  analytics.trackEvent("cli_template_used", {
2752
2927
  template_slug: selectedTemplate.slug,
2753
2928
  template_title: selectedTemplate.title
2754
2929
  });
2930
+ if (llmProvider) {
2931
+ analytics.trackEvent("cli_model_provider_selected", {
2932
+ provider: llmProvider,
2933
+ selection_method: args.llmProvider ? "cli_args" : "interactive"
2934
+ });
2935
+ }
2755
2936
  }
2756
- const projectPath = await cloneTemplate({
2937
+ const isBeta = version$1?.includes("beta") ?? false;
2938
+ const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
2939
+ const branch = isBeta && isMastraTemplate ? "beta" : void 0;
2940
+ projectPath = await cloneTemplate({
2757
2941
  template: selectedTemplate,
2758
- projectName
2942
+ projectName,
2943
+ branch,
2944
+ llmProvider
2759
2945
  });
2760
2946
  await installDependencies(projectPath);
2947
+ if (initGit) {
2948
+ const s2 = Y();
2949
+ try {
2950
+ s2.start("Initializing git repository");
2951
+ await gitInit({ cwd: projectPath });
2952
+ s2.stop("Git repository initialized");
2953
+ } catch {
2954
+ s2.stop();
2955
+ }
2956
+ }
2761
2957
  Me(`
2762
2958
  ${color2.green("Mastra template installed!")}
2763
2959
 
@@ -2766,6 +2962,17 @@ async function createFromTemplate(args2) {
2766
2962
  `);
2767
2963
  postCreate({ projectName });
2768
2964
  } catch (error) {
2965
+ if (projectPath) {
2966
+ try {
2967
+ if (fs3__default__default.existsSync(projectPath)) {
2968
+ await fs4.rm(projectPath, { recursive: true, force: true });
2969
+ }
2970
+ } catch (cleanupError) {
2971
+ console.error(
2972
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
2973
+ );
2974
+ }
2975
+ }
2769
2976
  M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
2770
2977
  throw error;
2771
2978
  }
@@ -2774,7 +2981,7 @@ async function createFromTemplate(args2) {
2774
2981
  async function getPackageVersion() {
2775
2982
  const __filename = fileURLToPath(import.meta.url);
2776
2983
  const __dirname = dirname(__filename);
2777
- const pkgJsonPath = path.join(__dirname, "..", "package.json");
2984
+ const pkgJsonPath = path3.join(__dirname, "..", "package.json");
2778
2985
  const content = await fsExtra$1.readJSON(pkgJsonPath);
2779
2986
  return content.version;
2780
2987
  }