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/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 fs4__default from 'node:fs';
5
- import fs4__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
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 path3, { dirname } from 'node:path';
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 fs from 'node:fs/promises';
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 { execa } from 'execa';
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 = path3.dirname(__filename);
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 = path3.join(__dirname, "mastra-cli.json");
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(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
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$1 = {};
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$1;
691
+ if (hasRequiredShellQuote) return shellQuote;
692
692
  hasRequiredShellQuote = 1;
693
693
 
694
- shellQuote$1.quote = requireQuote();
695
- shellQuote$1.parse = requireParse();
696
- return shellQuote$1;
694
+ shellQuote.quote = requireQuote();
695
+ shellQuote.parse = requireParse();
696
+ return shellQuote;
697
697
  }
698
698
 
699
699
  var shellQuoteExports = requireShellQuote();
700
- var shellQuote = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
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) + openCode;
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 = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1511
- var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1512
- path3.join(process.cwd(), ".vscode", "mcp.json");
1513
- var vscodeGlobalMCPConfigPath = path3.join(
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" ? 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")
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(path3.join(directory, ".cursor", "mcp.json"), "cursor");
1242
+ await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
1520
1243
  }
1521
1244
  if (editor === `vscode`) {
1522
- await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode");
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
- var EnvService = class {
1571
- };
1572
- var FileEnvService = class extends EnvService {
1573
- filePath;
1574
- constructor(filePath) {
1575
- super();
1576
- this.filePath = filePath;
1577
- }
1578
- readFile(filePath) {
1579
- return new Promise((resolve, reject) => {
1580
- fs4__default.readFile(filePath, "utf8", (err, data) => {
1581
- if (err) reject(err);
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
- fs4__default.writeFile(filePath, data, "utf8", (err) => {
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.log(`${key} set to ${value} in ENV file.`);
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 = path3.dirname(__filename);
1642
- const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1643
- const fileString = fs4__default__default.readFileSync(filePath, "utf8");
1644
- if (fs4__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1645
- console.log(`${outputFilePath} already exists`);
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 fsExtra3.outputFile(outputFilePath, fileString);
1467
+ await fsExtra.outputFile(outputFilePath, fileString);
1649
1468
  return true;
1650
1469
  }
1651
1470
  async setupEnvFile({ dbUrl }) {
1652
- const envPath = path3.join(process.cwd(), ".env.development");
1653
- await fsExtra3.ensureFile(envPath);
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 (fs4__default__default.existsSync(f)) {
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 = fs4__default__default.readFileSync(filePath, "utf8");
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
- fs4__default__default.writeFileSync(filePath, fileContent);
1492
+ fs3__default__default.writeFileSync(filePath, fileContent);
1674
1493
  }
1675
1494
  };
1676
- var exec2 = util.promisify(child_process.exec);
1677
- var getAISDKPackage = (llmProvider) => {
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
- providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
1698
- modelItem = `openai('gpt-4o-mini')`;
1498
+ return `'openai/gpt-4o-mini'`;
1699
1499
  } else if (llmProvider === "anthropic") {
1700
- providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
1701
- modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
1500
+ return `'anthropic/claude-sonnet-4-5-20250929'`;
1702
1501
  } else if (llmProvider === "groq") {
1703
- providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1704
- modelItem = `groq('llama-3.3-70b-versatile')`;
1502
+ return `'groq/llama-3.3-70b-versatile'`;
1705
1503
  } else if (llmProvider === "google") {
1706
- providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
1707
- modelItem = `google('gemini-2.5-pro-exp-03-25')`;
1504
+ return `'google/gemini-2.5-pro'`;
1708
1505
  } else if (llmProvider === "cerebras") {
1709
- providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
1710
- modelItem = `cerebras('llama-3.3-70b')`;
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 { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
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: ${modelItem},
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 fs.writeFile(destPath, "");
1754
- await fs.writeFile(destPath, formattedContent);
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 fs.writeFile(destPath, formattedContent);
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(llmprovider, destPath, importComponents.includes("tools"));
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 fsExtra3.ensureDir(componentPath);
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 = path3.join(indexPath);
1890
+ const destPath = path.join(indexPath);
1977
1891
  try {
1978
- await fs.writeFile(destPath, "");
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 fs.writeFile(
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 fs.writeFile(
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 telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
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
- provider,
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 = shellQuote.quote([key]);
2046
- const escapedApiKey = shellQuote.quote([apiKey]);
2047
- await exec2(`echo ${escapedKey}=${escapedApiKey} >> .env`);
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 = path3.join(process.cwd(), ...dir, "mastra");
1971
+ const dirPath = path.join(process.cwd(), ...dir, "mastra");
2052
1972
  try {
2053
- await fs.access(dirPath);
1973
+ await fs4.access(dirPath);
2054
1974
  return { ok: false };
2055
1975
  } catch {
2056
- await fsExtra3.ensureDir(dirPath);
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 interactivePrompt = async () => {
2069
- Ie(color2.inverse(" Mastra Init "));
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 ${llmProvider} API key?`,
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 AI IDE into a Mastra expert? (installs Mastra docs MCP server)`,
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 confirm2 = await ve({
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 (confirm2 !== `yes`) {
2090
+ if (confirm !== `yes`) {
2161
2091
  return void 0;
2162
2092
  }
2163
2093
  }
2164
2094
  if (editor === `windsurf`) {
2165
- const confirm2 = await ve({
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 (confirm2 !== `yes`) {
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 exec4 = util.promisify(child_process.exec);
2382
+ var exec3 = util.promisify(child_process.exec);
2270
2383
  var execWithTimeout = async (command, timeoutMs) => {
2271
2384
  try {
2272
- const promise = exec4(command, { killSignal: "SIGTERM" });
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 = getPackageManagerInstallCommand(pm);
2409
+ let installCommand = getPackageManagerAddCommand(pm);
2297
2410
  if (isDev) {
2298
- installCommand = `${installCommand} --save-dev`;
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 fs.mkdir(projectName);
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 = getPackageManagerInstallCommand(pm);
2477
+ const installCommand = getPackageManagerAddCommand(pm);
2349
2478
  s2.message("Initializing project structure");
2350
2479
  try {
2351
- await exec4(`npm init -y`);
2352
- await exec4(`npm pkg set type="module"`);
2353
- await exec4(`npm pkg set engines.node=">=20.9.0"`);
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 exec4(`${pm} ${installCommand} zod@^3`);
2369
- await exec4(`${pm} ${installCommand} typescript @types/node --save-dev`);
2370
- await exec4(`echo '{
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 mastra");
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("mastra installed");
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 exec4(`echo output.txt >> .gitignore`);
2414
- await exec4(`echo node_modules >> .gitignore`);
2415
- await exec4(`echo dist >> .gitignore`);
2416
- await exec4(`echo .mastra >> .gitignore`);
2417
- await exec4(`echo .env.development >> .gitignore`);
2418
- await exec4(`echo .env >> .gitignore`);
2419
- await exec4(`echo *.db >> .gitignore`);
2420
- await exec4(`echo *.db-* >> .gitignore`);
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.log("");
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 { projectName } = await createMastraProject({
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 (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
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
- selectedTemplate = await selectTemplate(templates);
2482
- if (!selectedTemplate) {
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
- } else if (args2.template) {
2487
- selectedTemplate = findTemplateByName(templates, args2.template);
2488
- if (!selectedTemplate) {
2489
- M.error(`Template "${args2.template}" not found. Available templates:`);
2490
- templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2491
- throw new Error(`Template "${args2.template}" not found`);
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 = path3.join(__dirname, "..", "package.json");
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.log(`create-mastra ${version}`);
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["llm-api-key"],
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);