create-mastra 1.0.0-beta.1 → 1.0.0-beta.3
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 +20 -0
- package/dist/index.js +322 -207
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
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() {
|
|
@@ -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);
|
|
@@ -1535,7 +1555,7 @@ export const weatherAgent = new Agent({
|
|
|
1535
1555
|
id: 'weather-agent',
|
|
1536
1556
|
name: 'Weather Agent',
|
|
1537
1557
|
instructions: \`${instructions}\`,
|
|
1538
|
-
model: ${modelString},
|
|
1558
|
+
model: '${modelString}',
|
|
1539
1559
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1540
1560
|
${addScorers ? `scorers: {
|
|
1541
1561
|
toolCallAppropriateness: {
|
|
@@ -1794,7 +1814,7 @@ export const translationScorer = createScorer({
|
|
|
1794
1814
|
description: 'Checks that non-English location names are translated and used correctly',
|
|
1795
1815
|
type: 'agent',
|
|
1796
1816
|
judge: {
|
|
1797
|
-
model: ${modelString},
|
|
1817
|
+
model: '${modelString}',
|
|
1798
1818
|
instructions:
|
|
1799
1819
|
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1800
1820
|
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
@@ -1891,7 +1911,7 @@ var writeIndexFile = async ({
|
|
|
1891
1911
|
addScorers
|
|
1892
1912
|
}) => {
|
|
1893
1913
|
const indexPath = dirPath + "/index.ts";
|
|
1894
|
-
const destPath =
|
|
1914
|
+
const destPath = path3.join(indexPath);
|
|
1895
1915
|
try {
|
|
1896
1916
|
await fs4.writeFile(destPath, "");
|
|
1897
1917
|
const filteredExports = [
|
|
@@ -1974,7 +1994,7 @@ var writeAPIKey = async ({ provider, apiKey }) => {
|
|
|
1974
1994
|
};
|
|
1975
1995
|
var createMastraDir = async (directory) => {
|
|
1976
1996
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1977
|
-
const dirPath =
|
|
1997
|
+
const dirPath = path3.join(process.cwd(), ...dir, "mastra");
|
|
1978
1998
|
try {
|
|
1979
1999
|
await fs4.access(dirPath);
|
|
1980
2000
|
return { ok: false };
|
|
@@ -1999,8 +2019,8 @@ var LLM_PROVIDERS = [
|
|
|
1999
2019
|
{ value: "cerebras", label: "Cerebras" },
|
|
2000
2020
|
{ value: "mistral", label: "Mistral" }
|
|
2001
2021
|
];
|
|
2002
|
-
var interactivePrompt = async (
|
|
2003
|
-
const { skip = {}, options: { showBanner = true } = {} } =
|
|
2022
|
+
var interactivePrompt = async (args = {}) => {
|
|
2023
|
+
const { skip = {}, options: { showBanner = true } = {} } = args;
|
|
2004
2024
|
if (showBanner) {
|
|
2005
2025
|
Ie(color2.inverse(" Mastra Init "));
|
|
2006
2026
|
}
|
|
@@ -2038,46 +2058,29 @@ var interactivePrompt = async (args2 = {}) => {
|
|
|
2038
2058
|
return void 0;
|
|
2039
2059
|
},
|
|
2040
2060
|
configureEditorWithDocsMCP: async () => {
|
|
2041
|
-
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
2042
|
-
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2043
|
-
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2044
2061
|
const editor = await ve({
|
|
2045
2062
|
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2046
2063
|
options: [
|
|
2047
2064
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2048
2065
|
{
|
|
2049
2066
|
value: "cursor",
|
|
2050
|
-
label: "Cursor (project only)"
|
|
2051
|
-
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
2067
|
+
label: "Cursor (project only)"
|
|
2052
2068
|
},
|
|
2053
2069
|
{
|
|
2054
2070
|
value: "cursor-global",
|
|
2055
|
-
label: "Cursor (global, all projects)"
|
|
2056
|
-
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
2071
|
+
label: "Cursor (global, all projects)"
|
|
2057
2072
|
},
|
|
2058
2073
|
{
|
|
2059
2074
|
value: "windsurf",
|
|
2060
|
-
label: "Windsurf"
|
|
2061
|
-
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
2075
|
+
label: "Windsurf"
|
|
2062
2076
|
},
|
|
2063
2077
|
{
|
|
2064
2078
|
value: "vscode",
|
|
2065
|
-
label: "VSCode"
|
|
2066
|
-
hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
|
|
2079
|
+
label: "VSCode"
|
|
2067
2080
|
}
|
|
2068
2081
|
]
|
|
2069
2082
|
});
|
|
2070
2083
|
if (editor === `skip`) return void 0;
|
|
2071
|
-
if (editor === `windsurf` && windsurfIsAlreadyInstalled) {
|
|
2072
|
-
M.message(`
|
|
2073
|
-
Windsurf is already installed, skipping.`);
|
|
2074
|
-
return void 0;
|
|
2075
|
-
}
|
|
2076
|
-
if (editor === `vscode` && vscodeIsAlreadyInstalled) {
|
|
2077
|
-
M.message(`
|
|
2078
|
-
VSCode is already installed, skipping.`);
|
|
2079
|
-
return void 0;
|
|
2080
|
-
}
|
|
2081
2084
|
if (editor === `cursor`) {
|
|
2082
2085
|
M.message(
|
|
2083
2086
|
`
|
|
@@ -2125,6 +2128,9 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2125
2128
|
function getPackageManager() {
|
|
2126
2129
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
2127
2130
|
const execPath = process.env.npm_execpath || "";
|
|
2131
|
+
if (userAgent.includes("bun")) {
|
|
2132
|
+
return "bun";
|
|
2133
|
+
}
|
|
2128
2134
|
if (userAgent.includes("yarn")) {
|
|
2129
2135
|
return "yarn";
|
|
2130
2136
|
}
|
|
@@ -2134,6 +2140,9 @@ function getPackageManager() {
|
|
|
2134
2140
|
if (userAgent.includes("npm")) {
|
|
2135
2141
|
return "npm";
|
|
2136
2142
|
}
|
|
2143
|
+
if (execPath.includes("bun")) {
|
|
2144
|
+
return "bun";
|
|
2145
|
+
}
|
|
2137
2146
|
if (execPath.includes("yarn")) {
|
|
2138
2147
|
return "yarn";
|
|
2139
2148
|
}
|
|
@@ -2154,19 +2163,23 @@ function createLogger(debug = false) {
|
|
|
2154
2163
|
}
|
|
2155
2164
|
var exec2 = util.promisify(child_process.exec);
|
|
2156
2165
|
async function cloneTemplate(options) {
|
|
2157
|
-
const { template, projectName, targetDir } = options;
|
|
2158
|
-
const projectPath = targetDir ?
|
|
2166
|
+
const { template, projectName, targetDir, branch, llmProvider } = options;
|
|
2167
|
+
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
2159
2168
|
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2160
2169
|
try {
|
|
2161
2170
|
if (await directoryExists(projectPath)) {
|
|
2162
2171
|
spinner4.error(`Directory ${projectName} already exists`);
|
|
2163
2172
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2164
2173
|
}
|
|
2165
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2174
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath, branch);
|
|
2166
2175
|
await updatePackageJson(projectPath, projectName);
|
|
2167
|
-
const envExamplePath =
|
|
2176
|
+
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
2168
2177
|
if (await fileExists(envExamplePath)) {
|
|
2169
|
-
|
|
2178
|
+
const envPath = path3.join(projectPath, ".env");
|
|
2179
|
+
await fs4.copyFile(envExamplePath, envPath);
|
|
2180
|
+
if (llmProvider) {
|
|
2181
|
+
await updateEnvFile(envPath, llmProvider);
|
|
2182
|
+
}
|
|
2170
2183
|
}
|
|
2171
2184
|
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2172
2185
|
return projectPath;
|
|
@@ -2191,21 +2204,27 @@ async function fileExists(filePath) {
|
|
|
2191
2204
|
return false;
|
|
2192
2205
|
}
|
|
2193
2206
|
}
|
|
2194
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2207
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath, branch) {
|
|
2195
2208
|
await fs4.mkdir(targetPath, { recursive: true });
|
|
2196
2209
|
try {
|
|
2197
2210
|
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2198
|
-
const
|
|
2211
|
+
const degitRepoWithBranch = branch ? `${degitRepo}#${branch}` : degitRepo;
|
|
2212
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepoWithBranch, targetPath]);
|
|
2199
2213
|
await exec2(degitCommand, {
|
|
2200
2214
|
cwd: process.cwd()
|
|
2201
2215
|
});
|
|
2202
2216
|
} catch {
|
|
2203
2217
|
try {
|
|
2204
|
-
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);
|
|
2205
2224
|
await exec2(gitCommand, {
|
|
2206
2225
|
cwd: process.cwd()
|
|
2207
2226
|
});
|
|
2208
|
-
const gitDir =
|
|
2227
|
+
const gitDir = path3.join(targetPath, ".git");
|
|
2209
2228
|
if (await directoryExists(gitDir)) {
|
|
2210
2229
|
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2211
2230
|
}
|
|
@@ -2215,7 +2234,7 @@ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
|
2215
2234
|
}
|
|
2216
2235
|
}
|
|
2217
2236
|
async function updatePackageJson(projectPath, projectName) {
|
|
2218
|
-
const packageJsonPath =
|
|
2237
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
2219
2238
|
try {
|
|
2220
2239
|
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2221
2240
|
const packageJson = JSON.parse(packageJsonContent);
|
|
@@ -2225,6 +2244,22 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2225
2244
|
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2226
2245
|
}
|
|
2227
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
|
+
}
|
|
2228
2263
|
async function installDependencies(projectPath, packageManager) {
|
|
2229
2264
|
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2230
2265
|
try {
|
|
@@ -2364,7 +2399,8 @@ var init = async ({
|
|
|
2364
2399
|
if (configureEditorWithDocsMCP) {
|
|
2365
2400
|
await installMastraDocsMCPServer({
|
|
2366
2401
|
editor: configureEditorWithDocsMCP,
|
|
2367
|
-
directory: process.cwd()
|
|
2402
|
+
directory: process.cwd(),
|
|
2403
|
+
versionTag
|
|
2368
2404
|
});
|
|
2369
2405
|
}
|
|
2370
2406
|
s.stop();
|
|
@@ -2413,6 +2449,32 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2413
2449
|
throw error;
|
|
2414
2450
|
}
|
|
2415
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
|
+
}
|
|
2416
2478
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2417
2479
|
let installCommand = getPackageManagerAddCommand(pm);
|
|
2418
2480
|
if (isDev) {
|
|
@@ -2467,10 +2529,13 @@ var createMastraProject = async ({
|
|
|
2467
2529
|
});
|
|
2468
2530
|
}
|
|
2469
2531
|
const s2 = Y();
|
|
2532
|
+
const originalCwd = process.cwd();
|
|
2533
|
+
let projectPath = null;
|
|
2470
2534
|
try {
|
|
2471
2535
|
s2.start("Creating project");
|
|
2472
2536
|
try {
|
|
2473
2537
|
await fs4.mkdir(projectName);
|
|
2538
|
+
projectPath = path3.resolve(originalCwd, projectName);
|
|
2474
2539
|
} catch (error) {
|
|
2475
2540
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2476
2541
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2485,9 +2550,7 @@ var createMastraProject = async ({
|
|
|
2485
2550
|
const installCommand = getPackageManagerAddCommand(pm);
|
|
2486
2551
|
s2.message("Initializing project structure");
|
|
2487
2552
|
try {
|
|
2488
|
-
await
|
|
2489
|
-
await exec3(`npm pkg set type="module"`);
|
|
2490
|
-
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
2553
|
+
await initializePackageJson(pm);
|
|
2491
2554
|
const depsService = new DepsService();
|
|
2492
2555
|
await depsService.addScriptsToPackageJson({
|
|
2493
2556
|
dev: "mastra dev",
|
|
@@ -2566,44 +2629,61 @@ var createMastraProject = async ({
|
|
|
2566
2629
|
s2.stop();
|
|
2567
2630
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
2568
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
|
+
}
|
|
2569
2642
|
process.exit(1);
|
|
2570
2643
|
}
|
|
2571
2644
|
};
|
|
2572
|
-
var
|
|
2573
|
-
|
|
2574
|
-
|
|
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
|
+
});
|
|
2575
2655
|
return;
|
|
2576
2656
|
}
|
|
2577
|
-
const needsInteractive =
|
|
2657
|
+
const needsInteractive = args.components === void 0 || args.llmProvider === void 0 || args.addExample === void 0;
|
|
2578
2658
|
const { projectName, result } = await createMastraProject({
|
|
2579
|
-
projectName:
|
|
2580
|
-
createVersionTag:
|
|
2581
|
-
timeout:
|
|
2582
|
-
llmProvider:
|
|
2583
|
-
llmApiKey:
|
|
2659
|
+
projectName: args?.projectName,
|
|
2660
|
+
createVersionTag: args?.createVersionTag,
|
|
2661
|
+
timeout: args?.timeout,
|
|
2662
|
+
llmProvider: args?.llmProvider,
|
|
2663
|
+
llmApiKey: args?.llmApiKey,
|
|
2584
2664
|
needsInteractive
|
|
2585
2665
|
});
|
|
2586
|
-
const directory =
|
|
2666
|
+
const directory = args.directory || "src/";
|
|
2587
2667
|
if (needsInteractive && result) {
|
|
2588
2668
|
await init({
|
|
2589
2669
|
...result,
|
|
2590
2670
|
llmApiKey: result?.llmApiKey,
|
|
2591
2671
|
components: ["agents", "tools", "workflows", "scorers"],
|
|
2592
2672
|
addExample: true,
|
|
2593
|
-
versionTag:
|
|
2673
|
+
versionTag: args.createVersionTag
|
|
2594
2674
|
});
|
|
2595
2675
|
postCreate({ projectName });
|
|
2596
2676
|
return;
|
|
2597
2677
|
}
|
|
2598
|
-
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } =
|
|
2678
|
+
const { components = [], llmProvider = "openai", addExample = false, llmApiKey } = args;
|
|
2599
2679
|
await init({
|
|
2600
2680
|
directory,
|
|
2601
2681
|
components,
|
|
2602
2682
|
llmProvider,
|
|
2603
2683
|
addExample,
|
|
2604
2684
|
llmApiKey,
|
|
2605
|
-
configureEditorWithDocsMCP:
|
|
2606
|
-
versionTag:
|
|
2685
|
+
configureEditorWithDocsMCP: args.mcpServer,
|
|
2686
|
+
versionTag: args.createVersionTag
|
|
2607
2687
|
});
|
|
2608
2688
|
postCreate({ projectName });
|
|
2609
2689
|
};
|
|
@@ -2694,9 +2774,9 @@ async function createFromGitHubUrl(url) {
|
|
|
2694
2774
|
workflows: []
|
|
2695
2775
|
};
|
|
2696
2776
|
}
|
|
2697
|
-
async function createFromTemplate(
|
|
2777
|
+
async function createFromTemplate(args) {
|
|
2698
2778
|
let selectedTemplate;
|
|
2699
|
-
if (
|
|
2779
|
+
if (args.template === true) {
|
|
2700
2780
|
const templates = await loadTemplates();
|
|
2701
2781
|
const selected = await selectTemplate(templates);
|
|
2702
2782
|
if (!selected) {
|
|
@@ -2704,11 +2784,11 @@ async function createFromTemplate(args2) {
|
|
|
2704
2784
|
return;
|
|
2705
2785
|
}
|
|
2706
2786
|
selectedTemplate = selected;
|
|
2707
|
-
} else if (
|
|
2708
|
-
if (isGitHubUrl(
|
|
2787
|
+
} else if (args.template && typeof args.template === "string") {
|
|
2788
|
+
if (isGitHubUrl(args.template)) {
|
|
2709
2789
|
const spinner4 = Y();
|
|
2710
2790
|
spinner4.start("Validating GitHub repository...");
|
|
2711
|
-
const validation = await validateGitHubProject(
|
|
2791
|
+
const validation = await validateGitHubProject(args.template);
|
|
2712
2792
|
if (!validation.isValid) {
|
|
2713
2793
|
spinner4.stop("Validation failed");
|
|
2714
2794
|
M.error("This does not appear to be a valid Mastra project:");
|
|
@@ -2716,14 +2796,14 @@ async function createFromTemplate(args2) {
|
|
|
2716
2796
|
throw new Error("Invalid Mastra project");
|
|
2717
2797
|
}
|
|
2718
2798
|
spinner4.stop("Valid Mastra project \u2713");
|
|
2719
|
-
selectedTemplate = await createFromGitHubUrl(
|
|
2799
|
+
selectedTemplate = await createFromGitHubUrl(args.template);
|
|
2720
2800
|
} else {
|
|
2721
2801
|
const templates = await loadTemplates();
|
|
2722
|
-
const found = findTemplateByName(templates,
|
|
2802
|
+
const found = findTemplateByName(templates, args.template);
|
|
2723
2803
|
if (!found) {
|
|
2724
|
-
M.error(`Template "${
|
|
2804
|
+
M.error(`Template "${args.template}" not found. Available templates:`);
|
|
2725
2805
|
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2726
|
-
throw new Error(`Template "${
|
|
2806
|
+
throw new Error(`Template "${args.template}" not found`);
|
|
2727
2807
|
}
|
|
2728
2808
|
selectedTemplate = found;
|
|
2729
2809
|
}
|
|
@@ -2731,7 +2811,7 @@ async function createFromTemplate(args2) {
|
|
|
2731
2811
|
if (!selectedTemplate) {
|
|
2732
2812
|
throw new Error("No template selected");
|
|
2733
2813
|
}
|
|
2734
|
-
let projectName =
|
|
2814
|
+
let projectName = args.projectName;
|
|
2735
2815
|
if (!projectName) {
|
|
2736
2816
|
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2737
2817
|
const response = await he({
|
|
@@ -2745,17 +2825,41 @@ async function createFromTemplate(args2) {
|
|
|
2745
2825
|
}
|
|
2746
2826
|
projectName = response;
|
|
2747
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;
|
|
2748
2841
|
try {
|
|
2749
|
-
const analytics =
|
|
2842
|
+
const analytics = args.injectedAnalytics || getAnalytics();
|
|
2750
2843
|
if (analytics) {
|
|
2751
2844
|
analytics.trackEvent("cli_template_used", {
|
|
2752
2845
|
template_slug: selectedTemplate.slug,
|
|
2753
2846
|
template_title: selectedTemplate.title
|
|
2754
2847
|
});
|
|
2848
|
+
if (llmProvider) {
|
|
2849
|
+
analytics.trackEvent("cli_model_provider_selected", {
|
|
2850
|
+
provider: llmProvider,
|
|
2851
|
+
selection_method: args.llmProvider ? "cli_args" : "interactive"
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2755
2854
|
}
|
|
2756
|
-
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({
|
|
2757
2859
|
template: selectedTemplate,
|
|
2758
|
-
projectName
|
|
2860
|
+
projectName,
|
|
2861
|
+
branch,
|
|
2862
|
+
llmProvider
|
|
2759
2863
|
});
|
|
2760
2864
|
await installDependencies(projectPath);
|
|
2761
2865
|
Me(`
|
|
@@ -2766,6 +2870,17 @@ async function createFromTemplate(args2) {
|
|
|
2766
2870
|
`);
|
|
2767
2871
|
postCreate({ projectName });
|
|
2768
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
|
+
}
|
|
2769
2884
|
M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2770
2885
|
throw error;
|
|
2771
2886
|
}
|
|
@@ -2774,7 +2889,7 @@ async function createFromTemplate(args2) {
|
|
|
2774
2889
|
async function getPackageVersion() {
|
|
2775
2890
|
const __filename = fileURLToPath(import.meta.url);
|
|
2776
2891
|
const __dirname = dirname(__filename);
|
|
2777
|
-
const pkgJsonPath =
|
|
2892
|
+
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
2778
2893
|
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2779
2894
|
return content.version;
|
|
2780
2895
|
}
|