create-mastra 0.0.0-safe-stringify-telemetry-20251205024938 → 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/CHANGELOG.md +242 -34
- package/README.md +1 -1
- package/dist/index.js +484 -250
- package/dist/index.js.map +1 -1
- package/dist/starter-files/tools.ts +2 -2
- package/dist/templates/dev.entry.js +3 -46
- package/package.json +19 -27
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ 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
10
|
import fs4 from 'node:fs/promises';
|
|
@@ -18,12 +18,12 @@ 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
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
var __dirname =
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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(),
|
|
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(`
|
|
@@ -887,6 +894,7 @@ class YoctoSpinner {
|
|
|
887
894
|
#exitHandlerBound;
|
|
888
895
|
#isInteractive;
|
|
889
896
|
#lastSpinnerFrameTime = 0;
|
|
897
|
+
#isSpinning = false;
|
|
890
898
|
|
|
891
899
|
constructor(options = {}) {
|
|
892
900
|
const spinner = options.spinner ?? defaultSpinner;
|
|
@@ -908,13 +916,17 @@ class YoctoSpinner {
|
|
|
908
916
|
return this;
|
|
909
917
|
}
|
|
910
918
|
|
|
919
|
+
this.#isSpinning = true;
|
|
911
920
|
this.#hideCursor();
|
|
912
921
|
this.#render();
|
|
913
922
|
this.#subscribeToProcessEvents();
|
|
914
923
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
924
|
+
// Only start the timer in interactive mode
|
|
925
|
+
if (this.#isInteractive) {
|
|
926
|
+
this.#timer = setInterval(() => {
|
|
927
|
+
this.#render();
|
|
928
|
+
}, this.#interval);
|
|
929
|
+
}
|
|
918
930
|
|
|
919
931
|
return this;
|
|
920
932
|
}
|
|
@@ -924,8 +936,12 @@ class YoctoSpinner {
|
|
|
924
936
|
return this;
|
|
925
937
|
}
|
|
926
938
|
|
|
927
|
-
|
|
928
|
-
this.#timer
|
|
939
|
+
this.#isSpinning = false;
|
|
940
|
+
if (this.#timer) {
|
|
941
|
+
clearInterval(this.#timer);
|
|
942
|
+
this.#timer = undefined;
|
|
943
|
+
}
|
|
944
|
+
|
|
929
945
|
this.#showCursor();
|
|
930
946
|
this.clear();
|
|
931
947
|
this.#unsubscribeFromProcessEvents();
|
|
@@ -958,7 +974,7 @@ class YoctoSpinner {
|
|
|
958
974
|
}
|
|
959
975
|
|
|
960
976
|
get isSpinning() {
|
|
961
|
-
return this.#
|
|
977
|
+
return this.#isSpinning;
|
|
962
978
|
}
|
|
963
979
|
|
|
964
980
|
get text() {
|
|
@@ -1095,11 +1111,11 @@ var MastraLogger = class {
|
|
|
1095
1111
|
}
|
|
1096
1112
|
trackException(_error) {
|
|
1097
1113
|
}
|
|
1098
|
-
async
|
|
1114
|
+
async listLogs(transportId, params) {
|
|
1099
1115
|
if (!transportId || !this.transports.has(transportId)) {
|
|
1100
1116
|
return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
|
|
1101
1117
|
}
|
|
1102
|
-
return this.transports.get(transportId).
|
|
1118
|
+
return this.transports.get(transportId).listLogs(params) ?? {
|
|
1103
1119
|
logs: [],
|
|
1104
1120
|
total: 0,
|
|
1105
1121
|
page: params?.page ?? 1,
|
|
@@ -1107,7 +1123,7 @@ var MastraLogger = class {
|
|
|
1107
1123
|
hasMore: false
|
|
1108
1124
|
};
|
|
1109
1125
|
}
|
|
1110
|
-
async
|
|
1126
|
+
async listLogsByRunId({
|
|
1111
1127
|
transportId,
|
|
1112
1128
|
runId,
|
|
1113
1129
|
fromDate,
|
|
@@ -1120,7 +1136,7 @@ var MastraLogger = class {
|
|
|
1120
1136
|
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1121
1137
|
return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
|
|
1122
1138
|
}
|
|
1123
|
-
return this.transports.get(transportId).
|
|
1139
|
+
return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
|
|
1124
1140
|
logs: [],
|
|
1125
1141
|
total: 0,
|
|
1126
1142
|
page: page ?? 1,
|
|
@@ -1130,10 +1146,15 @@ var MastraLogger = class {
|
|
|
1130
1146
|
}
|
|
1131
1147
|
};
|
|
1132
1148
|
|
|
1133
|
-
var PinoLogger = class extends MastraLogger {
|
|
1149
|
+
var PinoLogger = class _PinoLogger extends MastraLogger {
|
|
1134
1150
|
logger;
|
|
1135
1151
|
constructor(options = {}) {
|
|
1136
1152
|
super(options);
|
|
1153
|
+
const internalOptions = options;
|
|
1154
|
+
if (internalOptions._logger) {
|
|
1155
|
+
this.logger = internalOptions._logger;
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1137
1158
|
let prettyStream = void 0;
|
|
1138
1159
|
if (!options.overrideDefaultTransports) {
|
|
1139
1160
|
prettyStream = pretty({
|
|
@@ -1150,7 +1171,8 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1150
1171
|
{
|
|
1151
1172
|
name: options.name || "app",
|
|
1152
1173
|
level: options.level || LogLevel.INFO,
|
|
1153
|
-
formatters: options.formatters
|
|
1174
|
+
formatters: options.formatters,
|
|
1175
|
+
redact: options.redact
|
|
1154
1176
|
},
|
|
1155
1177
|
options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
|
|
1156
1178
|
...transportsAry.map(([, transport]) => ({
|
|
@@ -1164,6 +1186,38 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1164
1186
|
])
|
|
1165
1187
|
);
|
|
1166
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
|
+
}
|
|
1167
1221
|
debug(message, args = {}) {
|
|
1168
1222
|
this.logger.debug(args, message);
|
|
1169
1223
|
}
|
|
@@ -1178,118 +1232,8 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1178
1232
|
}
|
|
1179
1233
|
};
|
|
1180
1234
|
|
|
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
|
-
}
|
|
1235
|
+
var package_default = {
|
|
1236
|
+
version: "1.0.1"};
|
|
1293
1237
|
function getPackageManagerAddCommand(pm) {
|
|
1294
1238
|
switch (pm) {
|
|
1295
1239
|
case "npm":
|
|
@@ -1310,13 +1254,13 @@ var DepsService = class {
|
|
|
1310
1254
|
this.packageManager = this.getPackageManager();
|
|
1311
1255
|
}
|
|
1312
1256
|
findLockFile(dir) {
|
|
1313
|
-
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"];
|
|
1314
1258
|
for (const file of lockFiles) {
|
|
1315
|
-
if (fs3__default__default.existsSync(
|
|
1259
|
+
if (fs3__default__default.existsSync(path3.join(dir, file))) {
|
|
1316
1260
|
return file;
|
|
1317
1261
|
}
|
|
1318
1262
|
}
|
|
1319
|
-
const parentDir =
|
|
1263
|
+
const parentDir = path3.resolve(dir, "..");
|
|
1320
1264
|
if (parentDir !== dir) {
|
|
1321
1265
|
return this.findLockFile(parentDir);
|
|
1322
1266
|
}
|
|
@@ -1332,6 +1276,7 @@ var DepsService = class {
|
|
|
1332
1276
|
case "yarn.lock":
|
|
1333
1277
|
return "yarn";
|
|
1334
1278
|
case "bun.lock":
|
|
1279
|
+
case "bun.lockb":
|
|
1335
1280
|
return "bun";
|
|
1336
1281
|
default:
|
|
1337
1282
|
return "npm";
|
|
@@ -1349,7 +1294,7 @@ var DepsService = class {
|
|
|
1349
1294
|
}
|
|
1350
1295
|
async checkDependencies(dependencies) {
|
|
1351
1296
|
try {
|
|
1352
|
-
const packageJsonPath =
|
|
1297
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1353
1298
|
try {
|
|
1354
1299
|
await fs4.access(packageJsonPath);
|
|
1355
1300
|
} catch {
|
|
@@ -1369,7 +1314,7 @@ var DepsService = class {
|
|
|
1369
1314
|
}
|
|
1370
1315
|
async getProjectName() {
|
|
1371
1316
|
try {
|
|
1372
|
-
const packageJsonPath =
|
|
1317
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1373
1318
|
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1374
1319
|
const pkg = JSON.parse(packageJson);
|
|
1375
1320
|
return pkg.name;
|
|
@@ -1457,8 +1402,8 @@ var FileService = class {
|
|
|
1457
1402
|
*/
|
|
1458
1403
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1459
1404
|
const __filename = fileURLToPath(import.meta.url);
|
|
1460
|
-
const __dirname =
|
|
1461
|
-
const filePath =
|
|
1405
|
+
const __dirname = path3.dirname(__filename);
|
|
1406
|
+
const filePath = path3.resolve(__dirname, "starter-files", inputFile);
|
|
1462
1407
|
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1463
1408
|
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1464
1409
|
console.info(`${outputFilePath} already exists`);
|
|
@@ -1468,7 +1413,7 @@ var FileService = class {
|
|
|
1468
1413
|
return true;
|
|
1469
1414
|
}
|
|
1470
1415
|
async setupEnvFile({ dbUrl }) {
|
|
1471
|
-
const envPath =
|
|
1416
|
+
const envPath = path3.join(process.cwd(), ".env.development");
|
|
1472
1417
|
await fsExtra.ensureFile(envPath);
|
|
1473
1418
|
const fileEnvService = new FileEnvService(envPath);
|
|
1474
1419
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
@@ -1492,21 +1437,152 @@ var FileService = class {
|
|
|
1492
1437
|
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1493
1438
|
}
|
|
1494
1439
|
};
|
|
1440
|
+
var createArgs = (versionTag) => {
|
|
1441
|
+
const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
|
|
1442
|
+
return ["-y", packageName];
|
|
1443
|
+
};
|
|
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
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
return {
|
|
1462
|
+
mcpServers: {
|
|
1463
|
+
mastra: {
|
|
1464
|
+
command: "npx",
|
|
1465
|
+
args
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
};
|
|
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
|
+
}
|
|
1495
1571
|
var exec = util.promisify(child_process.exec);
|
|
1496
1572
|
var getModelIdentifier = (llmProvider) => {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
return `'anthropic/claude-sonnet-4-5-20250929'`;
|
|
1573
|
+
let model = "openai/gpt-4o";
|
|
1574
|
+
if (llmProvider === "anthropic") {
|
|
1575
|
+
model = "anthropic/claude-sonnet-4-5";
|
|
1501
1576
|
} else if (llmProvider === "groq") {
|
|
1502
|
-
|
|
1577
|
+
model = "groq/llama-3.3-70b-versatile";
|
|
1503
1578
|
} else if (llmProvider === "google") {
|
|
1504
|
-
|
|
1579
|
+
model = "google/gemini-2.5-pro";
|
|
1505
1580
|
} else if (llmProvider === "cerebras") {
|
|
1506
|
-
|
|
1581
|
+
model = "cerebras/llama-3.3-70b";
|
|
1507
1582
|
} else if (llmProvider === "mistral") {
|
|
1508
|
-
|
|
1583
|
+
model = "mistral/mistral-medium-2508";
|
|
1509
1584
|
}
|
|
1585
|
+
return model;
|
|
1510
1586
|
};
|
|
1511
1587
|
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1512
1588
|
const modelString = getModelIdentifier(llmProvider);
|
|
@@ -1527,14 +1603,14 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorer
|
|
|
1527
1603
|
const content = `
|
|
1528
1604
|
import { Agent } from '@mastra/core/agent';
|
|
1529
1605
|
import { Memory } from '@mastra/memory';
|
|
1530
|
-
import { LibSQLStore } from '@mastra/libsql';
|
|
1531
1606
|
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1532
1607
|
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1533
1608
|
|
|
1534
1609
|
export const weatherAgent = new Agent({
|
|
1610
|
+
id: 'weather-agent',
|
|
1535
1611
|
name: 'Weather Agent',
|
|
1536
1612
|
instructions: \`${instructions}\`,
|
|
1537
|
-
model: ${modelString},
|
|
1613
|
+
model: '${modelString}',
|
|
1538
1614
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1539
1615
|
${addScorers ? `scorers: {
|
|
1540
1616
|
toolCallAppropriateness: {
|
|
@@ -1559,11 +1635,7 @@ export const weatherAgent = new Agent({
|
|
|
1559
1635
|
},
|
|
1560
1636
|
},
|
|
1561
1637
|
},` : ""}
|
|
1562
|
-
memory: new Memory(
|
|
1563
|
-
storage: new LibSQLStore({
|
|
1564
|
-
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1565
|
-
})
|
|
1566
|
-
})
|
|
1638
|
+
memory: new Memory()
|
|
1567
1639
|
});
|
|
1568
1640
|
`;
|
|
1569
1641
|
const formattedContent = await prettier.format(content, {
|
|
@@ -1773,9 +1845,10 @@ async function writeToolSample(destPath) {
|
|
|
1773
1845
|
async function writeScorersSample(llmProvider, destPath) {
|
|
1774
1846
|
const modelString = getModelIdentifier(llmProvider);
|
|
1775
1847
|
const content = `import { z } from 'zod';
|
|
1776
|
-
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/
|
|
1777
|
-
import { createCompletenessScorer } from '@mastra/evals/scorers/
|
|
1778
|
-
import {
|
|
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';
|
|
1779
1852
|
|
|
1780
1853
|
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1781
1854
|
expectedTool: 'weatherTool',
|
|
@@ -1786,11 +1859,12 @@ export const completenessScorer = createCompletenessScorer();
|
|
|
1786
1859
|
|
|
1787
1860
|
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1788
1861
|
export const translationScorer = createScorer({
|
|
1862
|
+
id: 'translation-quality-scorer',
|
|
1789
1863
|
name: 'Translation Quality',
|
|
1790
1864
|
description: 'Checks that non-English location names are translated and used correctly',
|
|
1791
1865
|
type: 'agent',
|
|
1792
1866
|
judge: {
|
|
1793
|
-
model: ${modelString},
|
|
1867
|
+
model: '${modelString}',
|
|
1794
1868
|
instructions:
|
|
1795
1869
|
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1796
1870
|
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
@@ -1799,8 +1873,8 @@ export const translationScorer = createScorer({
|
|
|
1799
1873
|
},
|
|
1800
1874
|
})
|
|
1801
1875
|
.preprocess(({ run }) => {
|
|
1802
|
-
const userText = (run.input
|
|
1803
|
-
const assistantText = (run.output
|
|
1876
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1877
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1804
1878
|
return { userText, assistantText };
|
|
1805
1879
|
})
|
|
1806
1880
|
.analyze({
|
|
@@ -1887,7 +1961,7 @@ var writeIndexFile = async ({
|
|
|
1887
1961
|
addScorers
|
|
1888
1962
|
}) => {
|
|
1889
1963
|
const indexPath = dirPath + "/index.ts";
|
|
1890
|
-
const destPath =
|
|
1964
|
+
const destPath = path3.join(indexPath);
|
|
1891
1965
|
try {
|
|
1892
1966
|
await fs4.writeFile(destPath, "");
|
|
1893
1967
|
const filteredExports = [
|
|
@@ -1899,7 +1973,7 @@ var writeIndexFile = async ({
|
|
|
1899
1973
|
await fs4.writeFile(
|
|
1900
1974
|
destPath,
|
|
1901
1975
|
`
|
|
1902
|
-
import { Mastra } from '@mastra/core';
|
|
1976
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1903
1977
|
|
|
1904
1978
|
export const mastra = new Mastra()
|
|
1905
1979
|
`
|
|
@@ -1912,6 +1986,7 @@ export const mastra = new Mastra()
|
|
|
1912
1986
|
import { Mastra } from '@mastra/core/mastra';
|
|
1913
1987
|
import { PinoLogger } from '@mastra/loggers';
|
|
1914
1988
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1989
|
+
import { Observability, DefaultExporter, CloudExporter, SensitiveDataFilter } from '@mastra/observability';
|
|
1915
1990
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1916
1991
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1917
1992
|
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
@@ -1919,6 +1994,7 @@ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, tran
|
|
|
1919
1994
|
export const mastra = new Mastra({
|
|
1920
1995
|
${filteredExports.join("\n ")}
|
|
1921
1996
|
storage: new LibSQLStore({
|
|
1997
|
+
id: "mastra-storage",
|
|
1922
1998
|
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1923
1999
|
url: ":memory:",
|
|
1924
2000
|
}),
|
|
@@ -1926,14 +2002,20 @@ export const mastra = new Mastra({
|
|
|
1926
2002
|
name: 'Mastra',
|
|
1927
2003
|
level: 'info',
|
|
1928
2004
|
}),
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
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
|
+
}),
|
|
1937
2019
|
});
|
|
1938
2020
|
`
|
|
1939
2021
|
);
|
|
@@ -1972,7 +2054,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
|
|
|
1972
2054
|
};
|
|
1973
2055
|
var createMastraDir = async (directory) => {
|
|
1974
2056
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1975
|
-
const dirPath =
|
|
2057
|
+
const dirPath = path3.join(process.cwd(), ...dir, "mastra");
|
|
1976
2058
|
try {
|
|
1977
2059
|
await fs4.access(dirPath);
|
|
1978
2060
|
return { ok: false };
|
|
@@ -1997,8 +2079,8 @@ var LLM_PROVIDERS = [
|
|
|
1997
2079
|
{ value: "cerebras", label: "Cerebras" },
|
|
1998
2080
|
{ value: "mistral", label: "Mistral" }
|
|
1999
2081
|
];
|
|
2000
|
-
var interactivePrompt = async (
|
|
2001
|
-
const { skip = {}, options: { showBanner = true } = {} } =
|
|
2082
|
+
var interactivePrompt = async (args = {}) => {
|
|
2083
|
+
const { skip = {}, options: { showBanner = true } = {} } = args;
|
|
2002
2084
|
if (showBanner) {
|
|
2003
2085
|
Ie(color2.inverse(" Mastra Init "));
|
|
2004
2086
|
}
|
|
@@ -2036,46 +2118,33 @@ var interactivePrompt = async (args2 = {}) => {
|
|
|
2036
2118
|
return void 0;
|
|
2037
2119
|
},
|
|
2038
2120
|
configureEditorWithDocsMCP: async () => {
|
|
2039
|
-
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
2040
|
-
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2041
|
-
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2042
2121
|
const editor = await ve({
|
|
2043
2122
|
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2044
2123
|
options: [
|
|
2045
2124
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2046
2125
|
{
|
|
2047
2126
|
value: "cursor",
|
|
2048
|
-
label: "Cursor (project only)"
|
|
2049
|
-
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
2127
|
+
label: "Cursor (project only)"
|
|
2050
2128
|
},
|
|
2051
2129
|
{
|
|
2052
2130
|
value: "cursor-global",
|
|
2053
|
-
label: "Cursor (global, all projects)"
|
|
2054
|
-
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
2131
|
+
label: "Cursor (global, all projects)"
|
|
2055
2132
|
},
|
|
2056
2133
|
{
|
|
2057
2134
|
value: "windsurf",
|
|
2058
|
-
label: "Windsurf"
|
|
2059
|
-
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
2135
|
+
label: "Windsurf"
|
|
2060
2136
|
},
|
|
2061
2137
|
{
|
|
2062
2138
|
value: "vscode",
|
|
2063
|
-
label: "VSCode"
|
|
2064
|
-
|
|
2139
|
+
label: "VSCode"
|
|
2140
|
+
},
|
|
2141
|
+
{
|
|
2142
|
+
value: "antigravity",
|
|
2143
|
+
label: "Antigravity"
|
|
2065
2144
|
}
|
|
2066
2145
|
]
|
|
2067
2146
|
});
|
|
2068
2147
|
if (editor === `skip`) return void 0;
|
|
2069
|
-
if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
|
|
2070
|
-
M.message(`
|
|
2071
|
-
Windsurf is already installed, skipping.`);
|
|
2072
|
-
return void 0;
|
|
2073
|
-
}
|
|
2074
|
-
if (editor === `vscode` && vscodeIsAlreadyInstalled) {
|
|
2075
|
-
M.message(`
|
|
2076
|
-
VSCode is already installed, skipping.`);
|
|
2077
|
-
return void 0;
|
|
2078
|
-
}
|
|
2079
2148
|
if (editor === `cursor`) {
|
|
2080
2149
|
M.message(
|
|
2081
2150
|
`
|
|
@@ -2084,19 +2153,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
2084
2153
|
);
|
|
2085
2154
|
}
|
|
2086
2155
|
if (editor === `cursor-global`) {
|
|
2087
|
-
const
|
|
2156
|
+
const confirm3 = await ve({
|
|
2088
2157
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2089
2158
|
options: [
|
|
2090
2159
|
{ value: "yes", label: "Yes, I understand" },
|
|
2091
2160
|
{ value: "skip", label: "No, skip for now" }
|
|
2092
2161
|
]
|
|
2093
2162
|
});
|
|
2094
|
-
if (
|
|
2163
|
+
if (confirm3 !== `yes`) {
|
|
2095
2164
|
return void 0;
|
|
2096
2165
|
}
|
|
2097
2166
|
}
|
|
2098
2167
|
if (editor === `windsurf`) {
|
|
2099
|
-
const
|
|
2168
|
+
const confirm3 = await ve({
|
|
2100
2169
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
2101
2170
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
2102
2171
|
options: [
|
|
@@ -2104,11 +2173,31 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2104
2173
|
{ value: "skip", label: "No, skip for now" }
|
|
2105
2174
|
]
|
|
2106
2175
|
});
|
|
2107
|
-
if (
|
|
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`) {
|
|
2108
2190
|
return void 0;
|
|
2109
2191
|
}
|
|
2110
2192
|
}
|
|
2111
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
|
+
});
|
|
2112
2201
|
}
|
|
2113
2202
|
},
|
|
2114
2203
|
{
|
|
@@ -2149,6 +2238,20 @@ function getPackageManager() {
|
|
|
2149
2238
|
}
|
|
2150
2239
|
return "npm";
|
|
2151
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
|
+
}
|
|
2152
2255
|
var logger = createLogger(false);
|
|
2153
2256
|
function createLogger(debug = false) {
|
|
2154
2257
|
return new PinoLogger({
|
|
@@ -2158,19 +2261,23 @@ function createLogger(debug = false) {
|
|
|
2158
2261
|
}
|
|
2159
2262
|
var exec2 = util.promisify(child_process.exec);
|
|
2160
2263
|
async function cloneTemplate(options) {
|
|
2161
|
-
const { template, projectName, targetDir } = options;
|
|
2162
|
-
const projectPath = targetDir ?
|
|
2264
|
+
const { template, projectName, targetDir, branch, llmProvider } = options;
|
|
2265
|
+
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
2163
2266
|
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2164
2267
|
try {
|
|
2165
2268
|
if (await directoryExists(projectPath)) {
|
|
2166
2269
|
spinner4.error(`Directory ${projectName} already exists`);
|
|
2167
2270
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2168
2271
|
}
|
|
2169
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2272
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
|
|
2170
2273
|
await updatePackageJson(projectPath, projectName);
|
|
2171
|
-
const envExamplePath =
|
|
2274
|
+
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
2172
2275
|
if (await fileExists(envExamplePath)) {
|
|
2173
|
-
|
|
2276
|
+
const envPath = path3.join(projectPath, ".env");
|
|
2277
|
+
await fs4.copyFile(envExamplePath, envPath);
|
|
2278
|
+
if (llmProvider) {
|
|
2279
|
+
await updateEnvFile(envPath, llmProvider);
|
|
2280
|
+
}
|
|
2174
2281
|
}
|
|
2175
2282
|
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2176
2283
|
return projectPath;
|
|
@@ -2195,21 +2302,27 @@ async function fileExists(filePath) {
|
|
|
2195
2302
|
return false;
|
|
2196
2303
|
}
|
|
2197
2304
|
}
|
|
2198
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2305
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
|
|
2199
2306
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
2200
2307
|
try {
|
|
2201
2308
|
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2202
|
-
const
|
|
2309
|
+
const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
|
|
2310
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
|
|
2203
2311
|
await exec2(degitCommand, {
|
|
2204
2312
|
cwd: process.cwd()
|
|
2205
2313
|
});
|
|
2206
2314
|
} catch {
|
|
2207
2315
|
try {
|
|
2208
|
-
const
|
|
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);
|
|
2209
2322
|
await exec2(gitCommand, {
|
|
2210
2323
|
cwd: process.cwd()
|
|
2211
2324
|
});
|
|
2212
|
-
const gitDir =
|
|
2325
|
+
const gitDir = path3.join(targetPath, ".git");
|
|
2213
2326
|
if (await directoryExists(gitDir)) {
|
|
2214
2327
|
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2215
2328
|
}
|
|
@@ -2219,7 +2332,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
|
2219
2332
|
}
|
|
2220
2333
|
}
|
|
2221
2334
|
async function updatePackageJson(projectPath, projectName) {
|
|
2222
|
-
const packageJsonPath =
|
|
2335
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
2223
2336
|
try {
|
|
2224
2337
|
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2225
2338
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -2229,6 +2342,22 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2229
2342
|
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2230
2343
|
}
|
|
2231
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
|
+
}
|
|
2232
2361
|
async function installDependencies(projectPath, packageManager) {
|
|
2233
2362
|
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2234
2363
|
try {
|
|
@@ -2313,9 +2442,12 @@ var init = async ({
|
|
|
2313
2442
|
llmProvider = "openai",
|
|
2314
2443
|
llmApiKey,
|
|
2315
2444
|
addExample = false,
|
|
2316
|
-
configureEditorWithDocsMCP
|
|
2445
|
+
configureEditorWithDocsMCP,
|
|
2446
|
+
versionTag,
|
|
2447
|
+
initGit = false
|
|
2317
2448
|
}) => {
|
|
2318
2449
|
s.start("Initializing Mastra");
|
|
2450
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2319
2451
|
try {
|
|
2320
2452
|
const result = await createMastraDir(directory);
|
|
2321
2453
|
if (!result.ok) {
|
|
@@ -2343,29 +2475,44 @@ var init = async ({
|
|
|
2343
2475
|
const depService = new DepsService();
|
|
2344
2476
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2345
2477
|
if (needsLibsql) {
|
|
2346
|
-
await depService.installPackages([
|
|
2478
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2347
2479
|
}
|
|
2348
2480
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2349
2481
|
if (needsMemory) {
|
|
2350
|
-
await depService.installPackages([
|
|
2482
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2351
2483
|
}
|
|
2352
2484
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2353
2485
|
if (needsLoggers) {
|
|
2354
|
-
await depService.installPackages([
|
|
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}`]);
|
|
2355
2491
|
}
|
|
2356
2492
|
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2357
2493
|
if (needsEvals) {
|
|
2358
|
-
await depService.installPackages([
|
|
2494
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2359
2495
|
}
|
|
2360
2496
|
}
|
|
2361
2497
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2362
2498
|
if (configureEditorWithDocsMCP) {
|
|
2363
2499
|
await installMastraDocsMCPServer({
|
|
2364
2500
|
editor: configureEditorWithDocsMCP,
|
|
2365
|
-
directory: process.cwd()
|
|
2501
|
+
directory: process.cwd(),
|
|
2502
|
+
versionTag
|
|
2366
2503
|
});
|
|
2367
2504
|
}
|
|
2368
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
|
+
}
|
|
2369
2516
|
if (!llmApiKey) {
|
|
2370
2517
|
Me(`
|
|
2371
2518
|
${color2.green("Mastra initialized successfully!")}
|
|
@@ -2428,7 +2575,7 @@ async function getInitCommand(pm) {
|
|
|
2428
2575
|
async function initializePackageJson(pm) {
|
|
2429
2576
|
const initCommand = await getInitCommand(pm);
|
|
2430
2577
|
await exec3(initCommand);
|
|
2431
|
-
const packageJsonPath =
|
|
2578
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
2432
2579
|
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
2433
2580
|
packageJson.type = "module";
|
|
2434
2581
|
packageJson.engines = {
|
|
@@ -2437,6 +2584,42 @@ async function initializePackageJson(pm) {
|
|
|
2437
2584
|
};
|
|
2438
2585
|
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
2439
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
|
+
};
|
|
2440
2623
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2441
2624
|
let installCommand = getPackageManagerAddCommand(pm);
|
|
2442
2625
|
if (isDev) {
|
|
@@ -2483,7 +2666,7 @@ var createMastraProject = async ({
|
|
|
2483
2666
|
xe("Operation cancelled");
|
|
2484
2667
|
process.exit(0);
|
|
2485
2668
|
}
|
|
2486
|
-
let result;
|
|
2669
|
+
let result = void 0;
|
|
2487
2670
|
if (needsInteractive) {
|
|
2488
2671
|
result = await interactivePrompt({
|
|
2489
2672
|
options: { showBanner: false },
|
|
@@ -2497,7 +2680,7 @@ var createMastraProject = async ({
|
|
|
2497
2680
|
s2.start("Creating project");
|
|
2498
2681
|
try {
|
|
2499
2682
|
await fs4.mkdir(projectName);
|
|
2500
|
-
projectPath =
|
|
2683
|
+
projectPath = path3.resolve(originalCwd, projectName);
|
|
2501
2684
|
} catch (error) {
|
|
2502
2685
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2503
2686
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2519,6 +2702,7 @@ var createMastraProject = async ({
|
|
|
2519
2702
|
build: "mastra build",
|
|
2520
2703
|
start: "mastra start"
|
|
2521
2704
|
});
|
|
2705
|
+
await writeReadmeFile({ dirPath: process.cwd(), projectName });
|
|
2522
2706
|
} catch (error) {
|
|
2523
2707
|
throw new Error(
|
|
2524
2708
|
`Failed to initialize project structure: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
@@ -2528,7 +2712,7 @@ var createMastraProject = async ({
|
|
|
2528
2712
|
s2.start(`Installing ${pm} dependencies`);
|
|
2529
2713
|
try {
|
|
2530
2714
|
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2531
|
-
await exec3(`${pm} ${installCommand} typescript @types/node
|
|
2715
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2532
2716
|
await exec3(`echo '{
|
|
2533
2717
|
"compilerOptions": {
|
|
2534
2718
|
"target": "ES2022",
|
|
@@ -2604,39 +2788,48 @@ var createMastraProject = async ({
|
|
|
2604
2788
|
process.exit(1);
|
|
2605
2789
|
}
|
|
2606
2790
|
};
|
|
2607
|
-
var
|
|
2608
|
-
|
|
2609
|
-
|
|
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
|
+
});
|
|
2610
2801
|
return;
|
|
2611
2802
|
}
|
|
2612
|
-
const needsInteractive =
|
|
2803
|
+
const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
|
|
2613
2804
|
const { projectName, result } = await createMastraProject({
|
|
2614
|
-
projectName:
|
|
2615
|
-
createVersionTag:
|
|
2616
|
-
timeout:
|
|
2617
|
-
llmProvider:
|
|
2618
|
-
llmApiKey:
|
|
2805
|
+
projectName: args?.projectName,
|
|
2806
|
+
createVersionTag: args?.createVersionTag,
|
|
2807
|
+
timeout: args?.timeout,
|
|
2808
|
+
llmProvider: args?.llmProvider,
|
|
2809
|
+
llmApiKey: args?.llmApiKey,
|
|
2619
2810
|
needsInteractive
|
|
2620
2811
|
});
|
|
2621
|
-
const directory =
|
|
2812
|
+
const directory = args.directory || "src/";
|
|
2622
2813
|
if (needsInteractive && result) {
|
|
2623
2814
|
await init({
|
|
2624
2815
|
...result,
|
|
2625
2816
|
llmApiKey: result?.llmApiKey,
|
|
2626
2817
|
components: ["agents", "tools", "workflows", "scorers"],
|
|
2627
|
-
addExample: true
|
|
2818
|
+
addExample: true,
|
|
2819
|
+
versionTag: args.createVersionTag
|
|
2628
2820
|
});
|
|
2629
2821
|
postCreate({ projectName });
|
|
2630
2822
|
return;
|
|
2631
2823
|
}
|
|
2632
|
-
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } =
|
|
2824
|
+
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
|
|
2633
2825
|
await init({
|
|
2634
2826
|
directory,
|
|
2635
2827
|
components,
|
|
2636
2828
|
llmProvider,
|
|
2637
2829
|
addExample,
|
|
2638
2830
|
llmApiKey,
|
|
2639
|
-
configureEditorWithDocsMCP:
|
|
2831
|
+
configureEditorWithDocsMCP: args.mcpServer,
|
|
2832
|
+
versionTag: args.createVersionTag
|
|
2640
2833
|
});
|
|
2641
2834
|
postCreate({ projectName });
|
|
2642
2835
|
};
|
|
@@ -2727,9 +2920,9 @@ async function createFromGitHubUrl(url) {
|
|
|
2727
2920
|
workflows: []
|
|
2728
2921
|
};
|
|
2729
2922
|
}
|
|
2730
|
-
async function createFromTemplate(
|
|
2923
|
+
async function createFromTemplate(args) {
|
|
2731
2924
|
let selectedTemplate;
|
|
2732
|
-
if (
|
|
2925
|
+
if (args.template === true) {
|
|
2733
2926
|
const templates = await loadTemplates();
|
|
2734
2927
|
const selected = await selectTemplate(templates);
|
|
2735
2928
|
if (!selected) {
|
|
@@ -2737,11 +2930,11 @@ async function createFromTemplate(args2) {
|
|
|
2737
2930
|
return;
|
|
2738
2931
|
}
|
|
2739
2932
|
selectedTemplate = selected;
|
|
2740
|
-
} else if (
|
|
2741
|
-
if (isGitHubUrl(
|
|
2933
|
+
} else if (args.template && typeof args.template === "string") {
|
|
2934
|
+
if (isGitHubUrl(args.template)) {
|
|
2742
2935
|
const spinner4 = Y();
|
|
2743
2936
|
spinner4.start("Validating GitHub repository...");
|
|
2744
|
-
const validation = await validateGitHubProject(
|
|
2937
|
+
const validation = await validateGitHubProject(args.template);
|
|
2745
2938
|
if (!validation.isValid) {
|
|
2746
2939
|
spinner4.stop("Validation failed");
|
|
2747
2940
|
M.error("This does not appear to be a valid Mastra project:");
|
|
@@ -2749,14 +2942,14 @@ async function createFromTemplate(args2) {
|
|
|
2749
2942
|
throw new Error("Invalid Mastra project");
|
|
2750
2943
|
}
|
|
2751
2944
|
spinner4.stop("Valid Mastra project \u2713");
|
|
2752
|
-
selectedTemplate = await createFromGitHubUrl(
|
|
2945
|
+
selectedTemplate = await createFromGitHubUrl(args.template);
|
|
2753
2946
|
} else {
|
|
2754
2947
|
const templates = await loadTemplates();
|
|
2755
|
-
const found = findTemplateByName(templates,
|
|
2948
|
+
const found = findTemplateByName(templates, args.template);
|
|
2756
2949
|
if (!found) {
|
|
2757
|
-
M.error(`Template "${
|
|
2950
|
+
M.error(`Template "${args.template}" not found. Available templates:`);
|
|
2758
2951
|
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2759
|
-
throw new Error(`Template "${
|
|
2952
|
+
throw new Error(`Template "${args.template}" not found`);
|
|
2760
2953
|
}
|
|
2761
2954
|
selectedTemplate = found;
|
|
2762
2955
|
}
|
|
@@ -2764,7 +2957,7 @@ async function createFromTemplate(args2) {
|
|
|
2764
2957
|
if (!selectedTemplate) {
|
|
2765
2958
|
throw new Error("No template selected");
|
|
2766
2959
|
}
|
|
2767
|
-
let projectName =
|
|
2960
|
+
let projectName = args.projectName;
|
|
2768
2961
|
if (!projectName) {
|
|
2769
2962
|
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2770
2963
|
const response = await he({
|
|
@@ -2778,20 +2971,61 @@ async function createFromTemplate(args2) {
|
|
|
2778
2971
|
}
|
|
2779
2972
|
projectName = response;
|
|
2780
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
|
+
}
|
|
2781
2994
|
let projectPath = null;
|
|
2782
2995
|
try {
|
|
2783
|
-
const analytics =
|
|
2996
|
+
const analytics = args.injectedAnalytics || getAnalytics();
|
|
2784
2997
|
if (analytics) {
|
|
2785
2998
|
analytics.trackEvent("cli_template_used", {
|
|
2786
2999
|
template_slug: selectedTemplate.slug,
|
|
2787
3000
|
template_title: selectedTemplate.title
|
|
2788
3001
|
});
|
|
3002
|
+
if (llmProvider) {
|
|
3003
|
+
analytics.trackEvent("cli_model_provider_selected", {
|
|
3004
|
+
provider: llmProvider,
|
|
3005
|
+
selection_method: args.llmProvider ? "cli_args" : "interactive"
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
2789
3008
|
}
|
|
3009
|
+
const isBeta = version$1?.includes("beta") ?? false;
|
|
3010
|
+
const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
|
|
3011
|
+
const branch = isBeta && isMastraTemplate ? "beta" : void 0;
|
|
2790
3012
|
projectPath = await cloneTemplate({
|
|
2791
3013
|
template: selectedTemplate,
|
|
2792
|
-
projectName
|
|
3014
|
+
projectName,
|
|
3015
|
+
branch,
|
|
3016
|
+
llmProvider
|
|
2793
3017
|
});
|
|
2794
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
|
+
}
|
|
2795
3029
|
Me(`
|
|
2796
3030
|
${color2.green("Mastra template installed!")}
|
|
2797
3031
|
|
|
@@ -2819,7 +3053,7 @@ async function createFromTemplate(args2) {
|
|
|
2819
3053
|
async function getPackageVersion() {
|
|
2820
3054
|
const __filename = fileURLToPath(import.meta.url);
|
|
2821
3055
|
const __dirname = dirname(__filename);
|
|
2822
|
-
const pkgJsonPath =
|
|
3056
|
+
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
2823
3057
|
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2824
3058
|
return content.version;
|
|
2825
3059
|
}
|
|
@@ -2857,7 +3091,7 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
2857
3091
|
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2858
3092
|
"-p, --project-name <string>",
|
|
2859
3093
|
"Project name that will be used in package.json and as the project directory name."
|
|
2860
|
-
).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)").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(
|
|
2861
3095
|
"--template [template-name]",
|
|
2862
3096
|
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2863
3097
|
).action(async (projectNameArg, args) => {
|