create-mastra 0.0.0-taofeeq-fix-tool-call-showing-after-message-20250806184630 → 0.0.0-testing-cloud-studios-20260114234039

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
@@ -1,26 +1,26 @@
1
1
  #! /usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import { randomUUID } from 'node:crypto';
4
- import * as fs4__default from 'node:fs';
5
- import fs4__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import * as fs3__default from 'node:fs';
5
+ import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
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 fs from 'node:fs/promises';
16
16
  import child_process from 'node:child_process';
17
17
  import tty from 'node:tty';
18
+ import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
19
+ import prettier from 'prettier';
20
+ import { execa } from 'execa';
21
+ import fsExtra$1 from 'fs-extra';
18
22
  import pino from 'pino';
19
23
  import pretty from 'pino-pretty';
20
- import { execa } from 'execa';
21
- import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
22
- import prettier from 'prettier';
23
- import fsExtra from 'fs-extra';
24
24
 
25
25
  var __filename = fileURLToPath(import.meta.url);
26
26
  var __dirname = path3.dirname(__filename);
@@ -105,6 +105,10 @@ var PosthogAnalytics = class {
105
105
  machine_id: os.hostname()
106
106
  };
107
107
  }
108
+ getDurationMs(startTime) {
109
+ const [seconds, nanoseconds] = process.hrtime(startTime);
110
+ return seconds * 1e3 + nanoseconds / 1e6;
111
+ }
108
112
  captureSessionStart() {
109
113
  if (!this.client) {
110
114
  return;
@@ -173,8 +177,7 @@ var PosthogAnalytics = class {
173
177
  const startTime = process.hrtime();
174
178
  try {
175
179
  const result = await execution();
176
- const [seconds, nanoseconds] = process.hrtime(startTime);
177
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
180
+ const durationMs = this.getDurationMs(startTime);
178
181
  this.trackCommand({
179
182
  command,
180
183
  args,
@@ -184,8 +187,7 @@ var PosthogAnalytics = class {
184
187
  });
185
188
  return result;
186
189
  } catch (error) {
187
- const [seconds, nanoseconds] = process.hrtime(startTime);
188
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
190
+ const durationMs = this.getDurationMs(startTime);
189
191
  this.trackCommand({
190
192
  command,
191
193
  args,
@@ -382,7 +384,7 @@ function DD({onlyFirst:e=false}={}){const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:
382
384
  `).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
385
  `);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
386
  `).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);});}}
387
+ `)),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
388
 
387
389
  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
390
  ${b(this.state)} ${t.message}
@@ -392,7 +394,12 @@ ${color2.yellow(d)} ${color2.yellow(this.error)}
392
394
  `;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
395
  ${color2.gray(o)}`:""}`;default:return `${n}${color2.cyan(o)} ${i}
394
396
  ${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)}
397
+ `}}}).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)}
398
+ ${b(this.state)} ${t.message}
399
+ `,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))}
400
+ ${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}`}
401
+ ${color2.cyan(d)}
402
+ `}}}).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
403
  ${b(this.state)} ${t.message}
397
404
  `;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
405
  ${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(`
@@ -422,7 +429,7 @@ ${color2.gray(d)} ${t}
422
429
  `):process.stdout.write(`${w} ${l}
