create-mastra 0.0.0-roamin-openaivoice-speak-options-passing-20250926163614 → 0.0.0-salesman-20260127182805

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,29 +1,29 @@
1
1
  #! /usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import { randomUUID } from 'node:crypto';
4
- import * as fs4__default from 'node:fs';
5
- import fs4__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import * as fs3__default from 'node:fs';
5
+ import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
7
  import path3, { dirname } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import { PostHog } from 'posthog-node';
10
+ import fs4 from 'node:fs/promises';
10
11
  import util, { stripVTControlCharacters } from 'node:util';
11
12
  import y$1, { stdout, stdin } from 'node:process';
12
13
  import * as g from 'node:readline';
13
14
  import g__default from 'node:readline';
14
15
  import { Writable } from 'node:stream';
15
- import fs5 from 'node:fs/promises';
16
16
  import child_process from 'node:child_process';
17
17
  import tty from 'node:tty';
18
- import pino from 'pino';
19
- import pretty from 'pino-pretty';
20
- import { execa } from 'execa';
21
18
  import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
22
19
  import prettier from 'prettier';
20
+ import { execa } from 'execa';
23
21
  import fsExtra$1 from 'fs-extra';
22
+ import pino from 'pino';
23
+ import pretty from 'pino-pretty';
24
24
 
25
- var __filename = fileURLToPath(import.meta.url);
26
- var __dirname = path3.dirname(__filename);
25
+ var __filename$1 = fileURLToPath(import.meta.url);
26
+ var __dirname$1 = path3.dirname(__filename$1);
27
27
  var analyticsInstance = null;
