create-mastra 0.0.0-sidebar-window-undefined-fix-20251029233656 → 0.0.0-span-scorring-test-20251124132129
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 +59 -1
- package/dist/index.js +351 -226
- 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 -9
package/dist/index.js
CHANGED
|
@@ -4,15 +4,15 @@ import { randomUUID } from 'node:crypto';
|
|
|
4
4
|
import * as fs3__default from 'node:fs';
|
|
5
5
|
import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import
|
|
7
|
+
import path3, { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { PostHog } from 'posthog-node';
|
|
10
|
+
import fs4 from 'node:fs/promises';
|
|
10
11
|
import util, { stripVTControlCharacters } from 'node:util';
|
|
11
12
|
import y$1, { stdout, stdin } from 'node:process';
|
|
12
13
|
import * as g from 'node:readline';
|
|
13
14
|
import g__default from 'node:readline';
|
|
14
15
|
import { Writable } from 'node:stream';
|
|
15
|
-
import fs4 from 'node:fs/promises';
|
|
16
16
|
import child_process from 'node:child_process';
|
|
17
17
|
import tty from 'node:tty';
|
|
18
18
|
import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
@@ -23,7 +23,7 @@ import pretty from 'pino-pretty';
|
|
|
23
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
|
}
|
|
@@ -887,6 +887,7 @@ class YoctoSpinner {
|
|
|
887
887
|
#exitHandlerBound;
|
|
888
888
|
#isInteractive;
|
|
889
889
|
#lastSpinnerFrameTime = 0;
|
|
890
|
+
#isSpinning = false;
|
|
890
891
|
|
|
891
892
|
constructor(options = {}) {
|
|
892
893
|
const spinner = options.spinner ?? defaultSpinner;
|
|
@@ -908,13 +909,17 @@ class YoctoSpinner {
|
|
|
908
909
|
return this;
|
|
909
910
|
}
|
|
910
911
|
|
|
912
|
+
this.#isSpinning = true;
|
|
911
913
|
this.#hideCursor();
|
|
912
914
|
this.#render();
|
|
913
915
|
this.#subscribeToProcessEvents();
|
|
914
916
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
917
|
+
// Only start the timer in interactive mode
|
|
918
|
+
if (this.#isInteractive) {
|
|
919
|
+
this.#timer = setInterval(() => {
|
|
920
|
+
this.#render();
|
|
921
|
+
}, this.#interval);
|
|
922
|
+
}
|
|
918
923
|
|
|
919
924
|
return this;
|
|
920
925
|
}
|
|
@@ -924,8 +929,12 @@ class YoctoSpinner {
|
|
|
924
929
|
return this;
|
|
925
930
|
}
|
|
926
931
|
|
|
927
|
-
|
|
928
|
-
this.#timer
|
|
932
|
+
this.#isSpinning = false;
|
|
933
|
+
if (this.#timer) {
|
|
934
|
+
clearInterval(this.#timer);
|
|
935
|
+
this.#timer = undefined;
|
|
936
|
+
}
|
|
937
|
+
|
|
929
938
|
this.#showCursor();
|
|
930
939
|
this.clear();
|
|
931
940
|
this.#unsubscribeFromProcessEvents();
|
|
@@ -958,7 +967,7 @@ class YoctoSpinner {
|
|
|
958
967
|
}
|
|
959
968
|
|
|
960
969
|
get isSpinning() {
|
|
961
|
-
return this.#
|
|
970
|
+
return this.#isSpinning;
|
|
962
971
|
}
|
|
963
972
|
|
|
964
973
|
get text() {
|
|
@@ -1095,11 +1104,11 @@ var MastraLogger = class {
|
|
|
1095
1104
|
}
|
|
1096
1105
|
trackException(_error) {
|
|
1097
1106
|
}
|
|
1098
|
-
async
|
|
1107
|
+
async listLogs(transportId, params) {
|
|
1099
1108
|
if (!transportId || !this.transports.has(transportId)) {
|
|
1100
1109
|
return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
|
|
1101
1110
|
}
|
|
1102
|
-
return this.transports.get(transportId).
|
|
1111
|
+
return this.transports.get(transportId).listLogs(params) ?? {
|
|
1103
1112
|
logs: [],
|
|
1104
1113
|
total: 0,
|
|
1105
1114
|
page: params?.page ?? 1,
|
|
@@ -1107,7 +1116,7 @@ var MastraLogger = class {
|
|
|
1107
1116
|
hasMore: false
|
|
1108
1117
|
};
|
|
1109
1118
|
}
|
|
1110
|
-
async
|
|
1119
|
+
async listLogsByRunId({
|
|
1111
1120
|
transportId,
|
|
1112
1121
|
runId,
|
|
1113
1122
|
fromDate,
|
|
@@ -1120,7 +1129,7 @@ var MastraLogger = class {
|
|
|
1120
1129
|
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1121
1130
|
return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
|
|
1122
1131
|
}
|
|
1123
|
-
return this.transports.get(transportId).
|
|
1132
|
+
return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
|
|
1124
1133
|
logs: [],
|
|
1125
1134
|
total: 0,
|
|
1126
1135
|
page: page ?? 1,
|
|
@@ -1178,118 +1187,8 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1178
1187
|
}
|
|
1179
1188
|
};
|
|
1180
1189
|
|
|
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
|
-
}
|
|
1190
|
+
var package_default = {
|
|
1191
|
+
version: "1.0.0-beta.3"};
|
|
1293
1192
|
function getPackageManagerAddCommand(pm) {
|
|
1294
1193
|
switch (pm) {
|
|
1295
1194
|
case "npm":
|
|
@@ -1312,11 +1211,11 @@ var DepsService = class {
|
|
|
1312
1211
|
findLockFile(dir) {
|
|
1313
1212
|
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1314
1213
|
for (const file of lockFiles) {
|
|
1315
|
-
if (fs3__default__default.existsSync(
|
|
1214
|
+
if (fs3__default__default.existsSync(path3.join(dir, file))) {
|
|
1316
1215
|
return file;
|
|
1317
1216
|
}
|
|
1318
1217
|
}
|
|
1319
|
-
const parentDir =
|
|
1218
|
+
const parentDir = path3.resolve(dir, "..");
|
|
1320
1219
|
if (parentDir !== dir) {
|
|
1321
1220
|
return this.findLockFile(parentDir);
|
|
1322
1221
|
}
|
|
@@ -1349,7 +1248,7 @@ var DepsService = class {
|
|
|
1349
1248
|
}
|
|
1350
1249
|
async checkDependencies(dependencies) {
|
|
1351
1250
|
try {
|
|
1352
|
-
const packageJsonPath =
|
|
1251
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1353
1252
|
try {
|
|
1354
1253
|
await fs4.access(packageJsonPath);
|
|
1355
1254
|
} catch {
|
|
@@ -1369,7 +1268,7 @@ var DepsService = class {
|
|
|
1369
1268
|
}
|
|
1370
1269
|
async getProjectName() {
|
|
1371
1270
|
try {
|
|
1372
|
-
const packageJsonPath =
|
|
1271
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1373
1272
|
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1374
1273
|
const pkg = JSON.parse(packageJson);
|
|
1375
1274
|
return pkg.name;
|
|
@@ -1457,8 +1356,8 @@ var FileService = class {
|
|
|
1457
1356
|
*/
|
|
1458
1357
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1459
1358
|
const __filename = fileURLToPath(import.meta.url);
|
|
1460
|
-
const __dirname =
|
|
1461
|
-
const filePath =
|
|
1359
|
+
const __dirname = path3.dirname(__filename);
|
|
1360
|
+
const filePath = path3.resolve(__dirname, "starter-files", inputFile);
|
|
1462
1361
|
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1463
1362
|
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1464
1363
|
console.info(`${outputFilePath} already exists`);
|
|
@@ -1468,7 +1367,7 @@ var FileService = class {
|
|
|
1468
1367
|
return true;
|
|
1469
1368
|
}
|
|
1470
1369
|
async setupEnvFile({ dbUrl }) {
|
|
1471
|
-
const envPath =
|
|
1370
|
+
const envPath = path3.join(process.cwd(), ".env.development");
|
|
1472
1371
|
await fsExtra.ensureFile(envPath);
|
|
1473
1372
|
const fileEnvService = new FileEnvService(envPath);
|
|
1474
1373
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
@@ -1492,21 +1391,142 @@ var FileService = class {
|
|
|
1492
1391
|
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1493
1392
|
}
|
|
1494
1393
|
};
|
|
1394
|
+
var createArgs = (versionTag) => {
|
|
1395
|
+
const packageName = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
|
|
1396
|
+
return ["-y", packageName];
|
|
1397
|
+
};
|
|
1398
|
+
var createMcpConfig = (editor, versionTag) => {
|
|
1399
|
+
const args = createArgs(versionTag);
|
|
1400
|
+
if (editor === "vscode") {
|
|
1401
|
+
return {
|
|
1402
|
+
servers: {
|
|
1403
|
+
mastra: process.platform === `win32` ? {
|
|
1404
|
+
command: "cmd",
|
|
1405
|
+
args: ["/c", "npx", ...args],
|
|
1406
|
+
type: "stdio"
|
|
1407
|
+
} : {
|
|
1408
|
+
command: "npx",
|
|
1409
|
+
args,
|
|
1410
|
+
type: "stdio"
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
return {
|
|
1416
|
+
mcpServers: {
|
|
1417
|
+
mastra: {
|
|
1418
|
+
command: "npx",
|
|
1419
|
+
args
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
};
|
|
1424
|
+
function makeConfig(original, editor, versionTag) {
|
|
1425
|
+
if (editor === "vscode") {
|
|
1426
|
+
return {
|
|
1427
|
+
...original,
|
|
1428
|
+
servers: {
|
|
1429
|
+
...original?.servers || {},
|
|
1430
|
+
...createMcpConfig(editor, versionTag).servers
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1434
|
+
return {
|
|
1435
|
+
...original,
|
|
1436
|
+
mcpServers: {
|
|
1437
|
+
...original?.mcpServers || {},
|
|
1438
|
+
...createMcpConfig(editor, versionTag).mcpServers
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
async function writeMergedConfig(configPath, editor, versionTag) {
|
|
1443
|
+
const configExists = existsSync(configPath);
|
|
1444
|
+
const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor, versionTag);
|
|
1445
|
+
await ensureFile(configPath);
|
|
1446
|
+
await writeJSON(configPath, config, {
|
|
1447
|
+
spaces: 2
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1451
|
+
var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
|
|
1452
|
+
path3.join(process.cwd(), ".vscode", "mcp.json");
|
|
1453
|
+
var vscodeGlobalMCPConfigPath = path3.join(
|
|
1454
|
+
os.homedir(),
|
|
1455
|
+
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")
|
|
1456
|
+
);
|
|
1457
|
+
async function installMastraDocsMCPServer({
|
|
1458
|
+
editor,
|
|
1459
|
+
directory,
|
|
1460
|
+
versionTag
|
|
1461
|
+
}) {
|
|
1462
|
+
if (editor === `cursor`) {
|
|
1463
|
+
await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor", versionTag);
|
|
1464
|
+
}
|
|
1465
|
+
if (editor === `vscode`) {
|
|
1466
|
+
await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode", versionTag);
|
|
1467
|
+
}
|
|
1468
|
+
if (editor === `cursor-global`) {
|
|
1469
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
|
|
1470
|
+
if (alreadyInstalled) {
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global", versionTag);
|
|
1474
|
+
}
|
|
1475
|
+
if (editor === `windsurf`) {
|
|
1476
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor, versionTag);
|
|
1477
|
+
if (alreadyInstalled) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
await writeMergedConfig(windsurfGlobalMCPConfigPath, editor, versionTag);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
async function globalMCPIsAlreadyInstalled(editor, versionTag) {
|
|
1484
|
+
let configPath = ``;
|
|
1485
|
+
if (editor === "windsurf") {
|
|
1486
|
+
configPath = windsurfGlobalMCPConfigPath;
|
|
1487
|
+
} else if (editor === "cursor-global") {
|
|
1488
|
+
configPath = cursorGlobalMCPConfigPath;
|
|
1489
|
+
} else if (editor === "vscode") {
|
|
1490
|
+
configPath = vscodeGlobalMCPConfigPath;
|
|
1491
|
+
}
|
|
1492
|
+
if (!configPath || !existsSync(configPath)) {
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
try {
|
|
1496
|
+
const configContents = await readJSON(configPath);
|
|
1497
|
+
if (!configContents) return false;
|
|
1498
|
+
const expectedPackage = versionTag ? `@mastra/mcp-docs-server@${versionTag}` : "@mastra/mcp-docs-server";
|
|
1499
|
+
if (editor === "vscode") {
|
|
1500
|
+
if (!configContents.servers) return false;
|
|
1501
|
+
const hasMastraMCP2 = Object.values(configContents.servers).some(
|
|
1502
|
+
(server) => server?.args?.find((arg) => arg === expectedPackage)
|
|
1503
|
+
);
|
|
1504
|
+
return hasMastraMCP2;
|
|
1505
|
+
}
|
|
1506
|
+
if (!configContents?.mcpServers) return false;
|
|
1507
|
+
const hasMastraMCP = Object.values(configContents.mcpServers).some(
|
|
1508
|
+
(server) => server?.args?.find((arg) => arg === expectedPackage)
|
|
1509
|
+
);
|
|
1510
|
+
return hasMastraMCP;
|
|
1511
|
+
} catch {
|
|
1512
|
+
return false;
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1495
1515
|
var exec = util.promisify(child_process.exec);
|
|
1496
1516
|
var getModelIdentifier = (llmProvider) => {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
return `'anthropic/claude-sonnet-4-5-20250929'`;
|
|
1517
|
+
let model = "openai/gpt-4o";
|
|
1518
|
+
if (llmProvider === "anthropic") {
|
|
1519
|
+
model = "anthropic/claude-sonnet-4-5";
|
|
1501
1520
|
} else if (llmProvider === "groq") {
|
|
1502
|
-
|
|
1521
|
+
model = "groq/llama-3.3-70b-versatile";
|
|
1503
1522
|
} else if (llmProvider === "google") {
|
|
1504
|
-
|
|
1523
|
+
model = "google/gemini-2.5-pro";
|
|
1505
1524
|
} else if (llmProvider === "cerebras") {
|
|
1506
|
-
|
|
1525
|
+
model = "cerebras/llama-3.3-70b";
|
|
1507
1526
|
} else if (llmProvider === "mistral") {
|
|
1508
|
-
|
|
1527
|
+
model = "mistral/mistral-medium-2508";
|
|
1509
1528
|
}
|
|
1529
|
+
return model;
|
|
1510
1530
|
};
|
|
1511
1531
|
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1512
1532
|
const modelString = getModelIdentifier(llmProvider);
|
|
@@ -1532,9 +1552,10 @@ ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
|
1532
1552
|
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1533
1553
|
|
|
1534
1554
|
export const weatherAgent = new Agent({
|
|
1555
|
+
id: 'weather-agent',
|
|
1535
1556
|
name: 'Weather Agent',
|
|
1536
1557
|
instructions: \`${instructions}\`,
|
|
1537
|
-
model: ${modelString},
|
|
1558
|
+
model: '${modelString}',
|
|
1538
1559
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1539
1560
|
${addScorers ? `scorers: {
|
|
1540
1561
|
toolCallAppropriateness: {
|
|
@@ -1561,6 +1582,7 @@ export const weatherAgent = new Agent({
|
|
|
1561
1582
|
},` : ""}
|
|
1562
1583
|
memory: new Memory({
|
|
1563
1584
|
storage: new LibSQLStore({
|
|
1585
|
+
id: "memory-storage",
|
|
1564
1586
|
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1565
1587
|
})
|
|
1566
1588
|
})
|
|
@@ -1773,9 +1795,10 @@ async function writeToolSample(destPath) {
|
|
|
1773
1795
|
async function writeScorersSample(llmProvider, destPath) {
|
|
1774
1796
|
const modelString = getModelIdentifier(llmProvider);
|
|
1775
1797
|
const content = `import { z } from 'zod';
|
|
1776
|
-
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/
|
|
1777
|
-
import { createCompletenessScorer } from '@mastra/evals/scorers/
|
|
1778
|
-
import {
|
|
1798
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
1799
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
|
|
1800
|
+
import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
1801
|
+
import { createScorer } from '@mastra/core/evals';
|
|
1779
1802
|
|
|
1780
1803
|
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1781
1804
|
expectedTool: 'weatherTool',
|
|
@@ -1786,11 +1809,12 @@ export const completenessScorer = createCompletenessScorer();
|
|
|
1786
1809
|
|
|
1787
1810
|
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1788
1811
|
export const translationScorer = createScorer({
|
|
1812
|
+
id: 'translation-quality-scorer',
|
|
1789
1813
|
name: 'Translation Quality',
|
|
1790
1814
|
description: 'Checks that non-English location names are translated and used correctly',
|
|
1791
1815
|
type: 'agent',
|
|
1792
1816
|
judge: {
|
|
1793
|
-
model: ${modelString},
|
|
1817
|
+
model: '${modelString}',
|
|
1794
1818
|
instructions:
|
|
1795
1819
|
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1796
1820
|
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
@@ -1799,8 +1823,8 @@ export const translationScorer = createScorer({
|
|
|
1799
1823
|
},
|
|
1800
1824
|
})
|
|
1801
1825
|
.preprocess(({ run }) => {
|
|
1802
|
-
const userText = (run.input
|
|
1803
|
-
const assistantText = (run.output
|
|
1826
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1827
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1804
1828
|
return { userText, assistantText };
|
|
1805
1829
|
})
|
|
1806
1830
|
.analyze({
|
|
@@ -1887,7 +1911,7 @@ var writeIndexFile = async ({
|
|
|
1887
1911
|
addScorers
|
|
1888
1912
|
}) => {
|
|
1889
1913
|
const indexPath = dirPath + "/index.ts";
|
|
1890
|
-
const destPath =
|
|
1914
|
+
const destPath = path3.join(indexPath);
|
|
1891
1915
|
try {
|
|
1892
1916
|
await fs4.writeFile(destPath, "");
|
|
1893
1917
|
const filteredExports = [
|
|
@@ -1899,7 +1923,7 @@ var writeIndexFile = async ({
|
|
|
1899
1923
|
await fs4.writeFile(
|
|
1900
1924
|
destPath,
|
|
1901
1925
|
`
|
|
1902
|
-
import { Mastra } from '@mastra/core';
|
|
1926
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1903
1927
|
|
|
1904
1928
|
export const mastra = new Mastra()
|
|
1905
1929
|
`
|
|
@@ -1912,6 +1936,7 @@ export const mastra = new Mastra()
|
|
|
1912
1936
|
import { Mastra } from '@mastra/core/mastra';
|
|
1913
1937
|
import { PinoLogger } from '@mastra/loggers';
|
|
1914
1938
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1939
|
+
import { Observability } from '@mastra/observability';
|
|
1915
1940
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1916
1941
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1917
1942
|
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
@@ -1919,6 +1944,7 @@ ${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, tran
|
|
|
1919
1944
|
export const mastra = new Mastra({
|
|
1920
1945
|
${filteredExports.join("\n ")}
|
|
1921
1946
|
storage: new LibSQLStore({
|
|
1947
|
+
id: "mastra-storage",
|
|
1922
1948
|
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1923
1949
|
url: ":memory:",
|
|
1924
1950
|
}),
|
|
@@ -1926,10 +1952,10 @@ export const mastra = new Mastra({
|
|
|
1926
1952
|
name: 'Mastra',
|
|
1927
1953
|
level: 'info',
|
|
1928
1954
|
}),
|
|
1929
|
-
observability: {
|
|
1930
|
-
// Enables DefaultExporter and CloudExporter for
|
|
1955
|
+
observability: new Observability({
|
|
1956
|
+
// Enables DefaultExporter and CloudExporter for tracing
|
|
1931
1957
|
default: { enabled: true },
|
|
1932
|
-
|
|
1958
|
+
}),
|
|
1933
1959
|
});
|
|
1934
1960
|
`
|
|
1935
1961
|
);
|
|
@@ -1968,7 +1994,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
|
|
|
1968
1994
|
};
|
|
1969
1995
|
var createMastraDir = async (directory) => {
|
|
1970
1996
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1971
|
-
const dirPath =
|
|
1997
|
+
const dirPath = path3.join(process.cwd(), ...dir, "mastra");
|
|
1972
1998
|
try {
|
|
1973
1999
|
await fs4.access(dirPath);
|
|
1974
2000
|
return { ok: false };
|
|
@@ -1993,8 +2019,8 @@ var LLM_PROVIDERS = [
|
|
|
1993
2019
|
{ value: "cerebras", label: "Cerebras" },
|
|
1994
2020
|
{ value: "mistral", label: "Mistral" }
|
|
1995
2021
|
];
|
|
1996
|
-
var interactivePrompt = async (
|
|
1997
|
-
const { skip = {}, options: { showBanner = true } = {} } =
|
|
2022
|
+
var interactivePrompt = async (args = {}) => {
|
|
2023
|
+
const { skip = {}, options: { showBanner = true } = {} } = args;
|
|
1998
2024
|
if (showBanner) {
|
|
1999
2025
|
Ie(color2.inverse(" Mastra Init "));
|
|
2000
2026
|
}
|
|
@@ -2032,46 +2058,29 @@ var interactivePrompt = async (args2 = {}) => {
|
|
|
2032
2058
|
return void 0;
|
|
2033
2059
|
},
|
|
2034
2060
|
configureEditorWithDocsMCP: async () => {
|
|
2035
|
-
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
2036
|
-
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2037
|
-
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2038
2061
|
const editor = await ve({
|
|
2039
2062
|
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2040
2063
|
options: [
|
|
2041
2064
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2042
2065
|
{
|
|
2043
2066
|
value: "cursor",
|
|
2044
|
-
label: "Cursor (project only)"
|
|
2045
|
-
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
2067
|
+
label: "Cursor (project only)"
|
|
2046
2068
|
},
|
|
2047
2069
|
{
|
|
2048
2070
|
value: "cursor-global",
|
|
2049
|
-
label: "Cursor (global, all projects)"
|
|
2050
|
-
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
2071
|
+
label: "Cursor (global, all projects)"
|
|
2051
2072
|
},
|
|
2052
2073
|
{
|
|
2053
2074
|
value: "windsurf",
|
|
2054
|
-
label: "Windsurf"
|
|
2055
|
-
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
2075
|
+
label: "Windsurf"
|
|
2056
2076
|
},
|
|
2057
2077
|
{
|
|
2058
2078
|
value: "vscode",
|
|
2059
|
-
label: "VSCode"
|
|
2060
|
-
hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
|
|
2079
|
+
label: "VSCode"
|
|
2061
2080
|
}
|
|
2062
2081
|
]
|
|
2063
2082
|
});
|
|
2064
2083
|
if (editor === `skip`) return void 0;
|
|
2065
|
-
if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
|
|
2066
|
-
M.message(`
|
|
2067
|
-
Windsurf is already installed, skipping.`);
|
|
2068
|
-
return void 0;
|
|
2069
|
-
}
|
|
2070
|
-
if (editor === `vscode` && vscodeIsAlreadyInstalled) {
|
|
2071
|
-
M.message(`
|
|
2072
|
-
VSCode is already installed, skipping.`);
|
|
2073
|
-
return void 0;
|
|
2074
|
-
}
|
|
2075
2084
|
if (editor === `cursor`) {
|
|
2076
2085
|
M.message(
|
|
2077
2086
|
`
|
|
@@ -2119,6 +2128,9 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2119
2128
|
function getPackageManager() {
|
|
2120
2129
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
2121
2130
|
const execPath = process.env.npm_execpath || "";
|
|
2131
|
+
if (userAgent.includes("bun")) {
|
|
2132
|
+
return "bun";
|
|
2133
|
+
}
|
|
2122
2134
|
if (userAgent.includes("yarn")) {
|
|
2123
2135
|
return "yarn";
|
|
2124
2136
|
}
|
|
@@ -2128,6 +2140,9 @@ function getPackageManager() {
|
|
|
2128
2140
|
if (userAgent.includes("npm")) {
|
|
2129
2141
|
return "npm";
|
|
2130
2142
|
}
|
|
2143
|
+
if (execPath.includes("bun")) {
|
|
2144
|
+
return "bun";
|
|
2145
|
+
}
|
|
2131
2146
|
if (execPath.includes("yarn")) {
|
|
2132
2147
|
return "yarn";
|
|
2133
2148
|
}
|
|
@@ -2148,19 +2163,23 @@ function createLogger(debug = false) {
|
|
|
2148
2163
|
}
|
|
2149
2164
|
var exec2 = util.promisify(child_process.exec);
|
|
2150
2165
|
async function cloneTemplate(options) {
|
|
2151
|
-
const { template, projectName, targetDir } = options;
|
|
2152
|
-
const projectPath = targetDir ?
|
|
2166
|
+
const { template, projectName, targetDir, branch, llmProvider } = options;
|
|
2167
|
+
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
2153
2168
|
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2154
2169
|
try {
|
|
2155
2170
|
if (await directoryExists(projectPath)) {
|
|
2156
2171
|
spinner4.error(`Directory ${projectName} already exists`);
|
|
2157
2172
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2158
2173
|
}
|
|
2159
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2174
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
|
|
2160
2175
|
await updatePackageJson(projectPath, projectName);
|
|
2161
|
-
const envExamplePath =
|
|
2176
|
+
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
2162
2177
|
if (await fileExists(envExamplePath)) {
|
|
2163
|
-
|
|
2178
|
+
const envPath = path3.join(projectPath, ".env");
|
|
2179
|
+
await fs4.copyFile(envExamplePath, envPath);
|
|
2180
|
+
if (llmProvider) {
|
|
2181
|
+
await updateEnvFile(envPath, llmProvider);
|
|
2182
|
+
}
|
|
2164
2183
|
}
|
|
2165
2184
|
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2166
2185
|
return projectPath;
|
|
@@ -2185,21 +2204,27 @@ async function fileExists(filePath) {
|
|
|
2185
2204
|
return false;
|
|
2186
2205
|
}
|
|
2187
2206
|
}
|
|
2188
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2207
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
|
|
2189
2208
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
2190
2209
|
try {
|
|
2191
2210
|
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2192
|
-
const
|
|
2211
|
+
const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
|
|
2212
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
|
|
2193
2213
|
await exec2(degitCommand, {
|
|
2194
2214
|
cwd: process.cwd()
|
|
2195
2215
|
});
|
|
2196
2216
|
} catch {
|
|
2197
2217
|
try {
|
|
2198
|
-
const
|
|
2218
|
+
const gitArgs = ["git", "clone"];
|
|
2219
|
+
if (branch) {
|
|
2220
|
+
gitArgs.push("--branch", branch);
|
|
2221
|
+
}
|
|
2222
|
+
gitArgs.push(repoUrl, targetPath);
|
|
2223
|
+
const gitCommand = shellQuote2.quote(gitArgs);
|
|
2199
2224
|
await exec2(gitCommand, {
|
|
2200
2225
|
cwd: process.cwd()
|
|
2201
2226
|
});
|
|
2202
|
-
const gitDir =
|
|
2227
|
+
const gitDir = path3.join(targetPath, ".git");
|
|
2203
2228
|
if (await directoryExists(gitDir)) {
|
|
2204
2229
|
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2205
2230
|
}
|
|
@@ -2209,7 +2234,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
|
2209
2234
|
}
|
|
2210
2235
|
}
|
|
2211
2236
|
async function updatePackageJson(projectPath, projectName) {
|
|
2212
|
-
const packageJsonPath =
|
|
2237
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
2213
2238
|
try {
|
|
2214
2239
|
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2215
2240
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -2219,6 +2244,22 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2219
2244
|
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2220
2245
|
}
|
|
2221
2246
|
}
|
|
2247
|
+
async function updateEnvFile(envPath, llmProvider) {
|
|
2248
|
+
try {
|
|
2249
|
+
const envContent = await fs4.readFile(envPath, "utf-8");
|
|
2250
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
2251
|
+
if (!modelString) {
|
|
2252
|
+
logger.warn(`Could not get model identifier for provider: ${llmProvider}`);
|
|
2253
|
+
return;
|
|
2254
|
+
}
|
|
2255
|
+
const modelValue = modelString.replace(/'/g, "");
|
|
2256
|
+
const updatedContent = envContent.replace(/^MODEL=.*/m, `MODEL=${modelValue}`);
|
|
2257
|
+
await fs4.writeFile(envPath, updatedContent, "utf-8");
|
|
2258
|
+
logger.info(`Updated MODEL in .env to ${modelValue}`);
|
|
2259
|
+
} catch (error) {
|
|
2260
|
+
logger.warn(`Could not update .env file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2222
2263
|
async function installDependencies(projectPath, packageManager) {
|
|
2223
2264
|
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2224
2265
|
try {
|
|
@@ -2303,9 +2344,11 @@ var init = async ({
|
|
|
2303
2344
|
llmProvider = "openai",
|
|
2304
2345
|
llmApiKey,
|
|
2305
2346
|
addExample = false,
|
|
2306
|
-
configureEditorWithDocsMCP
|
|
2347
|
+
configureEditorWithDocsMCP,
|
|
2348
|
+
versionTag
|
|
2307
2349
|
}) => {
|
|
2308
2350
|
s.start("Initializing Mastra");
|
|
2351
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2309
2352
|
try {
|
|
2310
2353
|
const result = await createMastraDir(directory);
|
|
2311
2354
|
if (!result.ok) {
|
|
@@ -2333,30 +2376,31 @@ var init = async ({
|
|
|
2333
2376
|
const depService = new DepsService();
|
|
2334
2377
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2335
2378
|
if (needsLibsql) {
|
|
2336
|
-
await depService.installPackages([
|
|
2379
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2337
2380
|
}
|
|
2338
2381
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2339
2382
|
if (needsMemory) {
|
|
2340
|
-
await depService.installPackages([
|
|
2383
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2341
2384
|
}
|
|
2342
2385
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2343
2386
|
if (needsLoggers) {
|
|
2344
|
-
await depService.installPackages([
|
|
2387
|
+
await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
|
|
2345
2388
|
}
|
|
2346
2389
|
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2347
2390
|
if (needsObservability) {
|
|
2348
|
-
await depService.installPackages([
|
|
2391
|
+
await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
|
|
2349
2392
|
}
|
|
2350
2393
|
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2351
2394
|
if (needsEvals) {
|
|
2352
|
-
await depService.installPackages([
|
|
2395
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2353
2396
|
}
|
|
2354
2397
|
}
|
|
2355
2398
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2356
2399
|
if (configureEditorWithDocsMCP) {
|
|
2357
2400
|
await installMastraDocsMCPServer({
|
|
2358
2401
|
editor: configureEditorWithDocsMCP,
|
|
2359
|
-
directory: process.cwd()
|
|
2402
|
+
directory: process.cwd(),
|
|
2403
|
+
versionTag
|
|
2360
2404
|
});
|
|
2361
2405
|
}
|
|
2362
2406
|
s.stop();
|
|
@@ -2405,6 +2449,32 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2405
2449
|
throw error;
|
|
2406
2450
|
}
|
|
2407
2451
|
};
|
|
2452
|
+
async function getInitCommand(pm) {
|
|
2453
|
+
switch (pm) {
|
|
2454
|
+
case "npm":
|
|
2455
|
+
return "npm init -y";
|
|
2456
|
+
case "pnpm":
|
|
2457
|
+
return "pnpm init";
|
|
2458
|
+
case "yarn":
|
|
2459
|
+
return "yarn init -y";
|
|
2460
|
+
case "bun":
|
|
2461
|
+
return "bun init -y";
|
|
2462
|
+
default:
|
|
2463
|
+
return "npm init -y";
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
async function initializePackageJson(pm) {
|
|
2467
|
+
const initCommand = await getInitCommand(pm);
|
|
2468
|
+
await exec3(initCommand);
|
|
2469
|
+
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
2470
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
2471
|
+
packageJson.type = "module";
|
|
2472
|
+
packageJson.engines = {
|
|
2473
|
+
...packageJson.engines,
|
|
2474
|
+
node: ">=22.13.0"
|
|
2475
|
+
};
|
|
2476
|
+
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
2477
|
+
}
|
|
2408
2478
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2409
2479
|
let installCommand = getPackageManagerAddCommand(pm);
|
|
2410
2480
|
if (isDev) {
|
|
@@ -2459,10 +2529,13 @@ var createMastraProject = async ({
|
|
|
2459
2529
|
});
|
|
2460
2530
|
}
|
|
2461
2531
|
const s2 = Y();
|
|
2532
|
+
const originalCwd = process.cwd();
|
|
2533
|
+
let projectPath = null;
|
|
2462
2534
|
try {
|
|
2463
2535
|
s2.start("Creating project");
|
|
2464
2536
|
try {
|
|
2465
2537
|
await fs4.mkdir(projectName);
|
|
2538
|
+
projectPath = path3.resolve(originalCwd, projectName);
|
|
2466
2539
|
} catch (error) {
|
|
2467
2540
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2468
2541
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2477,9 +2550,7 @@ var createMastraProject = async ({
|
|
|
2477
2550
|
const installCommand = getPackageManagerAddCommand(pm);
|
|
2478
2551
|
s2.message("Initializing project structure");
|
|
2479
2552
|
try {
|
|
2480
|
-
await
|
|
2481
|
-
await exec3(`npm pkg set type="module"`);
|
|
2482
|
-
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
2553
|
+
await initializePackageJson(pm);
|
|
2483
2554
|
const depsService = new DepsService();
|
|
2484
2555
|
await depsService.addScriptsToPackageJson({
|
|
2485
2556
|
dev: "mastra dev",
|
|
@@ -2495,7 +2566,7 @@ var createMastraProject = async ({
|
|
|
2495
2566
|
s2.start(`Installing ${pm} dependencies`);
|
|
2496
2567
|
try {
|
|
2497
2568
|
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2498
|
-
await exec3(`${pm} ${installCommand} typescript @types/node
|
|
2569
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2499
2570
|
await exec3(`echo '{
|
|
2500
2571
|
"compilerOptions": {
|
|
2501
2572
|
"target": "ES2022",
|
|
@@ -2558,42 +2629,61 @@ var createMastraProject = async ({
|
|
|
2558
2629
|
s2.stop();
|
|
2559
2630
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
2560
2631
|
xe(`Project creation failed: ${errorMessage}`);
|
|
2632
|
+
if (projectPath && fs3__default__default.existsSync(projectPath)) {
|
|
2633
|
+
try {
|
|
2634
|
+
process.chdir(originalCwd);
|
|
2635
|
+
await fs4.rm(projectPath, { recursive: true, force: true });
|
|
2636
|
+
} catch (cleanupError) {
|
|
2637
|
+
console.error(
|
|
2638
|
+
`Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
|
|
2639
|
+
);
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2561
2642
|
process.exit(1);
|
|
2562
2643
|
}
|
|
2563
2644
|
};
|
|
2564
|
-
var
|
|
2565
|
-
|
|
2566
|
-
|
|
2645
|
+
var version$1 = package_default.version;
|
|
2646
|
+
var create = async (args) => {
|
|
2647
|
+
if (args.template !== void 0) {
|
|
2648
|
+
await createFromTemplate({
|
|
2649
|
+
projectName: args.projectName,
|
|
2650
|
+
template: args.template,
|
|
2651
|
+
timeout: args.timeout,
|
|
2652
|
+
injectedAnalytics: args.analytics,
|
|
2653
|
+
llmProvider: args.llmProvider
|
|
2654
|
+
});
|
|
2567
2655
|
return;
|
|
2568
2656
|
}
|
|
2569
|
-
const needsInteractive =
|
|
2657
|
+
const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
|
|
2570
2658
|
const { projectName, result } = await createMastraProject({
|
|
2571
|
-
projectName:
|
|
2572
|
-
createVersionTag:
|
|
2573
|
-
timeout:
|
|
2574
|
-
llmProvider:
|
|
2575
|
-
llmApiKey:
|
|
2659
|
+
projectName: args?.projectName,
|
|
2660
|
+
createVersionTag: args?.createVersionTag,
|
|
2661
|
+
timeout: args?.timeout,
|
|
2662
|
+
llmProvider: args?.llmProvider,
|
|
2663
|
+
llmApiKey: args?.llmApiKey,
|
|
2576
2664
|
needsInteractive
|
|
2577
2665
|
});
|
|
2578
|
-
const directory =
|
|
2666
|
+
const directory = args.directory || "src/";
|
|
2579
2667
|
if (needsInteractive && result) {
|
|
2580
2668
|
await init({
|
|
2581
2669
|
...result,
|
|
2582
2670
|
llmApiKey: result?.llmApiKey,
|
|
2583
2671
|
components: ["agents", "tools", "workflows", "scorers"],
|
|
2584
|
-
addExample: true
|
|
2672
|
+
addExample: true,
|
|
2673
|
+
versionTag: args.createVersionTag
|
|
2585
2674
|
});
|
|
2586
2675
|
postCreate({ projectName });
|
|
2587
2676
|
return;
|
|
2588
2677
|
}
|
|
2589
|
-
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } =
|
|
2678
|
+
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
|
|
2590
2679
|
await init({
|
|
2591
2680
|
directory,
|
|
2592
2681
|
components,
|
|
2593
2682
|
llmProvider,
|
|
2594
2683
|
addExample,
|
|
2595
2684
|
llmApiKey,
|
|
2596
|
-
configureEditorWithDocsMCP:
|
|
2685
|
+
configureEditorWithDocsMCP: args.mcpServer,
|
|
2686
|
+
versionTag: args.createVersionTag
|
|
2597
2687
|
});
|
|
2598
2688
|
postCreate({ projectName });
|
|
2599
2689
|
};
|
|
@@ -2684,9 +2774,9 @@ async function createFromGitHubUrl(url) {
|
|
|
2684
2774
|
workflows: []
|
|
2685
2775
|
};
|
|
2686
2776
|
}
|
|
2687
|
-
async function createFromTemplate(
|
|
2777
|
+
async function createFromTemplate(args) {
|
|
2688
2778
|
let selectedTemplate;
|
|
2689
|
-
if (
|
|
2779
|
+
if (args.template === true) {
|
|
2690
2780
|
const templates = await loadTemplates();
|
|
2691
2781
|
const selected = await selectTemplate(templates);
|
|
2692
2782
|
if (!selected) {
|
|
@@ -2694,11 +2784,11 @@ async function createFromTemplate(args2) {
|
|
|
2694
2784
|
return;
|
|
2695
2785
|
}
|
|
2696
2786
|
selectedTemplate = selected;
|
|
2697
|
-
} else if (
|
|
2698
|
-
if (isGitHubUrl(
|
|
2787
|
+
} else if (args.template && typeof args.template === "string") {
|
|
2788
|
+
if (isGitHubUrl(args.template)) {
|
|
2699
2789
|
const spinner4 = Y();
|
|
2700
2790
|
spinner4.start("Validating GitHub repository...");
|
|
2701
|
-
const validation = await validateGitHubProject(
|
|
2791
|
+
const validation = await validateGitHubProject(args.template);
|
|
2702
2792
|
if (!validation.isValid) {
|
|
2703
2793
|
spinner4.stop("Validation failed");
|
|
2704
2794
|
M.error("This does not appear to be a valid Mastra project:");
|
|
@@ -2706,14 +2796,14 @@ async function createFromTemplate(args2) {
|
|
|
2706
2796
|
throw new Error("Invalid Mastra project");
|
|
2707
2797
|
}
|
|
2708
2798
|
spinner4.stop("Valid Mastra project \u2713");
|
|
2709
|
-
selectedTemplate = await createFromGitHubUrl(
|
|
2799
|
+
selectedTemplate = await createFromGitHubUrl(args.template);
|
|
2710
2800
|
} else {
|
|
2711
2801
|
const templates = await loadTemplates();
|
|
2712
|
-
const found = findTemplateByName(templates,
|
|
2802
|
+
const found = findTemplateByName(templates, args.template);
|
|
2713
2803
|
if (!found) {
|
|
2714
|
-
M.error(`Template "${
|
|
2804
|
+
M.error(`Template "${args.template}" not found. Available templates:`);
|
|
2715
2805
|
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2716
|
-
throw new Error(`Template "${
|
|
2806
|
+
throw new Error(`Template "${args.template}" not found`);
|
|
2717
2807
|
}
|
|
2718
2808
|
selectedTemplate = found;
|
|
2719
2809
|
}
|
|
@@ -2721,7 +2811,7 @@ async function createFromTemplate(args2) {
|
|
|
2721
2811
|
if (!selectedTemplate) {
|
|
2722
2812
|
throw new Error("No template selected");
|
|
2723
2813
|
}
|
|
2724
|
-
let projectName =
|
|
2814
|
+
let projectName = args.projectName;
|
|
2725
2815
|
if (!projectName) {
|
|
2726
2816
|
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2727
2817
|
const response = await he({
|
|
@@ -2735,17 +2825,41 @@ async function createFromTemplate(args2) {
|
|
|
2735
2825
|
}
|
|
2736
2826
|
projectName = response;
|
|
2737
2827
|
}
|
|
2828
|
+
let llmProvider = args.llmProvider;
|
|
2829
|
+
if (!llmProvider) {
|
|
2830
|
+
const providerResponse = await ve({
|
|
2831
|
+
message: "Select a default provider:",
|
|
2832
|
+
options: LLM_PROVIDERS
|
|
2833
|
+
});
|
|
2834
|
+
if (pD(providerResponse)) {
|
|
2835
|
+
M.info("Project creation cancelled.");
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
llmProvider = providerResponse;
|
|
2839
|
+
}
|
|
2840
|
+
let projectPath = null;
|
|
2738
2841
|
try {
|
|
2739
|
-
const analytics =
|
|
2842
|
+
const analytics = args.injectedAnalytics || getAnalytics();
|
|
2740
2843
|
if (analytics) {
|
|
2741
2844
|
analytics.trackEvent("cli_template_used", {
|
|
2742
2845
|
template_slug: selectedTemplate.slug,
|
|
2743
2846
|
template_title: selectedTemplate.title
|
|
2744
2847
|
});
|
|
2848
|
+
if (llmProvider) {
|
|
2849
|
+
analytics.trackEvent("cli_model_provider_selected", {
|
|
2850
|
+
provider: llmProvider,
|
|
2851
|
+
selection_method: args.llmProvider ? "cli_args" : "interactive"
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2745
2854
|
}
|
|
2746
|
-
const
|
|
2855
|
+
const isBeta = version$1?.includes("beta") ?? false;
|
|
2856
|
+
const isMastraTemplate = selectedTemplate.githubUrl.includes("github.com/mastra-ai/");
|
|
2857
|
+
const branch = isBeta && isMastraTemplate ? "beta" : void 0;
|
|
2858
|
+
projectPath = await cloneTemplate({
|
|
2747
2859
|
template: selectedTemplate,
|
|
2748
|
-
projectName
|
|
2860
|
+
projectName,
|
|
2861
|
+
branch,
|
|
2862
|
+
llmProvider
|
|
2749
2863
|
});
|
|
2750
2864
|
await installDependencies(projectPath);
|
|
2751
2865
|
Me(`
|
|
@@ -2756,6 +2870,17 @@ async function createFromTemplate(args2) {
|
|
|
2756
2870
|
`);
|
|
2757
2871
|
postCreate({ projectName });
|
|
2758
2872
|
} catch (error) {
|
|
2873
|
+
if (projectPath) {
|
|
2874
|
+
try {
|
|
2875
|
+
if (fs3__default__default.existsSync(projectPath)) {
|
|
2876
|
+
await fs4.rm(projectPath, { recursive: true, force: true });
|
|
2877
|
+
}
|
|
2878
|
+
} catch (cleanupError) {
|
|
2879
|
+
console.error(
|
|
2880
|
+
`Warning: Failed to clean up project directory: ${cleanupError instanceof Error ? cleanupError.message : "Unknown error"}`
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2759
2884
|
M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2760
2885
|
throw error;
|
|
2761
2886
|
}
|
|
@@ -2764,7 +2889,7 @@ async function createFromTemplate(args2) {
|
|
|
2764
2889
|
async function getPackageVersion() {
|
|
2765
2890
|
const __filename = fileURLToPath(import.meta.url);
|
|
2766
2891
|
const __dirname = dirname(__filename);
|
|
2767
|
-
const pkgJsonPath =
|
|
2892
|
+
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
2768
2893
|
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2769
2894
|
return content.version;
|
|
2770
2895
|
}
|