create-mastra 0.0.0-share-agent-metadata-with-cloud-20250718110128 → 0.0.0-sidebar-window-undefined-fix-20251029233656
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 +2085 -0
- package/README.md +11 -39
- package/dist/index.js +707 -473
- package/dist/index.js.map +1 -1
- package/dist/templates/dev.entry.js +12 -2
- package/package.json +20 -12
- package/dist/starter-files/config.ts +0 -25
- package/dist/starter-files/mastra-pg.docker-compose.yaml +0 -15
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
4
|
+
import * as fs3__default from 'node:fs';
|
|
5
|
+
import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import
|
|
7
|
+
import path, { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { PostHog } from 'posthog-node';
|
|
10
10
|
import util, { stripVTControlCharacters } from 'node:util';
|
|
@@ -12,18 +12,18 @@ import y$1, { stdout, stdin } from 'node:process';
|
|
|
12
12
|
import * as g from 'node:readline';
|
|
13
13
|
import g__default from 'node:readline';
|
|
14
14
|
import { Writable } from 'node:stream';
|
|
15
|
-
import
|
|
15
|
+
import fs4 from 'node:fs/promises';
|
|
16
16
|
import child_process from 'node:child_process';
|
|
17
17
|
import tty from 'node:tty';
|
|
18
|
+
import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
19
|
+
import prettier from 'prettier';
|
|
20
|
+
import { execa } from 'execa';
|
|
18
21
|
import pino from 'pino';
|
|
19
22
|
import pretty from 'pino-pretty';
|
|
20
|
-
import
|
|
21
|
-
import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
22
|
-
import prettier from 'prettier';
|
|
23
|
-
import fsExtra from 'fs-extra';
|
|
23
|
+
import fsExtra$1 from 'fs-extra';
|
|
24
24
|
|
|
25
25
|
var __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
var __dirname =
|
|
26
|
+
var __dirname = path.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 = path.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(path.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
|
|
71
71
|
} catch {
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -422,7 +422,7 @@ ${color2.gray(d)} ${t}
|
|
|
422
422
|
`):process.stdout.write(`${w} ${l}
|
|
423
423
|
`),E(),s();};return {start:H,stop:N,message:(m="")=>{l=R(m??l);}}},Ce=async(t,n)=>{const r={},i=Object.keys(t);for(const s of i){const c=t[s],a=await c({results:r})?.catch(l=>{throw l});if(typeof n?.onCancel=="function"&&pD(a)){r[s]="canceled",n.onCancel({results:r});continue}r[s]=a;}return r};
|
|
424
424
|
|
|
425
|
-
var shellQuote
|
|
425
|
+
var shellQuote = {};
|
|
426
426
|
|
|
427
427
|
var quote;
|
|
428
428
|
var hasRequiredQuote;
|
|
@@ -688,16 +688,16 @@ function requireParse () {
|
|
|
688
688
|
var hasRequiredShellQuote;
|
|
689
689
|
|
|
690
690
|
function requireShellQuote () {
|
|
691
|
-
if (hasRequiredShellQuote) return shellQuote
|
|
691
|
+
if (hasRequiredShellQuote) return shellQuote;
|
|
692
692
|
hasRequiredShellQuote = 1;
|
|
693
693
|
|
|
694
|
-
shellQuote
|
|
695
|
-
shellQuote
|
|
696
|
-
return shellQuote
|
|
694
|
+
shellQuote.quote = requireQuote();
|
|
695
|
+
shellQuote.parse = requireParse();
|
|
696
|
+
return shellQuote;
|
|
697
697
|
}
|
|
698
698
|
|
|
699
699
|
var shellQuoteExports = requireShellQuote();
|
|
700
|
-
var
|
|
700
|
+
var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
|
|
701
701
|
|
|
702
702
|
// eslint-disable-next-line no-warning-comments
|
|
703
703
|
// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
|
|
@@ -724,13 +724,18 @@ const format = (open, close) => {
|
|
|
724
724
|
// Handle nested colors.
|
|
725
725
|
|
|
726
726
|
// We could have done this, but it's too slow (as of Node.js 22).
|
|
727
|
-
// return openCode + string.replaceAll(closeCode, openCode) + closeCode;
|
|
727
|
+
// return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
|
|
728
728
|
|
|
729
729
|
let result = openCode;
|
|
730
730
|
let lastIndex = 0;
|
|
731
731
|
|
|
732
|
+
// SGR 22 resets both bold (1) and dim (2). When we encounter a nested
|
|
733
|
+
// close for styles that use 22, we need to re-open the outer style.
|
|
734
|
+
const reopenOnNestedClose = close === 22;
|
|
735
|
+
const replaceCode = (reopenOnNestedClose ? closeCode : '') + openCode;
|
|
736
|
+
|
|
732
737
|
while (index !== -1) {
|
|
733
|
-
result += string.slice(lastIndex, index) +
|
|
738
|
+
result += string.slice(lastIndex, index) + replaceCode;
|
|
734
739
|
lastIndex = index + closeCode.length;
|
|
735
740
|
index = string.indexOf(closeCode, lastIndex);
|
|
736
741
|
}
|
|
@@ -1173,288 +1178,6 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1173
1178
|
}
|
|
1174
1179
|
};
|
|
1175
1180
|
|
|
1176
|
-
function getPackageManager() {
|
|
1177
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
1178
|
-
const execPath = process.env.npm_execpath || "";
|
|
1179
|
-
if (userAgent.includes("yarn")) {
|
|
1180
|
-
return "yarn";
|
|
1181
|
-
}
|
|
1182
|
-
if (userAgent.includes("pnpm")) {
|
|
1183
|
-
return "pnpm";
|
|
1184
|
-
}
|
|
1185
|
-
if (userAgent.includes("npm")) {
|
|
1186
|
-
return "npm";
|
|
1187
|
-
}
|
|
1188
|
-
if (execPath.includes("yarn")) {
|
|
1189
|
-
return "yarn";
|
|
1190
|
-
}
|
|
1191
|
-
if (execPath.includes("pnpm")) {
|
|
1192
|
-
return "pnpm";
|
|
1193
|
-
}
|
|
1194
|
-
if (execPath.includes("npm")) {
|
|
1195
|
-
return "npm";
|
|
1196
|
-
}
|
|
1197
|
-
return "npm";
|
|
1198
|
-
}
|
|
1199
|
-
function getPackageManagerInstallCommand(pm) {
|
|
1200
|
-
switch (pm) {
|
|
1201
|
-
case "npm":
|
|
1202
|
-
return "install";
|
|
1203
|
-
case "yarn":
|
|
1204
|
-
return "add";
|
|
1205
|
-
case "pnpm":
|
|
1206
|
-
return "add";
|
|
1207
|
-
default:
|
|
1208
|
-
return "install";
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
var logger = new PinoLogger({
|
|
1212
|
-
name: "Mastra CLI",
|
|
1213
|
-
level: "info"
|
|
1214
|
-
});
|
|
1215
|
-
var exec = util.promisify(child_process.exec);
|
|
1216
|
-
async function cloneTemplate(options) {
|
|
1217
|
-
const { template, projectName, targetDir } = options;
|
|
1218
|
-
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
1219
|
-
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
1220
|
-
try {
|
|
1221
|
-
if (await directoryExists(projectPath)) {
|
|
1222
|
-
spinner4.error(`Directory ${projectName} already exists`);
|
|
1223
|
-
throw new Error(`Directory ${projectName} already exists`);
|
|
1224
|
-
}
|
|
1225
|
-
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
1226
|
-
await updatePackageJson(projectPath, projectName);
|
|
1227
|
-
const envExamplePath = path3.join(projectPath, ".env.example");
|
|
1228
|
-
if (await fileExists(envExamplePath)) {
|
|
1229
|
-
await fs.copyFile(envExamplePath, path3.join(projectPath, ".env"));
|
|
1230
|
-
}
|
|
1231
|
-
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
1232
|
-
return projectPath;
|
|
1233
|
-
} catch (error) {
|
|
1234
|
-
spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1235
|
-
throw error;
|
|
1236
|
-
}
|
|
1237
|
-
}
|
|
1238
|
-
async function directoryExists(dirPath) {
|
|
1239
|
-
try {
|
|
1240
|
-
const stat = await fs.stat(dirPath);
|
|
1241
|
-
return stat.isDirectory();
|
|
1242
|
-
} catch {
|
|
1243
|
-
return false;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
async function fileExists(filePath) {
|
|
1247
|
-
try {
|
|
1248
|
-
const stat = await fs.stat(filePath);
|
|
1249
|
-
return stat.isFile();
|
|
1250
|
-
} catch {
|
|
1251
|
-
return false;
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
1255
|
-
await fs.mkdir(targetPath, { recursive: true });
|
|
1256
|
-
try {
|
|
1257
|
-
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
1258
|
-
const degitCommand = shellQuote.quote(["npx", "degit", degitRepo, targetPath]);
|
|
1259
|
-
await exec(degitCommand, {
|
|
1260
|
-
cwd: process.cwd()
|
|
1261
|
-
});
|
|
1262
|
-
} catch {
|
|
1263
|
-
try {
|
|
1264
|
-
const gitCommand = shellQuote.quote(["git", "clone", repoUrl, targetPath]);
|
|
1265
|
-
await exec(gitCommand, {
|
|
1266
|
-
cwd: process.cwd()
|
|
1267
|
-
});
|
|
1268
|
-
const gitDir = path3.join(targetPath, ".git");
|
|
1269
|
-
if (await directoryExists(gitDir)) {
|
|
1270
|
-
await fs.rm(gitDir, { recursive: true, force: true });
|
|
1271
|
-
}
|
|
1272
|
-
} catch (gitError) {
|
|
1273
|
-
throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
async function updatePackageJson(projectPath, projectName) {
|
|
1278
|
-
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
1279
|
-
try {
|
|
1280
|
-
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
1281
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
1282
|
-
packageJson.name = projectName;
|
|
1283
|
-
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
1284
|
-
} catch (error) {
|
|
1285
|
-
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
async function installDependencies(projectPath, packageManager) {
|
|
1289
|
-
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
1290
|
-
try {
|
|
1291
|
-
const pm = packageManager || getPackageManager();
|
|
1292
|
-
const installCommand = shellQuote.quote([pm, "install"]);
|
|
1293
|
-
await exec(installCommand, {
|
|
1294
|
-
cwd: projectPath
|
|
1295
|
-
});
|
|
1296
|
-
spinner4.success("Dependencies installed successfully");
|
|
1297
|
-
} catch (error) {
|
|
1298
|
-
spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1299
|
-
throw error;
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
|
|
1303
|
-
async function loadTemplates() {
|
|
1304
|
-
try {
|
|
1305
|
-
const response = await fetch(TEMPLATES_API_URL);
|
|
1306
|
-
if (!response.ok) {
|
|
1307
|
-
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
1308
|
-
}
|
|
1309
|
-
const templates = await response.json();
|
|
1310
|
-
return templates;
|
|
1311
|
-
} catch (error) {
|
|
1312
|
-
console.error("Error loading templates:", error);
|
|
1313
|
-
throw new Error("Failed to load templates. Please check your internet connection and try again.");
|
|
1314
|
-
}
|
|
1315
|
-
}
|
|
1316
|
-
function pluralize(count, singular, plural) {
|
|
1317
|
-
return count === 1 ? singular : plural || `${singular}s`;
|
|
1318
|
-
}
|
|
1319
|
-
async function selectTemplate(templates) {
|
|
1320
|
-
const choices = templates.map((template) => {
|
|
1321
|
-
const parts = [];
|
|
1322
|
-
if (template.agents?.length) {
|
|
1323
|
-
parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
|
|
1324
|
-
}
|
|
1325
|
-
if (template.tools?.length) {
|
|
1326
|
-
parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
|
|
1327
|
-
}
|
|
1328
|
-
if (template.workflows?.length) {
|
|
1329
|
-
parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
|
|
1330
|
-
}
|
|
1331
|
-
if (template.mcp?.length) {
|
|
1332
|
-
parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
|
|
1333
|
-
}
|
|
1334
|
-
if (template.networks?.length) {
|
|
1335
|
-
parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
|
|
1336
|
-
}
|
|
1337
|
-
return {
|
|
1338
|
-
value: template,
|
|
1339
|
-
label: template.title,
|
|
1340
|
-
hint: parts.join(", ") || "Template components"
|
|
1341
|
-
};
|
|
1342
|
-
});
|
|
1343
|
-
const selected = await ve({
|
|
1344
|
-
message: "Select a template:",
|
|
1345
|
-
options: choices
|
|
1346
|
-
});
|
|
1347
|
-
if (pD(selected)) {
|
|
1348
|
-
return null;
|
|
1349
|
-
}
|
|
1350
|
-
return selected;
|
|
1351
|
-
}
|
|
1352
|
-
function findTemplateByName(templates, templateName) {
|
|
1353
|
-
let template = templates.find((t) => t.slug === templateName);
|
|
1354
|
-
if (template) return template;
|
|
1355
|
-
const slugWithPrefix = `template-${templateName}`;
|
|
1356
|
-
template = templates.find((t) => t.slug === slugWithPrefix);
|
|
1357
|
-
if (template) return template;
|
|
1358
|
-
template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
|
|
1359
|
-
if (template) return template;
|
|
1360
|
-
return null;
|
|
1361
|
-
}
|
|
1362
|
-
function getDefaultProjectName(template) {
|
|
1363
|
-
return template.slug.replace(/^template-/, "");
|
|
1364
|
-
}
|
|
1365
|
-
var DepsService = class {
|
|
1366
|
-
packageManager;
|
|
1367
|
-
constructor() {
|
|
1368
|
-
this.packageManager = this.getPackageManager();
|
|
1369
|
-
}
|
|
1370
|
-
findLockFile(dir) {
|
|
1371
|
-
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1372
|
-
for (const file of lockFiles) {
|
|
1373
|
-
if (fs4__default__default.existsSync(path3.join(dir, file))) {
|
|
1374
|
-
return file;
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
const parentDir = path3.resolve(dir, "..");
|
|
1378
|
-
if (parentDir !== dir) {
|
|
1379
|
-
return this.findLockFile(parentDir);
|
|
1380
|
-
}
|
|
1381
|
-
return null;
|
|
1382
|
-
}
|
|
1383
|
-
getPackageManager() {
|
|
1384
|
-
const lockFile = this.findLockFile(process.cwd());
|
|
1385
|
-
switch (lockFile) {
|
|
1386
|
-
case "pnpm-lock.yaml":
|
|
1387
|
-
return "pnpm";
|
|
1388
|
-
case "package-lock.json":
|
|
1389
|
-
return "npm";
|
|
1390
|
-
case "yarn.lock":
|
|
1391
|
-
return "yarn";
|
|
1392
|
-
case "bun.lock":
|
|
1393
|
-
return "bun";
|
|
1394
|
-
default:
|
|
1395
|
-
return "npm";
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
async installPackages(packages) {
|
|
1399
|
-
let runCommand = this.packageManager;
|
|
1400
|
-
if (this.packageManager === "npm") {
|
|
1401
|
-
runCommand = `${this.packageManager} i`;
|
|
1402
|
-
} else {
|
|
1403
|
-
runCommand = `${this.packageManager} add`;
|
|
1404
|
-
}
|
|
1405
|
-
const packageList = packages.join(" ");
|
|
1406
|
-
return execa(`${runCommand} ${packageList}`, {
|
|
1407
|
-
all: true,
|
|
1408
|
-
shell: true,
|
|
1409
|
-
stdio: "inherit"
|
|
1410
|
-
});
|
|
1411
|
-
}
|
|
1412
|
-
async checkDependencies(dependencies) {
|
|
1413
|
-
try {
|
|
1414
|
-
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1415
|
-
try {
|
|
1416
|
-
await fs.access(packageJsonPath);
|
|
1417
|
-
} catch {
|
|
1418
|
-
return "No package.json file found in the current directory";
|
|
1419
|
-
}
|
|
1420
|
-
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
|
|
1421
|
-
for (const dependency of dependencies) {
|
|
1422
|
-
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
1423
|
-
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
return "ok";
|
|
1427
|
-
} catch (err) {
|
|
1428
|
-
console.error(err);
|
|
1429
|
-
return "Could not check dependencies";
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
async getProjectName() {
|
|
1433
|
-
try {
|
|
1434
|
-
const packageJsonPath = path3.join(process.cwd(), "package.json");
|
|
1435
|
-
const packageJson = await fs.readFile(packageJsonPath, "utf-8");
|
|
1436
|
-
const pkg = JSON.parse(packageJson);
|
|
1437
|
-
return pkg.name;
|
|
1438
|
-
} catch (err) {
|
|
1439
|
-
throw err;
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
|
-
async getPackageVersion() {
|
|
1443
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
1444
|
-
const __dirname = dirname(__filename);
|
|
1445
|
-
const pkgJsonPath = path3.join(__dirname, "..", "package.json");
|
|
1446
|
-
const content = await fsExtra3.readJSON(pkgJsonPath);
|
|
1447
|
-
return content.version;
|
|
1448
|
-
}
|
|
1449
|
-
async addScriptsToPackageJson(scripts) {
|
|
1450
|
-
const packageJson = JSON.parse(await fs.readFile("package.json", "utf-8"));
|
|
1451
|
-
packageJson.scripts = {
|
|
1452
|
-
...packageJson.scripts,
|
|
1453
|
-
...scripts
|
|
1454
|
-
};
|
|
1455
|
-
await fs.writeFile("package.json", JSON.stringify(packageJson, null, 2));
|
|
1456
|
-
}
|
|
1457
|
-
};
|
|
1458
1181
|
var args = ["-y", "@mastra/mcp-docs-server"];
|
|
1459
1182
|
var createMcpConfig = (editor) => {
|
|
1460
1183
|
if (editor === "vscode") {
|
|
@@ -1507,19 +1230,19 @@ async function writeMergedConfig(configPath, editor) {
|
|
|
1507
1230
|
spaces: 2
|
|
1508
1231
|
});
|
|
1509
1232
|
}
|
|
1510
|
-
var windsurfGlobalMCPConfigPath =
|
|
1511
|
-
var cursorGlobalMCPConfigPath =
|
|
1512
|
-
|
|
1513
|
-
var vscodeGlobalMCPConfigPath =
|
|
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(
|
|
1514
1237
|
os.homedir(),
|
|
1515
|
-
process.platform === "win32" ?
|
|
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")
|
|
1516
1239
|
);
|
|
1517
1240
|
async function installMastraDocsMCPServer({ editor, directory }) {
|
|
1518
1241
|
if (editor === `cursor`) {
|
|
1519
|
-
await writeMergedConfig(
|
|
1242
|
+
await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
|
|
1520
1243
|
}
|
|
1521
1244
|
if (editor === `vscode`) {
|
|
1522
|
-
await writeMergedConfig(
|
|
1245
|
+
await writeMergedConfig(path.join(directory, ".vscode", "mcp.json"), "vscode");
|
|
1523
1246
|
}
|
|
1524
1247
|
if (editor === `cursor-global`) {
|
|
1525
1248
|
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
@@ -1567,25 +1290,121 @@ async function globalMCPIsAlreadyInstalled(editor) {
|
|
|
1567
1290
|
return false;
|
|
1568
1291
|
}
|
|
1569
1292
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1293
|
+
function getPackageManagerAddCommand(pm) {
|
|
1294
|
+
switch (pm) {
|
|
1295
|
+
case "npm":
|
|
1296
|
+
return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
|
|
1297
|
+
case "yarn":
|
|
1298
|
+
return "add";
|
|
1299
|
+
case "pnpm":
|
|
1300
|
+
return "add --loglevel=error";
|
|
1301
|
+
case "bun":
|
|
1302
|
+
return "add";
|
|
1303
|
+
default:
|
|
1304
|
+
return "add";
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
var DepsService = class {
|
|
1308
|
+
packageManager;
|
|
1309
|
+
constructor() {
|
|
1310
|
+
this.packageManager = this.getPackageManager();
|
|
1311
|
+
}
|
|
1312
|
+
findLockFile(dir) {
|
|
1313
|
+
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1314
|
+
for (const file of lockFiles) {
|
|
1315
|
+
if (fs3__default__default.existsSync(path.join(dir, file))) {
|
|
1316
|
+
return file;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
const parentDir = path.resolve(dir, "..");
|
|
1320
|
+
if (parentDir !== dir) {
|
|
1321
|
+
return this.findLockFile(parentDir);
|
|
1322
|
+
}
|
|
1323
|
+
return null;
|
|
1324
|
+
}
|
|
1325
|
+
getPackageManager() {
|
|
1326
|
+
const lockFile = this.findLockFile(process.cwd());
|
|
1327
|
+
switch (lockFile) {
|
|
1328
|
+
case "pnpm-lock.yaml":
|
|
1329
|
+
return "pnpm";
|
|
1330
|
+
case "package-lock.json":
|
|
1331
|
+
return "npm";
|
|
1332
|
+
case "yarn.lock":
|
|
1333
|
+
return "yarn";
|
|
1334
|
+
case "bun.lock":
|
|
1335
|
+
return "bun";
|
|
1336
|
+
default:
|
|
1337
|
+
return "npm";
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
async installPackages(packages) {
|
|
1341
|
+
const pm = this.packageManager;
|
|
1342
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
1343
|
+
const packageList = packages.join(" ");
|
|
1344
|
+
return execa(`${pm} ${installCommand} ${packageList}`, {
|
|
1345
|
+
all: true,
|
|
1346
|
+
shell: true,
|
|
1347
|
+
stdio: "inherit"
|
|
1348
|
+
});
|
|
1349
|
+
}
|
|
1350
|
+
async checkDependencies(dependencies) {
|
|
1351
|
+
try {
|
|
1352
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1353
|
+
try {
|
|
1354
|
+
await fs4.access(packageJsonPath);
|
|
1355
|
+
} catch {
|
|
1356
|
+
return "No package.json file found in the current directory";
|
|
1357
|
+
}
|
|
1358
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
1359
|
+
for (const dependency of dependencies) {
|
|
1360
|
+
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
1361
|
+
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
return "ok";
|
|
1365
|
+
} catch (err) {
|
|
1366
|
+
console.error(err);
|
|
1367
|
+
return "Could not check dependencies";
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
async getProjectName() {
|
|
1371
|
+
try {
|
|
1372
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1373
|
+
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1374
|
+
const pkg = JSON.parse(packageJson);
|
|
1375
|
+
return pkg.name;
|
|
1376
|
+
} catch (err) {
|
|
1377
|
+
throw err;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
async addScriptsToPackageJson(scripts) {
|
|
1381
|
+
const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
|
|
1382
|
+
packageJson.scripts = {
|
|
1383
|
+
...packageJson.scripts,
|
|
1384
|
+
...scripts
|
|
1385
|
+
};
|
|
1386
|
+
await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
|
|
1387
|
+
}
|
|
1388
|
+
};
|
|
1389
|
+
var EnvService = class {
|
|
1390
|
+
};
|
|
1391
|
+
var FileEnvService = class extends EnvService {
|
|
1392
|
+
filePath;
|
|
1393
|
+
constructor(filePath) {
|
|
1394
|
+
super();
|
|
1395
|
+
this.filePath = filePath;
|
|
1396
|
+
}
|
|
1397
|
+
readFile(filePath) {
|
|
1398
|
+
return new Promise((resolve, reject) => {
|
|
1399
|
+
fs3__default.readFile(filePath, "utf8", (err, data) => {
|
|
1400
|
+
if (err) reject(err);
|
|
1582
1401
|
else resolve(data);
|
|
1583
1402
|
});
|
|
1584
1403
|
});
|
|
1585
1404
|
}
|
|
1586
1405
|
writeFile({ filePath, data }) {
|
|
1587
1406
|
return new Promise((resolve, reject) => {
|
|
1588
|
-
|
|
1407
|
+
fs3__default.writeFile(filePath, data, "utf8", (err) => {
|
|
1589
1408
|
if (err) reject(err);
|
|
1590
1409
|
else resolve();
|
|
1591
1410
|
});
|
|
@@ -1605,7 +1424,7 @@ var FileEnvService = class extends EnvService {
|
|
|
1605
1424
|
${key}=${value}`;
|
|
1606
1425
|
}
|
|
1607
1426
|
await this.writeFile({ filePath, data });
|
|
1608
|
-
console.
|
|
1427
|
+
console.info(`${key} set to ${value} in ENV file.`);
|
|
1609
1428
|
return data;
|
|
1610
1429
|
}
|
|
1611
1430
|
async getEnvValue(key) {
|
|
@@ -1638,25 +1457,25 @@ var FileService = class {
|
|
|
1638
1457
|
*/
|
|
1639
1458
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1640
1459
|
const __filename = fileURLToPath(import.meta.url);
|
|
1641
|
-
const __dirname =
|
|
1642
|
-
const filePath =
|
|
1643
|
-
const fileString =
|
|
1644
|
-
if (
|
|
1645
|
-
console.
|
|
1460
|
+
const __dirname = path.dirname(__filename);
|
|
1461
|
+
const filePath = path.resolve(__dirname, "starter-files", inputFile);
|
|
1462
|
+
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1463
|
+
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1464
|
+
console.info(`${outputFilePath} already exists`);
|
|
1646
1465
|
return false;
|
|
1647
1466
|
}
|
|
1648
|
-
await
|
|
1467
|
+
await fsExtra.outputFile(outputFilePath, fileString);
|
|
1649
1468
|
return true;
|
|
1650
1469
|
}
|
|
1651
1470
|
async setupEnvFile({ dbUrl }) {
|
|
1652
|
-
const envPath =
|
|
1653
|
-
await
|
|
1471
|
+
const envPath = path.join(process.cwd(), ".env.development");
|
|
1472
|
+
await fsExtra.ensureFile(envPath);
|
|
1654
1473
|
const fileEnvService = new FileEnvService(envPath);
|
|
1655
1474
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
1656
1475
|
}
|
|
1657
1476
|
getFirstExistingFile(files) {
|
|
1658
1477
|
for (const f of files) {
|
|
1659
|
-
if (
|
|
1478
|
+
if (fs3__default__default.existsSync(f)) {
|
|
1660
1479
|
return f;
|
|
1661
1480
|
}
|
|
1662
1481
|
}
|
|
@@ -1666,53 +1485,31 @@ var FileService = class {
|
|
|
1666
1485
|
filePath,
|
|
1667
1486
|
replacements
|
|
1668
1487
|
}) {
|
|
1669
|
-
let fileContent =
|
|
1488
|
+
let fileContent = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1670
1489
|
replacements.forEach(({ search, replace }) => {
|
|
1671
1490
|
fileContent = fileContent.replaceAll(search, replace);
|
|
1672
1491
|
});
|
|
1673
|
-
|
|
1492
|
+
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1674
1493
|
}
|
|
1675
1494
|
};
|
|
1676
|
-
var
|
|
1677
|
-
var
|
|
1678
|
-
switch (llmProvider) {
|
|
1679
|
-
case "openai":
|
|
1680
|
-
return "@ai-sdk/openai";
|
|
1681
|
-
case "anthropic":
|
|
1682
|
-
return "@ai-sdk/anthropic";
|
|
1683
|
-
case "groq":
|
|
1684
|
-
return "@ai-sdk/groq";
|
|
1685
|
-
case "google":
|
|
1686
|
-
return "@ai-sdk/google";
|
|
1687
|
-
case "cerebras":
|
|
1688
|
-
return "@ai-sdk/cerebras";
|
|
1689
|
-
default:
|
|
1690
|
-
return "@ai-sdk/openai";
|
|
1691
|
-
}
|
|
1692
|
-
};
|
|
1693
|
-
var getProviderImportAndModelItem = (llmProvider) => {
|
|
1694
|
-
let providerImport = "";
|
|
1695
|
-
let modelItem = "";
|
|
1495
|
+
var exec = util.promisify(child_process.exec);
|
|
1496
|
+
var getModelIdentifier = (llmProvider) => {
|
|
1696
1497
|
if (llmProvider === "openai") {
|
|
1697
|
-
|
|
1698
|
-
modelItem = `openai('gpt-4o-mini')`;
|
|
1498
|
+
return `'openai/gpt-4o-mini'`;
|
|
1699
1499
|
} else if (llmProvider === "anthropic") {
|
|
1700
|
-
|
|
1701
|
-
modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
|
|
1500
|
+
return `'anthropic/claude-sonnet-4-5-20250929'`;
|
|
1702
1501
|
} else if (llmProvider === "groq") {
|
|
1703
|
-
|
|
1704
|
-
modelItem = `groq('llama-3.3-70b-versatile')`;
|
|
1502
|
+
return `'groq/llama-3.3-70b-versatile'`;
|
|
1705
1503
|
} else if (llmProvider === "google") {
|
|
1706
|
-
|
|
1707
|
-
modelItem = `google('gemini-2.5-pro-exp-03-25')`;
|
|
1504
|
+
return `'google/gemini-2.5-pro'`;
|
|
1708
1505
|
} else if (llmProvider === "cerebras") {
|
|
1709
|
-
|
|
1710
|
-
|
|
1506
|
+
return `'cerebras/llama-3.3-70b'`;
|
|
1507
|
+
} else if (llmProvider === "mistral") {
|
|
1508
|
+
return `'mistral/mistral-medium-2508'`;
|
|
1711
1509
|
}
|
|
1712
|
-
return { providerImport, modelItem };
|
|
1713
1510
|
};
|
|
1714
|
-
async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
1715
|
-
const
|
|
1511
|
+
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1512
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1716
1513
|
const instructions = `
|
|
1717
1514
|
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
|
|
1718
1515
|
|
|
@@ -1728,17 +1525,40 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
|
1728
1525
|
${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
|
|
1729
1526
|
`;
|
|
1730
1527
|
const content = `
|
|
1731
|
-
${providerImport}
|
|
1732
1528
|
import { Agent } from '@mastra/core/agent';
|
|
1733
1529
|
import { Memory } from '@mastra/memory';
|
|
1734
1530
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1735
1531
|
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1532
|
+
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1736
1533
|
|
|
1737
1534
|
export const weatherAgent = new Agent({
|
|
1738
1535
|
name: 'Weather Agent',
|
|
1739
1536
|
instructions: \`${instructions}\`,
|
|
1740
|
-
model: ${
|
|
1537
|
+
model: ${modelString},
|
|
1741
1538
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1539
|
+
${addScorers ? `scorers: {
|
|
1540
|
+
toolCallAppropriateness: {
|
|
1541
|
+
scorer: scorers.toolCallAppropriatenessScorer,
|
|
1542
|
+
sampling: {
|
|
1543
|
+
type: 'ratio',
|
|
1544
|
+
rate: 1,
|
|
1545
|
+
},
|
|
1546
|
+
},
|
|
1547
|
+
completeness: {
|
|
1548
|
+
scorer: scorers.completenessScorer,
|
|
1549
|
+
sampling: {
|
|
1550
|
+
type: 'ratio',
|
|
1551
|
+
rate: 1,
|
|
1552
|
+
},
|
|
1553
|
+
},
|
|
1554
|
+
translation: {
|
|
1555
|
+
scorer: scorers.translationScorer,
|
|
1556
|
+
sampling: {
|
|
1557
|
+
type: 'ratio',
|
|
1558
|
+
rate: 1,
|
|
1559
|
+
},
|
|
1560
|
+
},
|
|
1561
|
+
},` : ""}
|
|
1742
1562
|
memory: new Memory({
|
|
1743
1563
|
storage: new LibSQLStore({
|
|
1744
1564
|
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
@@ -1750,8 +1570,8 @@ export const weatherAgent = new Agent({
|
|
|
1750
1570
|
parser: "typescript",
|
|
1751
1571
|
singleQuote: true
|
|
1752
1572
|
});
|
|
1753
|
-
await
|
|
1754
|
-
await
|
|
1573
|
+
await fs4.writeFile(destPath, "");
|
|
1574
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1755
1575
|
}
|
|
1756
1576
|
async function writeWorkflowSample(destPath) {
|
|
1757
1577
|
const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
|
|
@@ -1944,44 +1764,139 @@ export { weatherWorkflow };`;
|
|
|
1944
1764
|
semi: true,
|
|
1945
1765
|
singleQuote: true
|
|
1946
1766
|
});
|
|
1947
|
-
await
|
|
1767
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1948
1768
|
}
|
|
1949
1769
|
async function writeToolSample(destPath) {
|
|
1950
1770
|
const fileService = new FileService();
|
|
1951
1771
|
await fileService.copyStarterFile("tools.ts", destPath);
|
|
1952
1772
|
}
|
|
1773
|
+
async function writeScorersSample(llmProvider, destPath) {
|
|
1774
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1775
|
+
const content = `import { z } from 'zod';
|
|
1776
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/code';
|
|
1777
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/code';
|
|
1778
|
+
import { createScorer } from '@mastra/core/scores';
|
|
1779
|
+
|
|
1780
|
+
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1781
|
+
expectedTool: 'weatherTool',
|
|
1782
|
+
strictMode: false,
|
|
1783
|
+
});
|
|
1784
|
+
|
|
1785
|
+
export const completenessScorer = createCompletenessScorer();
|
|
1786
|
+
|
|
1787
|
+
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1788
|
+
export const translationScorer = createScorer({
|
|
1789
|
+
name: 'Translation Quality',
|
|
1790
|
+
description: 'Checks that non-English location names are translated and used correctly',
|
|
1791
|
+
type: 'agent',
|
|
1792
|
+
judge: {
|
|
1793
|
+
model: ${modelString},
|
|
1794
|
+
instructions:
|
|
1795
|
+
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1796
|
+
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
1797
|
+
'Be lenient with transliteration differences and diacritics. ' +
|
|
1798
|
+
'Return only the structured JSON matching the provided schema.',
|
|
1799
|
+
},
|
|
1800
|
+
})
|
|
1801
|
+
.preprocess(({ run }) => {
|
|
1802
|
+
const userText = (run.input?.inputMessages?.[0]?.content as string) || '';
|
|
1803
|
+
const assistantText = (run.output?.[0]?.content as string) || '';
|
|
1804
|
+
return { userText, assistantText };
|
|
1805
|
+
})
|
|
1806
|
+
.analyze({
|
|
1807
|
+
description: 'Extract location names and detect language/translation adequacy',
|
|
1808
|
+
outputSchema: z.object({
|
|
1809
|
+
nonEnglish: z.boolean(),
|
|
1810
|
+
translated: z.boolean(),
|
|
1811
|
+
confidence: z.number().min(0).max(1).default(1),
|
|
1812
|
+
explanation: z.string().default(''),
|
|
1813
|
+
}),
|
|
1814
|
+
createPrompt: ({ results }) => \`
|
|
1815
|
+
You are evaluating if a weather assistant correctly handled translation of a non-English location.
|
|
1816
|
+
User text:
|
|
1817
|
+
"""
|
|
1818
|
+
\${results.preprocessStepResult.userText}
|
|
1819
|
+
"""
|
|
1820
|
+
Assistant response:
|
|
1821
|
+
"""
|
|
1822
|
+
\${results.preprocessStepResult.assistantText}
|
|
1823
|
+
"""
|
|
1824
|
+
Tasks:
|
|
1825
|
+
1) Identify if the user mentioned a location that appears non-English.
|
|
1826
|
+
2) If non-English, check whether the assistant used a correct English translation of that location in its response.
|
|
1827
|
+
3) Be lenient with transliteration differences (e.g., accents/diacritics).
|
|
1828
|
+
Return JSON with fields:
|
|
1829
|
+
{
|
|
1830
|
+
"nonEnglish": boolean,
|
|
1831
|
+
"translated": boolean,
|
|
1832
|
+
"confidence": number, // 0-1
|
|
1833
|
+
"explanation": string
|
|
1834
|
+
}
|
|
1835
|
+
\`,
|
|
1836
|
+
})
|
|
1837
|
+
.generateScore(({ results }) => {
|
|
1838
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1839
|
+
if (!r.nonEnglish) return 1; // If not applicable, full credit
|
|
1840
|
+
if (r.translated) return Math.max(0, Math.min(1, 0.7 + 0.3 * (r.confidence ?? 1)));
|
|
1841
|
+
return 0; // Non-English but not translated
|
|
1842
|
+
})
|
|
1843
|
+
.generateReason(({ results, score }) => {
|
|
1844
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1845
|
+
return \`Translation scoring: nonEnglish=\${r.nonEnglish ?? false}, translated=\${r.translated ?? false}, confidence=\${r.confidence ?? 0}. Score=\${score}. \${r.explanation ?? ''}\`;
|
|
1846
|
+
});
|
|
1847
|
+
|
|
1848
|
+
export const scorers = {
|
|
1849
|
+
toolCallAppropriatenessScorer,
|
|
1850
|
+
completenessScorer,
|
|
1851
|
+
translationScorer,
|
|
1852
|
+
};`;
|
|
1853
|
+
const formattedContent = await prettier.format(content, {
|
|
1854
|
+
parser: "typescript",
|
|
1855
|
+
singleQuote: true
|
|
1856
|
+
});
|
|
1857
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1858
|
+
}
|
|
1953
1859
|
async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
|
|
1954
1860
|
switch (component) {
|
|
1955
1861
|
case "agents":
|
|
1956
|
-
return writeAgentSample(
|
|
1862
|
+
return writeAgentSample(
|
|
1863
|
+
llmprovider,
|
|
1864
|
+
destPath,
|
|
1865
|
+
importComponents.includes("tools"),
|
|
1866
|
+
importComponents.includes("scorers")
|
|
1867
|
+
);
|
|
1957
1868
|
case "tools":
|
|
1958
1869
|
return writeToolSample(destPath);
|
|
1959
1870
|
case "workflows":
|
|
1960
1871
|
return writeWorkflowSample(destPath);
|
|
1872
|
+
case "scorers":
|
|
1873
|
+
return writeScorersSample(llmprovider, destPath);
|
|
1961
1874
|
default:
|
|
1962
1875
|
return "";
|
|
1963
1876
|
}
|
|
1964
1877
|
}
|
|
1965
1878
|
var createComponentsDir = async (dirPath, component) => {
|
|
1966
1879
|
const componentPath = dirPath + `/${component}`;
|
|
1967
|
-
await
|
|
1880
|
+
await fsExtra.ensureDir(componentPath);
|
|
1968
1881
|
};
|
|
1969
1882
|
var writeIndexFile = async ({
|
|
1970
1883
|
dirPath,
|
|
1971
1884
|
addAgent,
|
|
1972
1885
|
addExample,
|
|
1973
|
-
addWorkflow
|
|
1886
|
+
addWorkflow,
|
|
1887
|
+
addScorers
|
|
1974
1888
|
}) => {
|
|
1975
1889
|
const indexPath = dirPath + "/index.ts";
|
|
1976
|
-
const destPath =
|
|
1890
|
+
const destPath = path.join(indexPath);
|
|
1977
1891
|
try {
|
|
1978
|
-
await
|
|
1892
|
+
await fs4.writeFile(destPath, "");
|
|
1979
1893
|
const filteredExports = [
|
|
1980
1894
|
addWorkflow ? `workflows: { weatherWorkflow },` : "",
|
|
1981
|
-
addAgent ? `agents: { weatherAgent },` : ""
|
|
1895
|
+
addAgent ? `agents: { weatherAgent },` : "",
|
|
1896
|
+
addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
|
|
1982
1897
|
].filter(Boolean);
|
|
1983
1898
|
if (!addExample) {
|
|
1984
|
-
await
|
|
1899
|
+
await fs4.writeFile(
|
|
1985
1900
|
destPath,
|
|
1986
1901
|
`
|
|
1987
1902
|
import { Mastra } from '@mastra/core';
|
|
@@ -1991,7 +1906,7 @@ export const mastra = new Mastra()
|
|
|
1991
1906
|
);
|
|
1992
1907
|
return;
|
|
1993
1908
|
}
|
|
1994
|
-
await
|
|
1909
|
+
await fs4.writeFile(
|
|
1995
1910
|
destPath,
|
|
1996
1911
|
`
|
|
1997
1912
|
import { Mastra } from '@mastra/core/mastra';
|
|
@@ -1999,17 +1914,22 @@ import { PinoLogger } from '@mastra/loggers';
|
|
|
1999
1914
|
import { LibSQLStore } from '@mastra/libsql';
|
|
2000
1915
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
2001
1916
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1917
|
+
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
2002
1918
|
|
|
2003
1919
|
export const mastra = new Mastra({
|
|
2004
1920
|
${filteredExports.join("\n ")}
|
|
2005
1921
|
storage: new LibSQLStore({
|
|
2006
|
-
// stores
|
|
1922
|
+
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
2007
1923
|
url: ":memory:",
|
|
2008
1924
|
}),
|
|
2009
1925
|
logger: new PinoLogger({
|
|
2010
1926
|
name: 'Mastra',
|
|
2011
1927
|
level: 'info',
|
|
2012
1928
|
}),
|
|
1929
|
+
observability: {
|
|
1930
|
+
// Enables DefaultExporter and CloudExporter for AI tracing
|
|
1931
|
+
default: { enabled: true },
|
|
1932
|
+
},
|
|
2013
1933
|
});
|
|
2014
1934
|
`
|
|
2015
1935
|
);
|
|
@@ -2017,7 +1937,6 @@ export const mastra = new Mastra({
|
|
|
2017
1937
|
throw err;
|
|
2018
1938
|
}
|
|
2019
1939
|
};
|
|
2020
|
-
yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
|
|
2021
1940
|
var getAPIKey = async (provider) => {
|
|
2022
1941
|
let key = "OPENAI_API_KEY";
|
|
2023
1942
|
switch (provider) {
|
|
@@ -2033,27 +1952,28 @@ var getAPIKey = async (provider) => {
|
|
|
2033
1952
|
case "cerebras":
|
|
2034
1953
|
key = "CEREBRAS_API_KEY";
|
|
2035
1954
|
return key;
|
|
1955
|
+
case "mistral":
|
|
1956
|
+
key = "MISTRAL_API_KEY";
|
|
1957
|
+
return key;
|
|
2036
1958
|
default:
|
|
2037
1959
|
return key;
|
|
2038
1960
|
}
|
|
2039
1961
|
};
|
|
2040
|
-
var writeAPIKey = async ({
|
|
2041
|
-
|
|
2042
|
-
apiKey = "your-api-key"
|
|
2043
|
-
}) => {
|
|
1962
|
+
var writeAPIKey = async ({ provider, apiKey }) => {
|
|
1963
|
+
const envFileName = apiKey ? ".env" : ".env.example";
|
|
2044
1964
|
const key = await getAPIKey(provider);
|
|
2045
|
-
const escapedKey =
|
|
2046
|
-
const escapedApiKey =
|
|
2047
|
-
await
|
|
1965
|
+
const escapedKey = shellQuote2.quote([key]);
|
|
1966
|
+
const escapedApiKey = shellQuote2.quote([apiKey ? apiKey : "your-api-key"]);
|
|
1967
|
+
await exec(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
|
|
2048
1968
|
};
|
|
2049
1969
|
var createMastraDir = async (directory) => {
|
|
2050
1970
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
2051
|
-
const dirPath =
|
|
1971
|
+
const dirPath = path.join(process.cwd(), ...dir, "mastra");
|
|
2052
1972
|
try {
|
|
2053
|
-
await
|
|
1973
|
+
await fs4.access(dirPath);
|
|
2054
1974
|
return { ok: false };
|
|
2055
1975
|
} catch {
|
|
2056
|
-
await
|
|
1976
|
+
await fsExtra.ensureDir(dirPath);
|
|
2057
1977
|
return { ok: true, dirPath };
|
|
2058
1978
|
}
|
|
2059
1979
|
};
|
|
@@ -2065,8 +1985,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
|
|
|
2065
1985
|
throw err;
|
|
2066
1986
|
}
|
|
2067
1987
|
};
|
|
2068
|
-
var
|
|
2069
|
-
|
|
1988
|
+
var LLM_PROVIDERS = [
|
|
1989
|
+
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
1990
|
+
{ value: "anthropic", label: "Anthropic" },
|
|
1991
|
+
{ value: "groq", label: "Groq" },
|
|
1992
|
+
{ value: "google", label: "Google" },
|
|
1993
|
+
{ value: "cerebras", label: "Cerebras" },
|
|
1994
|
+
{ value: "mistral", label: "Mistral" }
|
|
1995
|
+
];
|
|
1996
|
+
var interactivePrompt = async (args2 = {}) => {
|
|
1997
|
+
const { skip = {}, options: { showBanner = true } = {} } = args2;
|
|
1998
|
+
if (showBanner) {
|
|
1999
|
+
Ie(color2.inverse(" Mastra Init "));
|
|
2000
|
+
}
|
|
2070
2001
|
const mastraProject = await Ce(
|
|
2071
2002
|
{
|
|
2072
2003
|
directory: () => he({
|
|
@@ -2074,19 +2005,15 @@ var interactivePrompt = async () => {
|
|
|
2074
2005
|
placeholder: "src/",
|
|
2075
2006
|
defaultValue: "src/"
|
|
2076
2007
|
}),
|
|
2077
|
-
llmProvider: () => ve({
|
|
2078
|
-
message: "Select default provider:",
|
|
2079
|
-
options:
|
|
2080
|
-
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
2081
|
-
{ value: "anthropic", label: "Anthropic" },
|
|
2082
|
-
{ value: "groq", label: "Groq" },
|
|
2083
|
-
{ value: "google", label: "Google" },
|
|
2084
|
-
{ value: "cerebras", label: "Cerebras" }
|
|
2085
|
-
]
|
|
2008
|
+
llmProvider: () => skip?.llmProvider ? void 0 : ve({
|
|
2009
|
+
message: "Select a default provider:",
|
|
2010
|
+
options: LLM_PROVIDERS
|
|
2086
2011
|
}),
|
|
2087
2012
|
llmApiKey: async ({ results: { llmProvider } }) => {
|
|
2013
|
+
if (skip?.llmApiKey) return void 0;
|
|
2014
|
+
const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
|
|
2088
2015
|
const keyChoice = await ve({
|
|
2089
|
-
message: `Enter your ${
|
|
2016
|
+
message: `Enter your ${llmName} API key?`,
|
|
2090
2017
|
options: [
|
|
2091
2018
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2092
2019
|
{ value: "enter", label: "Enter API key" }
|
|
@@ -2096,7 +2023,10 @@ var interactivePrompt = async () => {
|
|
|
2096
2023
|
if (keyChoice === "enter") {
|
|
2097
2024
|
return he({
|
|
2098
2025
|
message: "Enter your API key:",
|
|
2099
|
-
placeholder: "sk-..."
|
|
2026
|
+
placeholder: "sk-...",
|
|
2027
|
+
validate: (value) => {
|
|
2028
|
+
if (value.length === 0) return "API key cannot be empty";
|
|
2029
|
+
}
|
|
2100
2030
|
});
|
|
2101
2031
|
}
|
|
2102
2032
|
return void 0;
|
|
@@ -2106,7 +2036,7 @@ var interactivePrompt = async () => {
|
|
|
2106
2036
|
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2107
2037
|
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2108
2038
|
const editor = await ve({
|
|
2109
|
-
message: `Make your
|
|
2039
|
+
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2110
2040
|
options: [
|
|
2111
2041
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2112
2042
|
{
|
|
@@ -2150,19 +2080,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
2150
2080
|
);
|
|
2151
2081
|
}
|
|
2152
2082
|
if (editor === `cursor-global`) {
|
|
2153
|
-
const
|
|
2083
|
+
const confirm = await ve({
|
|
2154
2084
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2155
2085
|
options: [
|
|
2156
2086
|
{ value: "yes", label: "Yes, I understand" },
|
|
2157
2087
|
{ value: "skip", label: "No, skip for now" }
|
|
2158
2088
|
]
|
|
2159
2089
|
});
|
|
2160
|
-
if (
|
|
2090
|
+
if (confirm !== `yes`) {
|
|
2161
2091
|
return void 0;
|
|
2162
2092
|
}
|
|
2163
2093
|
}
|
|
2164
2094
|
if (editor === `windsurf`) {
|
|
2165
|
-
const
|
|
2095
|
+
const confirm = await ve({
|
|
2166
2096
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
2167
2097
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
2168
2098
|
options: [
|
|
@@ -2170,7 +2100,7 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2170
2100
|
{ value: "skip", label: "No, skip for now" }
|
|
2171
2101
|
]
|
|
2172
2102
|
});
|
|
2173
|
-
if (
|
|
2103
|
+
if (confirm !== `yes`) {
|
|
2174
2104
|
return void 0;
|
|
2175
2105
|
}
|
|
2176
2106
|
}
|
|
@@ -2186,14 +2116,193 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2186
2116
|
);
|
|
2187
2117
|
return mastraProject;
|
|
2188
2118
|
};
|
|
2119
|
+
function getPackageManager() {
|
|
2120
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
2121
|
+
const execPath = process.env.npm_execpath || "";
|
|
2122
|
+
if (userAgent.includes("yarn")) {
|
|
2123
|
+
return "yarn";
|
|
2124
|
+
}
|
|
2125
|
+
if (userAgent.includes("pnpm")) {
|
|
2126
|
+
return "pnpm";
|
|
2127
|
+
}
|
|
2128
|
+
if (userAgent.includes("npm")) {
|
|
2129
|
+
return "npm";
|
|
2130
|
+
}
|
|
2131
|
+
if (execPath.includes("yarn")) {
|
|
2132
|
+
return "yarn";
|
|
2133
|
+
}
|
|
2134
|
+
if (execPath.includes("pnpm")) {
|
|
2135
|
+
return "pnpm";
|
|
2136
|
+
}
|
|
2137
|
+
if (execPath.includes("npm")) {
|
|
2138
|
+
return "npm";
|
|
2139
|
+
}
|
|
2140
|
+
return "npm";
|
|
2141
|
+
}
|
|
2142
|
+
var logger = createLogger(false);
|
|
2143
|
+
function createLogger(debug = false) {
|
|
2144
|
+
return new PinoLogger({
|
|
2145
|
+
name: "Mastra CLI",
|
|
2146
|
+
level: debug ? "debug" : "info"
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
var exec2 = util.promisify(child_process.exec);
|
|
2150
|
+
async function cloneTemplate(options) {
|
|
2151
|
+
const { template, projectName, targetDir } = options;
|
|
2152
|
+
const projectPath = targetDir ? path.resolve(targetDir, projectName) : path.resolve(projectName);
|
|
2153
|
+
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2154
|
+
try {
|
|
2155
|
+
if (await directoryExists(projectPath)) {
|
|
2156
|
+
spinner4.error(`Directory ${projectName} already exists`);
|
|
2157
|
+
throw new Error(`Directory ${projectName} already exists`);
|
|
2158
|
+
}
|
|
2159
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2160
|
+
await updatePackageJson(projectPath, projectName);
|
|
2161
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
2162
|
+
if (await fileExists(envExamplePath)) {
|
|
2163
|
+
await fs4.copyFile(envExamplePath, path.join(projectPath, ".env"));
|
|
2164
|
+
}
|
|
2165
|
+
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2166
|
+
return projectPath;
|
|
2167
|
+
} catch (error) {
|
|
2168
|
+
spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2169
|
+
throw error;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
async function directoryExists(dirPath) {
|
|
2173
|
+
try {
|
|
2174
|
+
const stat = await fs4.stat(dirPath);
|
|
2175
|
+
return stat.isDirectory();
|
|
2176
|
+
} catch {
|
|
2177
|
+
return false;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
async function fileExists(filePath) {
|
|
2181
|
+
try {
|
|
2182
|
+
const stat = await fs4.stat(filePath);
|
|
2183
|
+
return stat.isFile();
|
|
2184
|
+
} catch {
|
|
2185
|
+
return false;
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2189
|
+
await fs4.mkdir(targetPath, { recursive: true });
|
|
2190
|
+
try {
|
|
2191
|
+
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2192
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepo, targetPath]);
|
|
2193
|
+
await exec2(degitCommand, {
|
|
2194
|
+
cwd: process.cwd()
|
|
2195
|
+
});
|
|
2196
|
+
} catch {
|
|
2197
|
+
try {
|
|
2198
|
+
const gitCommand = shellQuote2.quote(["git", "clone", repoUrl, targetPath]);
|
|
2199
|
+
await exec2(gitCommand, {
|
|
2200
|
+
cwd: process.cwd()
|
|
2201
|
+
});
|
|
2202
|
+
const gitDir = path.join(targetPath, ".git");
|
|
2203
|
+
if (await directoryExists(gitDir)) {
|
|
2204
|
+
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2205
|
+
}
|
|
2206
|
+
} catch (gitError) {
|
|
2207
|
+
throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
async function updatePackageJson(projectPath, projectName) {
|
|
2212
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
2213
|
+
try {
|
|
2214
|
+
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2215
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2216
|
+
packageJson.name = projectName;
|
|
2217
|
+
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
2218
|
+
} catch (error) {
|
|
2219
|
+
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2220
|
+
}
|
|
2221
|
+
}
|
|
2222
|
+
async function installDependencies(projectPath, packageManager) {
|
|
2223
|
+
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2224
|
+
try {
|
|
2225
|
+
const pm = packageManager || getPackageManager();
|
|
2226
|
+
const installCommand = shellQuote2.quote([pm, "install"]);
|
|
2227
|
+
await exec2(installCommand, {
|
|
2228
|
+
cwd: projectPath
|
|
2229
|
+
});
|
|
2230
|
+
spinner4.success("Dependencies installed successfully");
|
|
2231
|
+
} catch (error) {
|
|
2232
|
+
spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2233
|
+
throw error;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
|
|
2237
|
+
async function loadTemplates() {
|
|
2238
|
+
try {
|
|
2239
|
+
const response = await fetch(TEMPLATES_API_URL);
|
|
2240
|
+
if (!response.ok) {
|
|
2241
|
+
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
2242
|
+
}
|
|
2243
|
+
const templates = await response.json();
|
|
2244
|
+
return templates;
|
|
2245
|
+
} catch (error) {
|
|
2246
|
+
console.error("Error loading templates:", error);
|
|
2247
|
+
throw new Error("Failed to load templates. Please check your internet connection and try again.");
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
function pluralize(count, singular, plural) {
|
|
2251
|
+
return count === 1 ? singular : plural || `${singular}s`;
|
|
2252
|
+
}
|
|
2253
|
+
async function selectTemplate(templates) {
|
|
2254
|
+
const choices = templates.map((template) => {
|
|
2255
|
+
const parts = [];
|
|
2256
|
+
if (template.agents?.length) {
|
|
2257
|
+
parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
|
|
2258
|
+
}
|
|
2259
|
+
if (template.tools?.length) {
|
|
2260
|
+
parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
|
|
2261
|
+
}
|
|
2262
|
+
if (template.workflows?.length) {
|
|
2263
|
+
parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
|
|
2264
|
+
}
|
|
2265
|
+
if (template.mcp?.length) {
|
|
2266
|
+
parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
|
|
2267
|
+
}
|
|
2268
|
+
if (template.networks?.length) {
|
|
2269
|
+
parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
|
|
2270
|
+
}
|
|
2271
|
+
return {
|
|
2272
|
+
value: template,
|
|
2273
|
+
label: template.title,
|
|
2274
|
+
hint: parts.join(", ") || "Template components"
|
|
2275
|
+
};
|
|
2276
|
+
});
|
|
2277
|
+
const selected = await ve({
|
|
2278
|
+
message: "Select a template:",
|
|
2279
|
+
options: choices
|
|
2280
|
+
});
|
|
2281
|
+
if (pD(selected)) {
|
|
2282
|
+
return null;
|
|
2283
|
+
}
|
|
2284
|
+
return selected;
|
|
2285
|
+
}
|
|
2286
|
+
function findTemplateByName(templates, templateName) {
|
|
2287
|
+
let template = templates.find((t) => t.slug === templateName);
|
|
2288
|
+
if (template) return template;
|
|
2289
|
+
const slugWithPrefix = `template-${templateName}`;
|
|
2290
|
+
template = templates.find((t) => t.slug === slugWithPrefix);
|
|
2291
|
+
if (template) return template;
|
|
2292
|
+
template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
|
|
2293
|
+
if (template) return template;
|
|
2294
|
+
return null;
|
|
2295
|
+
}
|
|
2296
|
+
function getDefaultProjectName(template) {
|
|
2297
|
+
return template.slug.replace(/^template-/, "");
|
|
2298
|
+
}
|
|
2189
2299
|
var s = Y();
|
|
2190
|
-
var exec3 = util.promisify(child_process.exec);
|
|
2191
2300
|
var init = async ({
|
|
2192
|
-
directory,
|
|
2193
|
-
addExample = false,
|
|
2301
|
+
directory = "src/",
|
|
2194
2302
|
components,
|
|
2195
2303
|
llmProvider = "openai",
|
|
2196
2304
|
llmApiKey,
|
|
2305
|
+
addExample = false,
|
|
2197
2306
|
configureEditorWithDocsMCP
|
|
2198
2307
|
}) => {
|
|
2199
2308
|
s.start("Initializing Mastra");
|
|
@@ -2209,7 +2318,8 @@ var init = async ({
|
|
|
2209
2318
|
dirPath,
|
|
2210
2319
|
addExample,
|
|
2211
2320
|
addWorkflow: components.includes("workflows"),
|
|
2212
|
-
addAgent: components.includes("agents")
|
|
2321
|
+
addAgent: components.includes("agents"),
|
|
2322
|
+
addScorers: components.includes("scorers")
|
|
2213
2323
|
}),
|
|
2214
2324
|
...components.map((component) => createComponentsDir(dirPath, component)),
|
|
2215
2325
|
writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
|
|
@@ -2233,13 +2343,16 @@ var init = async ({
|
|
|
2233
2343
|
if (needsLoggers) {
|
|
2234
2344
|
await depService.installPackages(["@mastra/loggers"]);
|
|
2235
2345
|
}
|
|
2346
|
+
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2347
|
+
if (needsObservability) {
|
|
2348
|
+
await depService.installPackages(["@mastra/observability"]);
|
|
2349
|
+
}
|
|
2350
|
+
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2351
|
+
if (needsEvals) {
|
|
2352
|
+
await depService.installPackages(["@mastra/evals"]);
|
|
2353
|
+
}
|
|
2236
2354
|
}
|
|
2237
2355
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2238
|
-
const aiSdkPackage = getAISDKPackage(llmProvider);
|
|
2239
|
-
const depsService = new DepsService();
|
|
2240
|
-
const pm = depsService.packageManager;
|
|
2241
|
-
const installCommand = getPackageManagerInstallCommand(pm);
|
|
2242
|
-
await exec3(`${pm} ${installCommand} ${aiSdkPackage}`);
|
|
2243
2356
|
if (configureEditorWithDocsMCP) {
|
|
2244
2357
|
await installMastraDocsMCPServer({
|
|
2245
2358
|
editor: configureEditorWithDocsMCP,
|
|
@@ -2266,10 +2379,10 @@ var init = async ({
|
|
|
2266
2379
|
return { success: false };
|
|
2267
2380
|
}
|
|
2268
2381
|
};
|
|
2269
|
-
var
|
|
2382
|
+
var exec3 = util.promisify(child_process.exec);
|
|
2270
2383
|
var execWithTimeout = async (command, timeoutMs) => {
|
|
2271
2384
|
try {
|
|
2272
|
-
const promise =
|
|
2385
|
+
const promise = exec3(command, { killSignal: "SIGTERM" });
|
|
2273
2386
|
if (!timeoutMs) {
|
|
2274
2387
|
return await promise;
|
|
2275
2388
|
}
|
|
@@ -2293,9 +2406,9 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2293
2406
|
}
|
|
2294
2407
|
};
|
|
2295
2408
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2296
|
-
let installCommand =
|
|
2409
|
+
let installCommand = getPackageManagerAddCommand(pm);
|
|
2297
2410
|
if (isDev) {
|
|
2298
|
-
installCommand = `${installCommand}
|
|
2411
|
+
installCommand = `${installCommand} -D`;
|
|
2299
2412
|
}
|
|
2300
2413
|
try {
|
|
2301
2414
|
await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
|
|
@@ -2317,23 +2430,39 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
|
|
|
2317
2430
|
var createMastraProject = async ({
|
|
2318
2431
|
projectName: name,
|
|
2319
2432
|
createVersionTag,
|
|
2320
|
-
timeout
|
|
2433
|
+
timeout,
|
|
2434
|
+
llmProvider,
|
|
2435
|
+
llmApiKey,
|
|
2436
|
+
needsInteractive
|
|
2321
2437
|
}) => {
|
|
2322
2438
|
Ie(color2.inverse(" Mastra Create "));
|
|
2323
2439
|
const projectName = name ?? await he({
|
|
2324
2440
|
message: "What do you want to name your project?",
|
|
2325
2441
|
placeholder: "my-mastra-app",
|
|
2326
|
-
defaultValue: "my-mastra-app"
|
|
2442
|
+
defaultValue: "my-mastra-app",
|
|
2443
|
+
validate: (value) => {
|
|
2444
|
+
if (value.length === 0) return "Project name cannot be empty";
|
|
2445
|
+
if (fs3__default__default.existsSync(value)) {
|
|
2446
|
+
return `A directory named "${value}" already exists. Please choose a different name.`;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2327
2449
|
});
|
|
2328
2450
|
if (pD(projectName)) {
|
|
2329
2451
|
xe("Operation cancelled");
|
|
2330
2452
|
process.exit(0);
|
|
2331
2453
|
}
|
|
2454
|
+
let result;
|
|
2455
|
+
if (needsInteractive) {
|
|
2456
|
+
result = await interactivePrompt({
|
|
2457
|
+
options: { showBanner: false },
|
|
2458
|
+
skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
|
|
2459
|
+
});
|
|
2460
|
+
}
|
|
2332
2461
|
const s2 = Y();
|
|
2333
2462
|
try {
|
|
2334
2463
|
s2.start("Creating project");
|
|
2335
2464
|
try {
|
|
2336
|
-
await
|
|
2465
|
+
await fs4.mkdir(projectName);
|
|
2337
2466
|
} catch (error) {
|
|
2338
2467
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2339
2468
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2345,12 +2474,12 @@ var createMastraProject = async ({
|
|
|
2345
2474
|
}
|
|
2346
2475
|
process.chdir(projectName);
|
|
2347
2476
|
const pm = getPackageManager();
|
|
2348
|
-
const installCommand =
|
|
2477
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
2349
2478
|
s2.message("Initializing project structure");
|
|
2350
2479
|
try {
|
|
2351
|
-
await
|
|
2352
|
-
await
|
|
2353
|
-
await
|
|
2480
|
+
await exec3(`npm init -y`);
|
|
2481
|
+
await exec3(`npm pkg set type="module"`);
|
|
2482
|
+
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
2354
2483
|
const depsService = new DepsService();
|
|
2355
2484
|
await depsService.addScriptsToPackageJson({
|
|
2356
2485
|
dev: "mastra dev",
|
|
@@ -2365,9 +2494,9 @@ var createMastraProject = async ({
|
|
|
2365
2494
|
s2.stop("Project structure created");
|
|
2366
2495
|
s2.start(`Installing ${pm} dependencies`);
|
|
2367
2496
|
try {
|
|
2368
|
-
await
|
|
2369
|
-
await
|
|
2370
|
-
await
|
|
2497
|
+
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2498
|
+
await exec3(`${pm} ${installCommand} typescript @types/node --save-dev`);
|
|
2499
|
+
await exec3(`echo '{
|
|
2371
2500
|
"compilerOptions": {
|
|
2372
2501
|
"target": "ES2022",
|
|
2373
2502
|
"module": "ES2022",
|
|
@@ -2389,15 +2518,15 @@ var createMastraProject = async ({
|
|
|
2389
2518
|
);
|
|
2390
2519
|
}
|
|
2391
2520
|
s2.stop(`${pm} dependencies installed`);
|
|
2392
|
-
s2.start("Installing
|
|
2521
|
+
s2.start("Installing Mastra CLI");
|
|
2393
2522
|
const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
|
|
2394
2523
|
try {
|
|
2395
2524
|
await installMastraDependency(pm, "mastra", versionTag, true, timeout);
|
|
2396
2525
|
} catch (error) {
|
|
2397
2526
|
throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2398
2527
|
}
|
|
2399
|
-
s2.stop("
|
|
2400
|
-
s2.start("Installing dependencies");
|
|
2528
|
+
s2.stop("Mastra CLI installed");
|
|
2529
|
+
s2.start("Installing Mastra dependencies");
|
|
2401
2530
|
try {
|
|
2402
2531
|
await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
|
|
2403
2532
|
await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
|
|
@@ -2410,21 +2539,21 @@ var createMastraProject = async ({
|
|
|
2410
2539
|
s2.stop("Mastra dependencies installed");
|
|
2411
2540
|
s2.start("Adding .gitignore");
|
|
2412
2541
|
try {
|
|
2413
|
-
await
|
|
2414
|
-
await
|
|
2415
|
-
await
|
|
2416
|
-
await
|
|
2417
|
-
await
|
|
2418
|
-
await
|
|
2419
|
-
await
|
|
2420
|
-
await
|
|
2542
|
+
await exec3(`echo output.txt >> .gitignore`);
|
|
2543
|
+
await exec3(`echo node_modules >> .gitignore`);
|
|
2544
|
+
await exec3(`echo dist >> .gitignore`);
|
|
2545
|
+
await exec3(`echo .mastra >> .gitignore`);
|
|
2546
|
+
await exec3(`echo .env.development >> .gitignore`);
|
|
2547
|
+
await exec3(`echo .env >> .gitignore`);
|
|
2548
|
+
await exec3(`echo *.db >> .gitignore`);
|
|
2549
|
+
await exec3(`echo *.db-* >> .gitignore`);
|
|
2421
2550
|
} catch (error) {
|
|
2422
2551
|
throw new Error(`Failed to create .gitignore: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2423
2552
|
}
|
|
2424
2553
|
s2.stop(".gitignore added");
|
|
2425
2554
|
Se("Project created successfully");
|
|
2426
|
-
console.
|
|
2427
|
-
return { projectName };
|
|
2555
|
+
console.info("");
|
|
2556
|
+
return { projectName, result };
|
|
2428
2557
|
} catch (error) {
|
|
2429
2558
|
s2.stop();
|
|
2430
2559
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
@@ -2434,21 +2563,24 @@ var createMastraProject = async ({
|
|
|
2434
2563
|
};
|
|
2435
2564
|
var create = async (args2) => {
|
|
2436
2565
|
if (args2.template !== void 0) {
|
|
2437
|
-
await createFromTemplate(args2);
|
|
2566
|
+
await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
|
|
2438
2567
|
return;
|
|
2439
2568
|
}
|
|
2440
|
-
const
|
|
2569
|
+
const needsInteractive = args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0;
|
|
2570
|
+
const { projectName, result } = await createMastraProject({
|
|
2441
2571
|
projectName: args2?.projectName,
|
|
2442
2572
|
createVersionTag: args2?.createVersionTag,
|
|
2443
|
-
timeout: args2?.timeout
|
|
2573
|
+
timeout: args2?.timeout,
|
|
2574
|
+
llmProvider: args2?.llmProvider,
|
|
2575
|
+
llmApiKey: args2?.llmApiKey,
|
|
2576
|
+
needsInteractive
|
|
2444
2577
|
});
|
|
2445
2578
|
const directory = args2.directory || "src/";
|
|
2446
|
-
if (
|
|
2447
|
-
const result = await interactivePrompt();
|
|
2579
|
+
if (needsInteractive && result) {
|
|
2448
2580
|
await init({
|
|
2449
2581
|
...result,
|
|
2450
2582
|
llmApiKey: result?.llmApiKey,
|
|
2451
|
-
components: ["agents", "tools", "workflows"],
|
|
2583
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2452
2584
|
addExample: true
|
|
2453
2585
|
});
|
|
2454
2586
|
postCreate({ projectName });
|
|
@@ -2474,21 +2606,116 @@ var postCreate = ({ projectName }) => {
|
|
|
2474
2606
|
${color2.cyan(`${packageManager} run dev`)}
|
|
2475
2607
|
`);
|
|
2476
2608
|
};
|
|
2609
|
+
function isGitHubUrl(url) {
|
|
2610
|
+
try {
|
|
2611
|
+
const parsedUrl = new URL(url);
|
|
2612
|
+
return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
|
|
2613
|
+
} catch {
|
|
2614
|
+
return false;
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
async function validateGitHubProject(githubUrl) {
|
|
2618
|
+
const errors = [];
|
|
2619
|
+
try {
|
|
2620
|
+
const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
|
|
2621
|
+
const owner = urlParts[0];
|
|
2622
|
+
const repo = urlParts[1]?.replace(".git", "");
|
|
2623
|
+
if (!owner || !repo) {
|
|
2624
|
+
throw new Error("Invalid GitHub URL format");
|
|
2625
|
+
}
|
|
2626
|
+
const branches = ["main", "master"];
|
|
2627
|
+
let packageJsonContent = null;
|
|
2628
|
+
let indexContent = null;
|
|
2629
|
+
for (const branch of branches) {
|
|
2630
|
+
try {
|
|
2631
|
+
const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
|
|
2632
|
+
const packageJsonResponse = await fetch(packageJsonUrl);
|
|
2633
|
+
if (packageJsonResponse.ok) {
|
|
2634
|
+
packageJsonContent = await packageJsonResponse.text();
|
|
2635
|
+
const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
|
|
2636
|
+
const indexResponse = await fetch(indexUrl);
|
|
2637
|
+
if (indexResponse.ok) {
|
|
2638
|
+
indexContent = await indexResponse.text();
|
|
2639
|
+
}
|
|
2640
|
+
break;
|
|
2641
|
+
}
|
|
2642
|
+
} catch {
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
if (!packageJsonContent) {
|
|
2646
|
+
errors.push("Could not fetch package.json from repository");
|
|
2647
|
+
return { isValid: false, errors };
|
|
2648
|
+
}
|
|
2649
|
+
try {
|
|
2650
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2651
|
+
const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
|
|
2652
|
+
if (!hasMastraCore) {
|
|
2653
|
+
errors.push("Missing @mastra/core dependency in package.json");
|
|
2654
|
+
}
|
|
2655
|
+
} catch {
|
|
2656
|
+
errors.push("Invalid package.json format");
|
|
2657
|
+
}
|
|
2658
|
+
if (!indexContent) {
|
|
2659
|
+
errors.push("Missing src/mastra/index.ts file");
|
|
2660
|
+
} else {
|
|
2661
|
+
const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
|
|
2662
|
+
if (!hasMastraExport) {
|
|
2663
|
+
errors.push("src/mastra/index.ts does not export a Mastra instance");
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
return { isValid: errors.length === 0, errors };
|
|
2667
|
+
} catch (error) {
|
|
2668
|
+
errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2669
|
+
return { isValid: false, errors };
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
async function createFromGitHubUrl(url) {
|
|
2673
|
+
const urlParts = new URL(url).pathname.split("/").filter(Boolean);
|
|
2674
|
+
const owner = urlParts[0] || "unknown";
|
|
2675
|
+
const repo = urlParts[1] || "unknown";
|
|
2676
|
+
return {
|
|
2677
|
+
githubUrl: url,
|
|
2678
|
+
title: `${owner}/${repo}`,
|
|
2679
|
+
slug: repo,
|
|
2680
|
+
agents: [],
|
|
2681
|
+
mcp: [],
|
|
2682
|
+
tools: [],
|
|
2683
|
+
networks: [],
|
|
2684
|
+
workflows: []
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2477
2687
|
async function createFromTemplate(args2) {
|
|
2478
|
-
const templates = await loadTemplates();
|
|
2479
2688
|
let selectedTemplate;
|
|
2480
2689
|
if (args2.template === true) {
|
|
2481
|
-
|
|
2482
|
-
|
|
2690
|
+
const templates = await loadTemplates();
|
|
2691
|
+
const selected = await selectTemplate(templates);
|
|
2692
|
+
if (!selected) {
|
|
2483
2693
|
M.info("No template selected. Exiting.");
|
|
2484
2694
|
return;
|
|
2485
2695
|
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
if (
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2696
|
+
selectedTemplate = selected;
|
|
2697
|
+
} else if (args2.template && typeof args2.template === "string") {
|
|
2698
|
+
if (isGitHubUrl(args2.template)) {
|
|
2699
|
+
const spinner4 = Y();
|
|
2700
|
+
spinner4.start("Validating GitHub repository...");
|
|
2701
|
+
const validation = await validateGitHubProject(args2.template);
|
|
2702
|
+
if (!validation.isValid) {
|
|
2703
|
+
spinner4.stop("Validation failed");
|
|
2704
|
+
M.error("This does not appear to be a valid Mastra project:");
|
|
2705
|
+
validation.errors.forEach((error) => M.error(` - ${error}`));
|
|
2706
|
+
throw new Error("Invalid Mastra project");
|
|
2707
|
+
}
|
|
2708
|
+
spinner4.stop("Valid Mastra project \u2713");
|
|
2709
|
+
selectedTemplate = await createFromGitHubUrl(args2.template);
|
|
2710
|
+
} else {
|
|
2711
|
+
const templates = await loadTemplates();
|
|
2712
|
+
const found = findTemplateByName(templates, args2.template);
|
|
2713
|
+
if (!found) {
|
|
2714
|
+
M.error(`Template "${args2.template}" not found. Available templates:`);
|
|
2715
|
+
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2716
|
+
throw new Error(`Template "${args2.template}" not found`);
|
|
2717
|
+
}
|
|
2718
|
+
selectedTemplate = found;
|
|
2492
2719
|
}
|
|
2493
2720
|
}
|
|
2494
2721
|
if (!selectedTemplate) {
|
|
@@ -2509,8 +2736,13 @@ async function createFromTemplate(args2) {
|
|
|
2509
2736
|
projectName = response;
|
|
2510
2737
|
}
|
|
2511
2738
|
try {
|
|
2512
|
-
const analytics = getAnalytics();
|
|
2513
|
-
if (analytics)
|
|
2739
|
+
const analytics = args2.injectedAnalytics || getAnalytics();
|
|
2740
|
+
if (analytics) {
|
|
2741
|
+
analytics.trackEvent("cli_template_used", {
|
|
2742
|
+
template_slug: selectedTemplate.slug,
|
|
2743
|
+
template_title: selectedTemplate.title
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2514
2746
|
const projectPath = await cloneTemplate({
|
|
2515
2747
|
template: selectedTemplate,
|
|
2516
2748
|
projectName
|
|
@@ -2519,7 +2751,7 @@ async function createFromTemplate(args2) {
|
|
|
2519
2751
|
Me(`
|
|
2520
2752
|
${color2.green("Mastra template installed!")}
|
|
2521
2753
|
|
|
2522
|
-
Add the necessary environment
|
|
2754
|
+
Add the necessary environment
|
|
2523
2755
|
variables in your ${color2.cyan(".env")} file
|
|
2524
2756
|
`);
|
|
2525
2757
|
postCreate({ projectName });
|
|
@@ -2532,14 +2764,14 @@ async function createFromTemplate(args2) {
|
|
|
2532
2764
|
async function getPackageVersion() {
|
|
2533
2765
|
const __filename = fileURLToPath(import.meta.url);
|
|
2534
2766
|
const __dirname = dirname(__filename);
|
|
2535
|
-
const pkgJsonPath =
|
|
2536
|
-
const content = await fsExtra.readJSON(pkgJsonPath);
|
|
2767
|
+
const pkgJsonPath = path.join(__dirname, "..", "package.json");
|
|
2768
|
+
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2537
2769
|
return content.version;
|
|
2538
2770
|
}
|
|
2539
2771
|
async function getCreateVersionTag() {
|
|
2540
2772
|
try {
|
|
2541
2773
|
const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
|
|
2542
|
-
const json = await fsExtra.readJSON(pkgPath);
|
|
2774
|
+
const json = await fsExtra$1.readJSON(pkgPath);
|
|
2543
2775
|
const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
|
|
2544
2776
|
const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
|
|
2545
2777
|
const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
|
|
@@ -2563,29 +2795,30 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
2563
2795
|
analytics.trackCommand({
|
|
2564
2796
|
command: "version"
|
|
2565
2797
|
});
|
|
2566
|
-
console.
|
|
2798
|
+
console.info(`create-mastra ${version}`);
|
|
2567
2799
|
} catch {
|
|
2568
2800
|
}
|
|
2569
2801
|
});
|
|
2570
2802
|
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2571
2803
|
"-p, --project-name <string>",
|
|
2572
2804
|
"Project name that will be used in package.json and as the project directory name."
|
|
2573
|
-
).option("--default", "Quick start with defaults(src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
|
|
2805
|
+
).option("--default", "Quick start with defaults (src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows, scorers)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
|
|
2574
2806
|
"--template [template-name]",
|
|
2575
|
-
"Create project from a template (use template name or leave blank to select from list)"
|
|
2807
|
+
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2576
2808
|
).action(async (projectNameArg, args) => {
|
|
2577
2809
|
const projectName = projectNameArg || args.projectName;
|
|
2578
2810
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
2579
2811
|
if (args.default) {
|
|
2580
2812
|
await create({
|
|
2581
|
-
components: ["agents", "tools", "workflows"],
|
|
2813
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2582
2814
|
llmProvider: "openai",
|
|
2583
2815
|
addExample: true,
|
|
2584
2816
|
createVersionTag,
|
|
2585
2817
|
timeout,
|
|
2586
2818
|
mcpServer: args.mcp,
|
|
2587
2819
|
directory: "src/",
|
|
2588
|
-
template: args.template
|
|
2820
|
+
template: args.template,
|
|
2821
|
+
analytics
|
|
2589
2822
|
});
|
|
2590
2823
|
return;
|
|
2591
2824
|
}
|
|
@@ -2593,13 +2826,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2593
2826
|
components: args.components ? args.components.split(",") : [],
|
|
2594
2827
|
llmProvider: args.llm,
|
|
2595
2828
|
addExample: args.example,
|
|
2596
|
-
llmApiKey: args
|
|
2829
|
+
llmApiKey: args.llmApiKey,
|
|
2597
2830
|
createVersionTag,
|
|
2598
2831
|
timeout,
|
|
2599
2832
|
projectName,
|
|
2600
2833
|
directory: args.dir,
|
|
2601
2834
|
mcpServer: args.mcp,
|
|
2602
|
-
template: args.template
|
|
2835
|
+
template: args.template,
|
|
2836
|
+
analytics
|
|
2603
2837
|
});
|
|
2604
2838
|
});
|
|
2605
2839
|
program.parse(process.argv);
|