create-mastra 0.0.0-fix-backport-setserver-20251201151948 → 0.0.0-fix-request-context-as-query-key-20251209130646
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 +74 -32
- package/dist/index.js +399 -237
- 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 +9 -16
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
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.7"};
|
|
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);
|
|
@@ -1532,9 +1595,10 @@ ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
|
1532
1595
|
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1533
1596
|
|
|
1534
1597
|
export const weatherAgent = new Agent({
|
|
1598
|
+
id: 'weather-agent',
|
|
1535
1599
|
name: 'Weather Agent',
|
|
1536
1600
|
instructions: \`${instructions}\`,
|
|
1537
|
-
model: ${modelString},
|
|
1601
|
+
model: '${modelString}',
|
|
1538
1602
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1539
1603
|
${addScorers ? `scorers: {
|
|
1540
1604
|
toolCallAppropriateness: {
|
|
@@ -1561,6 +1625,7 @@ export const weatherAgent = new Agent({
|
|
|
1561
1625
|
},` : ""}
|
|
1562
1626
|
memory: new Memory({
|
|
1563
1627
|
storage: new LibSQLStore({
|
|
1628
|
+
id: "memory-storage",
|
|
1564
1629
|
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1565
1630
|
})
|
|
1566
1631
|
})
|
|
@@ -1773,9 +1838,10 @@ async function writeToolSample(destPath) {
|
|
|
1773
1838
|
async function writeScorersSample(llmProvider, destPath) {
|
|
1774
1839
|
const modelString = getModelIdentifier(llmProvider);
|
|
1775
1840
|
const content = `import { z } from 'zod';
|
|
1776
|
-
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/
|
|
1777
|
-
import { createCompletenessScorer } from '@mastra/evals/scorers/
|
|
1778
|
-
import {
|
|
1841
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
1842
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
|
|
1843
|
+
import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
1844
|
+
import { createScorer } from '@mastra/core/evals';
|
|
1779
1845
|
|
|
1780
1846
|
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1781
1847
|
expectedTool: 'weatherTool',
|
|
@@ -1786,11 +1852,12 @@ export const completenessScorer = createCompletenessScorer();
|
|
|
1786
1852
|
|
|
1787
1853
|
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1788
1854
|
export const translationScorer = createScorer({
|
|
1855
|
+
id: 'translation-quality-scorer',
|
|
1789
1856
|
name: 'Translation Quality',
|
|
1790
1857
|
description: 'Checks that non-English location names are translated and used correctly',
|
|
1791
1858
|
type: 'agent',
|
|
1792
1859
|
judge: {
|
|
1793
|
-
model: ${modelString},
|
|
1860
|
+
model: '${modelString}',
|
|
1794
1861
|
instructions:
|
|
1795
1862
|
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1796
1863
|
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
@@ -1799,8 +1866,8 @@ export const translationScorer = createScorer({
|
|
|
1799
1866
|
},
|
|
1800
1867
|
})
|
|
1801
1868
|
.preprocess(({ run }) => {
|
|
1802
|
-
const userText = (run.input
|
|
1803
|
-
const assistantText = (run.output
|
|
1869
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1870
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1804
1871
|
return { userText, assistantText };
|
|
1805
1872
|
})
|
|
1806
1873
|
.analyze({
|
|
@@ -1887,7 +1954,7 @@ var writeIndexFile = async ({
|
|
|
1887
1954
|
addScorers
|
|
1888
1955
|
}) => {
|
|
1889
1956
|
const indexPath = dirPath + "/index.ts";
|
|
1890
|
-
const destPath =
|
|
1957
|
+
const destPath = path3.join(indexPath);
|
|
1891
1958
|
try {
|
|
1892
1959
|
await fs4.writeFile(destPath, "");
|
|
1893
1960
|
const filteredExports = [
|
|
@@ -1899,7 +1966,7 @@ var writeIndexFile = async ({
|
|
|
1899
1966
|
await fs4.writeFile(
|
|
1900
1967
|
destPath,
|
|
1901
1968
|
`
|
|
1902
|
-
import { Mastra } from '@mastra/core';
|
|
1969
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1903
1970
|
|
|
1904
1971
|
export const mastra = new Mastra()
|
|
1905
1972
|
`
|
|
@@ -1912,6 +1979,7 @@ export const mastra = new Mastra()
|
|
|
1912
1979
|
import { Mastra } from '@mastra/core/mastra';
|
|
1913
1980
|
import { PinoLogger } from '@mastra/loggers';
|
|
1914
1981
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1982
|
+
import { Observability } from '@mastra/observability';
|
|
1915
1983
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1916
1984
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1917
1985
|
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
@@ -1919,6 +1987,7 @@ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, tran
|
|
|
1919
1987
|
export const mastra = new Mastra({
|
|
1920
1988
|
${filteredExports.join("\n ")}
|
|
1921
1989
|
storage: new LibSQLStore({
|
|
1990
|
+
id: "mastra-storage",
|
|
1922
1991
|
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1923
1992
|
url: ":memory:",
|
|
1924
1993
|
}),
|
|
@@ -1926,14 +1995,10 @@ export const mastra = new Mastra({
|
|
|
1926
1995
|
name: 'Mastra',
|
|
1927
1996
|
level: 'info',
|
|
1928
1997
|
}),
|
|
1929
|
-
|
|
1930
|
-
//
|
|
1931
|
-
enabled:
|
|
1932
|
-
|
|
1933
|
-
observability: {
|
|
1934
|
-
// Enables DefaultExporter and CloudExporter for AI tracing
|
|
1935
|
-
default: { enabled: true },
|
|
1936
|
-
},
|
|
1998
|
+
observability: new Observability({
|
|
1999
|
+
// Enables DefaultExporter and CloudExporter for tracing
|
|
2000
|
+
default: { enabled: true },
|
|
2001
|
+
}),
|
|
1937
2002
|
});
|
|
1938
2003
|
`
|
|
1939
2004
|
);
|
|
@@ -1972,7 +2037,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
|
|
|
1972
2037
|
};
|
|
1973
2038
|
var createMastraDir = async (directory) => {
|
|
1974
2039
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1975
|
-
const dirPath =
|
|
2040
|
+
const dirPath = path3.join(process.cwd(), ...dir, "mastra");
|
|
1976
2041
|
try {
|
|
1977
2042
|
await fs4.access(dirPath);
|
|
1978
2043
|
return { ok: false };
|
|
@@ -1997,8 +2062,8 @@ var LLM_PROVIDERS = [
|
|
|
1997
2062
|
{ value: "cerebras", label: "Cerebras" },
|
|
1998
2063
|
{ value: "mistral", label: "Mistral" }
|
|
1999
2064
|
];
|
|
2000
|
-
var interactivePrompt = async (
|
|
2001
|
-
const { skip = {}, options: { showBanner = true } = {} } =
|
|
2065
|
+
var interactivePrompt = async (args = {}) => {
|
|
2066
|
+
const { skip = {}, options: { showBanner = true } = {} } = args;
|
|
2002
2067
|
if (showBanner) {
|
|
2003
2068
|
Ie(color2.inverse(" Mastra Init "));
|
|
2004
2069
|
}
|
|
@@ -2036,46 +2101,29 @@ var interactivePrompt = async (args2 = {}) => {
|
|
|
2036
2101
|
return void 0;
|
|
2037
2102
|
},
|
|
2038
2103
|
configureEditorWithDocsMCP: async () => {
|
|
2039
|
-
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
2040
|
-
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2041
|
-
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2042
2104
|
const editor = await ve({
|
|
2043
2105
|
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2044
2106
|
options: [
|
|
2045
2107
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2046
2108
|
{
|
|
2047
2109
|
value: "cursor",
|
|
2048
|
-
label: "Cursor (project only)"
|
|
2049
|
-
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
2110
|
+
label: "Cursor (project only)"
|
|
2050
2111
|
},
|
|
2051
2112
|
{
|
|
2052
2113
|
value: "cursor-global",
|
|
2053
|
-
label: "Cursor (global, all projects)"
|
|
2054
|
-
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
2114
|
+
label: "Cursor (global, all projects)"
|
|
2055
2115
|
},
|
|
2056
2116
|
{
|
|
2057
2117
|
value: "windsurf",
|
|
2058
|
-
label: "Windsurf"
|
|
2059
|
-
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
2118
|
+
label: "Windsurf"
|
|
2060
2119
|
},
|
|
2061
2120
|
{
|
|
2062
2121
|
value: "vscode",
|
|
2063
|
-
label: "VSCode"
|
|
2064
|
-
hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
|
|
2122
|
+
label: "VSCode"
|
|
2065
2123
|
}
|
|
2066
2124
|
]
|
|
2067
2125
|
});
|
|
2068
2126
|
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
2127
|
if (editor === `cursor`) {
|
|
2080
2128
|
M.message(
|
|
2081
2129
|
`
|
|
@@ -2084,19 +2132,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
2084
2132
|
);
|
|
2085
2133
|
}
|
|
2086
2134
|
if (editor === `cursor-global`) {
|
|
2087
|
-
const
|
|
2135
|
+
const confirm3 = await ve({
|
|
2088
2136
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2089
2137
|
options: [
|
|
2090
2138
|
{ value: "yes", label: "Yes, I understand" },
|
|
2091
2139
|
{ value: "skip", label: "No, skip for now" }
|
|
2092
2140
|
]
|
|
2093
2141
|
});
|
|
2094
|
-
if (
|
|
2142
|
+
if (confirm3 !== `yes`) {
|
|
2095
2143
|
return void 0;
|
|
2096
2144
|
}
|
|
2097
2145
|
}
|
|
2098
2146
|
if (editor === `windsurf`) {
|
|
2099
|
-
const
|
|
2147
|
+
const confirm3 = await ve({
|
|
2100
2148
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
2101
2149
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
2102
2150
|
options: [
|
|
@@ -2104,11 +2152,17 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2104
2152
|
{ value: "skip", label: "No, skip for now" }
|
|
2105
2153
|
]
|
|
2106
2154
|
});
|
|
2107
|
-
if (
|
|
2155
|
+
if (confirm3 !== `yes`) {
|
|
2108
2156
|
return void 0;
|
|
2109
2157
|
}
|
|
2110
2158
|
}
|
|
2111
2159
|
return editor;
|
|
2160
|
+
},
|
|
2161
|
+
initGit: async () => {
|
|
2162
|
+
return ye({
|
|
2163
|
+
message: "Initialize a new git repository?",
|
|
2164
|
+
initialValue: true
|
|
2165
|
+
});
|
|
2112
2166
|
}
|
|
2113
2167
|
},
|
|
2114
2168
|
{
|
|
@@ -2149,6 +2203,20 @@ function getPackageManager() {
|
|
|
2149
2203
|
}
|
|
2150
2204
|
return "npm";
|
|
2151
2205
|
}
|
|
2206
|
+
async function gitInit({ cwd }) {
|
|
2207
|
+
await execa("git", ["init"], { cwd, stdio: "ignore" });
|
|
2208
|
+
await execa("git", ["add", "-A"], { cwd, stdio: "ignore" });
|
|
2209
|
+
await execa(
|
|
2210
|
+
"git",
|
|
2211
|
+
[
|
|
2212
|
+
"commit",
|
|
2213
|
+
"-m",
|
|
2214
|
+
'"Initial commit from Mastra"',
|
|
2215
|
+
'--author="dane-ai-mastra[bot] <dane-ai-mastra[bot]@users.noreply.github.com>"'
|
|
2216
|
+
],
|
|
2217
|
+
{ cwd, stdio: "ignore" }
|
|
2218
|
+
);
|
|
2219
|
+
}
|
|
2152
2220
|
var logger = createLogger(false);
|
|
2153
2221
|
function createLogger(debug = false) {
|
|
2154
2222
|
return new PinoLogger({
|
|
@@ -2158,19 +2226,23 @@ function createLogger(debug = false) {
|
|
|
2158
2226
|
}
|
|
2159
2227
|
var exec2 = util.promisify(child_process.exec);
|
|
2160
2228
|
async function cloneTemplate(options) {
|
|
2161
|
-
const { template, projectName, targetDir } = options;
|
|
2162
|
-
const projectPath = targetDir ?
|
|
2229
|
+
const { template, projectName, targetDir, branch, llmProvider } = options;
|
|
2230
|
+
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
2163
2231
|
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2164
2232
|
try {
|
|
2165
2233
|
if (await directoryExists(projectPath)) {
|
|
2166
2234
|
spinner4.error(`Directory ${projectName} already exists`);
|
|
2167
2235
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2168
2236
|
}
|
|
2169
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2237
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
|
|
2170
2238
|
await updatePackageJson(projectPath, projectName);
|
|
2171
|
-
const envExamplePath =
|
|
2239
|
+
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
2172
2240
|
if (await fileExists(envExamplePath)) {
|
|
2173
|
-
|
|
2241
|
+
const envPath = path3.join(projectPath, ".env");
|
|
2242
|
+
await fs4.copyFile(envExamplePath, envPath);
|
|
2243
|
+
if (llmProvider) {
|
|
2244
|
+
await updateEnvFile(envPath, llmProvider);
|
|
2245
|
+
}
|
|
2174
2246
|
}
|
|
2175
2247
|
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2176
2248
|
return projectPath;
|
|
@@ -2195,21 +2267,27 @@ async function fileExists(filePath) {
|
|
|
2195
2267
|
return false;
|
|
2196
2268
|
}
|
|
2197
2269
|
}
|
|
2198
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2270
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
|
|
2199
2271
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
2200
2272
|
try {
|
|
2201
2273
|
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2202
|
-
const
|
|
2274
|
+
const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
|
|
2275
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
|
|
2203
2276
|
await exec2(degitCommand, {
|
|
2204
2277
|
cwd: process.cwd()
|
|
2205
2278
|
});
|
|
2206
2279
|
} catch {
|
|
2207
2280
|
try {
|
|
2208
|
-
const
|
|
2281
|
+
const gitArgs = ["git", "clone"];
|
|
2282
|
+
if (branch) {
|
|
2283
|
+
gitArgs.push("--branch", branch);
|
|
2284
|
+
}
|
|
2285
|
+
gitArgs.push(repoUrl, targetPath);
|
|
2286
|
+
const gitCommand = shellQuote2.quote(gitArgs);
|
|
2209
2287
|
await exec2(gitCommand, {
|
|
2210
2288
|
cwd: process.cwd()
|
|
2211
2289
|
});
|
|
2212
|
-
const gitDir =
|
|
2290
|
+
const gitDir = path3.join(targetPath, ".git");
|
|
2213
2291
|
if (await directoryExists(gitDir)) {
|
|
2214
2292
|
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2215
2293
|
}
|
|
@@ -2219,7 +2297,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
|
2219
2297
|
}
|
|
2220
2298
|
}
|
|
2221
2299
|
async function updatePackageJson(projectPath, projectName) {
|
|
2222
|
-
const packageJsonPath =
|
|
2300
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
2223
2301
|
try {
|
|
2224
2302
|
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2225
2303
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -2229,6 +2307,22 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2229
2307
|
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2230
2308
|
}
|
|
2231
2309
|
}
|
|
2310
|
+
async function updateEnvFile(envPath, llmProvider) {
|
|
2311
|
+
try {
|
|
2312
|
+
const envContent = await fs4.readFile(envPath, "utf-8");
|
|
2313
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
2314
|
+
if (!modelString) {
|
|
2315
|
+
logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
const modelValue = modelString.replace(/'/g, "");
|
|
2319
|
+
const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
|
|
2320
|
+
await fs4.writeFile(envPath, updatedContent, "utf-8");
|
|
2321
|
+
logger.info(`Updated MODEL in .env to ${modelValue}`);
|
|
2322
|
+
} catch (error) {
|
|
2323
|
+
logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2232
2326
|
async function installDependencies(projectPath, packageManager) {
|
|
2233
2327
|
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2234
2328
|
try {
|
|
@@ -2313,9 +2407,12 @@ var init = async ({
|
|
|
2313
2407
|
llmProvider = "openai",
|
|
2314
2408
|
llmApiKey,
|
|
2315
2409
|
addExample = false,
|
|
2316
|
-
configureEditorWithDocsMCP
|
|
2410
|
+
configureEditorWithDocsMCP,
|
|
2411
|
+
versionTag,
|
|
2412
|
+
initGit = false
|
|
2317
2413
|
}) => {
|
|
2318
2414
|
s.start("Initializing Mastra");
|
|
2415
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2319
2416
|
try {
|
|
2320
2417
|
const result = await createMastraDir(directory);
|
|
2321
2418
|
if (!result.ok) {
|
|
@@ -2343,29 +2440,44 @@ var init = async ({
|
|
|
2343
2440
|
const depService = new DepsService();
|
|
2344
2441
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2345
2442
|
if (needsLibsql) {
|
|
2346
|
-
await depService.installPackages([
|
|
2443
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2347
2444
|
}
|
|
2348
2445
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2349
2446
|
if (needsMemory) {
|
|
2350
|
-
await depService.installPackages([
|
|
2447
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2351
2448
|
}
|
|
2352
2449
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2353
2450
|
if (needsLoggers) {
|
|
2354
|
-
await depService.installPackages([
|
|
2451
|
+
await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
|
|
2452
|
+
}
|
|
2453
|
+
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2454
|
+
if (needsObservability) {
|
|
2455
|
+
await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
|
|
2355
2456
|
}
|
|
2356
2457
|
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2357
2458
|
if (needsEvals) {
|
|
2358
|
-
await depService.installPackages([
|
|
2459
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2359
2460
|
}
|
|
2360
2461
|
}
|
|
2361
2462
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2362
2463
|
if (configureEditorWithDocsMCP) {
|
|
2363
2464
|
await installMastraDocsMCPServer({
|
|
2364
2465
|
editor: configureEditorWithDocsMCP,
|
|
2365
|
-
directory: process.cwd()
|
|
2466
|
+
directory: process.cwd(),
|
|
2467
|
+
versionTag
|
|
2366
2468
|
});
|
|
2367
2469
|
}
|
|
2368
2470
|
s.stop();
|
|
2471
|
+
if (initGit) {
|
|
2472
|
+
const s2 = Y();
|
|
2473
|
+
try {
|
|
2474
|
+
s2.start("Initializing git repository");
|
|
2475
|
+
await gitInit({ cwd: process.cwd() });
|
|
2476
|
+
s2.stop("Git repository initialized");
|
|
2477
|
+
} catch {
|
|
2478
|
+
s2.stop();
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2369
2481
|
if (!llmApiKey) {
|
|
2370
2482
|
Me(`
|
|
2371
2483
|
${color2.green("Mastra initialized successfully!")}
|
|
@@ -2428,7 +2540,7 @@ async function getInitCommand(pm) {
|
|
|
2428
2540
|
async function initializePackageJson(pm) {
|
|
2429
2541
|
const initCommand = await getInitCommand(pm);
|
|
2430
2542
|
await exec3(initCommand);
|
|
2431
|
-
const packageJsonPath =
|
|
2543
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
2432
2544
|
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
2433
2545
|
packageJson.type = "module";
|
|
2434
2546
|
packageJson.engines = {
|
|
@@ -2483,7 +2595,7 @@ var createMastraProject = async ({
|
|
|
2483
2595
|
xe("Operation cancelled");
|
|
2484
2596
|
process.exit(0);
|
|
2485
2597
|
}
|
|
2486
|
-
let result;
|
|
2598
|
+
let result = void 0;
|
|
2487
2599
|
if (needsInteractive) {
|
|
2488
2600
|
result = await interactivePrompt({
|
|
2489
2601
|
options: { showBanner: false },
|
|
@@ -2497,7 +2609,7 @@ var createMastraProject = async ({
|
|
|
2497
2609
|
s2.start("Creating project");
|
|
2498
2610
|
try {
|
|
2499
2611
|
await fs4.mkdir(projectName);
|
|
2500
|
-
projectPath =
|
|
2612
|
+
projectPath = path3.resolve(originalCwd, projectName);
|
|
2501
2613
|
} catch (error) {
|
|
2502
2614
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2503
2615
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2528,7 +2640,7 @@ var createMastraProject = async ({
|
|
|
2528
2640
|
s2.start(`Installing ${pm} dependencies`);
|
|
2529
2641
|
try {
|
|
2530
2642
|
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2531
|
-
await exec3(`${pm} ${installCommand} typescript @types/node
|
|
2643
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2532
2644
|
await exec3(`echo '{
|
|
2533
2645
|
"compilerOptions": {
|
|
2534
2646
|
"target": "ES2022",
|
|
@@ -2604,39 +2716,48 @@ var createMastraProject = async ({
|
|
|
2604
2716
|
process.exit(1);
|
|
2605
2717
|
}
|
|
2606
2718
|
};
|
|
2607
|
-
var
|
|
2608
|
-
|
|
2609
|
-
|
|
2719
|
+
var version$1 = package_default.version;
|
|
2720
|
+
var create = async (args) => {
|
|
2721
|
+
if (args.template !== void 0) {
|
|
2722
|
+
await createFromTemplate({
|
|
2723
|
+
projectName: args.projectName,
|
|
2724
|
+
template: args.template,
|
|
2725
|
+
timeout: args.timeout,
|
|
2726
|
+
injectedAnalytics: args.analytics,
|
|
2727
|
+
llmProvider: args.llmProvider
|
|
2728
|
+
});
|
|
2610
2729
|
return;
|
|
2611
2730
|
}
|
|
2612
|
-
const needsInteractive =
|
|
2731
|
+
const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
|
|
2613
2732
|
const { projectName, result } = await createMastraProject({
|
|
2614
|
-
projectName:
|
|
2615
|
-
createVersionTag:
|
|
2616
|
-
timeout:
|
|
2617
|
-
llmProvider:
|
|
2618
|
-
llmApiKey:
|
|
2733
|
+
projectName: args?.projectName,
|
|
2734
|
+
createVersionTag: args?.createVersionTag,
|
|
2735
|
+
timeout: args?.timeout,
|
|
2736
|
+
llmProvider: args?.llmProvider,
|
|
2737
|
+
llmApiKey: args?.llmApiKey,
|
|
2619
2738
|
needsInteractive
|
|
2620
2739
|
});
|
|
2621
|
-
const directory =
|
|
2740
|
+
const directory = args.directory || "src/";
|
|
2622
2741
|
if (needsInteractive && result) {
|
|
2623
2742
|
await init({
|
|
2624
2743
|
...result,
|
|
2625
2744
|
llmApiKey: result?.llmApiKey,
|
|
2626
2745
|
components: ["agents", "tools", "workflows", "scorers"],
|
|
2627
|
-
addExample: true
|
|
2746
|
+
addExample: true,
|
|
2747
|
+
versionTag: args.createVersionTag
|
|
2628
2748
|
});
|
|
2629
2749
|
postCreate({ projectName });
|
|
2630
2750
|
return;
|
|
2631
2751
|
}
|
|
2632
|
-
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } =
|
|
2752
|
+
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
|
|
2633
2753
|
await init({
|
|
2634
2754
|
directory,
|
|
2635
2755
|
components,
|
|
2636
2756
|
llmProvider,
|
|
2637
2757
|
addExample,
|
|
2638
2758
|
llmApiKey,
|
|
2639
|
-
configureEditorWithDocsMCP:
|
|
2759
|
+
configureEditorWithDocsMCP: args.mcpServer,
|
|
2760
|
+
versionTag: args.createVersionTag
|
|
2640
2761
|
});
|
|
2641
2762
|
postCreate({ projectName });
|
|
2642
2763
|
};
|
|
@@ -2727,9 +2848,9 @@ async function createFromGitHubUrl(url) {
|
|
|
2727
2848
|
workflows: []
|
|
2728
2849
|
};
|
|
2729
2850
|
}
|
|
2730
|
-
async function createFromTemplate(
|
|
2851
|
+
async function createFromTemplate(args) {
|
|
2731
2852
|
let selectedTemplate;
|
|
2732
|
-
if (
|
|
2853
|
+
if (args.template === true) {
|
|
2733
2854
|
const templates = await loadTemplates();
|
|
2734
2855
|
const selected = await selectTemplate(templates);
|
|
2735
2856
|
if (!selected) {
|
|
@@ -2737,11 +2858,11 @@ async function createFromTemplate(args2) {
|
|
|
2737
2858
|
return;
|
|
2738
2859
|
}
|
|
2739
2860
|
selectedTemplate = selected;
|
|
2740
|
-
} else if (
|
|
2741
|
-
if (isGitHubUrl(
|
|
2861
|
+
} else if (args.template && typeof args.template === "string") {
|
|
2862
|
+
if (isGitHubUrl(args.template)) {
|
|
2742
2863
|
const spinner4 = Y();
|
|
2743
2864
|
spinner4.start("Validating GitHub repository...");
|
|
2744
|
-
const validation = await validateGitHubProject(
|
|
2865
|
+
const validation = await validateGitHubProject(args.template);
|
|
2745
2866
|
if (!validation.isValid) {
|
|
2746
2867
|
spinner4.stop("Validation failed");
|
|
2747
2868
|
M.error("This does not appear to be a valid Mastra project:");
|
|
@@ -2749,14 +2870,14 @@ async function createFromTemplate(args2) {
|
|
|
2749
2870
|
throw new Error("Invalid Mastra project");
|
|
2750
2871
|
}
|
|
2751
2872
|
spinner4.stop("Valid Mastra project \u2713");
|
|
2752
|
-
selectedTemplate = await createFromGitHubUrl(
|
|
2873
|
+
selectedTemplate = await createFromGitHubUrl(args.template);
|
|
2753
2874
|
} else {
|
|
2754
2875
|
const templates = await loadTemplates();
|
|
2755
|
-
const found = findTemplateByName(templates,
|
|
2876
|
+
const found = findTemplateByName(templates, args.template);
|
|
2756
2877
|
if (!found) {
|
|
2757
|
-
M.error(`Template "${
|
|
2878
|
+
M.error(`Template "${args.template}" not found. Available templates:`);
|
|
2758
2879
|
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2759
|
-
throw new Error(`Template "${
|
|
2880
|
+
throw new Error(`Template "${args.template}" not found`);
|
|
2760
2881
|
}
|
|
2761
2882
|
selectedTemplate = found;
|
|
2762
2883
|
}
|
|
@@ -2764,7 +2885,7 @@ async function createFromTemplate(args2) {
|
|
|
2764
2885
|
if (!selectedTemplate) {
|
|
2765
2886
|
throw new Error("No template selected");
|
|
2766
2887
|
}
|
|
2767
|
-
let projectName =
|
|
2888
|
+
let projectName = args.projectName;
|
|
2768
2889
|
if (!projectName) {
|
|
2769
2890
|
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2770
2891
|
const response = await he({
|
|
@@ -2778,20 +2899,61 @@ async function createFromTemplate(args2) {
|
|
|
2778
2899
|
}
|
|
2779
2900
|
projectName = response;
|
|
2780
2901
|
}
|
|
2902
|
+
let llmProvider = args.llmProvider;
|
|
2903
|
+
if (!llmProvider) {
|
|
2904
|
+
const providerResponse = await ve({
|
|
2905
|
+
message: "Select a default provider:",
|
|
2906
|
+
options: LLM_PROVIDERS
|
|
2907
|
+
});
|
|
2908
|
+
if (pD(providerResponse)) {
|
|
2909
|
+
M.info("Project creation cancelled.");
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2912
|
+
llmProvider = providerResponse;
|
|
2913
|
+
}
|
|
2914
|
+
let initGit = false;
|
|
2915
|
+
const gitConfirmResult = await ye({
|
|
2916
|
+
message: "Initialize a new git repository?",
|
|
2917
|
+
initialValue: true
|
|
2918
|
+
});
|
|
2919
|
+
if (!pD(gitConfirmResult)) {
|
|
2920
|
+
initGit = gitConfirmResult;
|
|
2921
|
+
}
|
|
2781
2922
|
let projectPath = null;
|
|
2782
2923
|
try {
|
|
2783
|
-
const analytics =
|
|
2924
|
+
const analytics = args.injectedAnalytics || getAnalytics();
|
|
2784
2925
|
if (analytics) {
|
|
2785
2926
|
analytics.trackEvent("cli_template_used", {
|
|
2786
2927
|
template_slug: selectedTemplate.slug,
|
|
2787
2928
|
template_title: selectedTemplate.title
|
|
2788
2929
|
});
|
|
2930
|
+
if (llmProvider) {
|
|
2931
|
+
analytics.trackEvent("cli_model_provider_selected", {
|
|
2932
|
+
provider: llmProvider,
|
|
2933
|
+
selection_method: args.llmProvider ? "cli_args" : "interactive"
|
|
2934
|
+
});
|
|
2935
|
+
}
|
|
2789
2936
|
}
|
|
2937
|
+
const isBeta = version$1?.includes("beta") ?? false;
|
|
2938
|
+
const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
|
|
2939
|
+
const branch = isBeta && isMastraTemplate ? "beta" : void 0;
|
|
2790
2940
|
projectPath = await cloneTemplate({
|
|
2791
2941
|
template: selectedTemplate,
|
|
2792
|
-
projectName
|
|
2942
|
+
projectName,
|
|
2943
|
+
branch,
|
|
2944
|
+
llmProvider
|
|
2793
2945
|
});
|
|
2794
2946
|
await installDependencies(projectPath);
|
|
2947
|
+
if (initGit) {
|
|
2948
|
+
const s2 = Y();
|
|
2949
|
+
try {
|
|
2950
|
+
s2.start("Initializing git repository");
|
|
2951
|
+
await gitInit({ cwd: projectPath });
|
|
2952
|
+
s2.stop("Git repository initialized");
|
|
2953
|
+
} catch {
|
|
2954
|
+
s2.stop();
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2795
2957
|
Me(`
|
|
2796
2958
|
${color2.green("Mastra template installed!")}
|
|
2797
2959
|
|
|
@@ -2819,7 +2981,7 @@ async function createFromTemplate(args2) {
|
|
|
2819
2981
|
async function getPackageVersion() {
|
|
2820
2982
|
const __filename = fileURLToPath(import.meta.url);
|
|
2821
2983
|
const __dirname = dirname(__filename);
|
|
2822
|
-
const pkgJsonPath =
|
|
2984
|
+
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
2823
2985
|
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2824
2986
|
return content.version;
|
|
2825
2987
|
}
|