create-mastra 0.0.0-bundle-recursion-20251030002519 → 0.0.0-bundle-studio-cloud-20251222034739
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +179 -1
- package/dist/index.js +454 -242
- package/dist/index.js.map +1 -1
- package/dist/starter-files/tools.ts +2 -2
- package/dist/templates/dev.entry.js +2 -45
- package/package.json +17 -18
package/dist/index.js
CHANGED
|
@@ -4,26 +4,26 @@ import { randomUUID } from 'node:crypto';
|
|
|
4
4
|
import * as fs3__default from 'node:fs';
|
|
5
5
|
import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import
|
|
7
|
+
import path3, { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { PostHog } from 'posthog-node';
|
|
10
|
+
import fs4 from 'node:fs/promises';
|
|
10
11
|
import util, { stripVTControlCharacters } from 'node:util';
|
|
11
12
|
import y$1, { stdout, stdin } from 'node:process';
|
|
12
13
|
import * as g from 'node:readline';
|
|
13
14
|
import g__default from 'node:readline';
|
|
14
15
|
import { Writable } from 'node:stream';
|
|
15
|
-
import fs4 from 'node:fs/promises';
|
|
16
16
|
import child_process from 'node:child_process';
|
|
17
17
|
import tty from 'node:tty';
|
|
18
18
|
import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
19
19
|
import prettier from 'prettier';
|
|
20
20
|
import { execa } from 'execa';
|
|
21
|
+
import fsExtra$1 from 'fs-extra';
|
|
21
22
|
import pino from 'pino';
|
|
22
23
|
import pretty from 'pino-pretty';
|
|
23
|
-
import fsExtra$1 from 'fs-extra';
|
|
24
24
|
|
|
25
25
|
var __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
var __dirname =
|
|
26
|
+
var __dirname = path3.dirname(__filename);
|
|
27
27
|
var analyticsInstance = null;
|
|
28
28
|
function getAnalytics() {
|
|
29
29
|
return analyticsInstance;
|
|
@@ -39,7 +39,7 @@ var PosthogAnalytics = class {
|
|
|
39
39
|
host = "https://app.posthog.com"
|
|
40
40
|
}) {
|
|
41
41
|
this.version = version;
|
|
42
|
-
const cliConfigPath =
|
|
42
|
+
const cliConfigPath = path3.join(__dirname, "mastra-cli.json");
|
|
43
43
|
if (existsSync(cliConfigPath)) {
|
|
44
44
|
try {
|
|
45
45
|
const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
|
|
@@ -67,7 +67,7 @@ var PosthogAnalytics = class {
|
|
|
67
67
|
}
|
|
68
68
|
writeCliConfig({ distinctId, sessionId }) {
|
|
69
69
|
try {
|
|
70
|
-
writeFileSync(
|
|
70
|
+
writeFileSync(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
|
|
71
71
|
} catch {
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -382,7 +382,7 @@ function DD({onlyFirst:e=false}={}){const t=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:
|
|
|
382
382
|
`).length-1;this.output.write(srcExports.cursor.move(-999,u*-1));}render(){const u=Y$1(this._render(this)??"",process.stdout.columns,{hard:true});if(u!==this._prevFrame){if(this.state==="initial")this.output.write(srcExports.cursor.hide);else {const t=BD(this._prevFrame,u);if(this.restoreCursor(),t&&t?.length===1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.lines(1));const s=u.split(`
|
|
383
383
|
`);this.output.write(s[F]),this._prevFrame=u,this.output.write(srcExports.cursor.move(0,s.length-F-1));return}if(t&&t?.length>1){const F=t[0];this.output.write(srcExports.cursor.move(0,F)),this.output.write(srcExports.erase.down());const s=u.split(`
|
|
384
384
|
`).slice(F);this.output.write(s.join(`
|
|
385
|
-
`)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
|
|
385
|
+
`)),this._prevFrame=u;return}this.output.write(srcExports.erase.down());}this.output.write(u),this.state==="initial"&&(this.state="active"),this._prevFrame=u;}}}class dD extends x{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(u){super(u,false),this.value=!!u.initialValue,this.on("value",()=>{this.value=this._value;}),this.on("confirm",t=>{this.output.write(srcExports.cursor.move(0,-1)),this.value=t,this.state="submit",this.close();}),this.on("cursor",()=>{this.value=!this.value;});}}var OD=Object.defineProperty,PD=(e,u,t)=>u in e?OD(e,u,{enumerable:true,configurable:true,writable:true,value:t}):e[u]=t,J=(e,u,t)=>(PD(e,typeof u!="symbol"?u+"":u,t),t);class LD extends x{constructor(u){super(u,false),J(this,"options"),J(this,"cursor",0),this.options=u.options,this.cursor=this.options.findIndex(({value:t})=>t===u.initialValue),this.cursor===-1&&(this.cursor=0),this.changeValue(),this.on("cursor",t=>{switch(t){case "left":case "up":this.cursor=this.cursor===0?this.options.length-1:this.cursor-1;break;case "down":case "right":this.cursor=this.cursor===this.options.length-1?0:this.cursor+1;break}this.changeValue();});}get _value(){return this.options[this.cursor]}changeValue(){this.value=this._value.value;}}class RD extends x{get valueWithCursor(){if(this.state==="submit")return this.value;if(this.cursor>=this.value.length)return `${this.value}\u2588`;const u=this.value.slice(0,this.cursor),[t,...F]=this.value.slice(this.cursor);return `${u}${color2.inverse(t)}${F.join("")}`}get cursor(){return this._cursor}constructor(u){super(u),this.on("finalize",()=>{this.value||(this.value=u.defaultValue);});}}
|
|
386
386
|
|
|
387
387
|
function ce(){return y$1.platform!=="win32"?y$1.env.TERM!=="linux":!!y$1.env.CI||!!y$1.env.WT_SESSION||!!y$1.env.TERMINUS_SUBLIME||y$1.env.ConEmuTask==="{cmd::Cmder}"||y$1.env.TERM_PROGRAM==="Terminus-Sublime"||y$1.env.TERM_PROGRAM==="vscode"||y$1.env.TERM==="xterm-256color"||y$1.env.TERM==="alacritty"||y$1.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}const V=ce(),u=(t,n)=>V?t:n,le=u("\u25C6","*"),L=u("\u25A0","x"),W=u("\u25B2","x"),C=u("\u25C7","o"),ue=u("\u250C","T"),o=u("\u2502","|"),d=u("\u2514","\u2014"),k=u("\u25CF",">"),P=u("\u25CB"," "),_=u("\u2500","-"),me=u("\u256E","+"),de=u("\u251C","+"),pe=u("\u256F","+"),q=u("\u25CF","\u2022"),D=u("\u25C6","*"),U=u("\u25B2","!"),K=u("\u25A0","x"),b=t=>{switch(t){case "initial":case "active":return color2.cyan(le);case "cancel":return color2.red(L);case "error":return color2.yellow(W);case "submit":return color2.green(C)}},G=t=>{const{cursor:n,options:r,style:i}=t,s=t.maxItems??Number.POSITIVE_INFINITY,c=Math.max(process.stdout.rows-4,0),a=Math.min(c,Math.max(s,5));let l=0;n>=l+a-3?l=Math.max(Math.min(n-a+3,r.length-a),0):n<l+2&&(l=Math.max(n-2,0));const $=a<r.length&&l>0,g=a<r.length&&l+a<r.length;return r.slice(l,l+a).map((p,v,f)=>{const j=v===0&&$,E=v===f.length-1&&g;return j||E?color2.dim("..."):i(p,v+l===n)})},he=t=>new RD({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,render(){const n=`${color2.gray(o)}
|
|
388
388
|
${b(this.state)} ${t.message}
|
|
@@ -392,7 +392,12 @@ ${color2.yellow(d)} ${color2.yellow(this.error)}
|
|
|
392
392
|
`;case "submit":return `${n}${color2.gray(o)} ${color2.dim(this.value||t.placeholder)}`;case "cancel":return `${n}${color2.gray(o)} ${color2.strikethrough(color2.dim(this.value??""))}${this.value?.trim()?`
|
|
393
393
|
${color2.gray(o)}`:""}`;default:return `${n}${color2.cyan(o)} ${i}
|
|
394
394
|
${color2.cyan(d)}
|
|
395
|
-
`}}}).prompt(),
|
|
395
|
+
`}}}).prompt(),ye=t=>{const n=t.active??"Yes",r=t.inactive??"No";return new dD({active:n,inactive:r,initialValue:t.initialValue??true,render(){const i=`${color2.gray(o)}
|
|
396
|
+
${b(this.state)} ${t.message}
|
|
397
|
+
`,s=this.value?n:r;switch(this.state){case "submit":return `${i}${color2.gray(o)} ${color2.dim(s)}`;case "cancel":return `${i}${color2.gray(o)} ${color2.strikethrough(color2.dim(s))}
|
|
398
|
+
${color2.gray(o)}`;default:return `${i}${color2.cyan(o)} ${this.value?`${color2.green(k)} ${n}`:`${color2.dim(P)} ${color2.dim(n)}`} ${color2.dim("/")} ${this.value?`${color2.dim(P)} ${color2.dim(r)}`:`${color2.green(k)} ${r}`}
|
|
399
|
+
${color2.cyan(d)}
|
|
400
|
+
`}}}).prompt()},ve=t=>{const n=(r,i)=>{const s=r.label??String(r.value);switch(i){case "selected":return `${color2.dim(s)}`;case "active":return `${color2.green(k)} ${s} ${r.hint?color2.dim(`(${r.hint})`):""}`;case "cancelled":return `${color2.strikethrough(color2.dim(s))}`;default:return `${color2.dim(P)} ${color2.dim(s)}`}};return new LD({options:t.options,initialValue:t.initialValue,render(){const r=`${color2.gray(o)}
|
|
396
401
|
${b(this.state)} ${t.message}
|
|
397
402
|
`;switch(this.state){case "submit":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"selected")}`;case "cancel":return `${r}${color2.gray(o)} ${n(this.options[this.cursor],"cancelled")}
|
|
398
403
|
${color2.gray(o)}`;default:return `${r}${color2.cyan(o)} ${G({cursor:this.cursor,options:this.options,maxItems:t.maxItems,style:(i,s)=>n(i,s?"active":"inactive")}).join(`
|
|
@@ -887,6 +892,7 @@ class YoctoSpinner {
|
|
|
887
892
|
#exitHandlerBound;
|
|
888
893
|
#isInteractive;
|
|
889
894
|
#lastSpinnerFrameTime = 0;
|
|
895
|
+
#isSpinning = false;
|
|
890
896
|
|
|
891
897
|
constructor(options = {}) {
|
|
892
898
|
const spinner = options.spinner ?? defaultSpinner;
|
|
@@ -908,13 +914,17 @@ class YoctoSpinner {
|
|
|
908
914
|
return this;
|
|
909
915
|
}
|
|
910
916
|
|
|
917
|
+
this.#isSpinning = true;
|
|
911
918
|
this.#hideCursor();
|
|
912
919
|
this.#render();
|
|
913
920
|
this.#subscribeToProcessEvents();
|
|
914
921
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
922
|
+
// Only start the timer in interactive mode
|
|
923
|
+
if (this.#isInteractive) {
|
|
924
|
+
this.#timer = setInterval(() => {
|
|
925
|
+
this.#render();
|
|
926
|
+
}, this.#interval);
|
|
927
|
+
}
|
|
918
928
|
|
|
919
929
|
return this;
|
|
920
930
|
}
|
|
@@ -924,8 +934,12 @@ class YoctoSpinner {
|
|
|
924
934
|
return this;
|
|
925
935
|
}
|
|
926
936
|
|
|
927
|
-
|
|
928
|
-
this.#timer
|
|
937
|
+
this.#isSpinning = false;
|
|
938
|
+
if (this.#timer) {
|
|
939
|
+
clearInterval(this.#timer);
|
|
940
|
+
this.#timer = undefined;
|
|
941
|
+
}
|
|
942
|
+
|
|
929
943
|
this.#showCursor();
|
|
930
944
|
this.clear();
|
|
931
945
|
this.#unsubscribeFromProcessEvents();
|
|
@@ -958,7 +972,7 @@ class YoctoSpinner {
|
|
|
958
972
|
}
|
|
959
973
|
|
|
960
974
|
get isSpinning() {
|
|
961
|
-
return this.#
|
|
975
|
+
return this.#isSpinning;
|
|
962
976
|
}
|
|
963
977
|
|
|
964
978
|
get text() {
|
|
@@ -1095,11 +1109,11 @@ var MastraLogger = class {
|
|
|
1095
1109
|
}
|
|
1096
1110
|
trackException(_error) {
|
|
1097
1111
|
}
|
|
1098
|
-
async
|
|
1112
|
+
async listLogs(transportId, params) {
|
|
1099
1113
|
if (!transportId || !this.transports.has(transportId)) {
|
|
1100
1114
|
return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
|
|
1101
1115
|
}
|
|
1102
|
-
return this.transports.get(transportId).
|
|
1116
|
+
return this.transports.get(transportId).listLogs(params) ?? {
|
|
1103
1117
|
logs: [],
|
|
1104
1118
|
total: 0,
|
|
1105
1119
|
page: params?.page ?? 1,
|
|
@@ -1107,7 +1121,7 @@ var MastraLogger = class {
|
|
|
1107
1121
|
hasMore: false
|
|
1108
1122
|
};
|
|
1109
1123
|
}
|
|
1110
|
-
async
|
|
1124
|
+
async listLogsByRunId({
|
|
1111
1125
|
transportId,
|
|
1112
1126
|
runId,
|
|
1113
1127
|
fromDate,
|
|
@@ -1120,7 +1134,7 @@ var MastraLogger = class {
|
|
|
1120
1134
|
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1121
1135
|
return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
|
|
1122
1136
|
}
|
|
1123
|
-
return this.transports.get(transportId).
|
|
1137
|
+
return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
|
|
1124
1138
|
logs: [],
|
|
1125
1139
|
total: 0,
|
|
1126
1140
|
page: page ?? 1,
|
|
@@ -1130,10 +1144,15 @@ var MastraLogger = class {
|
|
|
1130
1144
|
}
|
|
1131
1145
|
};
|
|
1132
1146
|
|
|
1133
|
-
var PinoLogger = class extends MastraLogger {
|
|
1147
|
+
var PinoLogger = class _PinoLogger extends MastraLogger {
|
|
1134
1148
|
logger;
|
|
1135
1149
|
constructor(options = {}) {
|
|
1136
1150
|
super(options);
|
|
1151
|
+
const internalOptions = options;
|
|
1152
|
+
if (internalOptions._logger) {
|
|
1153
|
+
this.logger = internalOptions._logger;
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1137
1156
|
let prettyStream = void 0;
|
|
1138
1157
|
if (!options.overrideDefaultTransports) {
|
|
1139
1158
|
prettyStream = pretty({
|
|
@@ -1150,7 +1169,8 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1150
1169
|
{
|
|
1151
1170
|
name: options.name || "app",
|
|
1152
1171
|
level: options.level || LogLevel.INFO,
|
|
1153
|
-
formatters: options.formatters
|
|
1172
|
+
formatters: options.formatters,
|
|
1173
|
+
redact: options.redact
|
|
1154
1174
|
},
|
|
1155
1175
|
options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
|
|
1156
1176
|
...transportsAry.map(([, transport]) => ({
|
|
@@ -1164,6 +1184,38 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1164
1184
|
])
|
|
1165
1185
|
);
|
|
1166
1186
|
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Creates a child logger with additional bound context.
|
|
1189
|
+
* All logs from the child logger will include the bound context.
|
|
1190
|
+
*
|
|
1191
|
+
* @param bindings - Key-value pairs to include in all logs from this child logger
|
|
1192
|
+
* @returns A new PinoLogger instance with the bound context
|
|
1193
|
+
*
|
|
1194
|
+
* @example
|
|
1195
|
+
* ```typescript
|
|
1196
|
+
* const baseLogger = new PinoLogger({ name: 'MyApp' });
|
|
1197
|
+
*
|
|
1198
|
+
* // Create module-scoped logger
|
|
1199
|
+
* const serviceLogger = baseLogger.child({ module: 'UserService' });
|
|
1200
|
+
* serviceLogger.info('User created', { userId: '123' });
|
|
1201
|
+
* // Output includes: { module: 'UserService', userId: '123', msg: 'User created' }
|
|
1202
|
+
*
|
|
1203
|
+
* // Create request-scoped logger
|
|
1204
|
+
* const requestLogger = baseLogger.child({ requestId: req.id });
|
|
1205
|
+
* requestLogger.error('Request failed', { err: error });
|
|
1206
|
+
* // Output includes: { requestId: 'abc', msg: 'Request failed', err: {...} }
|
|
1207
|
+
* ```
|
|
1208
|
+
*/
|
|
1209
|
+
child(bindings) {
|
|
1210
|
+
const childPino = this.logger.child(bindings);
|
|
1211
|
+
const childOptions = {
|
|
1212
|
+
name: this.name,
|
|
1213
|
+
level: this.level,
|
|
1214
|
+
transports: Object.fromEntries(this.transports),
|
|
1215
|
+
_logger: childPino
|
|
1216
|
+
};
|
|
1217
|
+
return new _PinoLogger(childOptions);
|
|
1218
|
+
}
|
|
1167
1219
|
debug(message, args = {}) {
|
|
1168
1220
|
this.logger.debug(args, message);
|
|
1169
1221
|
}
|
|
@@ -1178,118 +1230,8 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1178
1230
|
}
|
|
1179
1231
|
};
|
|
1180
1232
|
|
|
1181
|
-
var
|
|
1182
|
-
|
|
1183
|
-
if (editor === "vscode") {
|
|
1184
|
-
return {
|
|
1185
|
-
servers: {
|
|
1186
|
-
mastra: process.platform === `win32` ? {
|
|
1187
|
-
command: "cmd",
|
|
1188
|
-
args: ["/c", "npx", ...args],
|
|
1189
|
-
type: "stdio"
|
|
1190
|
-
} : {
|
|
1191
|
-
command: "npx",
|
|
1192
|
-
args,
|
|
1193
|
-
type: "stdio"
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
};
|
|
1197
|
-
}
|
|
1198
|
-
return {
|
|
1199
|
-
mcpServers: {
|
|
1200
|
-
mastra: {
|
|
1201
|
-
command: "npx",
|
|
1202
|
-
args
|
|
1203
|
-
}
|
|
1204
|
-
}
|
|
1205
|
-
};
|
|
1206
|
-
};
|
|
1207
|
-
function makeConfig(original, editor) {
|
|
1208
|
-
if (editor === "vscode") {
|
|
1209
|
-
return {
|
|
1210
|
-
...original,
|
|
1211
|
-
servers: {
|
|
1212
|
-
...original?.servers || {},
|
|
1213
|
-
...createMcpConfig(editor).servers
|
|
1214
|
-
}
|
|
1215
|
-
};
|
|
1216
|
-
}
|
|
1217
|
-
return {
|
|
1218
|
-
...original,
|
|
1219
|
-
mcpServers: {
|
|
1220
|
-
...original?.mcpServers || {},
|
|
1221
|
-
...createMcpConfig(editor).mcpServers
|
|
1222
|
-
}
|
|
1223
|
-
};
|
|
1224
|
-
}
|
|
1225
|
-
async function writeMergedConfig(configPath, editor) {
|
|
1226
|
-
const configExists = existsSync(configPath);
|
|
1227
|
-
const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
|
|
1228
|
-
await ensureFile(configPath);
|
|
1229
|
-
await writeJSON(configPath, config, {
|
|
1230
|
-
spaces: 2
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
var windsurfGlobalMCPConfigPath = path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1234
|
-
var cursorGlobalMCPConfigPath = path.join(os.homedir(), ".cursor", "mcp.json");
|
|
1235
|
-
path.join(process.cwd(), ".vscode", "mcp.json");
|
|
1236
|
-
var vscodeGlobalMCPConfigPath = path.join(
|
|
1237
|
-
os.homedir(),
|
|
1238
|
-
process.platform === "win32" ? path.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path.join("Library", "Application Support", "Code", "User", "settings.json") : path.join(".config", "Code", "User", "settings.json")
|
|
1239
|
-
);
|
|
1240
|
-
async function installMastraDocsMCPServer({ editor, directory }) {
|
|
1241
|
-
if (editor === `cursor`) {
|
|
1242
|
-
await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
|
|
1243
|
-
}
|
|
1244
|
-
if (editor === `vscode`) {
|
|
1245
|
-
await writeMergedConfig(path.join(directory, ".vscode", "mcp.json"), "vscode");
|
|
1246
|
-
}
|
|
1247
|
-
if (editor === `cursor-global`) {
|
|
1248
|
-
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
1249
|
-
if (alreadyInstalled) {
|
|
1250
|
-
return;
|
|
1251
|
-
}
|
|
1252
|
-
await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
|
|
1253
|
-
}
|
|
1254
|
-
if (editor === `windsurf`) {
|
|
1255
|
-
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
1256
|
-
if (alreadyInstalled) {
|
|
1257
|
-
return;
|
|
1258
|
-
}
|
|
1259
|
-
await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
async function globalMCPIsAlreadyInstalled(editor) {
|
|
1263
|
-
let configPath = ``;
|
|
1264
|
-
if (editor === "windsurf") {
|
|
1265
|
-
configPath = windsurfGlobalMCPConfigPath;
|
|
1266
|
-
} else if (editor === "cursor-global") {
|
|
1267
|
-
configPath = cursorGlobalMCPConfigPath;
|
|
1268
|
-
} else if (editor === "vscode") {
|
|
1269
|
-
configPath = vscodeGlobalMCPConfigPath;
|
|
1270
|
-
}
|
|
1271
|
-
if (!configPath || !existsSync(configPath)) {
|
|
1272
|
-
return false;
|
|
1273
|
-
}
|
|
1274
|
-
try {
|
|
1275
|
-
const configContents = await readJSON(configPath);
|
|
1276
|
-
if (!configContents) return false;
|
|
1277
|
-
if (editor === "vscode") {
|
|
1278
|
-
if (!configContents.servers) return false;
|
|
1279
|
-
const hasMastraMCP2 = Object.values(configContents.servers).some(
|
|
1280
|
-
(server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
|
|
1281
|
-
);
|
|
1282
|
-
return hasMastraMCP2;
|
|
1283
|
-
}
|
|
1284
|
-
if (!configContents?.mcpServers) return false;
|
|
1285
|
-
const hasMastraMCP = Object.values(configContents.mcpServers).some(
|
|
1286
|
-
(server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
|
|
1287
|
-
);
|
|
1288
|
-
return hasMastraMCP;
|
|
1289
|
-
} catch {
|
|
1290
|
-
return false;
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1233
|
+
var package_default = {
|
|
1234
|
+
version: "1.0.0-beta.11"};
|
|
1293
1235
|
function getPackageManagerAddCommand(pm) {
|
|
1294
1236
|
switch (pm) {
|
|
1295
1237
|
case "npm":
|
|
@@ -1312,11 +1254,11 @@ var DepsService = class {
|
|
|
1312
1254
|
findLockFile(dir) {
|
|
1313
1255
|
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1314
1256
|
for (const file of lockFiles) {
|
|
1315
|
-
if (fs3__default__default.existsSync(
|
|
1257
|
+
if (fs3__default__default.existsSync(path3.join(dir, file))) {
|
|
1316
1258
|
return file;
|
|
1317
1259
|
}
|
|
1318
1260
|
}
|
|
1319
|
-
const parentDir =
|
|
1261
|
+
const parentDir = path3.resolve(dir, "..");
|
|
1320
1262
|
if (parentDir !== dir) {
|
|
1321
1263
|
return this.findLockFile(parentDir);
|
|
1322
1264
|
}
|
|
@@ -1349,7 +1291,7 @@ var DepsService = class {
|
|
|
1349
1291
|
}
|
|
1350
1292
|
async checkDependencies(dependencies) {
|
|
1351
1293
|
try {
|
|
1352
|
-
const packageJsonPath =
|
|
1294
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1353
1295
|
try {
|
|
1354
1296
|
await fs4.access(packageJsonPath);
|
|
1355
1297
|
} catch {
|
|
@@ -1369,7 +1311,7 @@ var DepsService = class {
|
|
|
1369
1311
|
}
|
|
1370
1312
|
async getProjectName() {
|
|
1371
1313
|
try {
|
|
1372
|
-
const packageJsonPath =
|
|
1314
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1373
1315
|
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1374
1316
|
const pkg = JSON.parse(packageJson);
|
|
1375
1317
|
return pkg.name;
|
|
@@ -1457,8 +1399,8 @@ var FileService = class {
|
|
|
1457
1399
|
*/
|
|
1458
1400
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1459
1401
|
const __filename = fileURLToPath(import.meta.url);
|
|
1460
|
-
const __dirname =
|
|
1461
|
-
const filePath =
|
|
1402
|
+
const __dirname = path3.dirname(__filename);
|
|
1403
|
+
const filePath = path3.resolve(__dirname, "starter-files", inputFile);
|
|
1462
1404
|
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1463
1405
|
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1464
1406
|
console.info(`${outputFilePath} already exists`);
|
|
@@ -1468,7 +1410,7 @@ var FileService = class {
|
|
|
1468
1410
|
return true;
|
|
1469
1411
|
}
|
|
1470
1412
|
async setupEnvFile({ dbUrl }) {
|
|
1471
|
-
const envPath =
|
|
1413
|
+
const envPath = path3.join(process.cwd(), ".env.development");
|
|
1472
1414
|
await fsExtra.ensureFile(envPath);
|
|
1473
1415
|
const fileEnvService = new FileEnvService(envPath);
|
|
1474
1416
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
@@ -1492,21 +1434,142 @@ var FileService = class {
|
|
|
1492
1434
|
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1493
1435
|
}
|
|
1494
1436
|
};
|
|
1437
|
+
var createArgs = (versionTag) => {
|
|
1438
|
+
const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
|
|
1439
|
+
return ["-y", packageName];
|
|
1440
|
+
};
|
|
1441
|
+
var createMcpConfig = (editor, versionTag) => {
|
|
1442
|
+
const args = createArgs(versionTag);
|
|
1443
|
+
if (editor === "vscode") {
|
|
1444
|
+
return {
|
|
1445
|
+
servers: {
|
|
1446
|
+
mastra: process.platform === `win32` ? {
|
|
1447
|
+
command: "cmd",
|
|
1448
|
+
args: ["/c", "npx", ...args],
|
|
1449
|
+
type: "stdio"
|
|
1450
|
+
} : {
|
|
1451
|
+
command: "npx",
|
|
1452
|
+
args,
|
|
1453
|
+
type: "stdio"
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
return {
|
|
1459
|
+
mcpServers: {
|
|
1460
|
+
mastra: {
|
|
1461
|
+
command: "npx",
|
|
1462
|
+
args
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
};
|
|
1467
|
+
function makeConfig(original, editor, versionTag) {
|
|
1468
|
+
if (editor === "vscode") {
|
|
1469
|
+
return {
|
|
1470
|
+
...original,
|
|
1471
|
+
servers: {
|
|
1472
|
+
...original?.servers || {},
|
|
1473
|
+
...createMcpConfig(editor, versionTag).servers
|
|
1474
|
+
}
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
return {
|
|
1478
|
+
...original,
|
|
1479
|
+
mcpServers: {
|
|
1480
|
+
...original?.mcpServers || {},
|
|
1481
|
+
...createMcpConfig(editor, versionTag).mcpServers
|
|
1482
|
+
}
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
async function writeMergedConfig(configPath, editor, versionTag) {
|
|
1486
|
+
const configExists = existsSync(configPath);
|
|
1487
|
+
const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor, versionTag);
|
|
1488
|
+
await ensureFile(configPath);
|
|
1489
|
+
await writeJSON(configPath, config, {
|
|
1490
|
+
spaces: 2
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1494
|
+
var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
|
|
1495
|
+
path3.join(process.cwd(), ".vscode", "mcp.json");
|
|
1496
|
+
var vscodeGlobalMCPConfigPath = path3.join(
|
|
1497
|
+
os.homedir(),
|
|
1498
|
+
process.platform === "win32" ? path3.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path3.join("Library", "Application Support", "Code", "User", "settings.json") : path3.join(".config", "Code", "User", "settings.json")
|
|
1499
|
+
);
|
|
1500
|
+
async function installMastraDocsMCPServer({
|
|
1501
|
+
editor,
|
|
1502
|
+
directory,
|
|
1503
|
+
versionTag
|
|
1504
|
+
}) {
|
|
1505
|
+
if (editor === `cursor`) {
|
|
1506
|
+
await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor", versionTag);
|
|
1507
|
+
}
|
|
1508
|
+
if (editor === `vscode`) {
|
|
1509
|
+
await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode", versionTag);
|
|
1510
|
+
}
|
|
1511
|
+
if (editor === `cursor-global`) {
|
|
1512
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
|
|
1513
|
+
if (alreadyInstalled) {
|
|
1514
|
+
return;
|
|
1515
|
+
}
|
|
1516
|
+
await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global", versionTag);
|
|
1517
|
+
}
|
|
1518
|
+
if (editor === `windsurf`) {
|
|
1519
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
|
|
1520
|
+
if (alreadyInstalled) {
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
await writeMergedConfig(windsurfGlobalMCPConfigPath, editor, versionTag);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
async function globalMCPIsAlreadyInstalled(editor, versionTag) {
|
|
1527
|
+
let configPath = ``;
|
|
1528
|
+
if (editor === "windsurf") {
|
|
1529
|
+
configPath = windsurfGlobalMCPConfigPath;
|
|
1530
|
+
} else if (editor === "cursor-global") {
|
|
1531
|
+
configPath = cursorGlobalMCPConfigPath;
|
|
1532
|
+
} else if (editor === "vscode") {
|
|
1533
|
+
configPath = vscodeGlobalMCPConfigPath;
|
|
1534
|
+
}
|
|
1535
|
+
if (!configPath || !existsSync(configPath)) {
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1538
|
+
try {
|
|
1539
|
+
const configContents = await readJSON(configPath);
|
|
1540
|
+
if (!configContents) return false;
|
|
1541
|
+
const expectedPackage = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
|
|
1542
|
+
if (editor === "vscode") {
|
|
1543
|
+
if (!configContents.servers) return false;
|
|
1544
|
+
const hasMastraMCP2 = Object.values(configContents.servers).some(
|
|
1545
|
+
(server) => server?.args?.find((arg) => arg === expectedPackage)
|
|
1546
|
+
);
|
|
1547
|
+
return hasMastraMCP2;
|
|
1548
|
+
}
|
|
1549
|
+
if (!configContents?.mcpServers) return false;
|
|
1550
|
+
const hasMastraMCP = Object.values(configContents.mcpServers).some(
|
|
1551
|
+
(server) => server?.args?.find((arg) => arg === expectedPackage)
|
|
1552
|
+
);
|
|
1553
|
+
return hasMastraMCP;
|
|
1554
|
+
} catch {
|
|
1555
|
+
return false;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1495
1558
|
var exec = util.promisify(child_process.exec);
|
|
1496
1559
|
var getModelIdentifier = (llmProvider) => {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
return `'anthropic/claude-sonnet-4-5-20250929'`;
|
|
1560
|
+
let model = "openai/gpt-4o";
|
|
1561
|
+
if (llmProvider === "anthropic") {
|
|
1562
|
+
model = "anthropic/claude-sonnet-4-5";
|
|
1501
1563
|
} else if (llmProvider === "groq") {
|
|
1502
|
-
|
|
1564
|
+
model = "groq/llama-3.3-70b-versatile";
|
|
1503
1565
|
} else if (llmProvider === "google") {
|
|
1504
|
-
|
|
1566
|
+
model = "google/gemini-2.5-pro";
|
|
1505
1567
|
} else if (llmProvider === "cerebras") {
|
|
1506
|
-
|
|
1568
|
+
model = "cerebras/llama-3.3-70b";
|
|
1507
1569
|
} else if (llmProvider === "mistral") {
|
|
1508
|
-
|
|
1570
|
+
model = "mistral/mistral-medium-2508";
|
|
1509
1571
|
}
|
|
1572
|
+
return model;
|
|
1510
1573
|
};
|
|
1511
1574
|
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1512
1575
|
const modelString = getModelIdentifier(llmProvider);
|
|
@@ -1527,14 +1590,14 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorer
|
|
|
1527
1590
|
const content = `
|
|
1528
1591
|
import { Agent } from '@mastra/core/agent';
|
|
1529
1592
|
import { Memory } from '@mastra/memory';
|
|
1530
|
-
import { LibSQLStore } from '@mastra/libsql';
|
|
1531
1593
|
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1532
1594
|
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1533
1595
|
|
|
1534
1596
|
export const weatherAgent = new Agent({
|
|
1597
|
+
id: 'weather-agent',
|
|
1535
1598
|
name: 'Weather Agent',
|
|
1536
1599
|
instructions: \`${instructions}\`,
|
|
1537
|
-
model: ${modelString},
|
|
1600
|
+
model: '${modelString}',
|
|
1538
1601
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1539
1602
|
${addScorers ? `scorers: {
|
|
1540
1603
|
toolCallAppropriateness: {
|
|
@@ -1559,11 +1622,7 @@ export const weatherAgent = new Agent({
|
|
|
1559
1622
|
},
|
|
1560
1623
|
},
|
|
1561
1624
|
},` : ""}
|
|
1562
|
-
memory: new Memory(
|
|
1563
|
-
storage: new LibSQLStore({
|
|
1564
|
-
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1565
|
-
})
|
|
1566
|
-
})
|
|
1625
|
+
memory: new Memory()
|
|
1567
1626
|
});
|
|
1568
1627
|
`;
|
|
1569
1628
|
const formattedContent = await prettier.format(content, {
|
|
@@ -1773,9 +1832,10 @@ async function writeToolSample(destPath) {
|
|
|
1773
1832
|
async function writeScorersSample(llmProvider, destPath) {
|
|
1774
1833
|
const modelString = getModelIdentifier(llmProvider);
|
|
1775
1834
|
const content = `import { z } from 'zod';
|
|
1776
|
-
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/
|
|
1777
|
-
import { createCompletenessScorer } from '@mastra/evals/scorers/
|
|
1778
|
-
import {
|
|
1835
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
1836
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
|
|
1837
|
+
import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
1838
|
+
import { createScorer } from '@mastra/core/evals';
|
|
1779
1839
|
|
|
1780
1840
|
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1781
1841
|
expectedTool: 'weatherTool',
|
|
@@ -1786,11 +1846,12 @@ export const completenessScorer = createCompletenessScorer();
|
|
|
1786
1846
|
|
|
1787
1847
|
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1788
1848
|
export const translationScorer = createScorer({
|
|
1849
|
+
id: 'translation-quality-scorer',
|
|
1789
1850
|
name: 'Translation Quality',
|
|
1790
1851
|
description: 'Checks that non-English location names are translated and used correctly',
|
|
1791
1852
|
type: 'agent',
|
|
1792
1853
|
judge: {
|
|
1793
|
-
model: ${modelString},
|
|
1854
|
+
model: '${modelString}',
|
|
1794
1855
|
instructions:
|
|
1795
1856
|
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1796
1857
|
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
@@ -1799,8 +1860,8 @@ export const translationScorer = createScorer({
|
|
|
1799
1860
|
},
|
|
1800
1861
|
})
|
|
1801
1862
|
.preprocess(({ run }) => {
|
|
1802
|
-
const userText = (run.input
|
|
1803
|
-
const assistantText = (run.output
|
|
1863
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1864
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1804
1865
|
return { userText, assistantText };
|
|
1805
1866
|
})
|
|
1806
1867
|
.analyze({
|
|
@@ -1887,7 +1948,7 @@ var writeIndexFile = async ({
|
|
|
1887
1948
|
addScorers
|
|
1888
1949
|
}) => {
|
|
1889
1950
|
const indexPath = dirPath + "/index.ts";
|
|
1890
|
-
const destPath =
|
|
1951
|
+
const destPath = path3.join(indexPath);
|
|
1891
1952
|
try {
|
|
1892
1953
|
await fs4.writeFile(destPath, "");
|
|
1893
1954
|
const filteredExports = [
|
|
@@ -1899,7 +1960,7 @@ var writeIndexFile = async ({
|
|
|
1899
1960
|
await fs4.writeFile(
|
|
1900
1961
|
destPath,
|
|
1901
1962
|
`
|
|
1902
|
-
import { Mastra } from '@mastra/core';
|
|
1963
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1903
1964
|
|
|
1904
1965
|
export const mastra = new Mastra()
|
|
1905
1966
|
`
|
|
@@ -1912,6 +1973,7 @@ export const mastra = new Mastra()
|
|
|
1912
1973
|
import { Mastra } from '@mastra/core/mastra';
|
|
1913
1974
|
import { PinoLogger } from '@mastra/loggers';
|
|
1914
1975
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1976
|
+
import { Observability } from '@mastra/observability';
|
|
1915
1977
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1916
1978
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1917
1979
|
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
@@ -1919,6 +1981,7 @@ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, tran
|
|
|
1919
1981
|
export const mastra = new Mastra({
|
|
1920
1982
|
${filteredExports.join("\n ")}
|
|
1921
1983
|
storage: new LibSQLStore({
|
|
1984
|
+
id: "mastra-storage",
|
|
1922
1985
|
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1923
1986
|
url: ":memory:",
|
|
1924
1987
|
}),
|
|
@@ -1926,10 +1989,10 @@ export const mastra = new Mastra({
|
|
|
1926
1989
|
name: 'Mastra',
|
|
1927
1990
|
level: 'info',
|
|
1928
1991
|
}),
|
|
1929
|
-
observability: {
|
|
1930
|
-
// Enables DefaultExporter and CloudExporter for
|
|
1992
|
+
observability: new Observability({
|
|
1993
|
+
// Enables DefaultExporter and CloudExporter for tracing
|
|
1931
1994
|
default: { enabled: true },
|
|
1932
|
-
},
|
|
1995
|
+
}),
|
|
1933
1996
|
});
|
|
1934
1997
|
`
|
|
1935
1998
|
);
|
|
@@ -1968,7 +2031,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
|
|
|
1968
2031
|
};
|
|
1969
2032
|
var createMastraDir = async (directory) => {
|
|
1970
2033
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1971
|
-
const dirPath =
|
|
2034
|
+
const dirPath = path3.join(process.cwd(), ...dir, "mastra");
|
|
1972
2035
|
try {
|
|
1973
2036
|
await fs4.access(dirPath);
|
|
1974
2037
|
return { ok: false };
|
|
@@ -1993,8 +2056,8 @@ var LLM_PROVIDERS = [
|
|
|
1993
2056
|
{ value: "cerebras", label: "Cerebras" },
|
|
1994
2057
|
{ value: "mistral", label: "Mistral" }
|
|
1995
2058
|
];
|
|
1996
|
-
var interactivePrompt = async (
|
|
1997
|
-
const { skip = {}, options: { showBanner = true } = {} } =
|
|
2059
|
+
var interactivePrompt = async (args = {}) => {
|
|
2060
|
+
const { skip = {}, options: { showBanner = true } = {} } = args;
|
|
1998
2061
|
if (showBanner) {
|
|
1999
2062
|
Ie(color2.inverse(" Mastra Init "));
|
|
2000
2063
|
}
|
|
@@ -2032,46 +2095,29 @@ var interactivePrompt = async (args2 = {}) => {
|
|
|
2032
2095
|
return void 0;
|
|
2033
2096
|
},
|
|
2034
2097
|
configureEditorWithDocsMCP: async () => {
|
|
2035
|
-
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
2036
|
-
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2037
|
-
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2038
2098
|
const editor = await ve({
|
|
2039
2099
|
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2040
2100
|
options: [
|
|
2041
2101
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2042
2102
|
{
|
|
2043
2103
|
value: "cursor",
|
|
2044
|
-
label: "Cursor (project only)"
|
|
2045
|
-
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
2104
|
+
label: "Cursor (project only)"
|
|
2046
2105
|
},
|
|
2047
2106
|
{
|
|
2048
2107
|
value: "cursor-global",
|
|
2049
|
-
label: "Cursor (global, all projects)"
|
|
2050
|
-
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
2108
|
+
label: "Cursor (global, all projects)"
|
|
2051
2109
|
},
|
|
2052
2110
|
{
|
|
2053
2111
|
value: "windsurf",
|
|
2054
|
-
label: "Windsurf"
|
|
2055
|
-
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
2112
|
+
label: "Windsurf"
|
|
2056
2113
|
},
|
|
2057
2114
|
{
|
|
2058
2115
|
value: "vscode",
|
|
2059
|
-
label: "VSCode"
|
|
2060
|
-
hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
|
|
2116
|
+
label: "VSCode"
|
|
2061
2117
|
}
|
|
2062
2118
|
]
|
|
2063
2119
|
});
|
|
2064
2120
|
if (editor === `skip`) return void 0;
|
|
2065
|
-
if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
|
|
2066
|
-
M.message(`
|
|
2067
|
-
Windsurf is already installed, skipping.`);
|
|
2068
|
-
return void 0;
|
|
2069
|
-
}
|
|
2070
|
-
if (editor === `vscode` && vscodeIsAlreadyInstalled) {
|
|
2071
|
-
M.message(`
|
|
2072
|
-
VSCode is already installed, skipping.`);
|
|
2073
|
-
return void 0;
|
|
2074
|
-
}
|
|
2075
2121
|
if (editor === `cursor`) {
|
|
2076
2122
|
M.message(
|
|
2077
2123
|
`
|
|
@@ -2080,19 +2126,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
2080
2126
|
);
|
|
2081
2127
|
}
|
|
2082
2128
|
if (editor === `cursor-global`) {
|
|
2083
|
-
const
|
|
2129
|
+
const confirm3 = await ve({
|
|
2084
2130
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2085
2131
|
options: [
|
|
2086
2132
|
{ value: "yes", label: "Yes, I understand" },
|
|
2087
2133
|
{ value: "skip", label: "No, skip for now" }
|
|
2088
2134
|
]
|
|
2089
2135
|
});
|
|
2090
|
-
if (
|
|
2136
|
+
if (confirm3 !== `yes`) {
|
|
2091
2137
|
return void 0;
|
|
2092
2138
|
}
|
|
2093
2139
|
}
|
|
2094
2140
|
if (editor === `windsurf`) {
|
|
2095
|
-
const
|
|
2141
|
+
const confirm3 = await ve({
|
|
2096
2142
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
2097
2143
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
2098
2144
|
options: [
|
|
@@ -2100,11 +2146,18 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2100
2146
|
{ value: "skip", label: "No, skip for now" }
|
|
2101
2147
|
]
|
|
2102
2148
|
});
|
|
2103
|
-
if (
|
|
2149
|
+
if (confirm3 !== `yes`) {
|
|
2104
2150
|
return void 0;
|
|
2105
2151
|
}
|
|
2106
2152
|
}
|
|
2107
2153
|
return editor;
|
|
2154
|
+
},
|
|
2155
|
+
initGit: async () => {
|
|
2156
|
+
if (skip?.gitInit) return false;
|
|
2157
|
+
return ye({
|
|
2158
|
+
message: "Initialize a new git repository?",
|
|
2159
|
+
initialValue: true
|
|
2160
|
+
});
|
|
2108
2161
|
}
|
|
2109
2162
|
},
|
|
2110
2163
|
{
|
|
@@ -2119,6 +2172,9 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2119
2172
|
function getPackageManager() {
|
|
2120
2173
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
2121
2174
|
const execPath = process.env.npm_execpath || "";
|
|
2175
|
+
if (userAgent.includes("bun")) {
|
|
2176
|
+
return "bun";
|
|
2177
|
+
}
|
|
2122
2178
|
if (userAgent.includes("yarn")) {
|
|
2123
2179
|
return "yarn";
|
|
2124
2180
|
}
|
|
@@ -2128,6 +2184,9 @@ function getPackageManager() {
|
|
|
2128
2184
|
if (userAgent.includes("npm")) {
|
|
2129
2185
|
return "npm";
|
|
2130
2186
|
}
|
|
2187
|
+
if (execPath.includes("bun")) {
|
|
2188
|
+
return "bun";
|
|
2189
|
+
}
|
|
2131
2190
|
if (execPath.includes("yarn")) {
|
|
2132
2191
|
return "yarn";
|
|
2133
2192
|
}
|
|
@@ -2139,6 +2198,20 @@ function getPackageManager() {
|
|
|
2139
2198
|
}
|
|
2140
2199
|
return "npm";
|
|
2141
2200
|
}
|
|
2201
|
+
async function gitInit({ cwd }) {
|
|
2202
|
+
await execa("git", ["init"], { cwd, stdio: "ignore" });
|
|
2203
|
+
await execa("git", ["add", "-A"], { cwd, stdio: "ignore" });
|
|
2204
|
+
await execa(
|
|
2205
|
+
"git",
|
|
2206
|
+
[
|
|
2207
|
+
"commit",
|
|
2208
|
+
"-m",
|
|
2209
|
+
'"Initial commit from Mastra"',
|
|
2210
|
+
'--author="dane-ai-mastra[bot] <dane-ai-mastra[bot]@users.noreply.github.com>"'
|
|
2211
|
+
],
|
|
2212
|
+
{ cwd, stdio: "ignore" }
|
|
2213
|
+
);
|
|
2214
|
+
}
|
|
2142
2215
|
var logger = createLogger(false);
|
|
2143
2216
|
function createLogger(debug = false) {
|
|
2144
2217
|
return new PinoLogger({
|
|
@@ -2148,19 +2221,23 @@ function createLogger(debug = false) {
|
|
|
2148
2221
|
}
|
|
2149
2222
|
var exec2 = util.promisify(child_process.exec);
|
|
2150
2223
|
async function cloneTemplate(options) {
|
|
2151
|
-
const { template, projectName, targetDir } = options;
|
|
2152
|
-
const projectPath = targetDir ?
|
|
2224
|
+
const { template, projectName, targetDir, branch, llmProvider } = options;
|
|
2225
|
+
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
2153
2226
|
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2154
2227
|
try {
|
|
2155
2228
|
if (await directoryExists(projectPath)) {
|
|
2156
2229
|
spinner4.error(`Directory ${projectName} already exists`);
|
|
2157
2230
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2158
2231
|
}
|
|
2159
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2232
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
|
|
2160
2233
|
await updatePackageJson(projectPath, projectName);
|
|
2161
|
-
const envExamplePath =
|
|
2234
|
+
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
2162
2235
|
if (await fileExists(envExamplePath)) {
|
|
2163
|
-
|
|
2236
|
+
const envPath = path3.join(projectPath, ".env");
|
|
2237
|
+
await fs4.copyFile(envExamplePath, envPath);
|
|
2238
|
+
if (llmProvider) {
|
|
2239
|
+
await updateEnvFile(envPath, llmProvider);
|
|
2240
|
+
}
|
|
2164
2241
|
}
|
|
2165
2242
|
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2166
2243
|
return projectPath;
|
|
@@ -2185,21 +2262,27 @@ async function fileExists(filePath) {
|
|
|
2185
2262
|
return false;
|
|
2186
2263
|
}
|
|
2187
2264
|
}
|
|
2188
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2265
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
|
|
2189
2266
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
2190
2267
|
try {
|
|
2191
2268
|
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2192
|
-
const
|
|
2269
|
+
const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
|
|
2270
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
|
|
2193
2271
|
await exec2(degitCommand, {
|
|
2194
2272
|
cwd: process.cwd()
|
|
2195
2273
|
});
|
|
2196
2274
|
} catch {
|
|
2197
2275
|
try {
|
|
2198
|
-
const
|
|
2276
|
+
const gitArgs = ["git", "clone"];
|
|
2277
|
+
if (branch) {
|
|
2278
|
+
gitArgs.push("--branch", branch);
|
|
2279
|
+
}
|
|
2280
|
+
gitArgs.push(repoUrl, targetPath);
|
|
2281
|
+
const gitCommand = shellQuote2.quote(gitArgs);
|
|
2199
2282
|
await exec2(gitCommand, {
|
|
2200
2283
|
cwd: process.cwd()
|
|
2201
2284
|
});
|
|
2202
|
-
const gitDir =
|
|
2285
|
+
const gitDir = path3.join(targetPath, ".git");
|
|
2203
2286
|
if (await directoryExists(gitDir)) {
|
|
2204
2287
|
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2205
2288
|
}
|
|
@@ -2209,7 +2292,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
|
2209
2292
|
}
|
|
2210
2293
|
}
|
|
2211
2294
|
async function updatePackageJson(projectPath, projectName) {
|
|
2212
|
-
const packageJsonPath =
|
|
2295
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
2213
2296
|
try {
|
|
2214
2297
|
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2215
2298
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -2219,6 +2302,22 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2219
2302
|
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2220
2303
|
}
|
|
2221
2304
|
}
|
|
2305
|
+
async function updateEnvFile(envPath, llmProvider) {
|
|
2306
|
+
try {
|
|
2307
|
+
const envContent = await fs4.readFile(envPath, "utf-8");
|
|
2308
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
2309
|
+
if (!modelString) {
|
|
2310
|
+
logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
const modelValue = modelString.replace(/'/g, "");
|
|
2314
|
+
const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
|
|
2315
|
+
await fs4.writeFile(envPath, updatedContent, "utf-8");
|
|
2316
|
+
logger.info(`Updated MODEL in .env to ${modelValue}`);
|
|
2317
|
+
} catch (error) {
|
|
2318
|
+
logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2222
2321
|
async function installDependencies(projectPath, packageManager) {
|
|
2223
2322
|
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2224
2323
|
try {
|
|
@@ -2303,9 +2402,12 @@ var init = async ({
|
|
|
2303
2402
|
llmProvider = "openai",
|
|
2304
2403
|
llmApiKey,
|
|
2305
2404
|
addExample = false,
|
|
2306
|
-
configureEditorWithDocsMCP
|
|
2405
|
+
configureEditorWithDocsMCP,
|
|
2406
|
+
versionTag,
|
|
2407
|
+
initGit = false
|
|
2307
2408
|
}) => {
|
|
2308
2409
|
s.start("Initializing Mastra");
|
|
2410
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2309
2411
|
try {
|
|
2310
2412
|
const result = await createMastraDir(directory);
|
|
2311
2413
|
if (!result.ok) {
|
|
@@ -2333,33 +2435,44 @@ var init = async ({
|
|
|
2333
2435
|
const depService = new DepsService();
|
|
2334
2436
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2335
2437
|
if (needsLibsql) {
|
|
2336
|
-
await depService.installPackages([
|
|
2438
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2337
2439
|
}
|
|
2338
2440
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2339
2441
|
if (needsMemory) {
|
|
2340
|
-
await depService.installPackages([
|
|
2442
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2341
2443
|
}
|
|
2342
2444
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2343
2445
|
if (needsLoggers) {
|
|
2344
|
-
await depService.installPackages([
|
|
2446
|
+
await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
|
|
2345
2447
|
}
|
|
2346
2448
|
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2347
2449
|
if (needsObservability) {
|
|
2348
|
-
await depService.installPackages([
|
|
2450
|
+
await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
|
|
2349
2451
|
}
|
|
2350
2452
|
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2351
2453
|
if (needsEvals) {
|
|
2352
|
-
await depService.installPackages([
|
|
2454
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2353
2455
|
}
|
|
2354
2456
|
}
|
|
2355
2457
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2356
2458
|
if (configureEditorWithDocsMCP) {
|
|
2357
2459
|
await installMastraDocsMCPServer({
|
|
2358
2460
|
editor: configureEditorWithDocsMCP,
|
|
2359
|
-
directory: process.cwd()
|
|
2461
|
+
directory: process.cwd(),
|
|
2462
|
+
versionTag
|
|
2360
2463
|
});
|
|
2361
2464
|
}
|
|
2362
2465
|
s.stop();
|
|
2466
|
+
if (initGit) {
|
|
2467
|
+
const s2 = Y();
|
|
2468
|
+
try {
|
|
2469
|
+
s2.start("Initializing git repository");
|
|
2470
|
+
await gitInit({ cwd: process.cwd() });
|
|
2471
|
+
s2.stop("Git repository initialized");
|
|
2472
|
+
} catch {
|
|
2473
|
+
s2.stop();
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2363
2476
|
if (!llmApiKey) {
|
|
2364
2477
|
Me(`
|
|
2365
2478
|
${color2.green("Mastra initialized successfully!")}
|
|
@@ -2405,6 +2518,32 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2405
2518
|
throw error;
|
|
2406
2519
|
}
|
|
2407
2520
|
};
|
|
2521
|
+
async function getInitCommand(pm) {
|
|
2522
|
+
switch (pm) {
|
|
2523
|
+
case "npm":
|
|
2524
|
+
return "npm init -y";
|
|
2525
|
+
case "pnpm":
|
|
2526
|
+
return "pnpm init";
|
|
2527
|
+
case "yarn":
|
|
2528
|
+
return "yarn init -y";
|
|
2529
|
+
case "bun":
|
|
2530
|
+
return "bun init -y";
|
|
2531
|
+
default:
|
|
2532
|
+
return "npm init -y";
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
async function initializePackageJson(pm) {
|
|
2536
|
+
const initCommand = await getInitCommand(pm);
|
|
2537
|
+
await exec3(initCommand);
|
|
2538
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
2539
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
2540
|
+
packageJson.type = "module";
|
|
2541
|
+
packageJson.engines = {
|
|
2542
|
+
...packageJson.engines,
|
|
2543
|
+
node: ">=22.13.0"
|
|
2544
|
+
};
|
|
2545
|
+
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
2546
|
+
}
|
|
2408
2547
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2409
2548
|
let installCommand = getPackageManagerAddCommand(pm);
|
|
2410
2549
|
if (isDev) {
|
|
@@ -2451,7 +2590,7 @@ var createMastraProject = async ({
|
|
|
2451
2590
|
xe("Operation cancelled");
|
|
2452
2591
|
process.exit(0);
|
|
2453
2592
|
}
|
|
2454
|
-
let result;
|
|
2593
|
+
let result = void 0;
|
|
2455
2594
|
if (needsInteractive) {
|
|
2456
2595
|
result = await interactivePrompt({
|
|
2457
2596
|
options: { showBanner: false },
|
|
@@ -2459,10 +2598,13 @@ var createMastraProject = async ({
|
|
|
2459
2598
|
});
|
|
2460
2599
|
}
|
|
2461
2600
|
const s2 = Y();
|
|
2601
|
+
const originalCwd = process.cwd();
|
|
2602
|
+
let projectPath = null;
|
|
2462
2603
|
try {
|
|
2463
2604
|
s2.start("Creating project");
|
|
2464
2605
|
try {
|
|
2465
2606
|
await fs4.mkdir(projectName);
|
|
2607
|
+
projectPath = path3.resolve(originalCwd, projectName);
|
|
2466
2608
|
} catch (error) {
|
|
2467
2609
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2468
2610
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2477,9 +2619,7 @@ var createMastraProject = async ({
|
|
|
2477
2619
|
const installCommand = getPackageManagerAddCommand(pm);
|
|
2478
2620
|
s2.message("Initializing project structure");
|
|
2479
2621
|
try {
|
|
2480
|
-
await
|
|
2481
|
-
await exec3(`npm pkg set type="module"`);
|
|
2482
|
-
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
2622
|
+
await initializePackageJson(pm);
|
|
2483
2623
|
const depsService = new DepsService();
|
|
2484
2624
|
await depsService.addScriptsToPackageJson({
|
|
2485
2625
|
dev: "mastra dev",
|
|
@@ -2495,7 +2635,7 @@ var createMastraProject = async ({
|
|
|
2495
2635
|
s2.start(`Installing ${pm} dependencies`);
|
|
2496
2636
|
try {
|
|
2497
2637
|
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2498
|
-
await exec3(`${pm} ${installCommand} typescript @types/node
|
|
2638
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2499
2639
|
await exec3(`echo '{
|
|
2500
2640
|
"compilerOptions": {
|
|
2501
2641
|
"target": "ES2022",
|
|
@@ -2558,42 +2698,61 @@ var createMastraProject = async ({
|
|
|
2558
2698
|
s2.stop();
|
|
2559
2699
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
2560
2700
|
xe(`Project creation failed: ${errorMessage}`);
|
|
2701
|
+
if (projectPath && fs3__default__default.existsSync(projectPath)) {
|
|
2702
|
+
try {
|
|
2703
|
+
process.chdir(originalCwd);
|
|
2704
|
+
await fs4.rm(projectPath, { recursive: true, force: true });
|
|
2705
|
+
} catch (cleanupError) {
|
|
2706
|
+
console.error(
|
|
2707
|
+
`Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2561
2711
|
process.exit(1);
|
|
2562
2712
|
}
|
|
2563
2713
|
};
|
|
2564
|
-
var
|
|
2565
|
-
|
|
2566
|
-
|
|
2714
|
+
var version$1 = package_default.version;
|
|
2715
|
+
var create = async (args) => {
|
|
2716
|
+
if (args.template !== void 0) {
|
|
2717
|
+
await createFromTemplate({
|
|
2718
|
+
projectName: args.projectName,
|
|
2719
|
+
template: args.template,
|
|
2720
|
+
timeout: args.timeout,
|
|
2721
|
+
injectedAnalytics: args.analytics,
|
|
2722
|
+
llmProvider: args.llmProvider
|
|
2723
|
+
});
|
|
2567
2724
|
return;
|
|
2568
2725
|
}
|
|
2569
|
-
const needsInteractive =
|
|
2726
|
+
const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
|
|
2570
2727
|
const { projectName, result } = await createMastraProject({
|
|
2571
|
-
projectName:
|
|
2572
|
-
createVersionTag:
|
|
2573
|
-
timeout:
|
|
2574
|
-
llmProvider:
|
|
2575
|
-
llmApiKey:
|
|
2728
|
+
projectName: args?.projectName,
|
|
2729
|
+
createVersionTag: args?.createVersionTag,
|
|
2730
|
+
timeout: args?.timeout,
|
|
2731
|
+
llmProvider: args?.llmProvider,
|
|
2732
|
+
llmApiKey: args?.llmApiKey,
|
|
2576
2733
|
needsInteractive
|
|
2577
2734
|
});
|
|
2578
|
-
const directory =
|
|
2735
|
+
const directory = args.directory || "src/";
|
|
2579
2736
|
if (needsInteractive && result) {
|
|
2580
2737
|
await init({
|
|
2581
2738
|
...result,
|
|
2582
2739
|
llmApiKey: result?.llmApiKey,
|
|
2583
2740
|
components: ["agents", "tools", "workflows", "scorers"],
|
|
2584
|
-
addExample: true
|
|
2741
|
+
addExample: true,
|
|
2742
|
+
versionTag: args.createVersionTag
|
|
2585
2743
|
});
|
|
2586
2744
|
postCreate({ projectName });
|
|
2587
2745
|
return;
|
|
2588
2746
|
}
|
|
2589
|
-
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } =
|
|
2747
|
+
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
|
|
2590
2748
|
await init({
|
|
2591
2749
|
directory,
|
|
2592
2750
|
components,
|
|
2593
2751
|
llmProvider,
|
|
2594
2752
|
addExample,
|
|
2595
2753
|
llmApiKey,
|
|
2596
|
-
configureEditorWithDocsMCP:
|
|
2754
|
+
configureEditorWithDocsMCP: args.mcpServer,
|
|
2755
|
+
versionTag: args.createVersionTag
|
|
2597
2756
|
});
|
|
2598
2757
|
postCreate({ projectName });
|
|
2599
2758
|
};
|
|
@@ -2684,9 +2843,9 @@ async function createFromGitHubUrl(url) {
|
|
|
2684
2843
|
workflows: []
|
|
2685
2844
|
};
|
|
2686
2845
|
}
|
|
2687
|
-
async function createFromTemplate(
|
|
2846
|
+
async function createFromTemplate(args) {
|
|
2688
2847
|
let selectedTemplate;
|
|
2689
|
-
if (
|
|
2848
|
+
if (args.template === true) {
|
|
2690
2849
|
const templates = await loadTemplates();
|
|
2691
2850
|
const selected = await selectTemplate(templates);
|
|
2692
2851
|
if (!selected) {
|
|
@@ -2694,11 +2853,11 @@ async function createFromTemplate(args2) {
|
|
|
2694
2853
|
return;
|
|
2695
2854
|
}
|
|
2696
2855
|
selectedTemplate = selected;
|
|
2697
|
-
} else if (
|
|
2698
|
-
if (isGitHubUrl(
|
|
2856
|
+
} else if (args.template && typeof args.template === "string") {
|
|
2857
|
+
if (isGitHubUrl(args.template)) {
|
|
2699
2858
|
const spinner4 = Y();
|
|
2700
2859
|
spinner4.start("Validating GitHub repository...");
|
|
2701
|
-
const validation = await validateGitHubProject(
|
|
2860
|
+
const validation = await validateGitHubProject(args.template);
|
|
2702
2861
|
if (!validation.isValid) {
|
|
2703
2862
|
spinner4.stop("Validation failed");
|
|
2704
2863
|
M.error("This does not appear to be a valid Mastra project:");
|
|
@@ -2706,14 +2865,14 @@ async function createFromTemplate(args2) {
|
|
|
2706
2865
|
throw new Error("Invalid Mastra project");
|
|
2707
2866
|
}
|
|
2708
2867
|
spinner4.stop("Valid Mastra project \u2713");
|
|
2709
|
-
selectedTemplate = await createFromGitHubUrl(
|
|
2868
|
+
selectedTemplate = await createFromGitHubUrl(args.template);
|
|
2710
2869
|
} else {
|
|
2711
2870
|
const templates = await loadTemplates();
|
|
2712
|
-
const found = findTemplateByName(templates,
|
|
2871
|
+
const found = findTemplateByName(templates, args.template);
|
|
2713
2872
|
if (!found) {
|
|
2714
|
-
M.error(`Template "${
|
|
2873
|
+
M.error(`Template "${args.template}" not found. Available templates:`);
|
|
2715
2874
|
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2716
|
-
throw new Error(`Template "${
|
|
2875
|
+
throw new Error(`Template "${args.template}" not found`);
|
|
2717
2876
|
}
|
|
2718
2877
|
selectedTemplate = found;
|
|
2719
2878
|
}
|
|
@@ -2721,7 +2880,7 @@ async function createFromTemplate(args2) {
|
|
|
2721
2880
|
if (!selectedTemplate) {
|
|
2722
2881
|
throw new Error("No template selected");
|
|
2723
2882
|
}
|
|
2724
|
-
let projectName =
|
|
2883
|
+
let projectName = args.projectName;
|
|
2725
2884
|
if (!projectName) {
|
|
2726
2885
|
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2727
2886
|
const response = await he({
|
|
@@ -2735,19 +2894,61 @@ async function createFromTemplate(args2) {
|
|
|
2735
2894
|
}
|
|
2736
2895
|
projectName = response;
|
|
2737
2896
|
}
|
|
2897
|
+
let llmProvider = args.llmProvider;
|
|
2898
|
+
if (!llmProvider) {
|
|
2899
|
+
const providerResponse = await ve({
|
|
2900
|
+
message: "Select a default provider:",
|
|
2901
|
+
options: LLM_PROVIDERS
|
|
2902
|
+
});
|
|
2903
|
+
if (pD(providerResponse)) {
|
|
2904
|
+
M.info("Project creation cancelled.");
|
|
2905
|
+
return;
|
|
2906
|
+
}
|
|
2907
|
+
llmProvider = providerResponse;
|
|
2908
|
+
}
|
|
2909
|
+
let initGit = false;
|
|
2910
|
+
const gitConfirmResult = await ye({
|
|
2911
|
+
message: "Initialize a new git repository?",
|
|
2912
|
+
initialValue: true
|
|
2913
|
+
});
|
|
2914
|
+
if (!pD(gitConfirmResult)) {
|
|
2915
|
+
initGit = gitConfirmResult;
|
|
2916
|
+
}
|
|
2917
|
+
let projectPath = null;
|
|
2738
2918
|
try {
|
|
2739
|
-
const analytics =
|
|
2919
|
+
const analytics = args.injectedAnalytics || getAnalytics();
|
|
2740
2920
|
if (analytics) {
|
|
2741
2921
|
analytics.trackEvent("cli_template_used", {
|
|
2742
2922
|
template_slug: selectedTemplate.slug,
|
|
2743
2923
|
template_title: selectedTemplate.title
|
|
2744
2924
|
});
|
|
2925
|
+
if (llmProvider) {
|
|
2926
|
+
analytics.trackEvent("cli_model_provider_selected", {
|
|
2927
|
+
provider: llmProvider,
|
|
2928
|
+
selection_method: args.llmProvider ? "cli_args" : "interactive"
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2745
2931
|
}
|
|
2746
|
-
const
|
|
2932
|
+
const isBeta = version$1?.includes("beta") ?? false;
|
|
2933
|
+
const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
|
|
2934
|
+
const branch = isBeta && isMastraTemplate ? "beta" : void 0;
|
|
2935
|
+
projectPath = await cloneTemplate({
|
|
2747
2936
|
template: selectedTemplate,
|
|
2748
|
-
projectName
|
|
2937
|
+
projectName,
|
|
2938
|
+
branch,
|
|
2939
|
+
llmProvider
|
|
2749
2940
|
});
|
|
2750
2941
|
await installDependencies(projectPath);
|
|
2942
|
+
if (initGit) {
|
|
2943
|
+
const s2 = Y();
|
|
2944
|
+
try {
|
|
2945
|
+
s2.start("Initializing git repository");
|
|
2946
|
+
await gitInit({ cwd: projectPath });
|
|
2947
|
+
s2.stop("Git repository initialized");
|
|
2948
|
+
} catch {
|
|
2949
|
+
s2.stop();
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2751
2952
|
Me(`
|
|
2752
2953
|
${color2.green("Mastra template installed!")}
|
|
2753
2954
|
|
|
@@ -2756,6 +2957,17 @@ async function createFromTemplate(args2) {
|
|
|
2756
2957
|
`);
|
|
2757
2958
|
postCreate({ projectName });
|
|
2758
2959
|
} catch (error) {
|
|
2960
|
+
if (projectPath) {
|
|
2961
|
+
try {
|
|
2962
|
+
if (fs3__default__default.existsSync(projectPath)) {
|
|
2963
|
+
await fs4.rm(projectPath, { recursive: true, force: true });
|
|
2964
|
+
}
|
|
2965
|
+
} catch (cleanupError) {
|
|
2966
|
+
console.error(
|
|
2967
|
+
`Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
|
|
2968
|
+
);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2759
2971
|
M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2760
2972
|
throw error;
|
|
2761
2973
|
}
|
|
@@ -2764,7 +2976,7 @@ async function createFromTemplate(args2) {
|
|
|
2764
2976
|
async function getPackageVersion() {
|
|
2765
2977
|
const __filename = fileURLToPath(import.meta.url);
|
|
2766
2978
|
const __dirname = dirname(__filename);
|
|
2767
|
-
const pkgJsonPath =
|
|
2979
|
+
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
2768
2980
|
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2769
2981
|
return content.version;
|
|
2770
2982
|
}
|