423
430
  `),E(),s();};return {start:H,stop:N,message:(m="")=>{l=R(m??l);}}},Ce=async(t,n)=>{const r={},i=Object.keys(t);for(const s of i){const c=t[s],a=await c({results:r})?.catch(l=>{throw l});if(typeof n?.onCancel=="function"&&pD(a)){r[s]="canceled",n.onCancel({results:r});continue}r[s]=a;}return r};
424
431
 
425
- var shellQuote$1 = {};
432
+ var shellQuote = {};
426
433
 
427
434
  var quote;
428
435
  var hasRequiredQuote;
@@ -688,16 +695,16 @@ function requireParse () {
688
695
  var hasRequiredShellQuote;
689
696
 
690
697
  function requireShellQuote () {
691
- if (hasRequiredShellQuote) return shellQuote$1;
698
+ if (hasRequiredShellQuote) return shellQuote;
692
699
  hasRequiredShellQuote = 1;
693
700
 
694
- shellQuote$1.quote = requireQuote();
695
- shellQuote$1.parse = requireParse();
696
- return shellQuote$1;
701
+ shellQuote.quote = requireQuote();
702
+ shellQuote.parse = requireParse();
703
+ return shellQuote;
697
704
  }
698
705
 
699
706
  var shellQuoteExports = requireShellQuote();
700
- var shellQuote = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
707
+ var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
701
708
 
702
709
  // eslint-disable-next-line no-warning-comments
703
710
  // TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
@@ -724,13 +731,18 @@ const format = (open, close) => {
724
731
  // Handle nested colors.
725
732
 
726
733
  // We could have done this, but it's too slow (as of Node.js 22).
727
- // return openCode + string.replaceAll(closeCode, openCode) + closeCode;
734
+ // return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
728
735
 
729
736
  let result = openCode;
730
737
  let lastIndex = 0;
731
738
 
739
+ // SGR 22 resets both bold (1) and dim (2). When we encounter a nested
740
+ // close for styles that use 22, we need to re-open the outer style.
741
+ const reopenOnNestedClose = close === 22;
742
+ const replaceCode = (reopenOnNestedClose ? closeCode : '') + openCode;
743
+
732
744
  while (index !== -1) {
733
- result += string.slice(lastIndex, index) + openCode;
745
+ result += string.slice(lastIndex, index) + replaceCode;
734
746
  lastIndex = index + closeCode.length;
735
747
  index = string.indexOf(closeCode, lastIndex);
736
748
  }
@@ -882,6 +894,7 @@ class YoctoSpinner {
882
894
  #exitHandlerBound;
883
895
  #isInteractive;
884
896
  #lastSpinnerFrameTime = 0;
897
+ #isSpinning = false;
885
898
 
886
899
  constructor(options = {}) {
887
900
  const spinner = options.spinner ?? defaultSpinner;
@@ -903,13 +916,17 @@ class YoctoSpinner {
903
916
  return this;
904
917
  }
905
918
 
919
+ this.#isSpinning = true;
906
920
  this.#hideCursor();
907
921
  this.#render();
908
922
  this.#subscribeToProcessEvents();
909
923
 
910
- this.#timer = setInterval(() => {
911
- this.#render();
912
- }, this.#interval);
924
+ // Only start the timer in interactive mode
925
+ if (this.#isInteractive) {
926
+ this.#timer = setInterval(() => {
927
+ this.#render();
928
+ }, this.#interval);
929
+ }
913
930
 
914
931
  return this;
915
932
  }
@@ -919,8 +936,12 @@ class YoctoSpinner {
919
936
  return this;
920
937
  }
921
938
 
922
- clearInterval(this.#timer);
923
- this.#timer = undefined;
939
+ this.#isSpinning = false;
940
+ if (this.#timer) {
941
+ clearInterval(this.#timer);
942
+ this.#timer = undefined;
943
+ }
944
+
924
945
  this.#showCursor();
925
946
  this.clear();
926
947
  this.#unsubscribeFromProcessEvents();
@@ -953,7 +974,7 @@ class YoctoSpinner {
953
974
  }
954
975
 
955
976
  get isSpinning() {
956
- return this.#timer !== undefined;
977
+ return this.#isSpinning;
957
978
  }
958
979
 
959
980
  get text() {
@@ -1090,11 +1111,11 @@ var MastraLogger = class {
1090
1111
  }
1091
1112
  trackException(_error) {
1092
1113
  }
1093
- async getLogs(transportId, params) {
1114
+ async listLogs(transportId, params) {
1094
1115
  if (!transportId || !this.transports.has(transportId)) {
1095
1116
  return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
1096
1117
  }
1097
- return this.transports.get(transportId).getLogs(params) ?? {
1118
+ return this.transports.get(transportId).listLogs(params) ?? {
1098
1119
  logs: [],
1099
1120
  total: 0,
1100
1121
  page: params?.page ?? 1,
@@ -1102,7 +1123,7 @@ var MastraLogger = class {
1102
1123
  hasMore: false
1103
1124
  };
1104
1125
  }
1105
- async getLogsByRunId({
1126
+ async listLogsByRunId({
1106
1127
  transportId,
1107
1128
  runId,
1108
1129
  fromDate,
@@ -1115,7 +1136,7 @@ var MastraLogger = class {
1115
1136
  if (!transportId || !this.transports.has(transportId) || !runId) {
1116
1137
  return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
1117
1138
  }
1118
- return this.transports.get(transportId).getLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
1139
+ return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
1119
1140
  logs: [],
1120
1141
  total: 0,
1121
1142
  page: page ?? 1,
@@ -1125,10 +1146,15 @@ var MastraLogger = class {
1125
1146
  }
1126
1147
  };
1127
1148
 
1128
- var PinoLogger = class extends MastraLogger {
1149
+ var PinoLogger = class _PinoLogger extends MastraLogger {
1129
1150
  logger;
1130
1151
  constructor(options = {}) {
1131
1152
  super(options);
1153
+ const internalOptions = options;
1154
+ if (internalOptions._logger) {
1155
+ this.logger = internalOptions._logger;
1156
+ return;
1157
+ }
1132
1158
  let prettyStream = void 0;
1133
1159
  if (!options.overrideDefaultTransports) {
1134
1160
  prettyStream = pretty({
@@ -1145,7 +1171,8 @@ var PinoLogger = class extends MastraLogger {
1145
1171
  {
1146
1172
  name: options.name || "app",
1147
1173
  level: options.level || LogLevel.INFO,
1148
- formatters: options.formatters
1174
+ formatters: options.formatters,
1175
+ redact: options.redact
1149
1176
  },
1150
1177
  options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
1151
1178
  ...transportsAry.map(([, transport]) => ({
@@ -1159,6 +1186,38 @@ var PinoLogger = class extends MastraLogger {
1159
1186
  ])
1160
1187
  );
1161
1188
  }
1189
+ /**
1190
+ * Creates a child logger with additional bound context.
1191
+ * All logs from the child logger will include the bound context.
1192
+ *
1193
+ * @param bindings - Key-value pairs to include in all logs from this child logger
1194
+ * @returns A new PinoLogger instance with the bound context
1195
+ *
1196
+ * @example
1197
+ * ```typescript
1198
+ * const baseLogger = new PinoLogger({ name: 'MyApp' });
1199
+ *
1200
+ * // Create module-scoped logger
1201
+ * const serviceLogger = baseLogger.child({ module: 'UserService' });
1202
+ * serviceLogger.info('User created', { userId: '123' });
1203
+ * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }
1204
+ *
1205
+ * // Create request-scoped logger
1206
+ * const requestLogger = baseLogger.child({ requestId: req.id });
1207
+ * requestLogger.error('Request failed', { err: error });
1208
+ * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }
1209
+ * ```
1210
+ */
1211
+ child(bindings) {
1212
+ const childPino = this.logger.child(bindings);
1213
+ const childOptions = {
1214
+ name: this.name,
1215
+ level: this.level,
1216
+ transports: Object.fromEntries(this.transports),
1217
+ _logger: childPino
1218
+ };
1219
+ return new _PinoLogger(childOptions);
1220
+ }
1162
1221
  debug(message, args = {}) {
1163
1222
  this.logger.debug(args, message);
1164
1223
  }
@@ -1173,194 +1232,21 @@ var PinoLogger = class extends MastraLogger {
1173
1232
  }
1174
1233
  };
1175
1234
 
1176
- function getPackageManager() {
1177
- const userAgent = process.env.npm_config_user_agent || "";
1178
- const execPath = process.env.npm_execpath || "";
1179
- if (userAgent.includes("yarn")) {
1180
- return "yarn";
1181
- }
1182
- if (userAgent.includes("pnpm")) {
1183
- return "pnpm";
1184
- }
1185
- if (userAgent.includes("npm")) {
1186
- return "npm";
1187
- }
1188
- if (execPath.includes("yarn")) {
1189
- return "yarn";
1190
- }
1191
- if (execPath.includes("pnpm")) {
1192
- return "pnpm";
1193
- }
1194
- if (execPath.includes("npm")) {
1195
- return "npm";
1196
- }
1197
- return "npm";
1198
- }
1199
- function getPackageManagerInstallCommand(pm) {
1235
+ var package_default = {
1236
+ version: "1.0.0-beta.13"};
1237
+ function getPackageManagerAddCommand(pm) {
1200
1238
  switch (pm) {
1201
1239
  case "npm":
1202
- return "install";
1240
+ return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
1203
1241
  case "yarn":
1204
1242
  return "add";
1205
1243
  case "pnpm":
1244
+ return "add --loglevel=error";
1245
+ case "bun":
1206
1246
  return "add";
1207
1247
  default:
1208
- return "install";
1209
- }
1210
- }
1211
- var logger = new PinoLogger({
1212
- name: "Mastra CLI",
1213
- level: "info"
1214
- });
1215
- var exec = util.promisify(child_process.exec);
1216
- async function cloneTemplate(options) {
1217
- const { template, projectName, targetDir } = options;
1218
- const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
1219
- const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
1220
- try {
1221
- if (await directoryExists(projectPath)) {
1222
- spinner5.error(`Directory ${projectName} already exists`);
1223
- throw new Error(`Directory ${projectName} already exists`);
1224
- }
1225
- await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
1226
- await updatePackageJson(projectPath, projectName);
1227
- const envExamplePath = path3.join(projectPath, ".env.example");
1228
- if (await fileExists(envExamplePath)) {
1229
- await fs.copyFile(envExamplePath, path3.join(projectPath, ".env"));
1230
- }
1231
- spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
1232
- return projectPath;
1233
- } catch (error) {
1234
- spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
1235
- throw error;
1236
- }
1237
- }
1238
- async function directoryExists(dirPath) {
1239
- try {
1240
- const stat = await fs.stat(dirPath);
1241
- return stat.isDirectory();
1242
- } catch {
1243
- return false;
1244
- }
1245
- }
1246
- async function fileExists(filePath) {
1247
- try {
1248
- const stat = await fs.stat(filePath);
1249
- return stat.isFile();
1250
- } catch {
1251
- return false;
1252
- }
1253
- }
1254
- async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
1255
- await fs.mkdir(targetPath, { recursive: true });
1256
- try {
1257
- const degitRepo = repoUrl.replace("https://github.com/", "");
1258
- const degitCommand = shellQuote.quote(["npx", "degit", degitRepo, targetPath]);
1259
- await exec(degitCommand, {
1260
- cwd: process.cwd()
1261
- });
1262
- } catch {
1263
- try {
1264
- const gitCommand = shellQuote.quote(["git", "clone", repoUrl, targetPath]);
1265
- await exec(gitCommand, {
1266
- cwd: process.cwd()
1267
- });
1268
- const gitDir = path3.join(targetPath, ".git");
1269
- if (await directoryExists(gitDir)) {
1270
- await fs.rm(gitDir, { recursive: true, force: true });
1271
- }
1272
- } catch (gitError) {
1273
- throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
1274
- }
1275
- }
1276
- }
1277
- async function updatePackageJson(projectPath, projectName) {
1278
- const packageJsonPath = path3.join(projectPath, "package.json");
1279
- try {
1280
- const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
1281
- const packageJson = JSON.parse(packageJsonContent);
1282
- packageJson.name = projectName;
1283
- await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
1284
- } catch (error) {
1285
- logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
1286
- }
1287
- }
1288
- async function installDependencies(projectPath, packageManager) {
1289
- const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
1290
- try {
1291
- const pm = packageManager || getPackageManager();
1292
- const installCommand = shellQuote.quote([pm, "install"]);
1293
- await exec(installCommand, {
1294
- cwd: projectPath
1295
- });
1296
- spinner5.success("Dependencies installed successfully");
1297
- } catch (error) {
1298
- spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
1299
- throw error;
1300
- }
1301
- }
1302
- var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
1303
- async function loadTemplates() {
1304
- try {
1305
- const response = await fetch(TEMPLATES_API_URL);
1306
- if (!response.ok) {
1307
- throw new Error(`Failed to fetch templates: ${response.statusText}`);
1308
- }
1309
- const templates = await response.json();
1310
- return templates;
1311
- } catch (error) {
1312
- console.error("Error loading templates:", error);
1313
- throw new Error("Failed to load templates. Please check your internet connection and try again.");
1314
- }
1315
- }
1316
- function pluralize(count, singular, plural) {
1317
- return count === 1 ? singular : plural || `${singular}s`;
1318
- }
1319
- async function selectTemplate(templates) {
1320
- const choices = templates.map((template) => {
1321
- const parts = [];
1322
- if (template.agents?.length) {
1323
- parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
1324
- }
1325
- if (template.tools?.length) {
1326
- parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
1327
- }
1328
- if (template.workflows?.length) {
1329
- parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
1330
- }
1331
- if (template.mcp?.length) {
1332
- parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
1333
- }
1334
- if (template.networks?.length) {
1335
- parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
1336
- }
1337
- return {
1338
- value: template,
1339
- label: template.title,
1340
- hint: parts.join(", ") || "Template components"
1341
- };
1342
- });
1343
- const selected = await ve({
1344
- message: "Select a template:",
1345
- options: choices
1346
- });
1347
- if (pD(selected)) {
1348
- return null;
1248
+ return "add";
1349
1249
  }
1350
- return selected;
1351
- }
1352
- function findTemplateByName(templates, templateName) {
1353
- let template = templates.find((t) => t.slug === templateName);
1354
- if (template) return template;
1355
- const slugWithPrefix = `template-${templateName}`;
1356
- template = templates.find((t) => t.slug === slugWithPrefix);
1357
- if (template) return template;
1358
- template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
1359
- if (template) return template;
1360
- return null;
1361
- }
1362
- function getDefaultProjectName(template) {
1363
- return template.slug.replace(/^template-/, "");
1364
1250
  }
1365
1251
  var DepsService = class {
1366
1252
  packageManager;
@@ -1370,7 +1256,7 @@ var DepsService = class {
1370
1256
  findLockFile(dir) {
1371
1257
  const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
1372
1258
  for (const file of lockFiles) {
1373
- if (fs4__default__default.existsSync(path3.join(dir, file))) {
1259
+ if (fs3__default__default.existsSync(path3.join(dir, file))) {
1374
1260
  return file;
1375
1261
  }
1376
1262
  }
@@ -1396,14 +1282,10 @@ var DepsService = class {
1396
1282
  }
1397
1283
  }
1398
1284
  async installPackages(packages) {
1399
- let runCommand = this.packageManager;
1400
- if (this.packageManager === "npm") {
1401
- runCommand = `${this.packageManager} i`;
1402
- } else {
1403
- runCommand = `${this.packageManager} add`;
1404
- }
1285
+ const pm = this.packageManager;
1286
+ const installCommand = getPackageManagerAddCommand(pm);
1405
1287
  const packageList = packages.join(" ");
1406
- return execa(`${runCommand} ${packageList}`, {
1288
+ return execa(`${pm} ${installCommand} ${packageList}`, {
1407
1289
  all: true,
1408
1290
  shell: true,
1409
1291
  stdio: "inherit"
@@ -1413,11 +1295,11 @@ var DepsService = class {
1413
1295
  try {
1414
1296
  const packageJsonPath = path3.join(process.cwd(), "package.json");
1415
1297
  try {
1416
- await fs.access(packageJsonPath);
1298
+ await fs4.access(packageJsonPath);
1417
1299
  } catch {
1418
1300
  return "No package.json file found in the current directory";
1419
1301
  }
1420
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
1302
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
1421
1303
  for (const dependency of dependencies) {
1422
1304
  if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
1423
1305
  return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
@@ -1432,164 +1314,45 @@ var DepsService = class {
1432
1314
  async getProjectName() {
1433
1315
  try {
1434
1316
  const packageJsonPath = path3.join(process.cwd(), "package.json");
1435
- const packageJson = await fs.readFile(packageJsonPath, "utf-8");
1317
+ const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
1436
1318
  const pkg = JSON.parse(packageJson);
1437
1319
  return pkg.name;
1438
1320
  } catch (err) {
1439
1321
  throw err;
1440
1322
  }
1441
1323
  }
1442
- async getPackageVersion() {
1443
- const __filename = fileURLToPath(import.meta.url);
1444
- const __dirname = dirname(__filename);
1445
- const pkgJsonPath = path3.join(__dirname, "..", "package.json");
1446
- const content = await fsExtra3.readJSON(pkgJsonPath);
1447
- return content.version;
1448
- }
1449
1324
  async addScriptsToPackageJson(scripts) {
1450
- const packageJson = JSON.parse(await fs.readFile("package.json", "utf-8"));
1325
+ const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
1451
1326
  packageJson.scripts = {
1452
1327
  ...packageJson.scripts,
1453
1328
  ...scripts
1454
1329
  };
1455
- await fs.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1330
+ await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1456
1331
  }
1457
1332
  };
1458
- var args = ["-y", "@mastra/mcp-docs-server"];
1459
- var createMcpConfig = (editor) => {
1460
- if (editor === "vscode") {
1461
- return {
1462
- servers: {
1463
- mastra: process.platform === `win32` ? {
1464
- command: "cmd",
1465
- args: ["/c", "npx", ...args],
1466
- type: "stdio"
1467
- } : {
1468
- command: "npx",
1469
- args,
1470
- type: "stdio"
1471
- }
1472
- }
1473
- };
1474
- }
1475
- return {
1476
- mcpServers: {
1477
- mastra: {
1478
- command: "npx",
1479
- args
1480
- }
1481
- }
1482
- };
1333
+ var EnvService = class {
1483
1334
  };
1484
- function makeConfig(original, editor) {
1485
- if (editor === "vscode") {
1486
- return {
1487
- ...original,
1488
- servers: {
1489
- ...original?.servers || {},
1490
- ...createMcpConfig(editor).servers
1491
- }
1492
- };
1493
- }
1494
- return {
1495
- ...original,
1496
- mcpServers: {
1497
- ...original?.mcpServers || {},
1498
- ...createMcpConfig(editor).mcpServers
1499
- }
1500
- };
1501
- }
1502
- async function writeMergedConfig(configPath, editor) {
1503
- const configExists = existsSync(configPath);
1504
- const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
1505
- await ensureFile(configPath);
1506
- await writeJSON(configPath, config, {
1507
- spaces: 2
1508
- });
1509
- }
1510
- var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1511
- var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1512
- path3.join(process.cwd(), ".vscode", "mcp.json");
1513
- var vscodeGlobalMCPConfigPath = path3.join(
1514
- os.homedir(),
1515
- 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")
1516
- );
1517
- async function installMastraDocsMCPServer({ editor, directory }) {
1518
- if (editor === `cursor`) {
1519
- await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor");
1335
+ var FileEnvService = class extends EnvService {
1336
+ filePath;
1337
+ constructor(filePath) {
1338
+ super();
1339
+ this.filePath = filePath;
1520
1340
  }
1521
- if (editor === `vscode`) {
1522
- await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode");
1341
+ readFile(filePath) {
1342
+ return new Promise((resolve, reject) => {
1343
+ fs3__default.readFile(filePath, "utf8", (err, data) => {
1344
+ if (err) reject(err);
1345
+ else resolve(data);
1346
+ });
1347
+ });
1523
1348
  }
1524
- if (editor === `cursor-global`) {
1525
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1526
- if (alreadyInstalled) {
1527
- return;
1528
- }
1529
- await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
1530
- }
1531
- if (editor === `windsurf`) {
1532
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1533
- if (alreadyInstalled) {
1534
- return;
1535
- }
1536
- await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
1537
- }
1538
- }
1539
- async function globalMCPIsAlreadyInstalled(editor) {
1540
- let configPath = ``;
1541
- if (editor === "windsurf") {
1542
- configPath = windsurfGlobalMCPConfigPath;
1543
- } else if (editor === "cursor-global") {
1544
- configPath = cursorGlobalMCPConfigPath;
1545
- } else if (editor === "vscode") {
1546
- configPath = vscodeGlobalMCPConfigPath;
1547
- }
1548
- if (!configPath || !existsSync(configPath)) {
1549
- return false;
1550
- }
1551
- try {
1552
- const configContents = await readJSON(configPath);
1553
- if (!configContents) return false;
1554
- if (editor === "vscode") {
1555
- if (!configContents.servers) return false;
1556
- const hasMastraMCP2 = Object.values(configContents.servers).some(
1557
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1558
- );
1559
- return hasMastraMCP2;
1560
- }
1561
- if (!configContents?.mcpServers) return false;
1562
- const hasMastraMCP = Object.values(configContents.mcpServers).some(
1563
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1564
- );
1565
- return hasMastraMCP;
1566
- } catch {
1567
- return false;
1568
- }
1569
- }
1570
- var EnvService = class {
1571
- };
1572
- var FileEnvService = class extends EnvService {
1573
- filePath;
1574
- constructor(filePath) {
1575
- super();
1576
- this.filePath = filePath;
1577
- }
1578
- readFile(filePath) {
1579
- return new Promise((resolve, reject) => {
1580
- fs4__default.readFile(filePath, "utf8", (err, data) => {
1581
- if (err) reject(err);
1582
- else resolve(data);
1583
- });
1584
- });
1585
- }
1586
- writeFile({ filePath, data }) {
1587
- return new Promise((resolve, reject) => {
1588
- fs4__default.writeFile(filePath, data, "utf8", (err) => {
1589
- if (err) reject(err);
1590
- else resolve();
1591
- });
1592
- });
1349
+ writeFile({ filePath, data }) {
1350
+ return new Promise((resolve, reject) => {
1351
+ fs3__default.writeFile(filePath, data, "utf8", (err) => {
1352
+ if (err) reject(err);
1353
+ else resolve();
1354
+ });
1355
+ });
1593
1356
  }
1594
1357
  async updateEnvData({
1595
1358
  key,
@@ -1605,7 +1368,7 @@ var FileEnvService = class extends EnvService {
1605
1368
  ${key}=${value}`;
