create-mastra 0.0.0-tsconfig-compile-20250703214351 → 0.0.0-type-testing-20260120105120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,26 +4,30 @@ import { randomUUID } from 'node:crypto';
4
4
  import * as fs3__default from 'node:fs';
5
5
  import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
- import path2, { dirname } from 'node:path';
7
+ import path3, { dirname } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { PostHog } from 'posthog-node';
10
+ import fs4 from 'node:fs/promises';
10
11
  import util, { stripVTControlCharacters } from 'node:util';
11
12
  import y$1, { stdout, stdin } from 'node:process';
12
13
  import * as g from 'node:readline';
13
14
  import g__default from 'node:readline';
14
15
  import { Writable } from 'node:stream';
15
16
  import child_process from 'node:child_process';
16
- import fs4 from 'node:fs/promises';
17
- import { execa } from 'execa';
18
- import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
19
- import prettier from 'prettier';
20
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';
21
22
  import pino from 'pino';
22
23
  import pretty from 'pino-pretty';
23
- import fsExtra from 'fs-extra';
24
24
 
25
25
  var __filename = fileURLToPath(import.meta.url);
26
- var __dirname = path2.dirname(__filename);
26
+ var __dirname = path3.dirname(__filename);
27
+ var analyticsInstance = null;
28
+ function getAnalytics() {
29
+ return analyticsInstance;
30
+ }
27
31
  var PosthogAnalytics = class {
28
32
  sessionId;
29
33
  client;
@@ -35,7 +39,7 @@ var PosthogAnalytics = class {
35
39
  host = "https://app.posthog.com"
36
40
  }) {
37
41
  this.version = version;
38
- const cliConfigPath = path2.join(__dirname, "mastra-cli.json");
42
+ const cliConfigPath = path3.join(__dirname, "mastra-cli.json");
39
43
  if (existsSync(cliConfigPath)) {
40
44
  try {
41
45
  const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
@@ -63,7 +67,7 @@ var PosthogAnalytics = class {
63
67
  }
64
68
  writeCliConfig({ distinctId, sessionId }) {
65
69
  try {
66
- writeFileSync(path2.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
70
+ writeFileSync(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
67
71
  } catch {
68
72
  }
69
73
  }
@@ -101,6 +105,10 @@ var PosthogAnalytics = class {
101
105
  machine_id: os.hostname()
102
106
  };
103
107
  }
108
+ getDurationMs(startTime) {
109
+ const [seconds, nanoseconds] = process.hrtime(startTime);
110
+ return seconds * 1e3 + nanoseconds / 1e6;
111
+ }
104
112
  captureSessionStart() {
105
113
  if (!this.client) {
106
114
  return;
@@ -113,6 +121,22 @@ var PosthogAnalytics = class {
113
121
  }
114
122
  });
115
123
  }
124
+ trackEvent(eventName, properties) {
125
+ try {
126
+ if (!this.client) {
127
+ return;
128
+ }
129
+ this.client.capture({
130
+ distinctId: this.distinctId,
131
+ event: eventName,
132
+ properties: {
133
+ ...this.getSystemProperties(),
134
+ ...properties
135
+ }
136
+ });
137
+ } catch {
138
+ }
139
+ }
116
140
  trackCommand(options) {
117
141
  try {
118
142
  if (!this.client) {
@@ -153,8 +177,7 @@ var PosthogAnalytics = class {
153
177
  const startTime = process.hrtime();
154
178
  try {
155
179
  const result = await execution();
156
- const [seconds, nanoseconds] = process.hrtime(startTime);
157
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
180
+ const durationMs = this.getDurationMs(startTime);
158
181
  this.trackCommand({
159
182
  command,
160
183
  args,
@@ -164,8 +187,7 @@ var PosthogAnalytics = class {
164
187
  });
165
188
  return result;
166
189
  } catch (error) {
167
- const [seconds, nanoseconds] = process.hrtime(startTime);
168
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
190
+ const durationMs = this.getDurationMs(startTime);
169
191
  this.trackCommand({
170
192
  command,
171
193
  args,
@@ -362,7 +384,7 @@ function DD({onlyFirst:e=false}={}){const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:
362
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(`
363
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(`
364
386
  `).slice(F);this.output.write(s.join(`
365
- `)),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);});}}
366
388
 
367
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)}
368
390
  ${b(this.state)} ${t.message}
@@ -372,7 +394,12 @@ ${color2.yellow(d)} ${color2.yellow(this.error)}
372
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()?`
373
395
  ${color2.gray(o)}`:""}`;default:return `${n}${color2.cyan(o)} ${i}
374
396
  ${color2.cyan(d)}
375
- `}}}).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)}
376
403
  ${b(this.state)} ${t.message}
377
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")}
378
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(`
@@ -402,7 +429,7 @@ ${color2.gray(d)} ${t}
402
429
  `):process.stdout.write(`${w} ${l}
403
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};
404
431
 
405
- var shellQuote$1 = {};
432
+ var shellQuote = {};
406
433
 
407
434
  var quote;
408
435
  var hasRequiredQuote;
@@ -668,16 +695,16 @@ function requireParse () {
668
695
  var hasRequiredShellQuote;
669
696
 
670
697
  function requireShellQuote () {
671
- if (hasRequiredShellQuote) return shellQuote$1;
698
+ if (hasRequiredShellQuote) return shellQuote;
672
699
  hasRequiredShellQuote = 1;
673
700
 
674
- shellQuote$1.quote = requireQuote();
675
- shellQuote$1.parse = requireParse();
676
- return shellQuote$1;
701
+ shellQuote.quote = requireQuote();
702
+ shellQuote.parse = requireParse();
703
+ return shellQuote;
677
704
  }
678
705
 
679
706
  var shellQuoteExports = requireShellQuote();
680
- var shellQuote = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
707
+ var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
681
708
 
682
709
  // eslint-disable-next-line no-warning-comments
683
710
  // TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
@@ -704,13 +731,18 @@ const format = (open, close) => {
704
731
  // Handle nested colors.
705
732
 
706
733
  // We could have done this, but it's too slow (as of Node.js 22).
707
- // return openCode + string.replaceAll(closeCode, openCode) + closeCode;
734
+ // return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
708
735
 
709
736
  let result = openCode;
710
737
  let lastIndex = 0;
711
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
+
712
744
  while (index !== -1) {
713
- result += string.slice(lastIndex, index) + openCode;
745
+ result += string.slice(lastIndex, index) + replaceCode;
714
746
  lastIndex = index + closeCode.length;
715
747
  index = string.indexOf(closeCode, lastIndex);
716
748
  }
@@ -862,6 +894,7 @@ class YoctoSpinner {
862
894
  #exitHandlerBound;
863
895
  #isInteractive;
864
896
  #lastSpinnerFrameTime = 0;
897
+ #isSpinning = false;
865
898
 
866
899
  constructor(options = {}) {
867
900
  const spinner = options.spinner ?? defaultSpinner;
@@ -883,13 +916,17 @@ class YoctoSpinner {
883
916
  return this;
884
917
  }
885
918
 
919
+ this.#isSpinning = true;
886
920
  this.#hideCursor();
887
921
  this.#render();
888
922
  this.#subscribeToProcessEvents();
889
923
 
890
- this.#timer = setInterval(() => {
891
- this.#render();
892
- }, 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
+ }
893
930
 
894
931
  return this;
895
932
  }
@@ -899,8 +936,12 @@ class YoctoSpinner {
899
936
  return this;
900
937
  }
901
938
 
902
- clearInterval(this.#timer);
903
- this.#timer = undefined;
939
+ this.#isSpinning = false;
940
+ if (this.#timer) {
941
+ clearInterval(this.#timer);
942
+ this.#timer = undefined;
943
+ }
944
+
904
945
  this.#showCursor();
905
946
  this.clear();
906
947
  this.#unsubscribeFromProcessEvents();
@@ -933,7 +974,7 @@ class YoctoSpinner {
933
974
  }
934
975
 
935
976
  get isSpinning() {
936
- return this.#timer !== undefined;
977
+ return this.#isSpinning;
937
978
  }
938
979
 
939
980
  get text() {
@@ -1070,11 +1111,11 @@ var MastraLogger = class {
1070
1111
  }
1071
1112
  trackException(_error) {
1072
1113
  }
1073
- async getLogs(transportId, params) {
1114
+ async listLogs(transportId, params) {
1074
1115
  if (!transportId || !this.transports.has(transportId)) {
1075
1116
  return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
1076
1117
  }
1077
- return this.transports.get(transportId).getLogs(params) ?? {
1118
+ return this.transports.get(transportId).listLogs(params) ?? {
1078
1119
  logs: [],
1079
1120
  total: 0,
1080
1121
  page: params?.page ?? 1,
@@ -1082,7 +1123,7 @@ var MastraLogger = class {
1082
1123
  hasMore: false
1083
1124
  };
1084
1125
  }
1085
- async getLogsByRunId({
1126
+ async listLogsByRunId({
1086
1127
  transportId,
1087
1128
  runId,
1088
1129
  fromDate,
@@ -1095,7 +1136,7 @@ var MastraLogger = class {
1095
1136
  if (!transportId || !this.transports.has(transportId) || !runId) {
1096
1137
  return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
1097
1138
  }
1098
- 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 }) ?? {
1099
1140
  logs: [],
1100
1141
  total: 0,
1101
1142
  page: page ?? 1,
@@ -1105,10 +1146,15 @@ var MastraLogger = class {
1105
1146
  }
1106
1147
  };
1107
1148
 
1108
- var PinoLogger = class extends MastraLogger {
1149
+ var PinoLogger = class _PinoLogger extends MastraLogger {
1109
1150
  logger;
1110
1151
  constructor(options = {}) {
1111
1152
  super(options);
1153
+ const internalOptions = options;
1154
+ if (internalOptions._logger) {
1155
+ this.logger = internalOptions._logger;
1156
+ return;
1157
+ }
1112
1158
  let prettyStream = void 0;
1113
1159
  if (!options.overrideDefaultTransports) {
1114
1160
  prettyStream = pretty({
@@ -1125,7 +1171,8 @@ var PinoLogger = class extends MastraLogger {
1125
1171
  {
1126
1172
  name: options.name || "app",
1127
1173
  level: options.level || LogLevel.INFO,
1128
- formatters: options.formatters
1174
+ formatters: options.formatters,
1175
+ redact: options.redact
1129
1176
  },
1130
1177
  options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
1131
1178
  ...transportsAry.map(([, transport]) => ({
@@ -1139,6 +1186,38 @@ var PinoLogger = class extends MastraLogger {
1139
1186
  ])
1140
1187
  );
1141
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
+ }
1142
1221
  debug(message, args = {}) {
1143
1222
  this.logger.debug(args, message);
1144
1223
  }
@@ -1153,19 +1232,35 @@ var PinoLogger = class extends MastraLogger {
1153
1232
  }
1154
1233
  };
1155
1234
 
1235
+ var package_default = {
1236
+ version: "1.0.0-beta.16"};
1237
+ function getPackageManagerAddCommand(pm) {
1238
+ switch (pm) {
1239
+ case "npm":
1240
+ return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
1241
+ case "yarn":
1242
+ return "add";
1243
+ case "pnpm":
1244
+ return "add --loglevel=error";
1245
+ case "bun":
1246
+ return "add";
1247
+ default:
1248
+ return "add";
1249
+ }
1250
+ }
1156
1251
  var DepsService = class {
1157
1252
  packageManager;
1158
1253
  constructor() {
1159
1254
  this.packageManager = this.getPackageManager();
1160
1255
  }
1161
1256
  findLockFile(dir) {
1162
- const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
1257
+ const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock", "bun.lockb"];
1163
1258
  for (const file of lockFiles) {
1164
- if (fs3__default__default.existsSync(path2.join(dir, file))) {
1259
+ if (fs3__default__default.existsSync(path3.join(dir, file))) {
1165
1260
  return file;
1166
1261
  }
1167
1262
  }
1168
- const parentDir = path2.resolve(dir, "..");
1263
+ const parentDir = path3.resolve(dir, "..");
1169
1264
  if (parentDir !== dir) {
1170
1265
  return this.findLockFile(parentDir);
1171
1266
  }
@@ -1181,20 +1276,17 @@ var DepsService = class {
1181
1276
  case "yarn.lock":
1182
1277
  return "yarn";
1183
1278
  case "bun.lock":
1279
+ case "bun.lockb":
1184
1280
  return "bun";
1185
1281
  default:
1186
1282
  return "npm";
1187
1283
  }
1188
1284
  }
1189
1285
  async installPackages(packages) {
1190
- let runCommand = this.packageManager;
1191
- if (this.packageManager === "npm") {
1192
- runCommand = `${this.packageManager} i`;
1193
- } else {
1194
- runCommand = `${this.packageManager} add`;
1195
- }
1286
+ const pm = this.packageManager;
1287
+ const installCommand = getPackageManagerAddCommand(pm);
1196
1288
  const packageList = packages.join(" ");
1197
- return execa(`${runCommand} ${packageList}`, {
1289
+ return execa(`${pm} ${installCommand} ${packageList}`, {
1198
1290
  all: true,
1199
1291
  shell: true,
1200
1292
  stdio: "inherit"
@@ -1202,7 +1294,7 @@ var DepsService = class {
1202
1294
  }
1203
1295
  async checkDependencies(dependencies) {
1204
1296
  try {
1205
- const packageJsonPath = path2.join(process.cwd(), "package.json");
1297
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1206
1298
  try {
1207
1299
  await fs4.access(packageJsonPath);
1208
1300
  } catch {
@@ -1222,7 +1314,7 @@ var DepsService = class {
1222
1314
  }
1223
1315
  async getProjectName() {
1224
1316
  try {
1225
- const packageJsonPath = path2.join(process.cwd(), "package.json");
1317
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1226
1318
  const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
1227
1319
  const pkg = JSON.parse(packageJson);
1228
1320
  return pkg.name;
@@ -1230,13 +1322,6 @@ var DepsService = class {
1230
1322
  throw err;
1231
1323
  }
1232
1324
  }
1233
- async getPackageVersion() {
1234
- const __filename = fileURLToPath(import.meta.url);
1235
- const __dirname = dirname(__filename);
1236
- const pkgJsonPath = path2.join(__dirname, "..", "package.json");
1237
- const content = await fsExtra3.readJSON(pkgJsonPath);
1238
- return content.version;
1239
- }
1240
1325
  async addScriptsToPackageJson(scripts) {
1241
1326
  const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
1242
1327
  packageJson.scripts = {
@@ -1246,153 +1331,6 @@ var DepsService = class {
1246
1331
  await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1247
1332
  }
1248
1333
  };
1249
- function getPackageManager() {
1250
- const userAgent = process.env.npm_config_user_agent || "";
1251
- const execPath = process.env.npm_execpath || "";
1252
- if (userAgent.includes("yarn")) {
1253
- return "yarn";
1254
- }
1255
- if (userAgent.includes("pnpm")) {
1256
- return "pnpm";
1257
- }
1258
- if (userAgent.includes("npm")) {
1259
- return "npm";
1260
- }
1261
- if (execPath.includes("yarn")) {
1262
- return "yarn";
1263
- }
1264
- if (execPath.includes("pnpm")) {
1265
- return "pnpm";
1266
- }
1267
- if (execPath.includes("npm")) {
1268
- return "npm";
1269
- }
1270
- return "npm";
1271
- }
1272
- function getPackageManagerInstallCommand(pm) {
1273
- switch (pm) {
1274
- case "npm":
1275
- return "install";
1276
- case "yarn":
1277
- return "add";
1278
- case "pnpm":
1279
- return "add";
1280
- default:
1281
- return "install";
1282
- }
1283
- }
1284
- var args = ["-y", "@mastra/mcp-docs-server"];
1285
- var createMcpConfig = (editor) => {
1286
- if (editor === "vscode") {
1287
- return {
1288
- servers: {
1289
- mastra: process.platform === `win32` ? {
1290
- command: "cmd",
1291
- args: ["/c", "npx", ...args],
1292
- type: "stdio"
1293
- } : {
1294
- command: "npx",
1295
- args,
1296
- type: "stdio"
1297
- }
1298
- }
1299
- };
1300
- }
1301
- return {
1302
- mcpServers: {
1303
- mastra: {
1304
- command: "npx",
1305
- args
1306
- }
1307
- }
1308
- };
1309
- };
1310
- function makeConfig(original, editor) {
1311
- if (editor === "vscode") {
1312
- return {
1313
- ...original,
1314
- servers: {
1315
- ...original?.servers || {},
1316
- ...createMcpConfig(editor).servers
1317
- }
1318
- };
1319
- }
1320
- return {
1321
- ...original,
1322
- mcpServers: {
1323
- ...original?.mcpServers || {},
1324
- ...createMcpConfig(editor).mcpServers
1325
- }
1326
- };
1327
- }
1328
- async function writeMergedConfig(configPath, editor) {
1329
- const configExists = existsSync(configPath);
1330
- const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
1331
- await ensureFile(configPath);
1332
- await writeJSON(configPath, config, {
1333
- spaces: 2
1334
- });
1335
- }
1336
- var windsurfGlobalMCPConfigPath = path2.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1337
- var cursorGlobalMCPConfigPath = path2.join(os.homedir(), ".cursor", "mcp.json");
1338
- path2.join(process.cwd(), ".vscode", "mcp.json");
1339
- var vscodeGlobalMCPConfigPath = path2.join(
1340
- os.homedir(),
1341
- process.platform === "win32" ? path2.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path2.join("Library", "Application Support", "Code", "User", "settings.json") : path2.join(".config", "Code", "User", "settings.json")
1342
- );
1343
- async function installMastraDocsMCPServer({ editor, directory }) {
1344
- if (editor === `cursor`) {
1345
- await writeMergedConfig(path2.join(directory, ".cursor", "mcp.json"), "cursor");
1346
- }
1347
- if (editor === `vscode`) {
1348
- await writeMergedConfig(path2.join(directory, ".vscode", "mcp.json"), "vscode");
1349
- }
1350
- if (editor === `cursor-global`) {
1351
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1352
- if (alreadyInstalled) {
1353
- return;
1354
- }
1355
- await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
1356
- }
1357
- if (editor === `windsurf`) {
1358
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1359
- if (alreadyInstalled) {
1360
- return;
1361
- }
1362
- await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
1363
- }
1364
- }
1365
- async function globalMCPIsAlreadyInstalled(editor) {
1366
- let configPath = ``;
1367
- if (editor === "windsurf") {
1368
- configPath = windsurfGlobalMCPConfigPath;
1369
- } else if (editor === "cursor-global") {
1370
- configPath = cursorGlobalMCPConfigPath;
1371
- } else if (editor === "vscode") {
1372
- configPath = vscodeGlobalMCPConfigPath;
1373
- }
1374
- if (!configPath || !existsSync(configPath)) {
1375
- return false;
1376
- }
1377
- try {
1378
- const configContents = await readJSON(configPath);
1379
- if (!configContents) return false;
1380
- if (editor === "vscode") {
1381
- if (!configContents.servers) return false;
1382
- const hasMastraMCP2 = Object.values(configContents.servers).some(
1383
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1384
- );
1385
- return hasMastraMCP2;
1386
- }
1387
- if (!configContents?.mcpServers) return false;
1388
- const hasMastraMCP = Object.values(configContents.mcpServers).some(
1389
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1390
- );
1391
- return hasMastraMCP;
1392
- } catch {
1393
- return false;
1394
- }
1395
- }
1396
1334
  var EnvService = class {
1397
1335
  };
1398
1336
  var FileEnvService = class extends EnvService {
@@ -1431,7 +1369,7 @@ var FileEnvService = class extends EnvService {
1431
1369
  ${key}=${value}`;
1432
1370
  }
1433
1371
  await this.writeFile({ filePath, data });
1434
- console.log(`${key} set to ${value} in ENV file.`);
1372
+ console.info(`${key} set to ${value} in ENV file.`);
1435
1373
  return data;
1436
1374
  }
1437
1375
  async getEnvValue(key) {
@@ -1464,19 +1402,19 @@ var FileService = class {
1464
1402
  */
1465
1403
  async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
1466
1404
  const __filename = fileURLToPath(import.meta.url);
1467
- const __dirname = path2.dirname(__filename);
1468
- const filePath = path2.resolve(__dirname, "starter-files", inputFile);
1405
+ const __dirname = path3.dirname(__filename);
1406
+ const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1469
1407
  const fileString = fs3__default__default.readFileSync(filePath, "utf8");
1470
1408
  if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1471
- console.log(`${outputFilePath} already exists`);
1409
+ console.info(`${outputFilePath} already exists`);
1472
1410
  return false;
1473
1411
  }
1474
- await fsExtra3.outputFile(outputFilePath, fileString);
1412
+ await fsExtra.outputFile(outputFilePath, fileString);
1475
1413
  return true;
1476
1414
  }
1477
1415
  async setupEnvFile({ dbUrl }) {
1478
- const envPath = path2.join(process.cwd(), ".env.development");
1479
- await fsExtra3.ensureFile(envPath);
1416
+ const envPath = path3.join(process.cwd(), ".env.development");
1417
+ await fsExtra.ensureFile(envPath);
1480
1418
  const fileEnvService = new FileEnvService(envPath);
1481
1419
  await fileEnvService.setEnvValue("DB_URL", dbUrl);
1482
1420
  }
@@ -1499,92 +1437,216 @@ var FileService = class {
1499
1437
  fs3__default__default.writeFileSync(filePath, fileContent);
1500
1438
  }
1501
1439
  };
1502
- new PinoLogger({
1503
- name: "Mastra CLI",
1504
- level: "info"
1505
- });
1506
- var exec = util.promisify(child_process.exec);
1507
- var getAISDKPackage = (llmProvider) => {
1508
- switch (llmProvider) {
1509
- case "openai":
1510
- return "@ai-sdk/openai";
1511
- case "anthropic":
1512
- return "@ai-sdk/anthropic";
1513
- case "groq":
1514
- return "@ai-sdk/groq";
1515
- case "google":
1516
- return "@ai-sdk/google";
1517
- case "cerebras":
1518
- return "@ai-sdk/cerebras";
1519
- default:
1520
- return "@ai-sdk/openai";
1521
- }
1440
+ var createArgs = (versionTag) => {
1441
+ const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1442
+ return ["-y", packageName];
1522
1443
  };
1523
- var getProviderImportAndModelItem = (llmProvider) => {
1524
- let providerImport = "";
1525
- let modelItem = "";
1526
- if (llmProvider === "openai") {
1527
- providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
1528
- modelItem = `openai('gpt-4o-mini')`;
1529
- } else if (llmProvider === "anthropic") {
1530
- providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
1531
- modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
1532
- } else if (llmProvider === "groq") {
1533
- providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1534
- modelItem = `groq('llama-3.3-70b-versatile')`;
1535
- } else if (llmProvider === "google") {
1536
- providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
1537
- modelItem = `google('gemini-2.5-pro-exp-03-25')`;
1538
- } else if (llmProvider === "cerebras") {
1539
- providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
1540
- modelItem = `cerebras('llama-3.3-70b')`;
1444
+ var createMcpConfig = (editor, versionTag) => {
1445
+ const args = createArgs(versionTag);
1446
+ if (editor === "vscode") {
1447
+ return {
1448
+ servers: {
1449
+ mastra: process.platform === `win32` ? {
1450
+ command: "cmd",
1451
+ args: ["/c", "npx", ...args],
1452
+ type: "stdio"
1453
+ } : {
1454
+ command: "npx",
1455
+ args,
1456
+ type: "stdio"
1457
+ }
1458
+ }
1459
+ };
1541
1460
  }
1542
- return { providerImport, modelItem };
1461
+ return {
1462
+ mcpServers: {
1463
+ mastra: {
1464
+ command: "npx",
1465
+ args
1466
+ }
1467
+ }
1468
+ };
1543
1469
  };
1544
- async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1545
- const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1546
- const instructions = `
1547
- You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
1548
-
1549
- Your primary function is to help users get weather details for specific locations. When responding:
1550
- - Always ask for a location if none is provided
1551
- - If the location name isn't in English, please translate it
1552
- - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
1553
- - Include relevant details like humidity, wind conditions, and precipitation
1554
- - Keep responses concise but informative
1555
- - If the user asks for activities and provides the weather forecast, suggest activities based on the weather forecast.
1556
- - If the user asks for activities, respond in the format they request.
1557
-
1558
- ${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
1559
- `;
1560
- const content = `
1561
- ${providerImport}
1562
- import { Agent } from '@mastra/core/agent';
1563
- import { Memory } from '@mastra/memory';
1564
- import { LibSQLStore } from '@mastra/libsql';
1565
- ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
1566
-
1567
- export const weatherAgent = new Agent({
1568
- name: 'Weather Agent',
1569
- instructions: \`${instructions}\`,
1570
- model: ${modelItem},
1571
- ${addExampleTool ? "tools: { weatherTool }," : ""}
1572
- memory: new Memory({
1573
- storage: new LibSQLStore({
1574
- url: "file:../mastra.db", // path is relative to the .mastra/output directory
1575
- })
1576
- })
1577
- });
1578
- `;
1579
- const formattedContent = await prettier.format(content, {
1580
- parser: "typescript",
1581
- singleQuote: true
1582
- });
1583
- await fs4.writeFile(destPath, "");
1584
- await fs4.writeFile(destPath, formattedContent);
1470
+ function makeConfig(original, editor, versionTag) {
1471
+ if (editor === "vscode") {
1472
+ return {
1473
+ ...original,
1474
+ servers: {
1475
+ ...original?.servers || {},
1476
+ ...createMcpConfig(editor, versionTag).servers
1477
+ }
1478
+ };
1479
+ }
1480
+ return {
1481
+ ...original,
1482
+ mcpServers: {
1483
+ ...original?.mcpServers || {},
1484
+ ...createMcpConfig(editor, versionTag).mcpServers
1485
+ }
1486
+ };
1585
1487
  }
1586
- async function writeWorkflowSample(destPath) {
1587
- const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
1488
+ async function writeMergedConfig(configPath, editor, versionTag) {
1489
+ const configExists = existsSync(configPath);
1490
+ const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor, versionTag);
1491
+ await ensureFile(configPath);
1492
+ await writeJSON(configPath, config, {
1493
+ spaces: 2
1494
+ });
1495
+ }
1496
+ var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1497
+ var antigravityGlobalMCPConfigPath = path3.join(os.homedir(), ".gemini", "antigravity", "mcp_config.json");
1498
+ var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1499
+ path3.join(process.cwd(), ".vscode", "mcp.json");
1500
+ var vscodeGlobalMCPConfigPath = path3.join(
1501
+ os.homedir(),
1502
+ 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")
1503
+ );
1504
+ async function installMastraDocsMCPServer({
1505
+ editor,
1506
+ directory,
1507
+ versionTag
1508
+ }) {
1509
+ if (editor === `cursor`) {
1510
+ await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor", versionTag);
1511
+ }
1512
+ if (editor === `vscode`) {
1513
+ await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode", versionTag);
1514
+ }
1515
+ if (editor === `cursor-global`) {
1516
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1517
+ if (alreadyInstalled) {
1518
+ return;
1519
+ }
1520
+ await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global", versionTag);
1521
+ }
1522
+ if (editor === `windsurf`) {
1523
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1524
+ if (alreadyInstalled) {
1525
+ return;
1526
+ }
1527
+ await writeMergedConfig(windsurfGlobalMCPConfigPath, editor, versionTag);
1528
+ }
1529
+ if (editor === `antigravity`) {
1530
+ const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
1531
+ if (alreadyInstalled) {
1532
+ return;
1533
+ }
1534
+ await writeMergedConfig(antigravityGlobalMCPConfigPath, editor, versionTag);
1535
+ }
1536
+ }
1537
+ async function globalMCPIsAlreadyInstalled(editor, versionTag) {
1538
+ let configPath = ``;
1539
+ if (editor === "windsurf") {
1540
+ configPath = windsurfGlobalMCPConfigPath;
1541
+ } else if (editor === "antigravity") {
1542
+ configPath = antigravityGlobalMCPConfigPath;
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
+ const expectedPackage = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1555
+ if (editor === "vscode") {
1556
+ if (!configContents.servers) return false;
1557
+ const hasMastraMCP2 = Object.values(configContents.servers).some(
1558
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1559
+ );
1560
+ return hasMastraMCP2;
1561
+ }
1562
+ if (!configContents?.mcpServers) return false;
1563
+ const hasMastraMCP = Object.values(configContents.mcpServers).some(
1564
+ (server) => server?.args?.find((arg) => arg === expectedPackage)
1565
+ );
1566
+ return hasMastraMCP;
1567
+ } catch {
1568
+ return false;
1569
+ }
1570
+ }
1571
+ var exec = util.promisify(child_process.exec);
1572
+ var getModelIdentifier = (llmProvider) => {
1573
+ let model = "openai/gpt-4o";
1574
+ if (llmProvider === "anthropic") {
1575
+ model = "anthropic/claude-sonnet-4-5";
1576
+ } else if (llmProvider === "groq") {
1577
+ model = "groq/llama-3.3-70b-versatile";
1578
+ } else if (llmProvider === "google") {
1579
+ model = "google/gemini-2.5-pro";
1580
+ } else if (llmProvider === "cerebras") {
1581
+ model = "cerebras/llama-3.3-70b";
1582
+ } else if (llmProvider === "mistral") {
1583
+ model = "mistral/mistral-medium-2508";
1584
+ }
1585
+ return model;
1586
+ };
1587
+ async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
1588
+ const modelString = getModelIdentifier(llmProvider);
1589
+ const instructions = `
1590
+ You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
1591
+
1592
+ Your primary function is to help users get weather details for specific locations. When responding:
1593
+ - Always ask for a location if none is provided
1594
+ - If the location name isn't in English, please translate it
1595
+ - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
1596
+ - Include relevant details like humidity, wind conditions, and precipitation
1597
+ - Keep responses concise but informative
1598
+ - If the user asks for activities and provides the weather forecast, suggest activities based on the weather forecast.
1599
+ - If the user asks for activities, respond in the format they request.
1600
+
1601
+ ${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
1602
+ `;
1603
+ const content = `
1604
+ import { Agent } from '@mastra/core/agent';
1605
+ import { Memory } from '@mastra/memory';
1606
+ ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
1607
+ ${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
1608
+
1609
+ export const weatherAgent = new Agent({
1610
+ id: 'weather-agent',
1611
+ name: 'Weather Agent',
1612
+ instructions: \`${instructions}\`,
1613
+ model: '${modelString}',
1614
+ ${addExampleTool ? "tools: { weatherTool }," : ""}
1615
+ ${addScorers ? `scorers: {
1616
+ toolCallAppropriateness: {
1617
+ scorer: scorers.toolCallAppropriatenessScorer,
1618
+ sampling: {
1619
+ type: 'ratio',
1620
+ rate: 1,
1621
+ },
1622
+ },
1623
+ completeness: {
1624
+ scorer: scorers.completenessScorer,
1625
+ sampling: {
1626
+ type: 'ratio',
1627
+ rate: 1,
1628
+ },
1629
+ },
1630
+ translation: {
1631
+ scorer: scorers.translationScorer,
1632
+ sampling: {
1633
+ type: 'ratio',
1634
+ rate: 1,
1635
+ },
1636
+ },
1637
+ },` : ""}
1638
+ memory: new Memory()
1639
+ });
1640
+ `;
1641
+ const formattedContent = await prettier.format(content, {
1642
+ parser: "typescript",
1643
+ singleQuote: true
1644
+ });
1645
+ await fs4.writeFile(destPath, "");
1646
+ await fs4.writeFile(destPath, formattedContent);
1647
+ }
1648
+ async function writeWorkflowSample(destPath) {
1649
+ const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
1588
1650
  import { z } from 'zod';
1589
1651
 
1590
1652
  const forecastSchema = z.object({
@@ -1780,41 +1842,138 @@ async function writeToolSample(destPath) {
1780
1842
  const fileService = new FileService();
1781
1843
  await fileService.copyStarterFile("tools.ts", destPath);
1782
1844
  }
1845
+ async function writeScorersSample(llmProvider, destPath) {
1846
+ const modelString = getModelIdentifier(llmProvider);
1847
+ const content = `import { z } from 'zod';
1848
+ import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
1849
+ import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
1850
+ import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
1851
+ import { createScorer } from '@mastra/core/evals';
1852
+
1853
+ export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
1854
+ expectedTool: 'weatherTool',
1855
+ strictMode: false,
1856
+ });
1857
+
1858
+ export const completenessScorer = createCompletenessScorer();
1859
+
1860
+ // Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
1861
+ export const translationScorer = createScorer({
1862
+ id: 'translation-quality-scorer',
1863
+ name: 'Translation Quality',
1864
+ description: 'Checks that non-English location names are translated and used correctly',
1865
+ type: 'agent',
1866
+ judge: {
1867
+ model: '${modelString}',
1868
+ instructions:
1869
+ 'You are an expert evaluator of translation quality for geographic locations. ' +
1870
+ 'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
1871
+ 'Be lenient with transliteration differences and diacritics. ' +
1872
+ 'Return only the structured JSON matching the provided schema.',
1873
+ },
1874
+ })
1875
+ .preprocess(({ run }) => {
1876
+ const userText = getUserMessageFromRunInput(run.input) || '';
1877
+ const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
1878
+ return { userText, assistantText };
1879
+ })
1880
+ .analyze({
1881
+ description: 'Extract location names and detect language/translation adequacy',
1882
+ outputSchema: z.object({
1883
+ nonEnglish: z.boolean(),
1884
+ translated: z.boolean(),
1885
+ confidence: z.number().min(0).max(1).default(1),
1886
+ explanation: z.string().default(''),
1887
+ }),
1888
+ createPrompt: ({ results }) => \`
1889
+ You are evaluating if a weather assistant correctly handled translation of a non-English location.
1890
+ User text:
1891
+ """
1892
+ \${results.preprocessStepResult.userText}
1893
+ """
1894
+ Assistant response:
1895
+ """
1896
+ \${results.preprocessStepResult.assistantText}
1897
+ """
1898
+ Tasks:
1899
+ 1) Identify if the user mentioned a location that appears non-English.
1900
+ 2) If non-English, check whether the assistant used a correct English translation of that location in its response.
1901
+ 3) Be lenient with transliteration differences (e.g., accents/diacritics).
1902
+ Return JSON with fields:
1903
+ {
1904
+ "nonEnglish": boolean,
1905
+ "translated": boolean,
1906
+ "confidence": number, // 0-1
1907
+ "explanation": string
1908
+ }
1909
+ \`,
1910
+ })
1911
+ .generateScore(({ results }) => {
1912
+ const r = (results as any)?.analyzeStepResult || {};
1913
+ if (!r.nonEnglish) return 1; // If not applicable, full credit
1914
+ if (r.translated) return Math.max(0, Math.min(1, 0.7 + 0.3 * (r.confidence ?? 1)));
1915
+ return 0; // Non-English but not translated
1916
+ })
1917
+ .generateReason(({ results, score }) => {
1918
+ const r = (results as any)?.analyzeStepResult || {};
1919
+ return \`Translation scoring: nonEnglish=\${r.nonEnglish ?? false}, translated=\${r.translated ?? false}, confidence=\${r.confidence ?? 0}. Score=\${score}. \${r.explanation ?? ''}\`;
1920
+ });
1921
+
1922
+ export const scorers = {
1923
+ toolCallAppropriatenessScorer,
1924
+ completenessScorer,
1925
+ translationScorer,
1926
+ };`;
1927
+ const formattedContent = await prettier.format(content, {
1928
+ parser: "typescript",
1929
+ singleQuote: true
1930
+ });
1931
+ await fs4.writeFile(destPath, formattedContent);
1932
+ }
1783
1933
  async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
1784
1934
  switch (component) {
1785
1935
  case "agents":
1786
- return writeAgentSample(llmprovider, destPath, importComponents.includes("tools"));
1936
+ return writeAgentSample(
1937
+ llmprovider,
1938
+ destPath,
1939
+ importComponents.includes("tools"),
1940
+ importComponents.includes("scorers")
1941
+ );
1787
1942
  case "tools":
1788
1943
  return writeToolSample(destPath);
1789
1944
  case "workflows":
1790
1945
  return writeWorkflowSample(destPath);
1946
+ case "scorers":
1947
+ return writeScorersSample(llmprovider, destPath);
1791
1948
  default:
1792
1949
  return "";
1793
1950
  }
1794
1951
  }
1795
1952
  var createComponentsDir = async (dirPath, component) => {
1796
1953
  const componentPath = dirPath + `/${component}`;
1797
- await fsExtra3.ensureDir(componentPath);
1954
+ await fsExtra.ensureDir(componentPath);
1798
1955
  };
1799
1956
  var writeIndexFile = async ({
1800
1957
  dirPath,
1801
1958
  addAgent,
1802
1959
  addExample,
1803
- addWorkflow
1960
+ addWorkflow,
1961
+ addScorers
1804
1962
  }) => {
1805
1963
  const indexPath = dirPath + "/index.ts";
1806
- const destPath = path2.join(indexPath);
1964
+ const destPath = path3.join(indexPath);
1807
1965
  try {
1808
1966
  await fs4.writeFile(destPath, "");
1809
1967
  const filteredExports = [
1810
1968
  addWorkflow ? `workflows: { weatherWorkflow },` : "",
1811
- addAgent ? `agents: { weatherAgent },` : ""
1969
+ addAgent ? `agents: { weatherAgent },` : "",
1970
+ addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
1812
1971
  ].filter(Boolean);
1813
1972
  if (!addExample) {
1814
1973
  await fs4.writeFile(
1815
1974
  destPath,
1816
1975
  `
1817
- import { Mastra } from '@mastra/core';
1976
+ import { Mastra } from '@mastra/core/mastra';
1818
1977
 
1819
1978
  export const mastra = new Mastra()
1820
1979
  `
@@ -1827,19 +1986,36 @@ export const mastra = new Mastra()
1827
1986
  import { Mastra } from '@mastra/core/mastra';
1828
1987
  import { PinoLogger } from '@mastra/loggers';
1829
1988
  import { LibSQLStore } from '@mastra/libsql';
1989
+ import { Observability, DefaultExporter, CloudExporter, SensitiveDataFilter } from '@mastra/observability';
1830
1990
  ${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
1831
1991
  ${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
1992
+ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
1832
1993
 
1833
1994
  export const mastra = new Mastra({
1834
1995
  ${filteredExports.join("\n ")}
1835
1996
  storage: new LibSQLStore({
1836
- // stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
1997
+ id: "mastra-storage",
1998
+ // stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
1837
1999
  url: ":memory:",
1838
2000
  }),
1839
2001
  logger: new PinoLogger({
1840
2002
  name: 'Mastra',
1841
2003
  level: 'info',
1842
2004
  }),
2005
+ observability: new Observability({
2006
+ configs: {
2007
+ default: {
2008
+ serviceName: 'mastra',
2009
+ exporters: [
2010
+ new DefaultExporter(), // Persists traces to storage for Mastra Studio
2011
+ new CloudExporter(), // Sends traces to Mastra Cloud (if MASTRA_CLOUD_ACCESS_TOKEN is set)
2012
+ ],
2013
+ spanOutputProcessors: [
2014
+ new SensitiveDataFilter(), // Redacts sensitive data like passwords, tokens, keys
2015
+ ],
2016
+ },
2017
+ },
2018
+ }),
1843
2019
  });
1844
2020
  `
1845
2021
  );
@@ -1847,7 +2023,6 @@ export const mastra = new Mastra({
1847
2023
  throw err;
1848
2024
  }
1849
2025
  };
1850
- yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
1851
2026
  var getAPIKey = async (provider) => {
1852
2027
  let key = "OPENAI_API_KEY";
1853
2028
  switch (provider) {
@@ -1863,27 +2038,28 @@ var getAPIKey = async (provider) => {
1863
2038
  case "cerebras":
1864
2039
  key = "CEREBRAS_API_KEY";
1865
2040
  return key;
2041
+ case "mistral":
2042
+ key = "MISTRAL_API_KEY";
2043
+ return key;
1866
2044
  default:
1867
2045
  return key;
1868
2046
  }
1869
2047
  };
1870
- var writeAPIKey = async ({
1871
- provider,
1872
- apiKey = "your-api-key"
1873
- }) => {
2048
+ var writeAPIKey = async ({ provider, apiKey }) => {
2049
+ const envFileName = apiKey ? ".env" : ".env.example";
1874
2050
  const key = await getAPIKey(provider);
1875
- const escapedKey = shellQuote.quote([key]);
1876
- const escapedApiKey = shellQuote.quote([apiKey]);
1877
- await exec(`echo ${escapedKey}=${escapedApiKey} >> .env`);
2051
+ const escapedKey = shellQuote2.quote([key]);
2052
+ const escapedApiKey = shellQuote2.quote([apiKey ? apiKey : "your-api-key"]);
2053
+ await exec(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
1878
2054
  };
1879
2055
  var createMastraDir = async (directory) => {
1880
2056
  let dir = directory.trim().split("/").filter((item) => item !== "");
1881
- const dirPath = path2.join(process.cwd(), ...dir, "mastra");
2057
+ const dirPath = path3.join(process.cwd(), ...dir, "mastra");
1882
2058
  try {
1883
2059
  await fs4.access(dirPath);
1884
2060
  return { ok: false };
1885
2061
  } catch {
1886
- await fsExtra3.ensureDir(dirPath);
2062
+ await fsExtra.ensureDir(dirPath);
1887
2063
  return { ok: true, dirPath };
1888
2064
  }
1889
2065
  };
@@ -1895,8 +2071,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
1895
2071
  throw err;
1896
2072
  }
1897
2073
  };
1898
- var interactivePrompt = async () => {
1899
- Ie(color2.inverse(" Mastra Init "));
2074
+ var LLM_PROVIDERS = [
2075
+ { value: "openai", label: "OpenAI", hint: "recommended" },
2076
+ { value: "anthropic", label: "Anthropic" },
2077
+ { value: "groq", label: "Groq" },
2078
+ { value: "google", label: "Google" },
2079
+ { value: "cerebras", label: "Cerebras" },
2080
+ { value: "mistral", label: "Mistral" }
2081
+ ];
2082
+ var interactivePrompt = async (args = {}) => {
2083
+ const { skip = {}, options: { showBanner = true } = {} } = args;
2084
+ if (showBanner) {
2085
+ Ie(color2.inverse(" Mastra Init "));
2086
+ }
1900
2087
  const mastraProject = await Ce(
1901
2088
  {
1902
2089
  directory: () => he({
@@ -1904,19 +2091,15 @@ var interactivePrompt = async () => {
1904
2091
  placeholder: "src/",
1905
2092
  defaultValue: "src/"
1906
2093
  }),
1907
- llmProvider: () => ve({
1908
- message: "Select default provider:",
1909
- options: [
1910
- { value: "openai", label: "OpenAI", hint: "recommended" },
1911
- { value: "anthropic", label: "Anthropic" },
1912
- { value: "groq", label: "Groq" },
1913
- { value: "google", label: "Google" },
1914
- { value: "cerebras", label: "Cerebras" }
1915
- ]
2094
+ llmProvider: () => skip?.llmProvider ? void 0 : ve({
2095
+ message: "Select a default provider:",
2096
+ options: LLM_PROVIDERS
1916
2097
  }),
1917
2098
  llmApiKey: async ({ results: { llmProvider } }) => {
2099
+ if (skip?.llmApiKey) return void 0;
2100
+ const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
1918
2101
  const keyChoice = await ve({
1919
- message: `Enter your ${llmProvider} API key?`,
2102
+ message: `Enter your ${llmName} API key?`,
1920
2103
  options: [
1921
2104
  { value: "skip", label: "Skip for now", hint: "default" },
1922
2105
  { value: "enter", label: "Enter API key" }
@@ -1926,52 +2109,42 @@ var interactivePrompt = async () => {
1926
2109
  if (keyChoice === "enter") {
1927
2110
  return he({
1928
2111
  message: "Enter your API key:",
1929
- placeholder: "sk-..."
2112
+ placeholder: "sk-...",
2113
+ validate: (value) => {
2114
+ if (value.length === 0) return "API key cannot be empty";
2115
+ }
1930
2116
  });
1931
2117
  }
1932
2118
  return void 0;
1933
2119
  },
1934
2120
  configureEditorWithDocsMCP: async () => {
1935
- const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
1936
- const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
1937
- const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
1938
2121
  const editor = await ve({
1939
- message: `Make your AI IDE into a Mastra expert? (installs Mastra docs MCP server)`,
2122
+ message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
1940
2123
  options: [
1941
2124
  { value: "skip", label: "Skip for now", hint: "default" },
1942
2125
  {
1943
2126
  value: "cursor",
1944
- label: "Cursor (project only)",
1945
- hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
2127
+ label: "Cursor (project only)"
1946
2128
  },
1947
2129
  {
1948
2130
  value: "cursor-global",
1949
- label: "Cursor (global, all projects)",
1950
- hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
2131
+ label: "Cursor (global, all projects)"
1951
2132
  },
1952
2133
  {
1953
2134
  value: "windsurf",
1954
- label: "Windsurf",
1955
- hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
2135
+ label: "Windsurf"
1956
2136
  },
1957
2137
  {
1958
2138
  value: "vscode",
1959
- label: "VSCode",
1960
- hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
2139
+ label: "VSCode"
2140
+ },
2141
+ {
2142
+ value: "antigravity",
2143
+ label: "Antigravity"
1961
2144
  }
1962
2145
  ]
1963
2146
  });
1964
2147
  if (editor === `skip`) return void 0;
1965
- if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
1966
- M.message(`
1967
- Windsurf is already installed, skipping.`);
1968
- return void 0;
1969
- }
1970
- if (editor === `vscode` && vscodeIsAlreadyInstalled) {
1971
- M.message(`
1972
- VSCode is already installed, skipping.`);
1973
- return void 0;
1974
- }
1975
2148
  if (editor === `cursor`) {
1976
2149
  M.message(
1977
2150
  `
@@ -1980,19 +2153,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
1980
2153
  );
1981
2154
  }
1982
2155
  if (editor === `cursor-global`) {
1983
- const confirm2 = await ve({
2156
+ const confirm3 = await ve({
1984
2157
  message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
1985
2158
  options: [
1986
2159
  { value: "yes", label: "Yes, I understand" },
1987
2160
  { value: "skip", label: "No, skip for now" }
1988
2161
  ]
1989
2162
  });
1990
- if (confirm2 !== `yes`) {
2163
+ if (confirm3 !== `yes`) {
1991
2164
  return void 0;
1992
2165
  }
1993
2166
  }
1994
2167
  if (editor === `windsurf`) {
1995
- const confirm2 = await ve({
2168
+ const confirm3 = await ve({
1996
2169
  message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
1997
2170
  This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
1998
2171
  options: [
@@ -2000,11 +2173,31 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2000
2173
  { value: "skip", label: "No, skip for now" }
2001
2174
  ]
2002
2175
  });
2003
- if (confirm2 !== `yes`) {
2176
+ if (confirm3 !== `yes`) {
2177
+ return void 0;
2178
+ }
2179
+ }
2180
+ if (editor === `antigravity`) {
2181
+ const confirm3 = await ve({
2182
+ message: `Antigravity only supports a global MCP config (at ${antigravityGlobalMCPConfigPath}). Is it ok to add/update that global config?
2183
+ This will make the Mastra docs MCP server available in all Antigravity projects.`,
2184
+ options: [
2185
+ { value: "yes", label: "Yes, I understand" },
2186
+ { value: "skip", label: "No, skip for now" }
2187
+ ]
2188
+ });
2189
+ if (confirm3 !== `yes`) {
2004
2190
  return void 0;
2005
2191
  }
2006
2192
  }
2007
2193
  return editor;
2194
+ },
2195
+ initGit: async () => {
2196
+ if (skip?.gitInit) return false;
2197
+ return ye({
2198
+ message: "Initialize a new git repository?",
2199
+ initialValue: true
2200
+ });
2008
2201
  }
2009
2202
  },
2010
2203
  {
@@ -2016,17 +2209,245 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2016
2209
  );
2017
2210
  return mastraProject;
2018
2211
  };
2019
- var s = Y();
2212
+ function getPackageManager() {
2213
+ const userAgent = process.env.npm_config_user_agent || "";
2214
+ const execPath = process.env.npm_execpath || "";
2215
+ if (userAgent.includes("bun")) {
2216
+ return "bun";
2217
+ }
2218
+ if (userAgent.includes("yarn")) {
2219
+ return "yarn";
2220
+ }
2221
+ if (userAgent.includes("pnpm")) {
2222
+ return "pnpm";
2223
+ }
2224
+ if (userAgent.includes("npm")) {
2225
+ return "npm";
2226
+ }
2227
+ if (execPath.includes("bun")) {
2228
+ return "bun";
2229
+ }
2230
+ if (execPath.includes("yarn")) {
2231
+ return "yarn";
2232
+ }
2233
+ if (execPath.includes("pnpm")) {
2234
+ return "pnpm";
2235
+ }
2236
+ if (execPath.includes("npm")) {
2237
+ return "npm";
2238
+ }
2239
+ return "npm";
2240
+ }
2241
+ async function gitInit({ cwd }) {
2242
+ await execa("git", ["init"], { cwd, stdio: "ignore" });
2243
+ await execa("git", ["add", "-A"], { cwd, stdio: "ignore" });
2244
+ await execa(
2245
+ "git",
2246
+ [
2247
+ "commit",
2248
+ "-m",
2249
+ '"Initial commit from Mastra"',
2250
+ '--author="dane-ai-mastra[bot] <dane-ai-mastra[bot]@users.noreply.github.com>"'
2251
+ ],
2252
+ { cwd, stdio: "ignore" }
2253
+ );
2254
+ }
2255
+ var logger = createLogger(false);
2256
+ function createLogger(debug = false) {
2257
+ return new PinoLogger({
2258
+ name: "Mastra CLI",
2259
+ level: debug ? "debug" : "info"
2260
+ });
2261
+ }
2020
2262
  var exec2 = util.promisify(child_process.exec);
2263
+ async function cloneTemplate(options) {
2264
+ const { template, projectName, targetDir, branch, llmProvider } = options;
2265
+ const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
2266
+ const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
2267
+ try {
2268
+ if (await directoryExists(projectPath)) {
2269
+ spinner4.error(`Directory ${projectName} already exists`);
2270
+ throw new Error(`Directory ${projectName} already exists`);
2271
+ }
2272
+ await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
2273
+ await updatePackageJson(projectPath, projectName);
2274
+ const envExamplePath = path3.join(projectPath, ".env.example");
2275
+ if (await fileExists(envExamplePath)) {
2276
+ const envPath = path3.join(projectPath, ".env");
2277
+ await fs4.copyFile(envExamplePath, envPath);
2278
+ if (llmProvider) {
2279
+ await updateEnvFile(envPath, llmProvider);
2280
+ }
2281
+ }
2282
+ spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
2283
+ return projectPath;
2284
+ } catch (error) {
2285
+ spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
2286
+ throw error;
2287
+ }
2288
+ }
2289
+ async function directoryExists(dirPath) {
2290
+ try {
2291
+ const stat = await fs4.stat(dirPath);
2292
+ return stat.isDirectory();
2293
+ } catch {
2294
+ return false;
2295
+ }
2296
+ }
2297
+ async function fileExists(filePath) {
2298
+ try {
2299
+ const stat = await fs4.stat(filePath);
2300
+ return stat.isFile();
2301
+ } catch {
2302
+ return false;
2303
+ }
2304
+ }
2305
+ async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
2306
+ await fs4.mkdir(targetPath, { recursive: true });
2307
+ try {
2308
+ const degitRepo = repoUrl.replace("https://github.com/", "");
2309
+ const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
2310
+ const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
2311
+ await exec2(degitCommand, {
2312
+ cwd: process.cwd()
2313
+ });
2314
+ } catch {
2315
+ try {
2316
+ const gitArgs = ["git", "clone"];
2317
+ if (branch) {
2318
+ gitArgs.push("--branch", branch);
2319
+ }
2320
+ gitArgs.push(repoUrl, targetPath);
2321
+ const gitCommand = shellQuote2.quote(gitArgs);
2322
+ await exec2(gitCommand, {
2323
+ cwd: process.cwd()
2324
+ });
2325
+ const gitDir = path3.join(targetPath, ".git");
2326
+ if (await directoryExists(gitDir)) {
2327
+ await fs4.rm(gitDir, { recursive: true, force: true });
2328
+ }
2329
+ } catch (gitError) {
2330
+ throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
2331
+ }
2332
+ }
2333
+ }
2334
+ async function updatePackageJson(projectPath, projectName) {
2335
+ const packageJsonPath = path3.join(projectPath, "package.json");
2336
+ try {
2337
+ const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
2338
+ const packageJson = JSON.parse(packageJsonContent);
2339
+ packageJson.name = projectName;
2340
+ await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
2341
+ } catch (error) {
2342
+ logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
2343
+ }
2344
+ }
2345
+ async function updateEnvFile(envPath, llmProvider) {
2346
+ try {
2347
+ const envContent = await fs4.readFile(envPath, "utf-8");
2348
+ const modelString = getModelIdentifier(llmProvider);
2349
+ if (!modelString) {
2350
+ logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
2351
+ return;
2352
+ }
2353
+ const modelValue = modelString.replace(/'/g, "");
2354
+ const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
2355
+ await fs4.writeFile(envPath, updatedContent, "utf-8");
2356
+ logger.info(`Updated MODEL in .env to ${modelValue}`);
2357
+ } catch (error) {
2358
+ logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
2359
+ }
2360
+ }
2361
+ async function installDependencies(projectPath, packageManager) {
2362
+ const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
2363
+ try {
2364
+ const pm = packageManager || getPackageManager();
2365
+ const installCommand = shellQuote2.quote([pm, "install"]);
2366
+ await exec2(installCommand, {
2367
+ cwd: projectPath
2368
+ });
2369
+ spinner4.success("Dependencies installed successfully");
2370
+ } catch (error) {
2371
+ spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
2372
+ throw error;
2373
+ }
2374
+ }
2375
+ var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
2376
+ async function loadTemplates() {
2377
+ try {
2378
+ const response = await fetch(TEMPLATES_API_URL);
2379
+ if (!response.ok) {
2380
+ throw new Error(`Failed to fetch templates: ${response.statusText}`);
2381
+ }
2382
+ const templates = await response.json();
2383
+ return templates;
2384
+ } catch (error) {
2385
+ console.error("Error loading templates:", error);
2386
+ throw new Error("Failed to load templates. Please check your internet connection and try again.");
2387
+ }
2388
+ }
2389
+ function pluralize(count, singular, plural) {
2390
+ return count === 1 ? singular : plural || `${singular}s`;
2391
+ }
2392
+ async function selectTemplate(templates) {
2393
+ const choices = templates.map((template) => {
2394
+ const parts = [];
2395
+ if (template.agents?.length) {
2396
+ parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
2397
+ }
2398
+ if (template.tools?.length) {
2399
+ parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
2400
+ }
2401
+ if (template.workflows?.length) {
2402
+ parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
2403
+ }
2404
+ if (template.mcp?.length) {
2405
+ parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
2406
+ }
2407
+ if (template.networks?.length) {
2408
+ parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
2409
+ }
2410
+ return {
2411
+ value: template,
2412
+ label: template.title,
2413
+ hint: parts.join(", ") || "Template components"
2414
+ };
2415
+ });
2416
+ const selected = await ve({
2417
+ message: "Select a template:",
2418
+ options: choices
2419
+ });
2420
+ if (pD(selected)) {
2421
+ return null;
2422
+ }
2423
+ return selected;
2424
+ }
2425
+ function findTemplateByName(templates, templateName) {
2426
+ let template = templates.find((t) => t.slug === templateName);
2427
+ if (template) return template;
2428
+ const slugWithPrefix = `template-${templateName}`;
2429
+ template = templates.find((t) => t.slug === slugWithPrefix);
2430
+ if (template) return template;
2431
+ template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
2432
+ if (template) return template;
2433
+ return null;
2434
+ }
2435
+ function getDefaultProjectName(template) {
2436
+ return template.slug.replace(/^template-/, "");
2437
+ }
2438
+ var s = Y();
2021
2439
  var init = async ({
2022
- directory,
2023
- addExample = false,
2440
+ directory = "src/",
2024
2441
  components,
2025
2442
  llmProvider = "openai",
2026
2443
  llmApiKey,
2027
- configureEditorWithDocsMCP
2444
+ addExample = false,
2445
+ configureEditorWithDocsMCP,
2446
+ versionTag,
2447
+ initGit = false
2028
2448
  }) => {
2029
2449
  s.start("Initializing Mastra");
2450
+ const packageVersionTag = versionTag ? `@${versionTag}` : "";
2030
2451
  try {
2031
2452
  const result = await createMastraDir(directory);
2032
2453
  if (!result.ok) {
@@ -2039,7 +2460,8 @@ var init = async ({
2039
2460
  dirPath,
2040
2461
  addExample,
2041
2462
  addWorkflow: components.includes("workflows"),
2042
- addAgent: components.includes("agents")
2463
+ addAgent: components.includes("agents"),
2464
+ addScorers: components.includes("scorers")
2043
2465
  }),
2044
2466
  ...components.map((component) => createComponentsDir(dirPath, component)),
2045
2467
  writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
@@ -2053,30 +2475,44 @@ var init = async ({
2053
2475
  const depService = new DepsService();
2054
2476
  const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
2055
2477
  if (needsLibsql) {
2056
- await depService.installPackages(["@mastra/libsql"]);
2478
+ await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
2057
2479
  }
2058
2480
  const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
2059
2481
  if (needsMemory) {
2060
- await depService.installPackages(["@mastra/memory"]);
2482
+ await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
2061
2483
  }
2062
2484
  const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
2063
2485
  if (needsLoggers) {
2064
- await depService.installPackages(["@mastra/loggers"]);
2486
+ await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
2487
+ }
2488
+ const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
2489
+ if (needsObservability) {
2490
+ await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
2491
+ }
2492
+ const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
2493
+ if (needsEvals) {
2494
+ await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
2065
2495
  }
2066
2496
  }
2067
2497
  const key = await getAPIKey(llmProvider || "openai");
2068
- const aiSdkPackage = getAISDKPackage(llmProvider);
2069
- const depsService = new DepsService();
2070
- const pm = depsService.packageManager;
2071
- const installCommand = getPackageManagerInstallCommand(pm);
2072
- await exec2(`${pm} ${installCommand} ${aiSdkPackage}`);
2073
2498
  if (configureEditorWithDocsMCP) {
2074
2499
  await installMastraDocsMCPServer({
2075
2500
  editor: configureEditorWithDocsMCP,
2076
- directory: process.cwd()
2501
+ directory: process.cwd(),
2502
+ versionTag
2077
2503
  });
2078
2504
  }
2079
2505
  s.stop();
2506
+ if (initGit) {
2507
+ const s2 = Y();
2508
+ try {
2509
+ s2.start("Initializing git repository");
2510
+ await gitInit({ cwd: process.cwd() });
2511
+ s2.stop("Git repository initialized");
2512
+ } catch {
2513
+ s2.stop();
2514
+ }
2515
+ }
2080
2516
  if (!llmApiKey) {
2081
2517
  Me(`
2082
2518
  ${color2.green("Mastra initialized successfully!")}
@@ -2122,10 +2558,72 @@ var execWithTimeout = async (command, timeoutMs) => {
2122
2558
  throw error;
2123
2559
  }
2124
2560
  };
2561
+ async function getInitCommand(pm) {
2562
+ switch (pm) {
2563
+ case "npm":
2564
+ return "npm init -y";
2565
+ case "pnpm":
2566
+ return "pnpm init";
2567
+ case "yarn":
2568
+ return "yarn init -y";
2569
+ case "bun":
2570
+ return "bun init -y";
2571
+ default:
2572
+ return "npm init -y";
2573
+ }
2574
+ }
2575
+ async function initializePackageJson(pm) {
2576
+ const initCommand = await getInitCommand(pm);
2577
+ await exec3(initCommand);
2578
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
2579
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
2580
+ packageJson.type = "module";
2581
+ packageJson.engines = {
2582
+ ...packageJson.engines,
2583
+ node: ">=22.13.0"
2584
+ };
2585
+ await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2586
+ }
2587
+ var writeReadmeFile = async ({ dirPath, projectName }) => {
2588
+ const packageManager = getPackageManager();
2589
+ const readmePath = path3.join(dirPath, "README.md");
2590
+ const content = `# ${projectName}
2591
+
2592
+ Welcome to your new [Mastra](https://mastra.ai/) project! We're excited to see what you'll build.
2593
+
2594
+ ## Getting Started
2595
+
2596
+ Start the development server:
2597
+
2598
+ \`\`\`shell
2599
+ ${packageManager} run dev
2600
+ \`\`\`
2601
+
2602
+ Open [http://localhost:4111](http://localhost:4111) in your browser to access [Mastra Studio](https://mastra.ai/docs/v1/getting-started/studio). It provides an interactive UI for building and testing your agents, along with a REST API that exposes your Mastra application as a local service. This lets you start building without worrying about integration right away.
2603
+
2604
+ You can start editing files inside the \`src/mastra\` directory. The development server will automatically reload whenever you make changes.
2605
+
2606
+ ## Learn more
2607
+
2608
+ To learn more about Mastra, visit our [documentation](https://mastra.ai/docs/v1/). Your bootstrapped project includes example code for [agents](https://mastra.ai/docs/v1/agents/overview), [tools](https://mastra.ai/docs/v1/agents/using-tools), [workflows](https://mastra.ai/docs/v1/workflows/overview), [scorers](https://mastra.ai/docs/v1/evals/overview), and [observability](https://mastra.ai/docs/v1/observability/overview).
2609
+
2610
+ If you're new to AI agents, check out our [course](https://mastra.ai/course) and [YouTube videos](https://youtube.com/@mastra-ai). You can also join our [Discord](https://discord.gg/BTYqqHKUrf) community to get help and share your projects.
2611
+
2612
+ ## Deploy on Mastra Cloud
2613
+
2614
+ [Mastra Cloud](https://cloud.mastra.ai/) gives you a serverless agent environment with atomic deployments. Access your agents from anywhere and monitor performance. Make sure they don't go off the rails with evals and tracing.
2615
+
2616
+ Check out the [deployment guide](https://mastra.ai/docs/v1/deployment/overview) for more details.`;
2617
+ const formattedContent = await prettier.format(content, {
2618
+ parser: "markdown",
2619
+ singleQuote: true
2620
+ });
2621
+ await fs4.writeFile(readmePath, formattedContent);
2622
+ };
2125
2623
  async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
2126
- let installCommand = getPackageManagerInstallCommand(pm);
2624
+ let installCommand = getPackageManagerAddCommand(pm);
2127
2625
  if (isDev) {
2128
- installCommand = `${installCommand} --save-dev`;
2626
+ installCommand = `${installCommand} -D`;
2129
2627
  }
2130
2628
  try {
2131
2629
  await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
@@ -2147,23 +2645,42 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
2147
2645
  var createMastraProject = async ({
2148
2646
  projectName: name,
2149
2647
  createVersionTag,
2150
- timeout
2648
+ timeout,
2649
+ llmProvider,
2650
+ llmApiKey,
2651
+ needsInteractive
2151
2652
  }) => {
2152
2653
  Ie(color2.inverse(" Mastra Create "));
2153
2654
  const projectName = name ?? await he({
2154
2655
  message: "What do you want to name your project?",
2155
2656
  placeholder: "my-mastra-app",
2156
- defaultValue: "my-mastra-app"
2657
+ defaultValue: "my-mastra-app",
2658
+ validate: (value) => {
2659
+ if (value.length === 0) return "Project name cannot be empty";
2660
+ if (fs3__default__default.existsSync(value)) {
2661
+ return `A directory named "${value}" already exists. Please choose a different name.`;
2662
+ }
2663
+ }
2157
2664
  });
2158
2665
  if (pD(projectName)) {
2159
2666
  xe("Operation cancelled");
2160
2667
  process.exit(0);
2161
2668
  }
2669
+ let result = void 0;
2670
+ if (needsInteractive) {
2671
+ result = await interactivePrompt({
2672
+ options: { showBanner: false },
2673
+ skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
2674
+ });
2675
+ }
2162
2676
  const s2 = Y();
2677
+ const originalCwd = process.cwd();
2678
+ let projectPath = null;
2163
2679
  try {
2164
2680
  s2.start("Creating project");
2165
2681
  try {
2166
2682
  await fs4.mkdir(projectName);
2683
+ projectPath = path3.resolve(originalCwd, projectName);
2167
2684
  } catch (error) {
2168
2685
  if (error instanceof Error && "code" in error && error.code === "EEXIST") {
2169
2686
  s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
@@ -2175,18 +2692,17 @@ var createMastraProject = async ({
2175
2692
  }
2176
2693
  process.chdir(projectName);
2177
2694
  const pm = getPackageManager();
2178
- const installCommand = getPackageManagerInstallCommand(pm);
2695
+ const installCommand = getPackageManagerAddCommand(pm);
2179
2696
  s2.message("Initializing project structure");
2180
2697
  try {
2181
- await exec3(`npm init -y`);
2182
- await exec3(`npm pkg set type="module"`);
2183
- await exec3(`npm pkg set engines.node=">=20.9.0"`);
2698
+ await initializePackageJson(pm);
2184
2699
  const depsService = new DepsService();
2185
2700
  await depsService.addScriptsToPackageJson({
2186
2701
  dev: "mastra dev",
2187
2702
  build: "mastra build",
2188
2703
  start: "mastra start"
2189
2704
  });
2705
+ await writeReadmeFile({ dirPath: process.cwd(), projectName });
2190
2706
  } catch (error) {
2191
2707
  throw new Error(
2192
2708
  `Failed to initialize project structure: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -2195,8 +2711,8 @@ var createMastraProject = async ({
2195
2711
  s2.stop("Project structure created");
2196
2712
  s2.start(`Installing ${pm} dependencies`);
2197
2713
  try {
2198
- await exec3(`${pm} ${installCommand} zod`);
2199
- await exec3(`${pm} ${installCommand} typescript @types/node --save-dev`);
2714
+ await exec3(`${pm} ${installCommand} zod@^4`);
2715
+ await exec3(`${pm} ${installCommand} -D typescript @types/node`);
2200
2716
  await exec3(`echo '{
2201
2717
  "compilerOptions": {
2202
2718
  "target": "ES2022",
@@ -2219,15 +2735,15 @@ var createMastraProject = async ({
2219
2735
  );
2220
2736
  }
2221
2737
  s2.stop(`${pm} dependencies installed`);
2222
- s2.start("Installing mastra");
2738
+ s2.start("Installing Mastra CLI");
2223
2739
  const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
2224
2740
  try {
2225
2741
  await installMastraDependency(pm, "mastra", versionTag, true, timeout);
2226
2742
  } catch (error) {
2227
2743
  throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
2228
2744
  }
2229
- s2.stop("mastra installed");
2230
- s2.start("Installing dependencies");
2745
+ s2.stop("Mastra CLI installed");
2746
+ s2.start("Installing Mastra dependencies");
2231
2747
  try {
2232
2748
  await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
2233
2749
  await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
@@ -2253,41 +2769,67 @@ var createMastraProject = async ({
2253
2769
  }
2254
2770
  s2.stop(".gitignore added");
2255
2771
  Se("Project created successfully");
2256
- console.log("");
2257
- return { projectName };
2772
+ console.info("");
2773
+ return { projectName, result };
2258
2774
  } catch (error) {
2259
2775
  s2.stop();
2260
2776
  const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
2261
2777
  xe(`Project creation failed: ${errorMessage}`);
2778
+ if (projectPath && fs3__default__default.existsSync(projectPath)) {
2779
+ try {
2780
+ process.chdir(originalCwd);
2781
+ await fs4.rm(projectPath, { recursive: true, force: true });
2782
+ } catch (cleanupError) {
2783
+ console.error(
2784
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
2785
+ );
2786
+ }
2787
+ }
2262
2788
  process.exit(1);
2263
2789
  }
2264
2790
  };
2265
- var create = async (args2) => {
2266
- const { projectName } = await createMastraProject({
2267
- projectName: args2?.projectName,
2268
- createVersionTag: args2?.createVersionTag,
2269
- timeout: args2?.timeout
2791
+ var version$1 = package_default.version;
2792
+ var create = async (args) => {
2793
+ if (args.template !== void 0) {
2794
+ await createFromTemplate({
2795
+ projectName: args.projectName,
2796
+ template: args.template,
2797
+ timeout: args.timeout,
2798
+ injectedAnalytics: args.analytics,
2799
+ llmProvider: args.llmProvider
2800
+ });
2801
+ return;
2802
+ }
2803
+ const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
2804
+ const { projectName, result } = await createMastraProject({
2805
+ projectName: args?.projectName,
2806
+ createVersionTag: args?.createVersionTag,
2807
+ timeout: args?.timeout,
2808
+ llmProvider: args?.llmProvider,
2809
+ llmApiKey: args?.llmApiKey,
2810
+ needsInteractive
2270
2811
  });
2271
- const directory = args2.directory || "src/";
2272
- if (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
2273
- const result = await interactivePrompt();
2812
+ const directory = args.directory || "src/";
2813
+ if (needsInteractive && result) {
2274
2814
  await init({
2275
2815
  ...result,
2276
2816
  llmApiKey: result?.llmApiKey,
2277
- components: ["agents", "tools", "workflows"],
2278
- addExample: true
2817
+ components: ["agents", "tools", "workflows", "scorers"],
2818
+ addExample: true,
2819
+ versionTag: args.createVersionTag
2279
2820
  });
2280
2821
  postCreate({ projectName });
2281
2822
  return;
2282
2823
  }
2283
- const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args2;
2824
+ const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
2284
2825
  await init({
2285
2826
  directory,
2286
2827
  components,
2287
2828
  llmProvider,
2288
2829
  addExample,
2289
2830
  llmApiKey,
2290
- configureEditorWithDocsMCP: args2.mcpServer
2831
+ configureEditorWithDocsMCP: args.mcpServer,
2832
+ versionTag: args.createVersionTag
2291
2833
  });
2292
2834
  postCreate({ projectName });
2293
2835
  };
@@ -2300,18 +2842,225 @@ var postCreate = ({ projectName }) => {
2300
2842
  ${color2.cyan(`${packageManager} run dev`)}
2301
2843
  `);
2302
2844
  };
2845
+ function isGitHubUrl(url) {
2846
+ try {
2847
+ const parsedUrl = new URL(url);
2848
+ return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
2849
+ } catch {
2850
+ return false;
2851
+ }
2852
+ }
2853
+ async function validateGitHubProject(githubUrl) {
2854
+ const errors = [];
2855
+ try {
2856
+ const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
2857
+ const owner = urlParts[0];
2858
+ const repo = urlParts[1]?.replace(".git", "");
2859
+ if (!owner || !repo) {
2860
+ throw new Error("Invalid GitHub URL format");
2861
+ }
2862
+ const branches = ["main", "master"];
2863
+ let packageJsonContent = null;
2864
+ let indexContent = null;
2865
+ for (const branch of branches) {
2866
+ try {
2867
+ const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
2868
+ const packageJsonResponse = await fetch(packageJsonUrl);
2869
+ if (packageJsonResponse.ok) {
2870
+ packageJsonContent = await packageJsonResponse.text();
2871
+ const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
2872
+ const indexResponse = await fetch(indexUrl);
2873
+ if (indexResponse.ok) {
2874
+ indexContent = await indexResponse.text();
2875
+ }
2876
+ break;
2877
+ }
2878
+ } catch {
2879
+ }
2880
+ }
2881
+ if (!packageJsonContent) {
2882
+ errors.push("Could not fetch package.json from repository");
2883
+ return { isValid: false, errors };
2884
+ }
2885
+ try {
2886
+ const packageJson = JSON.parse(packageJsonContent);
2887
+ const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
2888
+ if (!hasMastraCore) {
2889
+ errors.push("Missing @mastra/core dependency in package.json");
2890
+ }
2891
+ } catch {
2892
+ errors.push("Invalid package.json format");
2893
+ }
2894
+ if (!indexContent) {
2895
+ errors.push("Missing src/mastra/index.ts file");
2896
+ } else {
2897
+ const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
2898
+ if (!hasMastraExport) {
2899
+ errors.push("src/mastra/index.ts does not export a Mastra instance");
2900
+ }
2901
+ }
2902
+ return { isValid: errors.length === 0, errors };
2903
+ } catch (error) {
2904
+ errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
2905
+ return { isValid: false, errors };
2906
+ }
2907
+ }
2908
+ async function createFromGitHubUrl(url) {
2909
+ const urlParts = new URL(url).pathname.split("/").filter(Boolean);
2910
+ const owner = urlParts[0] || "unknown";
2911
+ const repo = urlParts[1] || "unknown";
2912
+ return {
2913
+ githubUrl: url,
2914
+ title: `${owner}/${repo}`,
2915
+ slug: repo,
2916
+ agents: [],
2917
+ mcp: [],
2918
+ tools: [],
2919
+ networks: [],
2920
+ workflows: []
2921
+ };
2922
+ }
2923
+ async function createFromTemplate(args) {
2924
+ let selectedTemplate;
2925
+ if (args.template === true) {
2926
+ const templates = await loadTemplates();
2927
+ const selected = await selectTemplate(templates);
2928
+ if (!selected) {
2929
+ M.info("No template selected. Exiting.");
2930
+ return;
2931
+ }
2932
+ selectedTemplate = selected;
2933
+ } else if (args.template && typeof args.template === "string") {
2934
+ if (isGitHubUrl(args.template)) {
2935
+ const spinner4 = Y();
2936
+ spinner4.start("Validating GitHub repository...");
2937
+ const validation = await validateGitHubProject(args.template);
2938
+ if (!validation.isValid) {
2939
+ spinner4.stop("Validation failed");
2940
+ M.error("This does not appear to be a valid Mastra project:");
2941
+ validation.errors.forEach((error) => M.error(` - ${error}`));
2942
+ throw new Error("Invalid Mastra project");
2943
+ }
2944
+ spinner4.stop("Valid Mastra project \u2713");
2945
+ selectedTemplate = await createFromGitHubUrl(args.template);
2946
+ } else {
2947
+ const templates = await loadTemplates();
2948
+ const found = findTemplateByName(templates, args.template);
2949
+ if (!found) {
2950
+ M.error(`Template "${args.template}" not found. Available templates:`);
2951
+ templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2952
+ throw new Error(`Template "${args.template}" not found`);
2953
+ }
2954
+ selectedTemplate = found;
2955
+ }
2956
+ }
2957
+ if (!selectedTemplate) {
2958
+ throw new Error("No template selected");
2959
+ }
2960
+ let projectName = args.projectName;
2961
+ if (!projectName) {
2962
+ const defaultName = getDefaultProjectName(selectedTemplate);
2963
+ const response = await he({
2964
+ message: "What is your project name?",
2965
+ defaultValue: defaultName,
2966
+ placeholder: defaultName
2967
+ });
2968
+ if (pD(response)) {
2969
+ M.info("Project creation cancelled.");
2970
+ return;
2971
+ }
2972
+ projectName = response;
2973
+ }
2974
+ let llmProvider = args.llmProvider;
2975
+ if (!llmProvider) {
2976
+ const providerResponse = await ve({
2977
+ message: "Select a default provider:",
2978
+ options: LLM_PROVIDERS
2979
+ });
2980
+ if (pD(providerResponse)) {
2981
+ M.info("Project creation cancelled.");
2982
+ return;
2983
+ }
2984
+ llmProvider = providerResponse;
2985
+ }
2986
+ let initGit = false;
2987
+ const gitConfirmResult = await ye({
2988
+ message: "Initialize a new git repository?",
2989
+ initialValue: true
2990
+ });
2991
+ if (!pD(gitConfirmResult)) {
2992
+ initGit = gitConfirmResult;
2993
+ }
2994
+ let projectPath = null;
2995
+ try {
2996
+ const analytics = args.injectedAnalytics || getAnalytics();
2997
+ if (analytics) {
2998
+ analytics.trackEvent("cli_template_used", {
2999
+ template_slug: selectedTemplate.slug,
3000
+ template_title: selectedTemplate.title
3001
+ });
3002
+ if (llmProvider) {
3003
+ analytics.trackEvent("cli_model_provider_selected", {
3004
+ provider: llmProvider,
3005
+ selection_method: args.llmProvider ? "cli_args" : "interactive"
3006
+ });
3007
+ }
3008
+ }
3009
+ const isBeta = version$1?.includes("beta") ?? false;
3010
+ const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
3011
+ const branch = isBeta && isMastraTemplate ? "beta" : void 0;
3012
+ projectPath = await cloneTemplate({
3013
+ template: selectedTemplate,
3014
+ projectName,
3015
+ branch,
3016
+ llmProvider
3017
+ });
3018
+ await installDependencies(projectPath);
3019
+ if (initGit) {
3020
+ const s2 = Y();
3021
+ try {
3022
+ s2.start("Initializing git repository");
3023
+ await gitInit({ cwd: projectPath });
3024
+ s2.stop("Git repository initialized");
3025
+ } catch {
3026
+ s2.stop();
3027
+ }
3028
+ }
3029
+ Me(`
3030
+ ${color2.green("Mastra template installed!")}
3031
+
3032
+ Add the necessary environment
3033
+ variables in your ${color2.cyan(".env")} file
3034
+ `);
3035
+ postCreate({ projectName });
3036
+ } catch (error) {
3037
+ if (projectPath) {
3038
+ try {
3039
+ if (fs3__default__default.existsSync(projectPath)) {
3040
+ await fs4.rm(projectPath, { recursive: true, force: true });
3041
+ }
3042
+ } catch (cleanupError) {
3043
+ console.error(
3044
+ `Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
3045
+ );
3046
+ }
3047
+ }
3048
+ M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
3049
+ throw error;
3050
+ }
3051
+ }
2303
3052
 
2304
3053
  async function getPackageVersion() {
2305
3054
  const __filename = fileURLToPath(import.meta.url);
2306
3055
  const __dirname = dirname(__filename);
2307
- const pkgJsonPath = path2.join(__dirname, "..", "package.json");
2308
- const content = await fsExtra.readJSON(pkgJsonPath);
3056
+ const pkgJsonPath = path3.join(__dirname, "..", "package.json");
3057
+ const content = await fsExtra$1.readJSON(pkgJsonPath);
2309
3058
  return content.version;
2310
3059
  }
2311
3060
  async function getCreateVersionTag() {
2312
3061
  try {
2313
3062
  const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
2314
- const json = await fsExtra.readJSON(pkgPath);
3063
+ const json = await fsExtra$1.readJSON(pkgPath);
2315
3064
  const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
2316
3065
  const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
2317
3066
  const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
@@ -2335,25 +3084,30 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
2335
3084
  analytics.trackCommand({
2336
3085
  command: "version"
2337
3086
  });
2338
- console.log(`create-mastra ${version}`);
3087
+ console.info(`create-mastra ${version}`);
2339
3088
  } catch {
2340
3089
  }
2341
3090
  });
2342
3091
  program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
2343
3092
  "-p, --project-name <string>",
2344
3093
  "Project name that will be used in package.json and as the project directory name."
2345
- ).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)").action(async (projectNameArg, args) => {
3094
+ ).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(
3095
+ "--template [template-name]",
3096
+ "Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
3097
+ ).action(async (projectNameArg, args) => {
2346
3098
  const projectName = projectNameArg || args.projectName;
2347
3099
  const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
2348
3100
  if (args.default) {
2349
3101
  await create({
2350
- components: ["agents", "tools", "workflows"],
3102
+ components: ["agents", "tools", "workflows", "scorers"],
2351
3103
  llmProvider: "openai",
2352
3104
  addExample: true,
2353
3105
  createVersionTag,
2354
3106
  timeout,
2355
3107
  mcpServer: args.mcp,
2356
- directory: "src/"
3108
+ directory: "src/",
3109
+ template: args.template,
3110
+ analytics
2357
3111
  });
2358
3112
  return;
2359
3113
  }
@@ -2361,12 +3115,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2361
3115
  components: args.components ? args.components.split(",") : [],
2362
3116
  llmProvider: args.llm,
2363
3117
  addExample: args.example,
2364
- llmApiKey: args["llm-api-key"],
3118
+ llmApiKey: args.llmApiKey,
2365
3119
  createVersionTag,
2366
3120
  timeout,
2367
3121
  projectName,
2368
3122
  directory: args.dir,
2369
- mcpServer: args.mcp
3123
+ mcpServer: args.mcp,
3124
+ template: args.template,
3125
+ analytics
2370
3126
  });
2371
3127
  });
2372
3128
  program.parse(process.argv);