28
28
  function getAnalytics() {
29
29
  return analyticsInstance;
@@ -39,7 +39,7 @@ var PosthogAnalytics = class {
39
39
  host = "https://app.posthog.com"
40
40
  }) {
41
41
  this.version = version;
42
- const cliConfigPath = path3.join(__dirname, "mastra-cli.json");
42
+ const cliConfigPath = path3.join(__dirname$1, "mastra-cli.json");
43
43
  if (existsSync(cliConfigPath)) {
44
44
  try {
45
45
  const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
@@ -67,7 +67,7 @@ var PosthogAnalytics = class {
67
67
  }
68
68
  writeCliConfig({ distinctId, sessionId }) {
69
69
  try {
70
- writeFileSync(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
70
+ writeFileSync(path3.join(__dirname$1, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
71
71
  } catch {
72
72
  }
73
73
  }
@@ -105,6 +105,10 @@ var PosthogAnalytics = class {
105
105
  machine_id: os.hostname()
106
106
  };
107
107
  }
108
+ getDurationMs(startTime) {
109
+ const [seconds, nanoseconds] = process.hrtime(startTime);
110
+ return seconds * 1e3 + nanoseconds / 1e6;
111
+ }
108
112
  captureSessionStart() {
109
113
  if (!this.client) {
110
114
  return;
@@ -173,8 +177,7 @@ var PosthogAnalytics = class {
173
177
  const startTime = process.hrtime();
174
178
  try {
175
179
  const result = await execution();
176
- const [seconds, nanoseconds] = process.hrtime(startTime);
177
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
180
+ const durationMs = this.getDurationMs(startTime);
178
181
  this.trackCommand({
179
182
  command,
180
183
  args,
@@ -184,8 +187,7 @@ var PosthogAnalytics = class {
184
187
  });
185
188
  return result;
186
189
  } catch (error) {
187
- const [seconds, nanoseconds] = process.hrtime(startTime);
188
- const durationMs = seconds * 1e3 + nanoseconds / 1e6;
190
+ const durationMs = this.getDurationMs(startTime);
189
191
  this.trackCommand({
190
192
  command,
191
193
  args,
@@ -382,7 +384,7 @@ function DD({onlyFirst:e=false}={}){const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:
382
384
  `).length-1;this.output.write(srcExports.cursor.move(-999,u*-1));}render(){const u=Y$1(this._render(this)??"",process.stdout.columns,{hard:true});if(u!==this._prevFrame){if(this.state==="initial")this.output.write(srcExports.cursor.hide);else {const t=BD(this._prevFrame,u);if(this.restoreCursor(),t&&t?.length===1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.lines(1));const s=u.split(`
383
385
  `);this.output.write(s[F]),this._prevFrame=u,this.output.write(srcExports.cursor.move(0,s.length-F-1));return}if(t&&t?.length>1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.down());const s=u.split(`
384
386
  `).slice(F);this.output.write(s.join(`
385
- `)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
387
+ `)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}class dD extends x{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(u){super(u,false),this.value=!!u.initialValue,this.on("value",()=>{this.value=this._value;}),this.on("confirm",t=>{this.output.write(srcExports.cursor.move(0,-1)),this.value=t,this.state="submit",this.close();}),this.on("cursor",()=>{this.value=!this.value;});}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
386
388
 
387
389
  function ce(){return y$1.platform!=="win32"?y$1.env.TERM!=="linux":!!y$1.env.CI||!!y$1.env.WT_SESSION||!!y$1.env.TERMINUS_SUBLIME||y$1.env.ConEmuTask==="{cmd::Cmder}"||y$1.env.TERM_PROGRAM==="Terminus-Sublime"||y$1.env.TERM_PROGRAM==="vscode"||y$1.env.TERM==="xterm-256color"||y$1.env.TERM==="alacritty"||y$1.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}const V=ce(),u=(t,n)=>V?t:n,le=u("\u25C6","*"),L=u("\u25A0","x"),W=u("\u25B2","x"),C=u("\u25C7","o"),ue=u("\u250C","T"),o=u("\u2502","|"),d=u("\u2514","\u2014"),k=u("\u25CF",">"),P=u("\u25CB"," "),_=u("\u2500","-"),me=u("\u256E","+"),de=u("\u251C","+"),pe=u("\u256F","+"),q=u("\u25CF","\u2022"),D=u("\u25C6","*"),U=u("\u25B2","!"),K=u("\u25A0","x"),b=t=>{switch(t){case "initial":case "active":return color2.cyan(le);case "cancel":return color2.red(L);case "error":return color2.yellow(W);case "submit":return color2.green(C)}},G=t=>{const{cursor:n,options:r,style:i}=t,s=t.maxItems??Number.POSITIVE_INFINITY,c=Math.max(process.stdout.rows-4,0),a=Math.min(c,Math.max(s,5));let l=0;n>=l+a-3?l=Math.max(Math.min(n-a+3,r.length-a),0):n<l+2&&(l=Math.max(n-2,0));const $=a<r.length&&l>0,g=a<r.length&&l+a<r.length;return r.slice(l,l+a).map((p,v,f)=>{const j=v===0&&$,E=v===f.length-1&&g;return j||E?color2.dim("..."):i(p,v+l===n)})},he=t=>new RD({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,render(){const n=`${color2.gray(o)}
388
390
  ${b(this.state)} ${t.message}
@@ -392,7 +394,12 @@ ${color2.yellow(d)} ${color2.yellow(this.error)}
392
394
  `;case "submit":return `${n}${color2.gray(o)} ${color2.dim(this.value||t.placeholder)}`;case "cancel":return `${n}${color2.gray(o)} ${color2.strikethrough(color2.dim(this.value??""))}${this.value?.trim()?`
393
395
  ${color2.gray(o)}`:""}`;default:return `${n}${color2.cyan(o)} ${i}
394
396
  ${color2.cyan(d)}
395
- `}}}).prompt(),ve=t=>{const n=(r,i)=>{const s=r.label??String(r.value);switch(i){case "selected":return `${color2.dim(s)}`;case "active":return `${color2.green(k)} ${s} ${r.hint?color2.dim(`(${r.hint})`):""}`;case "cancelled":return `${color2.strikethrough(color2.dim(s))}`;default:return `${color2.dim(P)} ${color2.dim(s)}`}};return new LD({options:t.options,initialValue:t.initialValue,render(){const r=`${color2.gray(o)}
397
+ `}}}).prompt(),ye=t=>{const n=t.active??"Yes",r=t.inactive??"No";return new dD({active:n,inactive:r,initialValue:t.initialValue??true,render(){const i=`${color2.gray(o)}
398
+ ${b(this.state)} ${t.message}
399
+ `,s=this.value?n:r;switch(this.state){case "submit":return `${i}${color2.gray(o)} ${color2.dim(s)}`;case "cancel":return `${i}${color2.gray(o)} ${color2.strikethrough(color2.dim(s))}
400
+ ${color2.gray(o)}`;default:return `${i}${color2.cyan(o)} ${this.value?`${color2.green(k)} ${n}`:`${color2.dim(P)} ${color2.dim(n)}`} ${color2.dim("/")} ${this.value?`${color2.dim(P)} ${color2.dim(r)}`:`${color2.green(k)} ${r}`}
401
+ ${color2.cyan(d)}
402
+ `}}}).prompt()},ve=t=>{const n=(r,i)=>{const s=r.label??String(r.value);switch(i){case "selected":return `${color2.dim(s)}`;case "active":return `${color2.green(k)} ${s} ${r.hint?color2.dim(`(${r.hint})`):""}`;case "cancelled":return `${color2.strikethrough(color2.dim(s))}`;default:return `${color2.dim(P)} ${color2.dim(s)}`}};return new LD({options:t.options,initialValue:t.initialValue,render(){const r=`${color2.gray(o)}
396
403
  ${b(this.state)} ${t.message}
397
404
  `;switch(this.state){case "submit":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"selected")}`;case "cancel":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"cancelled")}
398
405
  ${color2.gray(o)}`;default:return `${r}${color2.cyan(o)} ${G({cursor:this.cursor,options:this.options,maxItems:t.maxItems,style:(i,s)=>n(i,s?"active":"inactive")}).join(`
@@ -422,7 +429,7 @@ ${color2.gray(d)} ${t}
422
429
  `):process.stdout.write(`${w} ${l}
423
430
  `),E(),s();};return {start:H,stop:N,message:(m="")=>{l=R(m??l);}}},Ce=async(t,n)=>{const r={},i=Object.keys(t);for(const s of i){const c=t[s],a=await c({results:r})?.catch(l=>{throw l});if(typeof n?.onCancel=="function"&&pD(a)){r[s]="canceled",n.onCancel({results:r});continue}r[s]=a;}return r};
424
431
 
425
- var shellQuote$1 = {};
432
+ var shellQuote = {};
426
433
 
427
434
  var quote;
428
435
  var hasRequiredQuote;
@@ -688,16 +695,16 @@ function requireParse () {
688
695
  var hasRequiredShellQuote;
689
696
 
690
697
  function requireShellQuote () {
691
- if (hasRequiredShellQuote) return shellQuote$1;
698
+ if (hasRequiredShellQuote) return shellQuote;
692
699
  hasRequiredShellQuote = 1;
693
700
 
694
- shellQuote$1.quote = requireQuote();
695
- shellQuote$1.parse = requireParse();
696
- return shellQuote$1;
701
+ shellQuote.quote = requireQuote();
702
+ shellQuote.parse = requireParse();
703
+ return shellQuote;
697
704
  }
698
705
 
699
706
  var shellQuoteExports = requireShellQuote();
700
- var shellQuote = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
707
+ var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
701
708
 
702
709
  // eslint-disable-next-line no-warning-comments
703
710
  // TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
@@ -724,13 +731,18 @@ const format = (open, close) => {
724
731
  // Handle nested colors.
725
732
 
726
733
  // We could have done this, but it's too slow (as of Node.js 22).
727
- // return openCode + string.replaceAll(closeCode, openCode) + closeCode;
734
+ // return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
728
735
 
729
736
  let result = openCode;
730
737
  let lastIndex = 0;
731
738
 
739
+ // SGR 22 resets both bold (1) and dim (2). When we encounter a nested
740
+ // close for styles that use 22, we need to re-open the outer style.
741
+ const reopenOnNestedClose = close === 22;
742
+ const replaceCode = (reopenOnNestedClose ? closeCode : '') + openCode;
743
+
732
744
  while (index !== -1) {
733
- result += string.slice(lastIndex, index) + openCode;
745
+ result += string.slice(lastIndex, index) + replaceCode;
734
746
  lastIndex = index + closeCode.length;
735
747
  index = string.indexOf(closeCode, lastIndex);
736
748
  }
@@ -882,6 +894,7 @@ class YoctoSpinner {
882
894
  #exitHandlerBound;
883
895
  #isInteractive;
884
896
  #lastSpinnerFrameTime = 0;
897
+ #isSpinning = false;
885
898
 
886
899
  constructor(options = {}) {
887
900
  const spinner = options.spinner ?? defaultSpinner;
@@ -903,13 +916,17 @@ class YoctoSpinner {
903
916
  return this;
904
917
  }
905
918
 
919
+ this.#isSpinning = true;
906
920
  this.#hideCursor();
907
921
  this.#render();
908
922
  this.#subscribeToProcessEvents();
909
923
 
910
- this.#timer = setInterval(() => {
911
- this.#render();
912
- }, this.#interval);
924
+ // Only start the timer in interactive mode
925
+ if (this.#isInteractive) {
926
+ this.#timer = setInterval(() => {
927
+ this.#render();
928
+ }, this.#interval);
929
+ }
913
930
 
914
931
  return this;
915
932
  }
@@ -919,8 +936,12 @@ class YoctoSpinner {
919
936
  return this;
920
937
  }
921
938
 
922
- clearInterval(this.#timer);
923
- this.#timer = undefined;
939
+ this.#isSpinning = false;
940
+ if (this.#timer) {
941
+ clearInterval(this.#timer);
942
+ this.#timer = undefined;
943
+ }
944
+
924
945
  this.#showCursor();
925
946
  this.clear();
926
947
  this.#unsubscribeFromProcessEvents();
@@ -953,7 +974,7 @@ class YoctoSpinner {
953
974
  }
954
975
 
955
976
  get isSpinning() {
956
- return this.#timer !== undefined;
977
+ return this.#isSpinning;
957
978
  }
958
979
 
959
980
  get text() {
@@ -1090,11 +1111,11 @@ var MastraLogger = class {
1090
1111
  }
1091
1112
  trackException(_error) {
1092
1113
  }
1093
- async getLogs(transportId, params) {
1114
+ async listLogs(transportId, params) {
1094
1115
  if (!transportId || !this.transports.has(transportId)) {
1095
1116
  return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
1096
1117
  }
1097
- return this.transports.get(transportId).getLogs(params) ?? {
1118
+ return this.transports.get(transportId).listLogs(params) ?? {
1098
1119
  logs: [],
1099
1120
  total: 0,
1100
1121
  page: params?.page ?? 1,
@@ -1102,7 +1123,7 @@ var MastraLogger = class {
1102
1123
  hasMore: false
1103
1124
  };
1104
1125
  }
1105
- async getLogsByRunId({
1126
+ async listLogsByRunId({
1106
1127
  transportId,
1107
1128
  runId,
1108
1129
  fromDate,
@@ -1115,7 +1136,7 @@ var MastraLogger = class {
1115
1136
  if (!transportId || !this.transports.has(transportId) || !runId) {
1116
1137
  return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
1117
1138
  }
1118
- return this.transports.get(transportId).getLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
1139
+ return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
1119
1140
  logs: [],
1120
1141
  total: 0,
1121
1142
  page: page ?? 1,
@@ -1125,10 +1146,15 @@ var MastraLogger = class {
1125
1146
  }
1126
1147
  };
1127
1148
 
1128
- var PinoLogger = class extends MastraLogger {
1149
+ var PinoLogger = class _PinoLogger extends MastraLogger {
1129
1150
  logger;
1130
1151
  constructor(options = {}) {
1131
1152
  super(options);
1153
+ const internalOptions = options;
1154
+ if (internalOptions._logger) {
1155
+ this.logger = internalOptions._logger;
1156
+ return;
1157
+ }
1132
1158
  let prettyStream = void 0;
1133
1159
  if (!options.overrideDefaultTransports) {
1134
1160
  prettyStream = pretty({
@@ -1145,7 +1171,8 @@ var PinoLogger = class extends MastraLogger {
1145
1171
  {
1146
1172
  name: options.name || "app",
1147
1173
  level: options.level || LogLevel.INFO,
1148
- formatters: options.formatters
1174
+ formatters: options.formatters,
1175
+ redact: options.redact
1149
1176
  },
1150
1177
  options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
1151
1178
  ...transportsAry.map(([, transport]) => ({
@@ -1159,6 +1186,38 @@ var PinoLogger = class extends MastraLogger {
1159
1186
  ])
1160
1187
  );
1161
1188
  }
1189
+ /**
1190
+ * Creates a child logger with additional bound context.
1191
+ * All logs from the child logger will include the bound context.
1192
+ *
1193
+ * @param bindings - Key-value pairs to include in all logs from this child logger
1194
+ * @returns A new PinoLogger instance with the bound context
1195
+ *
1196
+ * @example
1197
+ * ```typescript
1198
+ * const baseLogger = new PinoLogger({ name: 'MyApp' });
1199
+ *
1200
+ * // Create module-scoped logger
1201
+ * const serviceLogger = baseLogger.child({ module: 'UserService' });
1202
+ * serviceLogger.info('User created', { userId: '123' });
1203
+ * // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }
1204
+ *
1205
+ * // Create request-scoped logger
1206
+ * const requestLogger = baseLogger.child({ requestId: req.id });
1207
+ * requestLogger.error('Request failed', { err: error });
1208
+ * // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }
1209
+ * ```
1210
+ */
1211
+ child(bindings) {
1212
+ const childPino = this.logger.child(bindings);
1213
+ const childOptions = {
1214
+ name: this.name,
1215
+ level: this.level,
1216
+ transports: Object.fromEntries(this.transports),
1217
+ _logger: childPino
1218
+ };
1219
+ return new _PinoLogger(childOptions);
1220
+ }
1162
1221
  debug(message, args = {}) {
1163
1222
  this.logger.debug(args, message);
1164
1223
  }
@@ -1173,183 +1232,8 @@ var PinoLogger = class extends MastraLogger {
1173
1232
  }
1174
1233
  };
1175
1234
 
1176
- function getPackageManager() {
1177
- const userAgent = process.env.npm_config_user_agent || "";
1178
- const execPath = process.env.npm_execpath || "";
1179
- if (userAgent.includes("yarn")) {
1180
- return "yarn";
1181
- }
1182
- if (userAgent.includes("pnpm")) {
1183
- return "pnpm";
1184
- }
1185
- if (userAgent.includes("npm")) {
1186
- return "npm";
1187
- }
1188
- if (execPath.includes("yarn")) {
1189
- return "yarn";
1190
- }
1191
- if (execPath.includes("pnpm")) {
1192
- return "pnpm";
1193
- }
1194
- if (execPath.includes("npm")) {
1195
- return "npm";
1196
- }
1197
- return "npm";
1198
- }
1199
- var logger = new PinoLogger({
1200
- name: "Mastra CLI",
1201
- level: "info"
1202
- });
1203
- var exec = util.promisify(child_process.exec);
1204
- async function cloneTemplate(options) {
1205
- const { template, projectName, targetDir } = options;
1206
- const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
1207
- const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
1208
- try {
1209
- if (await directoryExists(projectPath)) {
1210
- spinner5.error(`Directory ${projectName} already exists`);
1211
- throw new Error(`Directory ${projectName} already exists`);
1212
- }
1213
- await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
1214
- await updatePackageJson(projectPath, projectName);
1215
- const envExamplePath = path3.join(projectPath, ".env.example");
1216
- if (await fileExists(envExamplePath)) {
1217
- await fs5.copyFile(envExamplePath, path3.join(projectPath, ".env"));
1218
- }
1219
- spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
1220
- return projectPath;
1221
- } catch (error) {
1222
- spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
1223
- throw error;
1224
- }
1225
- }
1226
- async function directoryExists(dirPath) {
1227
- try {
1228
- const stat = await fs5.stat(dirPath);
1229
- return stat.isDirectory();
1230
- } catch {
1231
- return false;
1232
- }
1233
- }
1234
- async function fileExists(filePath) {
1235
- try {
1236
- const stat = await fs5.stat(filePath);
1237
- return stat.isFile();
1238
- } catch {
1239
- return false;
1240
- }
1241
- }
1242
- async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
1243
- await fs5.mkdir(targetPath, { recursive: true });
1244
- try {
1245
- const degitRepo = repoUrl.replace("https://github.com/", "");
1246
- const degitCommand = shellQuote.quote(["npx", "degit", degitRepo, targetPath]);
1247
- await exec(degitCommand, {
1248
- cwd: process.cwd()
1249
- });
1250
- } catch {
1251
- try {
1252
- const gitCommand = shellQuote.quote(["git", "clone", repoUrl, targetPath]);
1253
- await exec(gitCommand, {
1254
- cwd: process.cwd()
1255
- });
1256
- const gitDir = path3.join(targetPath, ".git");
1257
- if (await directoryExists(gitDir)) {
1258
- await fs5.rm(gitDir, { recursive: true, force: true });
1259
- }
1260
- } catch (gitError) {
1261
- throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
1262
- }
1263
- }
1264
- }
1265
- async function updatePackageJson(projectPath, projectName) {
1266
- const packageJsonPath = path3.join(projectPath, "package.json");
1267
- try {
1268
- const packageJsonContent = await fs5.readFile(packageJsonPath, "utf-8");
1269
- const packageJson = JSON.parse(packageJsonContent);
1270
- packageJson.name = projectName;
1271
- await fs5.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
1272
- } catch (error) {
1273
- logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
1274
- }
1275
- }
1276
- async function installDependencies(projectPath, packageManager) {
1277
- const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
1278
- try {
1279
- const pm = packageManager || getPackageManager();
1280
- const installCommand = shellQuote.quote([pm, "install"]);
1281
- await exec(installCommand, {
1282
- cwd: projectPath
1283
- });
1284
- spinner5.success("Dependencies installed successfully");
1285
- } catch (error) {
1286
- spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
1287
- throw error;
1288
- }
1289
- }
1290
- var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
1291
- async function loadTemplates() {
1292
- try {
1293
- const response = await fetch(TEMPLATES_API_URL);
1294
- if (!response.ok) {
1295
- throw new Error(`Failed to fetch templates: ${response.statusText}`);
1296
- }
1297
- const templates = await response.json();
1298
- return templates;
1299
- } catch (error) {
1300
- console.error("Error loading templates:", error);
1301
- throw new Error("Failed to load templates. Please check your internet connection and try again.");
1302
- }
1303
- }
1304
- function pluralize(count, singular, plural) {
1305
- return count === 1 ? singular : plural || `${singular}s`;
1306
- }
1307
- async function selectTemplate(templates) {
1308
- const choices = templates.map((template) => {
1309
- const parts = [];
1310
- if (template.agents?.length) {
1311
- parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
1312
- }
1313
- if (template.tools?.length) {
1314
- parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
1315
- }
1316
- if (template.workflows?.length) {
1317
- parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
1318
- }
1319
- if (template.mcp?.length) {
1320
- parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
1321
- }
1322
- if (template.networks?.length) {
1323
- parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
1324
- }
1325
- return {
1326
- value: template,
1327
- label: template.title,
1328
- hint: parts.join(", ") || "Template components"
1329
- };
1330
- });
1331
- const selected = await ve({
1332
- message: "Select a template:",
1333
- options: choices
1334
- });
1335
- if (pD(selected)) {
1336
- return null;
1337
- }
1338
- return selected;
1339
- }
1340
- function findTemplateByName(templates, templateName) {
1341
- let template = templates.find((t) => t.slug === templateName);
1342
- if (template) return template;
1343
- const slugWithPrefix = `template-${templateName}`;
1344
- template = templates.find((t) => t.slug === slugWithPrefix);
1345
- if (template) return template;
1346
- template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
1347
- if (template) return template;
1348
- return null;
1349
- }
1350
- function getDefaultProjectName(template) {
1351
- return template.slug.replace(/^template-/, "");
1352
- }
1235
+ var package_default = {
1236
+ version: "1.0.1"};
1353
1237
  function getPackageManagerAddCommand(pm) {
1354
1238
  switch (pm) {
1355
1239
  case "npm":
@@ -1370,9 +1254,9 @@ var DepsService = class {
1370
1254
  this.packageManager = this.getPackageManager();
1371
1255
  }
1372
1256
  findLockFile(dir) {
1373
- 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"];
1374
1258
  for (const file of lockFiles) {
1375
- if (fs4__default__default.existsSync(path3.join(dir, file))) {
1259
+ if (fs3__default__default.existsSync(path3.join(dir, file))) {
1376
1260
  return file;
1377
1261
  }
1378
1262
  }
@@ -1392,6 +1276,7 @@ var DepsService = class {
1392
1276
  case "yarn.lock":
1393
1277
  return "yarn";
1394
1278
  case "bun.lock":
1279
+ case "bun.lockb":
1395
1280
  return "bun";
1396
1281
  default:
1397
1282
  return "npm";
@@ -1411,11 +1296,11 @@ var DepsService = class {
1411
1296
  try {
1412
1297
  const packageJsonPath = path3.join(process.cwd(), "package.json");
1413
1298
  try {
1414
- await fs5.access(packageJsonPath);
1299
+ await fs4.access(packageJsonPath);
1415
1300
  } catch {
1416
1301
  return "No package.json file found in the current directory";
1417
1302
  }
1418
- const packageJson = JSON.parse(await fs5.readFile(packageJsonPath, "utf-8"));
1303
+ const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
1419
1304
  for (const dependency of dependencies) {
1420
1305
  if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
1421
1306
  return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
@@ -1430,7 +1315,7 @@ var DepsService = class {
1430
1315
  async getProjectName() {
1431
1316
  try {
1432
1317
  const packageJsonPath = path3.join(process.cwd(), "package.json");
1433
- const packageJson = await fs5.readFile(packageJsonPath, "utf-8");
1318
+ const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
1434
1319
  const pkg = JSON.parse(packageJson);
1435
1320
  return pkg.name;
1436
1321
  } catch (err) {
@@ -1438,149 +1323,37 @@ var DepsService = class {
1438
1323
  }
1439
1324
  }
1440
1325
  async addScriptsToPackageJson(scripts) {
1441
- const packageJson = JSON.parse(await fs5.readFile("package.json", "utf-8"));
1326
+ const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
1442
1327
  packageJson.scripts = {
1443
1328
  ...packageJson.scripts,
1444
1329
  ...scripts
1445
1330
  };
1446
- await fs5.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1331
+ await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1447
1332
  }
1448
1333
  };
1449
- var args = ["-y", "@mastra/mcp-docs-server"];
1450
- var createMcpConfig = (editor) => {
1451
- if (editor === "vscode") {
1452
- return {
1453
- servers: {
1454
- mastra: process.platform === `win32` ? {
1455
- command: "cmd",
1456
- args: ["/c", "npx", ...args],
1457
- type: "stdio"
1458
- } : {
1459
- command: "npx",
1460
- args,
1461
- type: "stdio"
1462
- }
1463
- }
1464
- };
1465
- }
1466
- return {
1467
- mcpServers: {
1468
- mastra: {
1469
- command: "npx",
1470
- args
1471
- }
1472
- }
1473
- };
1334
+ var EnvService = class {
1474
1335
  };
1475
- function makeConfig(original, editor) {
1476
- if (editor === "vscode") {
1477
- return {
1478
- ...original,
1479
- servers: {
1480
- ...original?.servers || {},
1481
- ...createMcpConfig(editor).servers
1482
- }
1483
- };
1484
- }
1485
- return {
1486
- ...original,
1487
- mcpServers: {
1488
- ...original?.mcpServers || {},
1489
- ...createMcpConfig(editor).mcpServers
1490
- }
1491
- };
1492
- }
1493
- async function writeMergedConfig(configPath, editor) {
1494
- const configExists = existsSync(configPath);
1495
- const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
1496
- await ensureFile(configPath);
1497
- await writeJSON(configPath, config, {
1498
- spaces: 2
1499
- });
1500
- }
1501
- var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1502
- var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1503
- path3.join(process.cwd(), ".vscode", "mcp.json");
1504
- var vscodeGlobalMCPConfigPath = path3.join(
1505
- os.homedir(),
1506
- 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")
1507
- );
1508
- async function installMastraDocsMCPServer({ editor, directory }) {
1509
- if (editor === `cursor`) {
1510
- await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor");
1511
- }
1512
- if (editor === `vscode`) {
1513
- await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode");
1336
+ var FileEnvService = class extends EnvService {
1337
+ filePath;
1338
+ constructor(filePath) {
1339
+ super();
1340
+ this.filePath = filePath;
1514
1341
  }
1515
- if (editor === `cursor-global`) {
1516
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1517
- if (alreadyInstalled) {
1518
- return;
1519
- }
1520
- await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
1342
+ readFile(filePath) {
1343
+ return new Promise((resolve, reject) => {
1344
+ fs3__default.readFile(filePath, "utf8", (err, data) => {
1345
+ if (err) reject(err);
1346
+ else resolve(data);
1347
+ });
1348
+ });
1521
1349
  }
1522
- if (editor === `windsurf`) {
1523
- const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
1524
- if (alreadyInstalled) {
1525
- return;
1526
- }
1527
- await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
1528
- }
1529
- }
1530
- async function globalMCPIsAlreadyInstalled(editor) {
1531
- let configPath = ``;
1532
- if (editor === "windsurf") {
1533
- configPath = windsurfGlobalMCPConfigPath;
1534
- } else if (editor === "cursor-global") {
1535
- configPath = cursorGlobalMCPConfigPath;
1536
- } else if (editor === "vscode") {
1537
- configPath = vscodeGlobalMCPConfigPath;
1538
- }
1539
- if (!configPath || !existsSync(configPath)) {
1540
- return false;
1541
- }
1542
- try {
1543
- const configContents = await readJSON(configPath);
1544
- if (!configContents) return false;
1545
- if (editor === "vscode") {
1546
- if (!configContents.servers) return false;
1547
- const hasMastraMCP2 = Object.values(configContents.servers).some(
1548
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1549
- );
1550
- return hasMastraMCP2;
1551
- }
1552
- if (!configContents?.mcpServers) return false;
1553
- const hasMastraMCP = Object.values(configContents.mcpServers).some(
1554
- (server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
1555
- );
1556
- return hasMastraMCP;
1557
- } catch {
1558
- return false;
1559
- }
1560
- }
1561
- var EnvService = class {
1562
- };
1563
- var FileEnvService = class extends EnvService {
1564
- filePath;
1565
- constructor(filePath) {
1566
- super();
1567
- this.filePath = filePath;
1568
- }
1569
- readFile(filePath) {
1570
- return new Promise((resolve, reject) => {
1571
- fs4__default.readFile(filePath, "utf8", (err, data) => {
1572
- if (err) reject(err);
1573
- else resolve(data);
1574
- });
1575
- });
1576
- }
1577
- writeFile({ filePath, data }) {
1578
- return new Promise((resolve, reject) => {
1579
- fs4__default.writeFile(filePath, data, "utf8", (err) => {
1580
- if (err) reject(err);
1581
- else resolve();
1582
- });
1583
- });
1350
+ writeFile({ filePath, data }) {
1351
+ return new Promise((resolve, reject) => {
1352
+ fs3__default.writeFile(filePath, data, "utf8", (err) => {
1353
+ if (err) reject(err);
1354
+ else resolve();
1355
+ });
1356
+ });
1584
1357
  }
1585
1358
  async updateEnvData({
1586
1359
  key,
@@ -1631,8 +1404,8 @@ var FileService = class {
1631
1404
  const __filename = fileURLToPath(import.meta.url);
1632
1405
  const __dirname = path3.dirname(__filename);
1633
1406
  const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1634
- const fileString = fs4__default__default.readFileSync(filePath, "utf8");
1635
- if (fs4__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1407
+ const fileString = fs3__default__default.readFileSync(filePath, "utf8");
1408
+ if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1636
1409
  console.info(`${outputFilePath} already exists`);
1637
1410
  return false;
1638
1411
  }
@@ -1647,7 +1420,7 @@ var FileService = class {
1647
1420
  }
1648
1421
  getFirstExistingFile(files) {
1649
1422
  for (const f of files) {
1650
- if (fs4__default__default.existsSync(f)) {
1423
+ if (fs3__default__default.existsSync(f)) {
1651
1424
  return f;
1652
1425
  }
1653
1426
  }
@@ -1657,66 +1430,162 @@ var FileService = class {
1657
1430
  filePath,
1658
1431
  replacements
1659
1432
  }) {
1660
- let fileContent = fs4__default__default.readFileSync(filePath, "utf8");
1433
+ let fileContent = fs3__default__default.readFileSync(filePath, "utf8");
1661
1434
  replacements.forEach(({ search, replace }) => {
1662
1435
  fileContent = fileContent.replaceAll(search, replace);
1663
1436
  });
1664
- fs4__default__default.writeFileSync(filePath, fileContent);
1437
+ fs3__default__default.writeFileSync(filePath, fileContent);
1665
1438
  }
1666
1439
  };
1667
- var exec2 = util.promisify(child_process.exec);
1668
- var getAISDKPackageVersion = (llmProvider) => {
1669
- switch (llmProvider) {
1670
- case "cerebras":
1671
- return "^0.2.14";
1672
- default:
1673
- return "^1.0.0";
1674
- }
1440
+ var createArgs = (versionTag) => {
1441
+ const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
1442
+ return ["-y", packageName];
1675
1443
  };
1676
- var getAISDKPackage = (llmProvider) => {
1677
- switch (llmProvider) {
1678
- case "openai":
1679
- return "@ai-sdk/openai";
1680
- case "anthropic":
1681
- return "@ai-sdk/anthropic";
1682
- case "groq":
1683
- return "@ai-sdk/groq";
1684
- case "google":
1685
- return "@ai-sdk/google";
1686
- case "cerebras":
1687
- return "@ai-sdk/cerebras";
1688
- case "mistral":
1689
- return "@ai-sdk/mistral";
1690
- default:
1691
- return "@ai-sdk/openai";
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
+ };
1692
1460
  }
1461
+ return {
1462
+ mcpServers: {
1463
+ mastra: {
1464
+ command: "npx",
1465
+ args
1466
+ }
1467
+ }
1468
+ };
1693
1469
  };
1694
- var getProviderImportAndModelItem = (llmProvider) => {
1695
- let providerImport = "";
1696
- let modelItem = "";
1697
- if (llmProvider === "openai") {
1698
- providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
1699
- modelItem = `openai('gpt-4o-mini')`;
1700
- } else if (llmProvider === "anthropic") {
1701
- providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
1702
- modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
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
+ };
1487
+ }
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";
1703
1576
  } else if (llmProvider === "groq") {
1704
- providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1705
- modelItem = `groq('llama-3.3-70b-versatile')`;
1577
+ model = "groq/llama-3.3-70b-versatile";
1706
1578
  } else if (llmProvider === "google") {
1707
- providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
1708
- modelItem = `google('gemini-2.5-pro')`;
1579
+ model = "google/gemini-2.5-pro";
1709
1580
  } else if (llmProvider === "cerebras") {
1710
- providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
1711
- modelItem = `cerebras('llama-3.3-70b')`;
1581
+ model = "cerebras/llama-3.3-70b";
1712
1582
  } else if (llmProvider === "mistral") {
1713
- providerImport = `import { mistral } from '${getAISDKPackage(llmProvider)}';`;
1714
- modelItem = `mistral('mistral-medium-2508')`;
1583
+ model = "mistral/mistral-medium-2508";
1715
1584
  }
1716
- return { providerImport, modelItem };
1585
+ return model;
1717
1586
  };
1718
- async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1719
- const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1587
+ async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
1588
+ const modelString = getModelIdentifier(llmProvider);
1720
1589
  const instructions = `
1721
1590
  You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
1722
1591
 
@@ -1732,30 +1601,49 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1732
1601
  ${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
1733
1602
  `;
1734
1603
  const content = `
1735
- ${providerImport}
1736
1604
  import { Agent } from '@mastra/core/agent';
1737
1605
  import { Memory } from '@mastra/memory';
1738
- import { LibSQLStore } from '@mastra/libsql';
1739
1606
  ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
1607
+ ${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
1740
1608
 
1741
1609
  export const weatherAgent = new Agent({
1610
+ id: 'weather-agent',
1742
1611
  name: 'Weather Agent',
1743
1612
  instructions: \`${instructions}\`,
1744
- model: ${modelItem},
1613
+ model: '${modelString}',
1745
1614
  ${addExampleTool ? "tools: { weatherTool }," : ""}
1746
- memory: new Memory({
1747
- storage: new LibSQLStore({
1748
- url: "file:../mastra.db", // path is relative to the .mastra/output directory
1749
- })
1750
- })
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()
1751
1639
  });
1752
1640
  `;
1753
1641
  const formattedContent = await prettier.format(content, {
1754
1642
  parser: "typescript",
1755
1643
  singleQuote: true
1756
1644
  });
1757
- await fs5.writeFile(destPath, "");
1758
- await fs5.writeFile(destPath, formattedContent);
1645
+ await fs4.writeFile(destPath, "");
1646
+ await fs4.writeFile(destPath, formattedContent);
1759
1647
  }
1760
1648
  async function writeWorkflowSample(destPath) {
1761
1649
  const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
@@ -1948,20 +1836,115 @@ export { weatherWorkflow };`;
1948
1836
  semi: true,
1949
1837
  singleQuote: true
1950
1838
  });
1951
- await fs5.writeFile(destPath, formattedContent);
1839
+ await fs4.writeFile(destPath, formattedContent);
1952
1840
  }
1953
1841
  async function writeToolSample(destPath) {
1954
1842
  const fileService = new FileService();
1955
1843
  await fileService.copyStarterFile("tools.ts", destPath);
1956
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
+ }
1957
1933
  async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
1958
1934
  switch (component) {
1959
1935
  case "agents":
1960
- return writeAgentSample(llmprovider, destPath, importComponents.includes("tools"));
1936
+ return writeAgentSample(
1937
+ llmprovider,
1938
+ destPath,
1939
+ importComponents.includes("tools"),
1940
+ importComponents.includes("scorers")
1941
+ );
1961
1942
  case "tools":
1962
1943
  return writeToolSample(destPath);
1963
1944
  case "workflows":
1964
1945
  return writeWorkflowSample(destPath);
1946
+ case "scorers":
1947
+ return writeScorersSample(llmprovider, destPath);
1965
1948
  default:
1966
1949
  return "";
1967
1950
  }
@@ -1974,46 +1957,65 @@ var writeIndexFile = async ({
1974
1957
  dirPath,
1975
1958
  addAgent,
1976
1959
  addExample,
1977
- addWorkflow
1960
+ addWorkflow,
1961
+ addScorers
1978
1962
  }) => {
1979
1963
  const indexPath = dirPath + "/index.ts";
1980
1964
  const destPath = path3.join(indexPath);
1981
1965
  try {
1982
- await fs5.writeFile(destPath, "");
1966
+ await fs4.writeFile(destPath, "");
1983
1967
  const filteredExports = [
1984
1968
  addWorkflow ? `workflows: { weatherWorkflow },` : "",
1985
- addAgent ? `agents: { weatherAgent },` : ""
1969
+ addAgent ? `agents: { weatherAgent },` : "",
1970
+ addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
1986
1971
  ].filter(Boolean);
1987
1972
  if (!addExample) {
1988
- await fs5.writeFile(
1973
+ await fs4.writeFile(
1989
1974
  destPath,
1990
1975
  `
1991
- import { Mastra } from '@mastra/core';
1976
+ import { Mastra } from '@mastra/core/mastra';
1992
1977
 
1993
1978
  export const mastra = new Mastra()
1994
1979
  `
1995
1980
  );
1996
1981
  return;
1997
1982
  }
1998
- await fs5.writeFile(
1983
+ await fs4.writeFile(
1999
1984
  destPath,
2000
1985
  `
2001
1986
  import { Mastra } from '@mastra/core/mastra';
2002
1987
  import { PinoLogger } from '@mastra/loggers';
2003
1988
  import { LibSQLStore } from '@mastra/libsql';
1989
+ import { Observability, DefaultExporter, CloudExporter, SensitiveDataFilter } from '@mastra/observability';
2004
1990
  ${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
2005
1991
  ${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
1992
+ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
2006
1993
 
2007
1994
  export const mastra = new Mastra({
2008
1995
  ${filteredExports.join("\n ")}
2009
1996
  storage: new LibSQLStore({
2010
- // 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
2011
1999
  url: ":memory:",
2012
2000
  }),
2013
2001
  logger: new PinoLogger({
2014
2002
  name: 'Mastra',
2015
2003
  level: 'info',
2016
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
+ }),
2017
2019
  });
2018
2020
  `
2019
2021
  );
@@ -2021,7 +2023,6 @@ export const mastra = new Mastra({
2021
2023
  throw err;
2022
2024
  }
2023
2025
  };
2024
- yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
2025
2026
  var getAPIKey = async (provider) => {
2026
2027
  let key = "OPENAI_API_KEY";
2027
2028
  switch (provider) {
@@ -2044,20 +2045,18 @@ var getAPIKey = async (provider) => {
2044
2045
  return key;
2045
2046
  }
2046
2047
  };
2047
- var writeAPIKey = async ({
2048
- provider,
2049
- apiKey = "your-api-key"
2050
- }) => {
2048
+ var writeAPIKey = async ({ provider, apiKey }) => {
2049
+ const envFileName = apiKey ? ".env" : ".env.example";
2051
2050
  const key = await getAPIKey(provider);
2052
- const escapedKey = shellQuote.quote([key]);
2053
- const escapedApiKey = shellQuote.quote([apiKey]);
2054
- await exec2(`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}`);
2055
2054
  };
2056
2055
  var createMastraDir = async (directory) => {
2057
2056
  let dir = directory.trim().split("/").filter((item) => item !== "");
2058
2057
  const dirPath = path3.join(process.cwd(), ...dir, "mastra");
2059
2058
  try {
2060
- await fs5.access(dirPath);
2059
+ await fs4.access(dirPath);
2061
2060
  return { ok: false };
2062
2061
  } catch {
2063
2062
  await fsExtra.ensureDir(dirPath);
@@ -2072,8 +2071,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
2072
2071
  throw err;
2073
2072
  }
2074
2073
  };
2075
- var interactivePrompt = async () => {
2076
- 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
+ }
2077
2087
  const mastraProject = await Ce(
2078
2088
  {
2079
2089
  directory: () => he({
@@ -2081,20 +2091,15 @@ var interactivePrompt = async () => {
2081
2091
  placeholder: "src/",
2082
2092
  defaultValue: "src/"
2083
2093
  }),
2084
- llmProvider: () => ve({
2085
- message: "Select default provider:",
2086
- options: [
2087
- { value: "openai", label: "OpenAI", hint: "recommended" },
2088
- { value: "anthropic", label: "Anthropic" },
2089
- { value: "groq", label: "Groq" },
2090
- { value: "google", label: "Google" },
2091
- { value: "cerebras", label: "Cerebras" },
2092
- { value: "mistral", label: "Mistral" }
2093
- ]
2094
+ llmProvider: () => skip?.llmProvider ? void 0 : ve({
2095
+ message: "Select a default provider:",
2096
+ options: LLM_PROVIDERS
2094
2097
  }),
2095
2098
  llmApiKey: async ({ results: { llmProvider } }) => {
2099
+ if (skip?.llmApiKey) return void 0;
2100
+ const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
2096
2101
  const keyChoice = await ve({
2097
- message: `Enter your ${llmProvider} API key?`,
2102
+ message: `Enter your ${llmName} API key?`,
2098
2103
  options: [
2099
2104
  { value: "skip", label: "Skip for now", hint: "default" },
2100
2105
  { value: "enter", label: "Enter API key" }
@@ -2104,52 +2109,42 @@ var interactivePrompt = async () => {
2104
2109
  if (keyChoice === "enter") {
2105
2110
  return he({
2106
2111
  message: "Enter your API key:",
2107
- placeholder: "sk-..."
2112
+ placeholder: "sk-...",
2113
+ validate: (value) => {
2114
+ if (value.length === 0) return "API key cannot be empty";
2115
+ }
2108
2116
  });
2109
2117
  }
2110
2118
  return void 0;
2111
2119
  },
2112
2120
  configureEditorWithDocsMCP: async () => {
2113
- const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
2114
- const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
2115
- const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
2116
2121
  const editor = await ve({
2117
- 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)`,
2118
2123
  options: [
2119
2124
  { value: "skip", label: "Skip for now", hint: "default" },
2120
2125
  {
2121
2126
  value: "cursor",
2122
- label: "Cursor (project only)",
2123
- hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
2127
+ label: "Cursor (project only)"
2124
2128
  },
2125
2129
  {
2126
2130
  value: "cursor-global",
2127
- label: "Cursor (global, all projects)",
2128
- hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
2131
+ label: "Cursor (global, all projects)"
2129
2132
  },
2130
2133
  {
2131
2134
  value: "windsurf",
2132
- label: "Windsurf",
2133
- hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
2135
+ label: "Windsurf"
2134
2136
  },
2135
2137
  {
2136
2138
  value: "vscode",
2137
- label: "VSCode",
2138
- hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
2139
+ label: "VSCode"
2140
+ },
2141
+ {
2142
+ value: "antigravity",
2143
+ label: "Antigravity"
2139
2144
  }
2140
2145
  ]
2141
2146
  });
2142
2147
  if (editor === `skip`) return void 0;
2143
- if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
2144
- M.message(`
2145
- Windsurf is already installed, skipping.`);
2146
- return void 0;
2147
- }
2148
- if (editor === `vscode` && vscodeIsAlreadyInstalled) {
2149
- M.message(`
2150
- VSCode is already installed, skipping.`);
2151
- return void 0;
2152
- }
2153
2148
  if (editor === `cursor`) {
2154
2149
  M.message(
2155
2150
  `
@@ -2158,19 +2153,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
2158
2153
  );
2159
2154
  }
2160
2155
  if (editor === `cursor-global`) {
2161
- const confirm2 = await ve({
2156
+ const confirm3 = await ve({
2162
2157
  message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
2163
2158
  options: [
2164
2159
  { value: "yes", label: "Yes, I understand" },
2165
2160
  { value: "skip", label: "No, skip for now" }
2166
2161
  ]
2167
2162
  });
2168
- if (confirm2 !== `yes`) {
2163
+ if (confirm3 !== `yes`) {
2169
2164
  return void 0;
2170
2165
  }
2171
2166
  }
2172
2167
  if (editor === `windsurf`) {
2173
- const confirm2 = await ve({
2168
+ const confirm3 = await ve({
2174
2169
  message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
2175
2170
  This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
2176
2171
  options: [
@@ -2178,11 +2173,31 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2178
2173
  { value: "skip", label: "No, skip for now" }
2179
2174
  ]
2180
2175
  });
2181
- 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`) {
2182
2190
  return void 0;
2183
2191
  }
2184
2192
  }
2185
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
+ });
2186
2201
  }
2187
2202
  },
2188
2203
  {
@@ -2194,17 +2209,245 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2194
2209
  );
2195
2210
  return mastraProject;
2196
2211
  };
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
+ }
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
+ }
2197
2438
  var s = Y();
2198
- var exec3 = util.promisify(child_process.exec);
2199
2439
  var init = async ({
2200
- directory,
2201
- addExample = false,
2440
+ directory = "src/",
2202
2441
  components,
2203
2442
  llmProvider = "openai",
2204
2443
  llmApiKey,
2205
- configureEditorWithDocsMCP
2444
+ addExample = false,
2445
+ configureEditorWithDocsMCP,
2446
+ versionTag,
2447
+ initGit = false
2206
2448
  }) => {
2207
2449
  s.start("Initializing Mastra");
2450
+ const packageVersionTag = versionTag ? `@${versionTag}` : "";
2208
2451
  try {
2209
2452
  const result = await createMastraDir(directory);
2210
2453
  if (!result.ok) {
@@ -2217,7 +2460,8 @@ var init = async ({
2217
2460
  dirPath,
2218
2461
  addExample,
2219
2462
  addWorkflow: components.includes("workflows"),
2220
- addAgent: components.includes("agents")
2463
+ addAgent: components.includes("agents"),
2464
+ addScorers: components.includes("scorers")
2221
2465
  }),
2222
2466
  ...components.map((component) => createComponentsDir(dirPath, component)),
2223
2467
  writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
@@ -2231,31 +2475,44 @@ var init = async ({
2231
2475
  const depService = new DepsService();
2232
2476
  const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
2233
2477
  if (needsLibsql) {
2234
- await depService.installPackages(["@mastra/libsql"]);
2478
+ await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
2235
2479
  }
2236
2480
  const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
2237
2481
  if (needsMemory) {
2238
- await depService.installPackages(["@mastra/memory"]);
2482
+ await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
2239
2483
  }
2240
2484
  const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
2241
2485
  if (needsLoggers) {
2242
- 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}`]);
2243
2495
  }
2244
2496
  }
2245
2497
  const key = await getAPIKey(llmProvider || "openai");
2246
- const aiSdkPackage = getAISDKPackage(llmProvider);
2247
- const aiSdkPackageVersion = getAISDKPackageVersion(llmProvider);
2248
- const depsService = new DepsService();
2249
- const pm = depsService.packageManager;
2250
- const installCommand = getPackageManagerAddCommand(pm);
2251
- await exec3(`${pm} ${installCommand} ${aiSdkPackage}@${aiSdkPackageVersion}`);
2252
2498
  if (configureEditorWithDocsMCP) {
2253
2499
  await installMastraDocsMCPServer({
2254
2500
  editor: configureEditorWithDocsMCP,
2255
- directory: process.cwd()
2501
+ directory: process.cwd(),
2502
+ versionTag
2256
2503
  });
2257
2504
  }
2258
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
+ }
2259
2516
  if (!llmApiKey) {
2260
2517
  Me(`
2261
2518
  ${color2.green("Mastra initialized successfully!")}
@@ -2275,10 +2532,10 @@ var init = async ({
2275
2532
  return { success: false };
2276
2533
  }
2277
2534
  };
2278
- var exec4 = util.promisify(child_process.exec);
2535
+ var exec3 = util.promisify(child_process.exec);
2279
2536
  var execWithTimeout = async (command, timeoutMs) => {
2280
2537
  try {
2281
- const promise = exec4(command, { killSignal: "SIGTERM" });
2538
+ const promise = exec3(command, { killSignal: "SIGTERM" });
2282
2539
  if (!timeoutMs) {
2283
2540
  return await promise;
2284
2541
  }
@@ -2301,6 +2558,68 @@ var execWithTimeout = async (command, timeoutMs) => {
2301
2558
  throw error;
2302
2559
  }
2303
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/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/). Your bootstrapped project includes example code for [agents](https://mastra.ai/docs/agents/overview), [tools](https://mastra.ai/docs/agents/using-tools), [workflows](https://mastra.ai/docs/workflows/overview), [scorers](https://mastra.ai/docs/evals/overview), and [observability](https://mastra.ai/docs/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/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
+ };
2304
2623
  async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
2305
2624
  let installCommand = getPackageManagerAddCommand(pm);
2306
2625
  if (isDev) {
@@ -2326,23 +2645,42 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
2326
2645
  var createMastraProject = async ({
2327
2646
  projectName: name,
2328
2647
  createVersionTag,
2329
- timeout
2648
+ timeout,
2649
+ llmProvider,
2650
+ llmApiKey,
2651
+ needsInteractive
2330
2652
  }) => {
2331
2653
  Ie(color2.inverse(" Mastra Create "));
2332
2654
  const projectName = name ?? await he({
2333
2655
  message: "What do you want to name your project?",
2334
2656
  placeholder: "my-mastra-app",
2335
- 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
+ }
2336
2664
  });
2337
2665
  if (pD(projectName)) {
2338
2666
  xe("Operation cancelled");
2339
2667
  process.exit(0);
2340
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
+ }
2341
2676
  const s2 = Y();
2677
+ const originalCwd = process.cwd();
2678
+ let projectPath = null;
2342
2679
  try {
2343
2680
  s2.start("Creating project");
2344
2681
  try {
2345
- await fs5.mkdir(projectName);
2682
+ await fs4.mkdir(projectName);
2683
+ projectPath = path3.resolve(originalCwd, projectName);
2346
2684
  } catch (error) {
2347
2685
  if (error instanceof Error && "code" in error && error.code === "EEXIST") {
2348
2686
  s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
@@ -2357,15 +2695,14 @@ var createMastraProject = async ({
2357
2695
  const installCommand = getPackageManagerAddCommand(pm);
2358
2696
  s2.message("Initializing project structure");
2359
2697
  try {
2360
- await exec4(`npm init -y`);
2361
- await exec4(`npm pkg set type="module"`);
2362
- await exec4(`npm pkg set engines.node=">=20.9.0"`);
2698
+ await initializePackageJson(pm);
2363
2699
  const depsService = new DepsService();
2364
2700
  await depsService.addScriptsToPackageJson({
2365
2701
  dev: "mastra dev",
2366
2702
  build: "mastra build",
2367
2703
  start: "mastra start"
2368
2704
  });
2705
+ await writeReadmeFile({ dirPath: process.cwd(), projectName });
2369
2706
  } catch (error) {
2370
2707
  throw new Error(
2371
2708
  `Failed to initialize project structure: ${error instanceof Error ? error.message : "Unknown error"}`
@@ -2374,9 +2711,9 @@ var createMastraProject = async ({
2374
2711
  s2.stop("Project structure created");
2375
2712
  s2.start(`Installing ${pm} dependencies`);
2376
2713
  try {
2377
- await exec4(`${pm} ${installCommand} zod@^3`);
2378
- await exec4(`${pm} ${installCommand} typescript @types/node --save-dev`);
2379
- await exec4(`echo '{
2714
+ await exec3(`${pm} ${installCommand} zod@^4`);
2715
+ await exec3(`${pm} ${installCommand} -D typescript @types/node`);
2716
+ await exec3(`echo '{
2380
2717
  "compilerOptions": {
2381
2718
  "target": "ES2022",
2382
2719
  "module": "ES2022",
@@ -2398,15 +2735,15 @@ var createMastraProject = async ({
2398
2735
  );
2399
2736
  }
2400
2737
  s2.stop(`${pm} dependencies installed`);
2401
- s2.start("Installing mastra");
2738
+ s2.start("Installing Mastra CLI");
2402
2739
  const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
2403
2740
  try {
2404
2741
  await installMastraDependency(pm, "mastra", versionTag, true, timeout);
2405
2742
  } catch (error) {
2406
2743
  throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
2407
2744
  }
2408
- s2.stop("mastra installed");
2409
- s2.start("Installing dependencies");
2745
+ s2.stop("Mastra CLI installed");
2746
+ s2.start("Installing Mastra dependencies");
2410
2747
  try {
2411
2748
  await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
2412
2749
  await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
@@ -2419,58 +2756,80 @@ var createMastraProject = async ({
2419
2756
  s2.stop("Mastra dependencies installed");
2420
2757
  s2.start("Adding .gitignore");
2421
2758
  try {
2422
- await exec4(`echo output.txt >> .gitignore`);
2423
- await exec4(`echo node_modules >> .gitignore`);
2424
- await exec4(`echo dist >> .gitignore`);
2425
- await exec4(`echo .mastra >> .gitignore`);
2426
- await exec4(`echo .env.development >> .gitignore`);
2427
- await exec4(`echo .env >> .gitignore`);
2428
- await exec4(`echo *.db >> .gitignore`);
2429
- await exec4(`echo *.db-* >> .gitignore`);
2759
+ await exec3(`echo output.txt >> .gitignore`);
2760
+ await exec3(`echo node_modules >> .gitignore`);
2761
+ await exec3(`echo dist >> .gitignore`);
2762
+ await exec3(`echo .mastra >> .gitignore`);
2763
+ await exec3(`echo .env.development >> .gitignore`);
2764
+ await exec3(`echo .env >> .gitignore`);
2765
+ await exec3(`echo *.db >> .gitignore`);
2766
+ await exec3(`echo *.db-* >> .gitignore`);
2430
2767
  } catch (error) {
2431
2768
  throw new Error(`Failed to create .gitignore: ${error instanceof Error ? error.message : "Unknown error"}`);
2432
2769
  }
2433
2770
  s2.stop(".gitignore added");
2434
2771
  Se("Project created successfully");
2435
2772
  console.info("");
2436
- return { projectName };
2773
+ return { projectName, result };
2437
2774
  } catch (error) {
2438
2775
  s2.stop();
2439
2776
  const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
2440
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
+ }
2441
2788
  process.exit(1);
2442
2789
  }
2443
2790
  };
2444
- var create = async (args2) => {
2445
- if (args2.template !== void 0) {
2446
- await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
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
+ });
2447
2801
  return;
2448
2802
  }
2449
- const { projectName } = await createMastraProject({
2450
- projectName: args2?.projectName,
2451
- createVersionTag: args2?.createVersionTag,
2452
- timeout: args2?.timeout
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
2453
2811
  });
2454
- const directory = args2.directory || "src/";
2455
- if (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
2456
- const result = await interactivePrompt();
2812
+ const directory = args.directory || "src/";
2813
+ if (needsInteractive && result) {
2457
2814
  await init({
2458
2815
  ...result,
2459
2816
  llmApiKey: result?.llmApiKey,
2460
- components: ["agents", "tools", "workflows"],
2461
- addExample: true
2817
+ components: ["agents", "tools", "workflows", "scorers"],
2818
+ addExample: true,
2819
+ versionTag: args.createVersionTag
2462
2820
  });
2463
2821
  postCreate({ projectName });
2464
2822
  return;
2465
2823
  }
2466
- const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args2;
2824
+ const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
2467
2825
  await init({
2468
2826
  directory,
2469
2827
  components,
2470
2828
  llmProvider,
2471
2829
  addExample,
2472
2830
  llmApiKey,
2473
- configureEditorWithDocsMCP: args2.mcpServer
2831
+ configureEditorWithDocsMCP: args.mcpServer,
2832
+ versionTag: args.createVersionTag
2474
2833
  });
2475
2834
  postCreate({ projectName });
2476
2835
  };
@@ -2561,9 +2920,9 @@ async function createFromGitHubUrl(url) {
2561
2920
  workflows: []
2562
2921
  };
2563
2922
  }
2564
- async function createFromTemplate(args2) {
2923
+ async function createFromTemplate(args) {
2565
2924
  let selectedTemplate;
2566
- if (args2.template === true) {
2925
+ if (args.template === true) {
2567
2926
  const templates = await loadTemplates();
2568
2927
  const selected = await selectTemplate(templates);
2569
2928
  if (!selected) {
@@ -2571,26 +2930,26 @@ async function createFromTemplate(args2) {
2571
2930
  return;
2572
2931
  }
2573
2932
  selectedTemplate = selected;
2574
- } else if (args2.template && typeof args2.template === "string") {
2575
- if (isGitHubUrl(args2.template)) {
2576
- const spinner5 = Y();
2577
- spinner5.start("Validating GitHub repository...");
2578
- const validation = await validateGitHubProject(args2.template);
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);
2579
2938
  if (!validation.isValid) {
2580
- spinner5.stop("Validation failed");
2939
+ spinner4.stop("Validation failed");
2581
2940
  M.error("This does not appear to be a valid Mastra project:");
2582
2941
  validation.errors.forEach((error) => M.error(` - ${error}`));
2583
2942
  throw new Error("Invalid Mastra project");
2584
2943
  }
2585
- spinner5.stop("Valid Mastra project \u2713");
2586
- selectedTemplate = await createFromGitHubUrl(args2.template);
2944
+ spinner4.stop("Valid Mastra project \u2713");
2945
+ selectedTemplate = await createFromGitHubUrl(args.template);
2587
2946
  } else {
2588
2947
  const templates = await loadTemplates();
2589
- const found = findTemplateByName(templates, args2.template);
2948
+ const found = findTemplateByName(templates, args.template);
2590
2949
  if (!found) {
2591
- M.error(`Template "${args2.template}" not found. Available templates:`);
2950
+ M.error(`Template "${args.template}" not found. Available templates:`);
2592
2951
  templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2593
- throw new Error(`Template "${args2.template}" not found`);
2952
+ throw new Error(`Template "${args.template}" not found`);
2594
2953
  }
2595
2954
  selectedTemplate = found;
2596
2955
  }
@@ -2598,7 +2957,7 @@ async function createFromTemplate(args2) {
2598
2957
  if (!selectedTemplate) {
2599
2958
  throw new Error("No template selected");
2600
2959
  }
2601
- let projectName = args2.projectName;
2960
+ let projectName = args.projectName;
2602
2961
  if (!projectName) {
2603
2962
  const defaultName = getDefaultProjectName(selectedTemplate);
2604
2963
  const response = await he({
@@ -2612,19 +2971,61 @@ async function createFromTemplate(args2) {
2612
2971
  }
2613
2972
  projectName = response;
2614
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;
2615
2995
  try {
2616
- const analytics = args2.injectedAnalytics || getAnalytics();
2996
+ const analytics = args.injectedAnalytics || getAnalytics();
2617
2997
  if (analytics) {
2618
2998
  analytics.trackEvent("cli_template_used", {
2619
2999
  template_slug: selectedTemplate.slug,
2620
3000
  template_title: selectedTemplate.title
2621
3001
  });
3002
+ if (llmProvider) {
3003
+ analytics.trackEvent("cli_model_provider_selected", {
3004
+ provider: llmProvider,
3005
+ selection_method: args.llmProvider ? "cli_args" : "interactive"
3006
+ });
3007
+ }
2622
3008
  }
2623
- const projectPath = await cloneTemplate({
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({
2624
3013
  template: selectedTemplate,
2625
- projectName
3014
+ projectName,
3015
+ branch,
3016
+ llmProvider
2626
3017
  });
2627
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
+ }
2628
3029
  Me(`
2629
3030
  ${color2.green("Mastra template installed!")}
2630
3031
 
@@ -2633,6 +3034,17 @@ async function createFromTemplate(args2) {
2633
3034
  `);
2634
3035
  postCreate({ projectName });
2635
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
+ }
2636
3048
  M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
2637
3049
  throw error;
2638
3050
  }
@@ -2679,7 +3091,7 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
2679
3091
  program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
2680
3092
  "-p, --project-name <string>",
2681
3093
  "Project name that will be used in package.json and as the project directory name."
2682
- ).option("--default", "Quick start with defaults(src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
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(
2683
3095
  "--template [template-name]",
2684
3096
  "Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
2685
3097
  ).action(async (projectNameArg, args) => {
@@ -2687,7 +3099,7 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2687
3099
  const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
2688
3100
  if (args.default) {
2689
3101
  await create({
2690
- components: ["agents", "tools", "workflows"],
3102
+ components: ["agents", "tools", "workflows", "scorers"],
2691
3103
  llmProvider: "openai",
2692
3104
  addExample: true,
2693
3105
  createVersionTag,
@@ -2703,7 +3115,7 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2703
3115
  components: args.components ? args.components.split(",") : [],
2704
3116
  llmProvider: args.llm,
2705
3117
  addExample: args.example,
2706
- llmApiKey: args["llm-api-key"],
3118
+ llmApiKey: args.llmApiKey,
2707
3119
  createVersionTag,
2708
3120
  timeout,
2709
3121
  projectName,