1606
1369
  }
1607
1370
  await this.writeFile({ filePath, data });
1608
- console.log(`${key} set to ${value} in ENV file.`);
1371
+ console.info(`${key} set to ${value} in ENV file.`);
1609
1372
  return data;
1610
1373
  }
1611
1374
  async getEnvValue(key) {
@@ -1640,23 +1403,23 @@ var FileService = class {
1640
1403
  const __filename = fileURLToPath(import.meta.url);
1641
1404
  const __dirname = path3.dirname(__filename);
1642
1405
  const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1643
- const fileString = fs4__default__default.readFileSync(filePath, "utf8");
1644
- if (fs4__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1645
- console.log(`${outputFilePath} already exists`);
1406
+ const fileString = fs3__default__default.readFileSync(filePath, "utf8");
1407
+ if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1408
+ console.info(`${outputFilePath} already exists`);
1646
1409
  return false;
1647
1410
  }
1648
- await fsExtra3.outputFile(outputFilePath, fileString);
1411
+ await fsExtra.outputFile(outputFilePath, fileString);
1649
1412
  return true;
1650
1413
  }
1651
1414
  async setupEnvFile({ dbUrl }) {
1652
1415
  const envPath = path3.join(process.cwd(), ".env.development");
1653
- await fsExtra3.ensureFile(envPath);
1416
+ await fsExtra.ensureFile(envPath);
1654
1417
  const fileEnvService = new FileEnvService(envPath);
1655
1418
  await fileEnvService.setEnvValue("DB_URL", dbUrl);
1656
1419
  }
1657
1420
  getFirstExistingFile(files) {
1658
1421
  for (const f of files) {
1659
- if (fs4__default__default.existsSync(f)) {
1422
+ if (fs3__default__default.existsSync(f)) {
1660
1423
  return f;
1661
1424
  }
1662
1425
  }
@@ -1666,61 +1429,162 @@ var FileService = class {
1666
1429
  filePath,
1667
1430
  replacements
1668
1431
  }) {
1669
- let fileContent = fs4__default__default.readFileSync(filePath, "utf8");
1432
+ let fileContent = fs3__default__default.readFileSync(filePath, "utf8");
1670
1433
  replacements.forEach(({ search, replace }) => {
1671
1434
  fileContent = fileContent.replaceAll(search, replace);
1672
1435
  });
1673
- fs4__default__default.writeFileSync(filePath, fileContent);
1436
+ fs3__default__default.writeFileSync(filePath, fileContent);
1674
1437
  }
1675
1438
  };
1676
- var exec2 = util.promisify(child_process.exec);
1677
- var getAISDKPackageVersion = (llmProvider) => {
1678
- switch (llmProvider) {
1679
- case "cerebras":
1680
- return "^0.2.14";
1681
- default:
1682
- return "^1.0.0";
1683
- }
1439
+ var createArgs = (versionTag) => {
1440
+ const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1441
+ return ["-y", packageName];
1684
1442
  };
1685
- var getAISDKPackage = (llmProvider) => {
1686
- switch (llmProvider) {
1687
- case "openai":
1688
- return "@ai-sdk/openai";
1689
- case "anthropic":
1690
- return "@ai-sdk/anthropic";
1691
- case "groq":
1692
- return "@ai-sdk/groq";
1693
- case "google":
1694
- return "@ai-sdk/google";
1695
- case "cerebras":
1696
- return "@ai-sdk/cerebras";
1697
- default:
1698
- return "@ai-sdk/openai";
1443
+ var createMcpConfig = (editor, versionTag) => {
1444
+ const args = createArgs(versionTag);
1445
+ if (editor === "vscode") {
1446
+ return {
1447
+ servers: {
1448
+ mastra: process.platform === `win32` ? {
1449
+ command: "cmd",
1450
+ args: ["/c", "npx", ...args],
1451
+ type: "stdio"
1452
+ } : {
1453
+ command: "npx",
1454
+ args,
1455
+ type: "stdio"
1456
+ }
1457
+ }
1458
+ };
1699
1459
  }
1460
+ return {
1461
+ mcpServers: {
1462
+ mastra: {
1463
+ command: "npx",
1464
+ args
1465
+ }
1466
+ }
1467
+ };
1700
1468
  };
1701
- var getProviderImportAndModelItem = (llmProvider) => {
1702
- let providerImport = "";
1703
- let modelItem = "";
1704
- if (llmProvider === "openai") {
1705
- providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
1706
- modelItem = `openai('gpt-4o-mini')`;
1707
- } else if (llmProvider === "anthropic") {
1708
- providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
1709
- modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
1469
+ function makeConfig(original, editor, versionTag) {
1470
+ if (editor === "vscode") {
1471
+ return {
1472
+ ...original,
1473
+ servers: {
1474
+ ...original?.servers || {},
1475
+ ...createMcpConfig(editor, versionTag).servers
1476
+ }
1477
+ };
1478
+ }
1479
+ return {
1480
+ ...original,
1481
+ mcpServers: {
1482
+ ...original?.mcpServers || {},
1483
+ ...createMcpConfig(editor, versionTag).mcpServers
1484
+ }
1485
+ };
1486
+ }
1487
+ async function writeMergedConfig(configPath, editor, versionTag) {
1488
+ const configExists = existsSync(configPath);
1489
+ const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor, versionTag);
1490
+ await ensureFile(configPath);
1491
+ await writeJSON(configPath, config, {
1492
+ spaces: 2
1493
+ });
1494
+ }
1495
+ var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1496
+ var antigravityGlobalMCPConfigPath = path3.join(os.homedir(), ".gemini", "antigravity", "mcp_config.json");
1497
+ var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1498
+ path3.join(process.cwd(), ".vscode", "mcp.json");
1499
+ var vscodeGlobalMCPConfigPath = path3.join(
1500
+ os.homedir(),
1501
+ 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")
1502
+ );
1503
+ async function installMastraDocsMCPServer({
1504
+ editor,
1505
+ directory,
1506
+ versionTag
1507
+ }) {
1508
+ if (editor === `cursor`) {
1509
+ await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor", versionTag);
1510
+ }
1511
+ if (editor === `vscode`) {
1512
+ await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode", versionTag);
1513
+ }
1514
+ if (editor === `cursor-global`) {
1515
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1516
+ if (alreadyInstalled) {
1517
+ return;
1518
+ }
1519
+ await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global", versionTag);
1520
+ }
1521
+ if (editor === `windsurf`) {
1522
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1523
+ if (alreadyInstalled) {
1524
+ return;
1525
+ }
1526
+ await writeMergedConfig(windsurfGlobalMCPConfigPath, editor, versionTag);
1527
+ }
1528
+ if (editor === `antigravity`) {
1529
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1530
+ if (alreadyInstalled) {
1531
+ return;
1532
+ }
1533
+ await writeMergedConfig(antigravityGlobalMCPConfigPath, editor, versionTag);
1534
+ }
1535
+ }
1536
+ async function globalMCPIsAlreadyInstalled(editor, versionTag) {
1537
+ let configPath = ``;
1538
+ if (editor === "windsurf") {
1539
+ configPath = windsurfGlobalMCPConfigPath;
1540
+ } else if (editor === "antigravity") {
1541
+ configPath = antigravityGlobalMCPConfigPath;
1542
+ } else if (editor === "cursor-global") {
1543
+ configPath = cursorGlobalMCPConfigPath;
1544
+ } else if (editor === "vscode") {
1545
+ configPath = vscodeGlobalMCPConfigPath;
1546
+ }
1547
+ if (!configPath || !existsSync(configPath)) {
1548
+ return false;
1549
+ }
1550
+ try {
1551
+ const configContents = await readJSON(configPath);
1552
+ if (!configContents) return false;
1553
+ const expectedPackage = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1554
+ if (editor === "vscode") {
1555
+ if (!configContents.servers) return false;
1556
+ const hasMastraMCP2 = Object.values(configContents.servers).some(
1557
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1558
+ );
1559
+ return hasMastraMCP2;
1560
+ }
1561
+ if (!configContents?.mcpServers) return false;
1562
+ const hasMastraMCP = Object.values(configContents.mcpServers).some(
1563
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1564
+ );
1565
+ return hasMastraMCP;
1566
+ } catch {
1567
+ return false;
1568
+ }
1569
+ }
1570
+ var exec = util.promisify(child_process.exec);
1571
+ var getModelIdentifier = (llmProvider) => {
1572
+ let model = "openai/gpt-4o";
1573
+ if (llmProvider === "anthropic") {
1574
+ model = "anthropic/claude-sonnet-4-5";
1710
1575
  } else if (llmProvider === "groq") {
1711
- providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1712
- modelItem = `groq('llama-3.3-70b-versatile')`;
1576
+ model = "groq/llama-3.3-70b-versatile";
1713
1577
  } else if (llmProvider === "google") {
1714
- providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
1715
- modelItem = `google('gemini-2.5-pro')`;
1578
+ model = "google/gemini-2.5-pro";
1716
1579
  } else if (llmProvider === "cerebras") {
1717
- providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
1718
- modelItem = `cerebras('llama-3.3-70b')`;
1580
+ model = "cerebras/llama-3.3-70b";
1581
+ } else if (llmProvider === "mistral") {
1582
+ model = "mistral/mistral-medium-2508";
1719
1583
  }
1720
- return { providerImport, modelItem };
1584
+ return model;
1721
1585
  };
1722
- async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1723
- const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1586
+ async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
1587
+ const modelString = getModelIdentifier(llmProvider);
1724
1588
  const instructions = `
1725
1589
  You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
1726
1590
 
@@ -1736,30 +1600,49 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1736
1600
  ${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
1737
1601
  `;
1738
1602
  const content = `
1739
- ${providerImport}
1740
1603
  import { Agent } from '@mastra/core/agent';
1741
1604
  import { Memory } from '@mastra/memory';
1742
- import { LibSQLStore } from '@mastra/libsql';
1743
1605
  ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
1606
+ ${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
1744
1607
 
1745
1608
  export const weatherAgent = new Agent({
1609
+ id: 'weather-agent',
1746
1610
  name: 'Weather Agent',
1747
1611
  instructions: \`${instructions}\`,
1748
- model: ${modelItem},
1612
+ model: '${modelString}',
1749
1613
  ${addExampleTool ? "tools: { weatherTool }," : ""}
1750
- memory: new Memory({
1751
- storage: new LibSQLStore({
1752
- url: "file:../mastra.db", // path is relative to the .mastra/output directory
1753
- })
1754
- })
1614
+ ${addScorers ? `scorers: {
1615
+ toolCallAppropriateness: {
1616
+ scorer: scorers.toolCallAppropriatenessScorer,
1617
+ sampling: {
1618
+ type: 'ratio',
1619
+ rate: 1,
1620
+ },
1621
+ },
1622
+ completeness: {
1623
+ scorer: scorers.completenessScorer,
1624
+ sampling: {
1625
+ type: 'ratio',
1626
+ rate: 1,
1627
+ },
1628
+ },
1629
+ translation: {
1630
+ scorer: scorers.translationScorer,
1631
+ sampling: {
1632
+ type: 'ratio',
1633
+ rate: 1,
1634
+ },
1635
+ },
1636
+ },` : ""}
1637
+ memory: new Memory()
1755
1638
  });
1756
1639
  `;
1757
1640
  const formattedContent = await prettier.format(content, {
1758
1641
  parser: "typescript",
1759
1642
  singleQuote: true
1760
1643
  });
1761
- await fs.writeFile(destPath, "");
1762
- await fs.writeFile(destPath, formattedContent);
1644
+ await fs4.writeFile(destPath, "");
1645
+ await fs4.writeFile(destPath, formattedContent);
1763
1646
  }
1764
1647
  async function writeWorkflowSample(destPath) {
1765
1648
  const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
@@ -1952,72 +1835,176 @@ export { weatherWorkflow };`;
1952
1835
  semi: true,
1953
1836
  singleQuote: true
1954
1837
  });
1955
- await fs.writeFile(destPath, formattedContent);
1838
+ await fs4.writeFile(destPath, formattedContent);
1956
1839
  }
1957
1840
  async function writeToolSample(destPath) {
1958
1841
  const fileService = new FileService();
1959
1842
  await fileService.copyStarterFile("tools.ts", destPath);
1960
1843
  }
1844
+ async function writeScorersSample(llmProvider, destPath) {
1845
+ const modelString = getModelIdentifier(llmProvider);
1846
+ const content = `import { z } from 'zod';
1847
+ import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
1848
+ import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
1849
+ import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
1850
+ import { createScorer } from '@mastra/core/evals';
1851
+
1852
+ export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
1853
+ expectedTool: 'weatherTool',
1854
+ strictMode: false,
1855
+ });
1856
+
1857
+ export const completenessScorer = createCompletenessScorer();
1858
+
1859
+ // Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
1860
+ export const translationScorer = createScorer({
1861
+ id: 'translation-quality-scorer',
1862
+ name: 'Translation Quality',
1863
+ description: 'Checks that non-English location names are translated and used correctly',
1864
+ type: 'agent',
1865
+ judge: {
1866
+ model: '${modelString}',
1867
+ instructions:
1868
+ 'You are an expert evaluator of translation quality for geographic locations. ' +
1869
+ 'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
1870
+ 'Be lenient with transliteration differences and diacritics. ' +
1871
+ 'Return only the structured JSON matching the provided schema.',
1872
+ },
1873
+ })
1874
+ .preprocess(({ run }) => {
1875
+ const userText = getUserMessageFromRunInput(run.input) || '';
1876
+ const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
1877
+ return { userText, assistantText };
1878
+ })
1879
+ .analyze({
1880
+ description: 'Extract location names and detect language/translation adequacy',
1881
+ outputSchema: z.object({
1882
+ nonEnglish: z.boolean(),
1883
+ translated: z.boolean(),
1884
+ confidence: z.number().min(0).max(1).default(1),
1885
+ explanation: z.string().default(''),
1886
+ }),
1887
+ createPrompt: ({ results }) => \`
1888
+ You are evaluating if a weather assistant correctly handled translation of a non-English location.
1889
+ User text:
1890
+ """
1891
+ \${results.preprocessStepResult.userText}
1892
+ """
1893
+ Assistant response:
1894
+ """
1895
+ \${results.preprocessStepResult.assistantText}
1896
+ """
1897
+ Tasks:
1898
+ 1) Identify if the user mentioned a location that appears non-English.
1899
+ 2) If non-English, check whether the assistant used a correct English translation of that location in its response.
1900
+ 3) Be lenient with transliteration differences (e.g., accents/diacritics).
1901
+ Return JSON with fields:
1902
+ {
1903
+ "nonEnglish": boolean,
1904
+ "translated": boolean,
1905
+ "confidence": number, // 0-1
1906
+ "explanation": string
1907
+ }
1908
+ \`,
1909
+ })
1910
+ .generateScore(({ results }) => {
1911
+ const r = (results as any)?.analyzeStepResult || {};
1912
+ if (!r.nonEnglish) return 1; // If not applicable, full credit
1913
+ if (r.translated) return Math.max(0, Math.min(1, 0.7 + 0.3 * (r.confidence ?? 1)));
1914
+ return 0; // Non-English but not translated
1915
+ })
1916
+ .generateReason(({ results, score }) => {
1917
+ const r = (results as any)?.analyzeStepResult || {};
1918
+ return \`Translation scoring: nonEnglish=\${r.nonEnglish ?? false}, translated=\${r.translated ?? false}, confidence=\${r.confidence ?? 0}. Score=\${score}. \${r.explanation ?? ''}\`;
1919
+ });
1920
+
1921
+ export const scorers = {
1922
+ toolCallAppropriatenessScorer,
1923
+ completenessScorer,
1924
+ translationScorer,
1925
+ };`;
1926
+ const formattedContent = await prettier.format(content, {
1927
+ parser: "typescript",
1928
+ singleQuote: true
1929
+ });
1930
+ await fs4.writeFile(destPath, formattedContent);
1931
+ }
1961
1932
  async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
1962
1933
  switch (component) {
1963
1934
  case "agents":
1964
- return writeAgentSample(llmprovider, destPath, importComponents.includes("tools"));
1935
+ return writeAgentSample(
1936
+ llmprovider,
1937
+ destPath,
1938
+ importComponents.includes("tools"),
1939
+ importComponents.includes("scorers")
1940
+ );
1965
1941
  case "tools":
1966
1942
  return writeToolSample(destPath);
1967
1943
  case "workflows":
1968
1944
  return writeWorkflowSample(destPath);
1945
+ case "scorers":
1946
+ return writeScorersSample(llmprovider, destPath);
1969
1947
  default:
1970
1948
  return "";
1971
1949
  }
1972
1950
  }
1973
1951
  var createComponentsDir = async (dirPath, component) => {
1974
1952
  const componentPath = dirPath + `/${component}`;
1975
- await fsExtra3.ensureDir(componentPath);
1953
+ await fsExtra.ensureDir(componentPath);
1976
1954
  };
1977
1955
  var writeIndexFile = async ({
1978
1956
  dirPath,
1979
1957
  addAgent,
1980
1958
  addExample,
1981
- addWorkflow
1959
+ addWorkflow,
1960
+ addScorers
1982
1961
  }) => {
1983
1962
  const indexPath = dirPath + "/index.ts";
1984
1963
  const destPath = path3.join(indexPath);
1985
1964
  try {
1986
- await fs.writeFile(destPath, "");
1965
+ await fs4.writeFile(destPath, "");
1987
1966
  const filteredExports = [
1988
1967
  addWorkflow ? `workflows: { weatherWorkflow },` : "",
1989
- addAgent ? `agents: { weatherAgent },` : ""
1968
+ addAgent ? `agents: { weatherAgent },` : "",
1969
+ addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
1990
1970
  ].filter(Boolean);
1991
1971
  if (!addExample) {
1992
- await fs.writeFile(
1972
+ await fs4.writeFile(
1993
1973
  destPath,
1994
1974
  `
1995
- import { Mastra } from '@mastra/core';
1975
+ import { Mastra } from '@mastra/core/mastra';
1996
1976
 
1997
1977
  export const mastra = new Mastra()
1998
1978
  `
1999
1979
  );
2000
1980
  return;
2001
1981
  }
2002
- await fs.writeFile(
1982
+ await fs4.writeFile(
2003
1983
  destPath,
2004
1984
  `
2005
1985
  import { Mastra } from '@mastra/core/mastra';
2006
1986
  import { PinoLogger } from '@mastra/loggers';
2007
1987
  import { LibSQLStore } from '@mastra/libsql';
1988
+ import { Observability } from '@mastra/observability';
2008
1989
  ${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
2009
1990
  ${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
1991
+ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
2010
1992
 
2011
1993
  export const mastra = new Mastra({
2012
1994
  ${filteredExports.join("\n ")}
2013
1995
  storage: new LibSQLStore({
2014
- // stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
1996
+ id: "mastra-storage",
1997
+ // stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
2015
1998
  url: ":memory:",
2016
1999
  }),
2017
2000
  logger: new PinoLogger({
2018
2001
  name: 'Mastra',
2019
2002
  level: 'info',
2020
2003
  }),
2004
+ observability: new Observability({
2005
+ // Enables DefaultExporter and CloudExporter for tracing
2006
+ default: { enabled: true },
2007
+ }),
2021
2008
  });
2022
2009
  `
2023
2010
  );
@@ -2025,7 +2012,6 @@ export const mastra = new Mastra({
2025
2012
  throw err;
2026
2013
  }
2027
2014
  };
2028
- yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
2029
2015
  var getAPIKey = async (provider) => {
2030
2016
  let key = "OPENAI_API_KEY";
2031
2017
  switch (provider) {
@@ -2041,27 +2027,28 @@ var getAPIKey = async (provider) => {
2041
2027
  case "cerebras":
2042
2028
  key = "CEREBRAS_API_KEY";
2043
2029
  return key;
2030
+ case "mistral":
2031
+ key = "MISTRAL_API_KEY";
2032
+ return key;
2044
2033
  default:
2045
2034
  return key;
2046
2035
  }
2047
2036
  };
2048
- var writeAPIKey = async ({
2049
- provider,
2050
- apiKey = "your-api-key"
2051
- }) => {
2037
+ var writeAPIKey = async ({ provider, apiKey }) => {
2038
+ const envFileName = apiKey ? ".env" : ".env.example";
2052
2039
  const key = await getAPIKey(provider);
2053
- const escapedKey = shellQuote.quote([key]);
2054
- const escapedApiKey = shellQuote.quote([apiKey]);
2055
- await exec2(`echo ${escapedKey}=${escapedApiKey} >> .env`);
2040
+ const escapedKey = shellQuote2.quote([key]);
2041
+ const escapedApiKey = shellQuote2.quote([apiKey ? apiKey : "your-api-key"]);
2042
+ await exec(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
2056
2043
  };
2057
2044
  var createMastraDir = async (directory) => {
2058
2045
  let dir = directory.trim().split("/").filter((item) => item !== "");
2059
2046
  const dirPath = path3.join(process.cwd(), ...dir, "mastra");
2060
2047
  try {
2061
- await fs.access(dirPath);
2048
+ await fs4.access(dirPath);
2062
2049
  return { ok: false };
2063
2050
  } catch {
2064
- await fsExtra3.ensureDir(dirPath);
2051
+ await fsExtra.ensureDir(dirPath);
2065
2052
  return { ok: true, dirPath };
2066
2053
  }
2067
2054
  };
@@ -2073,8 +2060,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
2073
2060
  throw err;
2074
2061
  }
2075
2062
  };
2076
- var interactivePrompt = async () => {
2077
- Ie(color2.inverse(" Mastra Init "));
2063
+ var LLM_PROVIDERS = [
2064
+ { value: "openai", label: "OpenAI", hint: "recommended" },
2065
+ { value: "anthropic", label: "Anthropic" },
2066
+ { value: "groq", label: "Groq" },
2067
+ { value: "google", label: "Google" },
2068
+ { value: "cerebras", label: "Cerebras" },
2069
+ { value: "mistral", label: "Mistral" }
2070
+ ];
2071
+ var interactivePrompt = async (args = {}) => {
2072
+ const { skip = {}, options: { showBanner = true } = {} } = args;
2073
+ if (showBanner) {
2074
+ Ie(color2.inverse(" Mastra Init "));
2075
+ }
2078
2076
  const mastraProject = await Ce(
2079
2077
  {
2080
2078
  directory: () => he({
@@ -2082,19 +2080,15 @@ var interactivePrompt = async () => {
2082
2080
  placeholder: "src/",
2083
2081
  defaultValue: "src/"
2084
2082
  }),
2085
- llmProvider: () => ve({
2086
- message: "Select default provider:",
2087
- options: [
2088
- { value: "openai", label: "OpenAI", hint: "recommended" },
2089
- { value: "anthropic", label: "Anthropic" },
2090
- { value: "groq", label: "Groq" },
2091
- { value: "google", label: "Google" },
2092
- { value: "cerebras", label: "Cerebras" }
2093
- ]
2083
+ llmProvider: () => skip?.llmProvider ? void 0 : ve({
2084
+ message: "Select a default provider:",
2085
+ options: LLM_PROVIDERS
2094
2086
  }),
2095
2087
  llmApiKey: async ({ results: { llmProvider } }) => {
2088
+ if (skip?.llmApiKey) return void 0;
2089
+ const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
2096
2090
  const keyChoice = await ve({
2097
- message: `Enter your ${llmProvider} API key?`,
2091
+ message: `Enter your ${llmName} API key?`,
2098
2092
  options: [
2099
2093
  { value: "skip", label: "Skip for now", hint: "default" },
2100
2094
  { value: "enter", label: "Enter API key" }
@@ -2104,52 +2098,42 @@ var interactivePrompt = async () => {
2104
2098
  if (keyChoice === "enter") {
2105
2099
  return he({
2106
2100
  message: "Enter your API key:",
2107
- placeholder: "sk-..."
2101
+ placeholder: "sk-...",
2102
+ validate: (value) => {
2103
+ if (value.length === 0) return "API key cannot be empty";
2104
+ }
2108
2105
  });
2109
2106
  }
2110
2107
  return void 0;
2111
2108
  },
2112
2109
  configureEditorWithDocsMCP: async () => {
2113
- const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
2114
- const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
2115
- const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
2116
2110
  const editor = await ve({
2117
- message: `Make your AI IDE into a Mastra expert? (installs Mastra docs MCP server)`,
2111
+ message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
2118
2112
  options: [
2119
2113
  { value: "skip", label: "Skip for now", hint: "default" },
2120
2114
  {
2121
2115
  value: "cursor",
2122
- label: "Cursor (project only)",
2123
- hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
2116
+ label: "Cursor (project only)"
2124
2117
  },
2125
2118
  {
2126
2119
  value: "cursor-global",
2127
- label: "Cursor (global, all projects)",
2128
- hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
2120
+ label: "Cursor (global, all projects)"
2129
2121
  },
2130
2122
  {
2131
2123
  value: "windsurf",
2132
- label: "Windsurf",
2133
- hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
2124
+ label: "Windsurf"
2134
2125
  },
2135
2126
  {
2136
2127
  value: "vscode",
2137
- label: "VSCode",
2138
- hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
2128
+ label: "VSCode"
2129
+ },
2130
+ {
2131
+ value: "antigravity",
2132
+ label: "Antigravity"
2139
2133
  }
2140
2134
  ]
2141
2135
  });
2142
2136
  if (editor === `skip`) return void 0;
2143
- if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
2144
- M.message(`
2145
- Windsurf is already installed, skipping.`);
2146
- return void 0;
2147
- }
2148
- if (editor === `vscode` && vscodeIsAlreadyInstalled) {
2149
- M.message(`
2150
- VSCode is already installed, skipping.`);
2151
- return void 0;
2152
- }
2153
2137
  if (editor === `cursor`) {
2154
2138
  M.message(
2155
2139
  `
@@ -2158,19 +2142,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
2158
2142
  );
2159
2143
  }
2160
2144
  if (editor === `cursor-global`) {
2161
- const confirm2 = await ve({
2145
+ const confirm3 = await ve({
2162
2146
  message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
2163
2147
  options: [
2164
2148
  { value: "yes", label: "Yes, I understand" },
2165
2149
  { value: "skip", label: "No, skip for now" }
2166
2150
  ]
2167
2151
  });
2168
- if (confirm2 !== `yes`) {
2152
+ if (confirm3 !== `yes`) {
2169
2153
  return void 0;
2170
2154
  }
2171
2155
  }
2172
2156
  if (editor === `windsurf`) {
2173
- const confirm2 = await ve({
2157
+ const confirm3 = await ve({
2174
2158
  message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
2175
2159
  This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
2176
2160
  options: [
@@ -2178,11 +2162,31 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2178
2162
  { value: "skip", label: "No, skip for now" }
2179
2163
  ]
2180
2164
  });
2181
- if (confirm2 !== `yes`) {
2165
+ if (confirm3 !== `yes`) {
2166
+ return void 0;
2167
+ }
2168
+ }
2169
+ if (editor === `antigravity`) {
2170
+ const confirm3 = await ve({
2171
+ message: `Antigravity only supports a global MCP config (at ${antigravityGlobalMCPConfigPath}). Is it ok to add/update that global config?
2172
+ This will make the Mastra docs MCP server available in all Antigravity projects.`,
2173
+ options: [
2174
+ { value: "yes", label: "Yes, I understand" },
2175
+ { value: "skip", label: "No, skip for now" }
2176
+ ]
2177
+ });
2178
+ if (confirm3 !== `yes`) {
2182
2179
  return void 0;
2183
2180
  }
2184
2181
  }
2185
2182
  return editor;
2183
+ },
2184
+ initGit: async () => {
2185
+ if (skip?.gitInit) return false;
2186
+ return ye({
2187
+ message: "Initialize a new git repository?",
2188
+ initialValue: true
2189
+ });
2186
2190
  }
2187
2191
  },
2188
2192
  {
@@ -2194,17 +2198,245 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2194
2198
  );
2195
2199
  return mastraProject;
2196
2200
  };
2201
+ function getPackageManager() {
2202
+ const userAgent = process.env.npm_config_user_agent || "";
2203
+ const execPath = process.env.npm_execpath || "";
2204
+ if (userAgent.includes("bun")) {
2205
+ return "bun";
2206
+ }
2207
+ if (userAgent.includes("yarn")) {
2208
+ return "yarn";
2209
+ }
2210
+ if (userAgent.includes("pnpm")) {
2211
+ return "pnpm";
2212
+ }
2213
+ if (userAgent.includes("npm")) {
2214
+ return "npm";
2215
+ }
2216
+ if (execPath.includes("bun")) {
2217
+ return "bun";
2218
+ }
2219
+ if (execPath.includes("yarn")) {
2220
+ return "yarn";
2221
+ }
2222
+ if (execPath.includes("pnpm")) {
2223
+ return "pnpm";
2224
+ }
2225
+ if (execPath.includes("npm")) {
2226
+ return "npm";
2227
+ }
2228
+ return "npm";
2229
+ }
2230
+ async function gitInit({ cwd }) {
2231
+ await execa("git", ["init"], { cwd, stdio: "ignore" });
2232
+ await execa("git", ["add", "-A"], { cwd, stdio: "ignore" });
2233
+ await execa(
2234
+ "git",
2235
+ [
2236
+ "commit",
2237
+ "-m",
2238
+ '"Initial commit from Mastra"',
2239
+ '--author="dane-ai-mastra[bot] <dane-ai-mastra[bot]@users.noreply.github.com>"'
2240
+ ],
2241
+ { cwd, stdio: "ignore" }
2242
+ );
2243
+ }
2244
+ var logger = createLogger(false);
2245
+ function createLogger(debug = false) {
2246
+ return new PinoLogger({
2247
+ name: "Mastra CLI",
2248
+ level: debug ? "debug" : "info"
2249
+ });
2250
+ }
2251
+ var exec2 = util.promisify(child_process.exec);
2252
+ async function cloneTemplate(options) {
2253
+ const { template, projectName, targetDir, branch, llmProvider } = options;
2254
+ const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
2255
+ const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
2256
+ try {
2257
+ if (await directoryExists(projectPath)) {
2258
+ spinner4.error(`Directory ${projectName} already exists`);
2259
+ throw new Error(`Directory ${projectName} already exists`);
2260
+ }
2261
+ await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
2262
+ await updatePackageJson(projectPath, projectName);
2263
+ const envExamplePath = path3.join(projectPath, ".env.example");
2264
+ if (await fileExists(envExamplePath)) {
2265
+ const envPath = path3.join(projectPath, ".env");
2266
+ await fs4.copyFile(envExamplePath, envPath);
2267
+ if (llmProvider) {
2268
+ await updateEnvFile(envPath, llmProvider);
2269
+ }
2270
+ }
2271
+ spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
2272
+ return projectPath;
2273
+ } catch (error) {
2274
+ spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
2275
+ throw error;
2276
+ }
2277
+ }
2278
+ async function directoryExists(dirPath) {
2279
+ try {
2280
+ const stat = await fs4.stat(dirPath);
2281
+ return stat.isDirectory();
2282
+ } catch {
2283
+ return false;
2284
+ }
2285
+ }
2286
+ async function fileExists(filePath) {
2287
+ try {
2288
+ const stat = await fs4.stat(filePath);
2289
+ return stat.isFile();
2290
+ } catch {
2291
+ return false;
2292
+ }
2293
+ }
2294
+ async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
2295
+ await fs4.mkdir(targetPath, { recursive: true });
2296
+ try {
2297
+ const degitRepo = repoUrl.replace("https://github.com/", "");
2298
+ const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
2299
+ const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
2300
+ await exec2(degitCommand, {
2301
+ cwd: process.cwd()
2302
+ });
2303
+ } catch {
2304
+ try {
2305
+ const gitArgs = ["git", "clone"];
2306
+ if (branch) {
2307
+ gitArgs.push("--branch", branch);
2308
+ }
2309
+ gitArgs.push(repoUrl, targetPath);
2310
+ const gitCommand = shellQuote2.quote(gitArgs);
2311
+ await exec2(gitCommand, {
2312
+ cwd: process.cwd()
2313
+ });
2314
+ const gitDir = path3.join(targetPath, ".git");
2315
+ if (await directoryExists(gitDir)) {
2316
+ await fs4.rm(gitDir, { recursive: true, force: true });
2317
+ }
2318
+ } catch (gitError) {
2319
+ throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
2320
+ }
2321
+ }
2322
+ }
2323
+ async function updatePackageJson(projectPath, projectName) {
2324
+ const packageJsonPath = path3.join(projectPath, "package.json");
2325
+ try {
2326
+ const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
2327
+ const packageJson = JSON.parse(packageJsonContent);
2328
+ packageJson.name = projectName;
2329
+ await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
2330
+ } catch (error) {
2331
+ logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
2332
+ }
2333
+ }
2334
+ async function updateEnvFile(envPath, llmProvider) {
2335
+ try {
2336
+ const envContent = await fs4.readFile(envPath, "utf-8");
2337
+ const modelString = getModelIdentifier(llmProvider);
2338
+ if (!modelString) {
2339
+ logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
2340
+ return;
2341
+ }
2342
+ const modelValue = modelString.replace(/'/g, "");
2343
+ const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
2344
+ await fs4.writeFile(envPath, updatedContent, "utf-8");
2345
+ logger.info(`Updated MODEL in .env to ${modelValue}`);
2346
+ } catch (error) {
2347
+ logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
2348
+ }
2349
+ }
2350
+ async function installDependencies(projectPath, packageManager) {
2351
+ const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
2352
+ try {
2353
+ const pm = packageManager || getPackageManager();
2354
+ const installCommand = shellQuote2.quote([pm, "install"]);
2355
+ await exec2(installCommand, {
2356
+ cwd: projectPath
2357
+ });
2358
+ spinner4.success("Dependencies installed successfully");
2359
+ } catch (error) {
2360
+ spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
2361
+ throw error;
2362
+ }
2363
+ }
2364
+ var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
2365
+ async function loadTemplates() {
2366
+ try {
2367
+ const response = await fetch(TEMPLATES_API_URL);
2368
+ if (!response.ok) {
2369
+ throw new Error(`Failed to fetch templates: ${response.statusText}`);
2370
+ }
2371
+ const templates = await response.json();
2372
+ return templates;
2373
+ } catch (error) {
2374
+ console.error("Error loading templates:", error);
2375
+ throw new Error("Failed to load templates. Please check your internet connection and try again.");
2376
+ }
2377
+ }
2378
+ function pluralize(count, singular, plural) {
2379
+ return count === 1 ? singular : plural || `${singular}s`;
2380
+ }
2381
+ async function selectTemplate(templates) {
2382
+ const choices = templates.map((template) => {
2383
+ const parts = [];
2384
+ if (template.agents?.length) {
2385
+ parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
2386
+ }
2387
+ if (template.tools?.length) {
2388
+ parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
2389
+ }
2390
+ if (template.workflows?.length) {
2391
+ parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
2392
+ }
2393
+ if (template.mcp?.length) {
2394
+ parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
2395
+ }
2396
+ if (template.networks?.length) {
2397
+ parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
2398
+ }
2399
+ return {
2400
+ value: template,
2401
+ label: template.title,
2402
+ hint: parts.join(", ") || "Template components"
2403
+ };
2404
+ });
2405
+ const selected = await ve({
2406
+ message: "Select a template:",
2407
+ options: choices
2408
+ });
2409
+ if (pD(selected)) {
2410
+ return null;
2411
+ }
2412
+ return selected;
2413
+ }
2414
+ function findTemplateByName(templates, templateName) {
2415
+ let template = templates.find((t) => t.slug === templateName);
2416
+ if (template) return template;
2417
+ const slugWithPrefix = `template-${templateName}`;
2418
+ template = templates.find((t) => t.slug === slugWithPrefix);
2419
+ if (template) return template;
2420
+ template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
2421
+ if (template) return template;
2422
+ return null;
2423
+ }
2424
+ function getDefaultProjectName(template) {
2425
+ return template.slug.replace(/^template-/, "");
2426
+ }
2197
2427
  var s = Y();
2198
- var exec3 = util.promisify(child_process.exec);
2199
2428
  var init = async ({
2200
- directory,
2201
- addExample = false,
2429
+ directory = "src/",
2202
2430
  components,
2203
2431
  llmProvider = "openai",
2204
2432
  llmApiKey,
2205
- configureEditorWithDocsMCP
2433
+ addExample = false,
2434
+ configureEditorWithDocsMCP,
2435
+ versionTag,
2436
+ initGit = false
2206
2437
  }) => {
2207
2438
  s.start("Initializing Mastra");
2439
+ const packageVersionTag = versionTag ? `@${versionTag}` : "";
2208
2440
  try {
2209
2441
  const result = await createMastraDir(directory);
2210
2442
  if (!result.ok) {
@@ -2217,7 +2449,8 @@ var init = async ({
2217
2449
  dirPath,
2218
2450
  addExample,
2219
2451
  addWorkflow: components.includes("workflows"),
2220
- addAgent: components.includes("agents")
2452
+ addAgent: components.includes("agents"),
2453
+ addScorers: components.includes("scorers")
2221
2454
  }),
2222
2455
  ...components.map((component) => createComponentsDir(dirPath, component)),
2223
2456
  writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
@@ -2231,31 +2464,44 @@ var init = async ({
2231
2464
  const depService = new DepsService();
2232
2465
  const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
2233
2466
  if (needsLibsql) {
2234
- await depService.installPackages(["@mastra/libsql"]);
2467
+ await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
2235
2468
  }
2236
2469
  const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
2237
2470
  if (needsMemory) {
2238
- await depService.installPackages(["@mastra/memory"]);
2471
+ await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
2239
2472
  }
2240
2473
  const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
2241
2474
  if (needsLoggers) {
2242
- await depService.installPackages(["@mastra/loggers"]);
2475
+ await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
2476
+ }
2477
+ const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
2478
+ if (needsObservability) {
2479
+ await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
2480
+ }
2481
+ const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
2482
+ if (needsEvals) {
2483
+ await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
2243
2484
  }
2244
2485
  }
2245
2486
  const key = await getAPIKey(llmProvider || "openai");
2246
- const aiSdkPackage = getAISDKPackage(llmProvider);
2247
- const aiSdkPackageVersion = getAISDKPackageVersion(llmProvider);
2248
- const depsService = new DepsService();
2249
- const pm = depsService.packageManager;
2250
- const installCommand = getPackageManagerInstallCommand(pm);
2251
- await exec3(`${pm} ${installCommand} ${aiSdkPackage}@${aiSdkPackageVersion}`);
2252
2487
  if (configureEditorWithDocsMCP) {
2253
2488
  await installMastraDocsMCPServer({
2254
2489
  editor: configureEditorWithDocsMCP,
2255
- directory: process.cwd()
2490
+ directory: process.cwd(),
2491
+ versionTag
2256
2492
  });
2257
2493
  }
2258
2494
  s.stop();
2495
+ if (initGit) {
2496
+ const s2 = Y();
2497
+ try {
2498
+ s2.start("Initializing git repository");
2499
+ await gitInit({ cwd: process.cwd() });
2500
+ s2.stop("Git repository initialized");
2501
+ } catch {
2502
+ s2.stop();
2503
+ }
2504
+ }
2259
2505
  if (!llmApiKey) {
2260
2506
  Me(`
2261
2507
  ${color2.green("Mastra initialized successfully!")}
@@ -2275,10 +2521,10 @@ var init = async ({
2275
2521
  return { success: false };
2276
2522
  }
2277
2523
  };
2278
- var exec4 = util.promisify(child_process.exec);
2524
+ var exec3 = util.promisify(child_process.exec);
2279
2525
  var execWithTimeout = async (command, timeoutMs) => {
2280
2526
  try {
2281
- const promise = exec4(command, { killSignal: "SIGTERM" });
2527
+ const promise = exec3(command, { killSignal: "SIGTERM" });
2282
2528
  if (!timeoutMs) {
2283
2529
  return await promise;
2284
2530
  }
@@ -2301,10 +2547,36 @@ var execWithTimeout = async (command, timeoutMs) => {
2301
2547
  throw error;
2302
2548
  }
2303
2549
  };
2550
+ async function getInitCommand(pm) {
2551
+ switch (pm) {
2552
+ case "npm":
2553
+ return "npm init -y";
2554
+ case "pnpm":
2555
+ return "pnpm init";
2556
+ case "yarn":
2557
+ return "yarn init -y";
2558
+ case "bun":
2559
+ return "bun init -y";
2560
+ default:
2561
+ return "npm init -y";
2562
+ }
2563
+ }
2564
+ async function initializePackageJson(pm) {
2565
+ const initCommand = await getInitCommand(pm);
2566
+ await exec3(initCommand);
2567
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
2568
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
2569
+ packageJson.type = "module";
2570
+ packageJson.engines = {
2571
+ ...packageJson.engines,
2572
+ node: ">=22.13.0"
2573
+ };
2574
+ await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2575
+ }
2304
2576
  async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
2305
- let installCommand = getPackageManagerInstallCommand(pm);
2577
+ let installCommand = getPackageManagerAddCommand(pm);
2306
2578
  if (isDev) {
2307
- installCommand = `${installCommand} --save-dev`;
2579
+ installCommand = `${installCommand} -D`;
2308
2580
  }
2309
2581
  try {
2310
2582
  await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
@@ -2326,23 +2598,42 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
2326
2598
  var createMastraProject = async ({
2327
2599
  projectName: name,
2328
2600
  createVersionTag,
2329
- timeout
2601
+ timeout,
2602
+ llmProvider,
2603
+ llmApiKey,
2604
+ needsInteractive
2330
2605
  }) => {
2331
2606
  Ie(color2.inverse(" Mastra Create "));
2332
2607
  const projectName = name ?? await he({
2333
2608
  message: "What do you want to name your project?",
2334
2609
  placeholder: "my-mastra-app",
2335
- defaultValue: "my-mastra-app"
2610
+ defaultValue: "my-mastra-app",
2611
+ validate: (value) => {
2612
+ if (value.length === 0) return "Project name cannot be empty";
2613
+ if (fs3__default__default.existsSync(value)) {
2614
+ return `A directory named "${value}" already exists. Please choose a different name.`;
2615
+ }
2616
+ }
2336
2617
  });
2337
2618
  if (pD(projectName)) {
2338
2619
  xe("Operation cancelled");
2339
2620
  process.exit(0);
2340
2621
  }
2622
+ let result = void 0;
2623
+ if (needsInteractive) {
2624
+ result = await interactivePrompt({
2625
+ options: { showBanner: false },
2626
+ skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
2627
+ });
2628
+ }
2341
2629
  const s2 = Y();
2630
+ const originalCwd = process.cwd();
2631
+ let projectPath = null;
2342
2632
  try {
2343
2633
  s2.start("Creating project");
2344
2634
  try {
2345
- await fs.mkdir(projectName);
2635
+ await fs4.mkdir(projectName);
2636
+ projectPath = path3.resolve(originalCwd, projectName);
2346
2637
  } catch (error) {
2347
2638
  if (error instanceof Error && "code" in error && error.code === "EEXIST") {
2348
2639
  s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
@@ -2354,12 +2645,10 @@ var createMastraProject = async ({
2354
2645
  }
2355
2646
  process.chdir(projectName);
2356
2647
  const pm = getPackageManager();
2357
- const installCommand = getPackageManagerInstallCommand(pm);
2648
+ const installCommand = getPackageManagerAddCommand(pm);
2358
2649
  s2.message("Initializing project structure");
2359
2650
  try {
2360
- await exec4(`npm init -y`);
2361
- await exec4(`npm pkg set type="module"`);
2362
- await exec4(`npm pkg set engines.node=">=20.9.0"`);
2651
+ await initializePackageJson(pm);
2363
2652
  const depsService = new DepsService();
2364
2653
  await depsService.addScriptsToPackageJson({
2365
2654
  dev: "mastra dev",
@@ -2374,9 +2663,9 @@ var createMastraProject = async ({
2374
2663
  s2.stop("Project structure created");
2375
2664
  s2.start(`Installing ${pm} dependencies`);
2376
2665
  try {
2377
- await exec4(`${pm} ${installCommand} zod@^3`);
2378
- await exec4(`${pm} ${installCommand} typescript @types/node --save-dev`);
2379
- await exec4(`echo '{
2666
+ await exec3(`${pm} ${installCommand} zod@^4`);
2667
+ await exec3(`${pm} ${installCommand} -D typescript @types/node`);
2668
+ await exec3(`echo '{
2380
2669
  "compilerOptions": {
2381
2670
  "target": "ES2022",
2382
2671
  "module": "ES2022",
@@ -2398,15 +2687,15 @@ var createMastraProject = async ({
2398
2687
  );
2399
2688
  }
2400
2689
  s2.stop(`${pm} dependencies installed`);
2401
- s2.start("Installing mastra");
2690
+ s2.start("Installing Mastra CLI");
2402
2691
  const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
2403
2692
  try {
2404
2693
  await installMastraDependency(pm, "mastra", versionTag, true, timeout);
2405
2694
  } catch (error) {
2406
2695
  throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
2407
2696
  }
2408
- s2.stop("mastra installed");
2409
- s2.start("Installing dependencies");
2697
+ s2.stop("Mastra CLI installed");
2698
+ s2.start("Installing Mastra dependencies");
2410
2699
  try {
2411
2700
  await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
2412
2701
  await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
@@ -2419,58 +2708,80 @@ var createMastraProject = async ({
2419
2708
  s2.stop("Mastra dependencies installed");
2420
2709
  s2.start("Adding .gitignore");
2421
2710
  try {
2422
- await exec4(`echo output.txt >> .gitignore`);
2423
- await exec4(`echo node_modules >> .gitignore`);
2424
- await exec4(`echo dist >> .gitignore`);
2425
- await exec4(`echo .mastra >> .gitignore`);
2426
- await exec4(`echo .env.development >> .gitignore`);
2427
- await exec4(`echo .env >> .gitignore`);
2428
- await exec4(`echo *.db >> .gitignore`);
2429
- await exec4(`echo *.db-* >> .gitignore`);
2711
+ await exec3(`echo output.txt >> .gitignore`);
2712
+ await exec3(`echo node_modules >> .gitignore`);
2713
+ await exec3(`echo dist >> .gitignore`);
2714
+ await exec3(`echo .mastra >> .gitignore`);
2715
+ await exec3(`echo .env.development >> .gitignore`);
2716
+ await exec3(`echo .env >> .gitignore`);
2717
+ await exec3(`echo *.db >> .gitignore`);
2718
+ await exec3(`echo *.db-* >> .gitignore`);
2430
2719
  } catch (error) {
2431
2720
  throw new Error(`Failed to create .gitignore: ${error instanceof Error ? error.message : "Unknown error"}`);
2432
2721
  }
2433
2722
  s2.stop(".gitignore added");
2434
2723
  Se("Project created successfully");
2435
- console.log("");
2436
- return { projectName };
2724
+ console.info("");
2725
+ return { projectName, result };
2437
2726
  } catch (error) {
2438
2727
  s2.stop();
2439
2728
  const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
2440
2729
  xe(`Project creation failed: ${errorMessage}`);
2730
+ if (projectPath && fs3__default__default.existsSync(projectPath)) {
2731
+ try {
2732
+ process.chdir(originalCwd);
2733
+ await fs4.rm(projectPath, { recursive: true, force: true });
2734
+ } catch (cleanupError) {
2735
+ console.error(
2736
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
2737
+ );
2738
+ }
2739
+ }
2441
2740
  process.exit(1);
2442
2741
  }
2443
2742
  };
2444
- var create = async (args2) => {
2445
- if (args2.template !== void 0) {
2446
- await createFromTemplate(args2);
2743
+ var version$1 = package_default.version;
2744
+ var create = async (args) => {
2745
+ if (args.template !== void 0) {
2746
+ await createFromTemplate({
2747
+ projectName: args.projectName,
2748
+ template: args.template,
2749
+ timeout: args.timeout,
2750
+ injectedAnalytics: args.analytics,
2751
+ llmProvider: args.llmProvider
2752
+ });
2447
2753
  return;
2448
2754
  }
2449
- const { projectName } = await createMastraProject({
2450
- projectName: args2?.projectName,
2451
- createVersionTag: args2?.createVersionTag,
2452
- timeout: args2?.timeout
2755
+ const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
2756
+ const { projectName, result } = await createMastraProject({
2757
+ projectName: args?.projectName,
2758
+ createVersionTag: args?.createVersionTag,
2759
+ timeout: args?.timeout,
2760
+ llmProvider: args?.llmProvider,
2761
+ llmApiKey: args?.llmApiKey,
2762
+ needsInteractive
2453
2763
  });
2454
- const directory = args2.directory || "src/";
2455
- if (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
2456
- const result = await interactivePrompt();
2764
+ const directory = args.directory || "src/";
2765
+ if (needsInteractive && result) {
2457
2766
  await init({
2458
2767
  ...result,
2459
2768
  llmApiKey: result?.llmApiKey,
2460
- components: ["agents", "tools", "workflows"],
2461
- addExample: true
2769
+ components: ["agents", "tools", "workflows", "scorers"],
2770
+ addExample: true,
2771
+ versionTag: args.createVersionTag
2462
2772
  });
2463
2773
  postCreate({ projectName });
2464
2774
  return;
2465
2775
  }
2466
- const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args2;
2776
+ const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
2467
2777
  await init({
2468
2778
  directory,
2469
2779
  components,
2470
2780
  llmProvider,
2471
2781
  addExample,
2472
2782
  llmApiKey,
2473
- configureEditorWithDocsMCP: args2.mcpServer
2783
+ configureEditorWithDocsMCP: args.mcpServer,
2784
+ versionTag: args.createVersionTag
2474
2785
  });
2475
2786
  postCreate({ projectName });
2476
2787
  };
@@ -2561,9 +2872,9 @@ async function createFromGitHubUrl(url) {
2561
2872
  workflows: []
2562
2873
  };
2563
2874
  }
2564
- async function createFromTemplate(args2) {
2875
+ async function createFromTemplate(args) {
2565
2876
  let selectedTemplate;
2566
- if (args2.template === true) {
2877
+ if (args.template === true) {
2567
2878
  const templates = await loadTemplates();
2568
2879
  const selected = await selectTemplate(templates);
2569
2880
  if (!selected) {
@@ -2571,26 +2882,26 @@ async function createFromTemplate(args2) {
2571
2882
  return;
2572
2883
  }
2573
2884
  selectedTemplate = selected;
2574
- } else if (args2.template && typeof args2.template === "string") {
2575
- if (isGitHubUrl(args2.template)) {
2576
- const spinner5 = Y();
2577
- spinner5.start("Validating GitHub repository...");
2578
- const validation = await validateGitHubProject(args2.template);
2885
+ } else if (args.template && typeof args.template === "string") {
2886
+ if (isGitHubUrl(args.template)) {
2887
+ const spinner4 = Y();
2888
+ spinner4.start("Validating GitHub repository...");
2889
+ const validation = await validateGitHubProject(args.template);
2579
2890
  if (!validation.isValid) {
2580
- spinner5.stop("Validation failed");
2891
+ spinner4.stop("Validation failed");
2581
2892
  M.error("This does not appear to be a valid Mastra project:");
2582
2893
  validation.errors.forEach((error) => M.error(` - ${error}`));
2583
2894
  throw new Error("Invalid Mastra project");
2584
2895
  }
2585
- spinner5.stop("Valid Mastra project \u2713");
2586
- selectedTemplate = await createFromGitHubUrl(args2.template);
2896
+ spinner4.stop("Valid Mastra project \u2713");
2897
+ selectedTemplate = await createFromGitHubUrl(args.template);
2587
2898
  } else {
2588
2899
  const templates = await loadTemplates();
2589
- const found = findTemplateByName(templates, args2.template);
2900
+ const found = findTemplateByName(templates, args.template);
2590
2901
  if (!found) {
2591
- M.error(`Template "${args2.template}" not found. Available templates:`);
2902
+ M.error(`Template "${args.template}" not found. Available templates:`);
2592
2903
  templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2593
- throw new Error(`Template "${args2.template}" not found`);
2904
+ throw new Error(`Template "${args.template}" not found`);
2594
2905
  }
2595
2906
  selectedTemplate = found;
2596
2907
  }
@@ -2598,7 +2909,7 @@ async function createFromTemplate(args2) {
2598
2909
  if (!selectedTemplate) {
2599
2910
  throw new Error("No template selected");
2600
2911
  }
2601
- let projectName = args2.projectName;
2912
+ let projectName = args.projectName;
2602
2913
  if (!projectName) {
2603
2914
  const defaultName = getDefaultProjectName(selectedTemplate);
2604
2915
  const response = await he({
@@ -2612,22 +2923,80 @@ async function createFromTemplate(args2) {
2612
2923
  }
2613
2924
  projectName = response;
2614
2925
  }
2926
+ let llmProvider = args.llmProvider;
2927
+ if (!llmProvider) {
2928
+ const providerResponse = await ve({
2929
+ message: "Select a default provider:",
2930
+ options: LLM_PROVIDERS
2931
+ });
2932
+ if (pD(providerResponse)) {
2933
+ M.info("Project creation cancelled.");
2934
+ return;
2935
+ }
2936
+ llmProvider = providerResponse;
2937
+ }
2938
+ let initGit = false;
2939
+ const gitConfirmResult = await ye({
2940
+ message: "Initialize a new git repository?",
2941
+ initialValue: true
2942
+ });
2943
+ if (!pD(gitConfirmResult)) {
2944
+ initGit = gitConfirmResult;
2945
+ }
2946
+ let projectPath = null;
2615
2947
  try {
2616
- const analytics = getAnalytics();
2617
- if (analytics) ;
2618
- const projectPath = await cloneTemplate({
2948
+ const analytics = args.injectedAnalytics || getAnalytics();
2949
+ if (analytics) {
2950
+ analytics.trackEvent("cli_template_used", {
2951
+ template_slug: selectedTemplate.slug,
2952
+ template_title: selectedTemplate.title
2953
+ });
2954
+ if (llmProvider) {
2955
+ analytics.trackEvent("cli_model_provider_selected", {
2956
+ provider: llmProvider,
2957
+ selection_method: args.llmProvider ? "cli_args" : "interactive"
2958
+ });
2959
+ }
2960
+ }
2961
+ const isBeta = version$1?.includes("beta") ?? false;
2962
+ const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
2963
+ const branch = isBeta && isMastraTemplate ? "beta" : void 0;
2964
+ projectPath = await cloneTemplate({
2619
2965
  template: selectedTemplate,
2620
- projectName
2966
+ projectName,
2967
+ branch,
2968
+ llmProvider
2621
2969
  });
2622
2970
  await installDependencies(projectPath);
2971
+ if (initGit) {
2972
+ const s2 = Y();
2973
+ try {
2974
+ s2.start("Initializing git repository");
2975
+ await gitInit({ cwd: projectPath });
2976
+ s2.stop("Git repository initialized");
2977
+ } catch {
2978
+ s2.stop();
2979
+ }
2980
+ }
2623
2981
  Me(`
2624
2982
  ${color2.green("Mastra template installed!")}
2625
2983
 
2626
- Add the necessary environment
2984
+ Add the necessary environment
2627
2985
  variables in your ${color2.cyan(".env")} file
2628
2986
  `);
2629
2987
  postCreate({ projectName });
2630
2988
  } catch (error) {
2989
+ if (projectPath) {
2990
+ try {
2991
+ if (fs3__default__default.existsSync(projectPath)) {
2992
+ await fs4.rm(projectPath, { recursive: true, force: true });
2993
+ }
2994
+ } catch (cleanupError) {
2995
+ console.error(
2996
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
2997
+ );
2998
+ }
2999
+ }
2631
3000
  M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
2632
3001
  throw error;
2633
3002
  }
@@ -2637,13 +3006,13 @@ async function getPackageVersion() {
2637
3006
  const __filename = fileURLToPath(import.meta.url);
2638
3007
  const __dirname = dirname(__filename);
2639
3008
  const pkgJsonPath = path3.join(__dirname, "..", "package.json");
2640
- const content = await fsExtra.readJSON(pkgJsonPath);
3009
+ const content = await fsExtra$1.readJSON(pkgJsonPath);
2641
3010
  return content.version;
2642
3011
  }
2643
3012
  async function getCreateVersionTag() {
2644
3013
  try {
2645
3014
  const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
2646
- const json = await fsExtra.readJSON(pkgPath);
3015
+ const json = await fsExtra$1.readJSON(pkgPath);
2647
3016
  const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
2648
3017
  const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
2649
3018
  const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
@@ -2667,14 +3036,14 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
2667
3036
  analytics.trackCommand({
2668
3037
  command: "version"
2669
3038
  });
2670
- console.log(`create-mastra ${version}`);
3039
+ console.info(`create-mastra ${version}`);
2671
3040
  } catch {
2672
3041
  }
2673
3042
  });
2674
3043
  program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
2675
3044
  "-p, --project-name <string>",
2676
3045
  "Project name that will be used in package.json and as the project directory name."
2677
- ).option("--default", "Quick start with defaults(src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
3046
+ ).option("--default", "Quick start with defaults (src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows, scorers)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode, antigravity)").option(
2678
3047
  "--template [template-name]",
2679
3048
  "Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
2680
3049
  ).action(async (projectNameArg, args) => {
@@ -2682,14 +3051,15 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2682
3051
  const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
2683
3052
  if (args.default) {
2684
3053
  await create({
2685
- components: ["agents", "tools", "workflows"],
3054
+ components: ["agents", "tools", "workflows", "scorers"],
2686
3055
  llmProvider: "openai",
2687
3056
  addExample: true,
2688
3057
  createVersionTag,
2689
3058
  timeout,
2690
3059
  mcpServer: args.mcp,
2691
3060
  directory: "src/",
2692
- template: args.template
3061
+ template: args.template,
3062
+ analytics
2693
3063
  });
2694
3064
  return;
2695
3065
  }
@@ -2697,13 +3067,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2697
3067
  components: args.components ? args.components.split(",") : [],
2698
3068
  llmProvider: args.llm,
2699
3069
  addExample: args.example,
2700
- llmApiKey: args["llm-api-key"],
3070
+ llmApiKey: args.llmApiKey,
2701
3071
  createVersionTag,
2702
3072
  timeout,
2703
3073
  projectName,
2704
3074
  directory: args.dir,
2705
3075
  mcpServer: args.mcp,
2706
- template: args.template
3076
+ template: args.template,
3077
+ analytics
2707
3078
  });
2708
3079
  });
2709
3080
  program.parse(process.argv);