create-mastra 0.0.0-message-list-update-20250715150321 → 0.0.0-monorepo-binary-20251013210052

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 fs3__default from 'node:fs';
5
- import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import * as fs4__default from 'node:fs';
5
+ import fs4__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
- import path2, { dirname } from 'node:path';
7
+ import path3, { 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,22 @@ 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 fs5 from 'node:fs/promises';
15
16
  import child_process from 'node:child_process';
16
- import fs4 from 'node:fs/promises';
17
- import { execa } from 'execa';
18
- import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
19
- import prettier from 'prettier';
20
17
  import tty from 'node:tty';
21
18
  import pino from 'pino';
22
19
  import pretty from 'pino-pretty';
23
- import fsExtra from 'fs-extra';
20
+ import { execa } from 'execa';
21
+ import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
22
+ import prettier from 'prettier';
23
+ import fsExtra$1 from 'fs-extra';
24
24
 
25
25
  var __filename = fileURLToPath(import.meta.url);
26
- var __dirname = path2.dirname(__filename);
26
+ var __dirname = path3.dirname(__filename);
27
+ var analyticsInstance = null;
28
+ function getAnalytics() {
29
+ return analyticsInstance;
30
+ }
27
31
  var PosthogAnalytics = class {
28
32
  sessionId;
29
33
  client;
@@ -35,7 +39,7 @@ var PosthogAnalytics = class {
35
39
  host = "https://app.posthog.com"
36
40
  }) {
37
41
  this.version = version;
38
- const cliConfigPath = path2.join(__dirname, "mastra-cli.json");
42
+ const cliConfigPath = path3.join(__dirname, "mastra-cli.json");
39
43
  if (existsSync(cliConfigPath)) {
40
44
  try {
41
45
  const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
@@ -63,7 +67,7 @@ var PosthogAnalytics = class {
63
67
  }
64
68
  writeCliConfig({ distinctId, sessionId }) {
65
69
  try {
66
- writeFileSync(path2.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
70
+ writeFileSync(path3.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
67
71
  } catch {
68
72
  }
69
73
  }
@@ -113,6 +117,22 @@ var PosthogAnalytics = class {
113
117
  }
114
118
  });
115
119
  }
120
+ trackEvent(eventName, properties) {
121
+ try {
122
+ if (!this.client) {
123
+ return;
124
+ }
125
+ this.client.capture({
126
+ distinctId: this.distinctId,
127
+ event: eventName,
128
+ properties: {
129
+ ...this.getSystemProperties(),
130
+ ...properties
131
+ }
132
+ });
133
+ } catch {
134
+ }
135
+ }
116
136
  trackCommand(options) {
117
137
  try {
118
138
  if (!this.client) {
@@ -704,13 +724,18 @@ const format = (open, close) => {
704
724
  // Handle nested colors.
705
725
 
706
726
  // We could have done this, but it's too slow (as of Node.js 22).
707
- // return openCode + string.replaceAll(closeCode, openCode) + closeCode;
727
+ // return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
708
728
 
709
729
  let result = openCode;
710
730
  let lastIndex = 0;
711
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
+
712
737
  while (index !== -1) {
713
- result += string.slice(lastIndex, index) + openCode;
738
+ result += string.slice(lastIndex, index) + replaceCode;
714
739
  lastIndex = index + closeCode.length;
715
740
  index = string.indexOf(closeCode, lastIndex);
716
741
  }
@@ -1153,6 +1178,197 @@ var PinoLogger = class extends MastraLogger {
1153
1178
  }
1154
1179
  };
1155
1180
 
1181
+ function getPackageManager() {
1182
+ const userAgent = process.env.npm_config_user_agent || "";
1183
+ const execPath = process.env.npm_execpath || "";
1184
+ if (userAgent.includes("yarn")) {
1185
+ return "yarn";
1186
+ }
1187
+ if (userAgent.includes("pnpm")) {
1188
+ return "pnpm";
1189
+ }
1190
+ if (userAgent.includes("npm")) {
1191
+ return "npm";
1192
+ }
1193
+ if (execPath.includes("yarn")) {
1194
+ return "yarn";
1195
+ }
1196
+ if (execPath.includes("pnpm")) {
1197
+ return "pnpm";
1198
+ }
1199
+ if (execPath.includes("npm")) {
1200
+ return "npm";
1201
+ }
1202
+ return "npm";
1203
+ }
1204
+ var logger = new PinoLogger({
1205
+ name: "Mastra CLI",
1206
+ level: "info"
1207
+ });
1208
+ var exec = util.promisify(child_process.exec);
1209
+ async function cloneTemplate(options) {
1210
+ const { template, projectName, targetDir } = options;
1211
+ const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
1212
+ const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
1213
+ try {
1214
+ if (await directoryExists(projectPath)) {
1215
+ spinner5.error(`Directory ${projectName} already exists`);
1216
+ throw new Error(`Directory ${projectName} already exists`);
1217
+ }
1218
+ await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
1219
+ await updatePackageJson(projectPath, projectName);
1220
+ const envExamplePath = path3.join(projectPath, ".env.example");
1221
+ if (await fileExists(envExamplePath)) {
1222
+ await fs5.copyFile(envExamplePath, path3.join(projectPath, ".env"));
1223
+ }
1224
+ spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
1225
+ return projectPath;
1226
+ } catch (error) {
1227
+ spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
1228
+ throw error;
1229
+ }
1230
+ }
1231
+ async function directoryExists(dirPath) {
1232
+ try {
1233
+ const stat = await fs5.stat(dirPath);
1234
+ return stat.isDirectory();
1235
+ } catch {
1236
+ return false;
1237
+ }
1238
+ }
1239
+ async function fileExists(filePath) {
1240
+ try {
1241
+ const stat = await fs5.stat(filePath);
1242
+ return stat.isFile();
1243
+ } catch {
1244
+ return false;
1245
+ }
1246
+ }
1247
+ async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
1248
+ await fs5.mkdir(targetPath, { recursive: true });
1249
+ try {
1250
+ const degitRepo = repoUrl.replace("https://github.com/", "");
1251
+ const degitCommand = shellQuote.quote(["npx", "degit", degitRepo, targetPath]);
1252
+ await exec(degitCommand, {
1253
+ cwd: process.cwd()
1254
+ });
1255
+ } catch {
1256
+ try {
1257
+ const gitCommand = shellQuote.quote(["git", "clone", repoUrl, targetPath]);
1258
+ await exec(gitCommand, {
1259
+ cwd: process.cwd()
1260
+ });
1261
+ const gitDir = path3.join(targetPath, ".git");
1262
+ if (await directoryExists(gitDir)) {
1263
+ await fs5.rm(gitDir, { recursive: true, force: true });
1264
+ }
1265
+ } catch (gitError) {
1266
+ throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
1267
+ }
1268
+ }
1269
+ }
1270
+ async function updatePackageJson(projectPath, projectName) {
1271
+ const packageJsonPath = path3.join(projectPath, "package.json");
1272
+ try {
1273
+ const packageJsonContent = await fs5.readFile(packageJsonPath, "utf-8");
1274
+ const packageJson = JSON.parse(packageJsonContent);
1275
+ packageJson.name = projectName;
1276
+ await fs5.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
1277
+ } catch (error) {
1278
+ logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
1279
+ }
1280
+ }
1281
+ async function installDependencies(projectPath, packageManager) {
1282
+ const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
1283
+ try {
1284
+ const pm = packageManager || getPackageManager();
1285
+ const installCommand = shellQuote.quote([pm, "install"]);
1286
+ await exec(installCommand, {
1287
+ cwd: projectPath
1288
+ });
1289
+ spinner5.success("Dependencies installed successfully");
1290
+ } catch (error) {
1291
+ spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
1292
+ throw error;
1293
+ }
1294
+ }
1295
+ var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
1296
+ async function loadTemplates() {
1297
+ try {
1298
+ const response = await fetch(TEMPLATES_API_URL);
1299
+ if (!response.ok) {
1300
+ throw new Error(`Failed to fetch templates: ${response.statusText}`);
1301
+ }
1302
+ const templates = await response.json();
1303
+ return templates;
1304
+ } catch (error) {
1305
+ console.error("Error loading templates:", error);
1306
+ throw new Error("Failed to load templates. Please check your internet connection and try again.");
1307
+ }
1308
+ }
1309
+ function pluralize(count, singular, plural) {
1310
+ return count === 1 ? singular : plural || `${singular}s`;
1311
+ }
1312
+ async function selectTemplate(templates) {
1313
+ const choices = templates.map((template) => {
1314
+ const parts = [];
1315
+ if (template.agents?.length) {
1316
+ parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
1317
+ }
1318
+ if (template.tools?.length) {
1319
+ parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
1320
+ }
1321
+ if (template.workflows?.length) {
1322
+ parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
1323
+ }
1324
+ if (template.mcp?.length) {
1325
+ parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
1326
+ }
1327
+ if (template.networks?.length) {
1328
+ parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
1329
+ }
1330
+ return {
1331
+ value: template,
1332
+ label: template.title,
1333
+ hint: parts.join(", ") || "Template components"
1334
+ };
1335
+ });
1336
+ const selected = await ve({
1337
+ message: "Select a template:",
1338
+ options: choices
1339
+ });
1340
+ if (pD(selected)) {
1341
+ return null;
1342
+ }
1343
+ return selected;
1344
+ }
1345
+ function findTemplateByName(templates, templateName) {
1346
+ let template = templates.find((t) => t.slug === templateName);
1347
+ if (template) return template;
1348
+ const slugWithPrefix = `template-${templateName}`;
1349
+ template = templates.find((t) => t.slug === slugWithPrefix);
1350
+ if (template) return template;
1351
+ template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
1352
+ if (template) return template;
1353
+ return null;
1354
+ }
1355
+ function getDefaultProjectName(template) {
1356
+ return template.slug.replace(/^template-/, "");
1357
+ }
1358
+ function getPackageManagerAddCommand(pm) {
1359
+ switch (pm) {
1360
+ case "npm":
1361
+ return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
1362
+ case "yarn":
1363
+ return "add";
1364
+ case "pnpm":
1365
+ return "add --loglevel=error";
1366
+ case "bun":
1367
+ return "add";
1368
+ default:
1369
+ return "add";
1370
+ }
1371
+ }
1156
1372
  var DepsService = class {
1157
1373
  packageManager;
1158
1374
  constructor() {
@@ -1161,11 +1377,11 @@ var DepsService = class {
1161
1377
  findLockFile(dir) {
1162
1378
  const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
1163
1379
  for (const file of lockFiles) {
1164
- if (fs3__default__default.existsSync(path2.join(dir, file))) {
1380
+ if (fs4__default__default.existsSync(path3.join(dir, file))) {
1165
1381
  return file;
1166
1382
  }
1167
1383
  }
1168
- const parentDir = path2.resolve(dir, "..");
1384
+ const parentDir = path3.resolve(dir, "..");
1169
1385
  if (parentDir !== dir) {
1170
1386
  return this.findLockFile(parentDir);
1171
1387
  }
@@ -1187,14 +1403,10 @@ var DepsService = class {
1187
1403
  }
1188
1404
  }
1189
1405
  async installPackages(packages) {
1190
- let runCommand = this.packageManager;
1191
- if (this.packageManager === "npm") {
1192
- runCommand = `${this.packageManager} i`;
1193
- } else {
1194
- runCommand = `${this.packageManager} add`;
1195
- }
1406
+ const pm = this.packageManager;
1407
+ const installCommand = getPackageManagerAddCommand(pm);
1196
1408
  const packageList = packages.join(" ");
1197
- return execa(`${runCommand} ${packageList}`, {
1409
+ return execa(`${pm} ${installCommand} ${packageList}`, {
1198
1410
  all: true,
1199
1411
  shell: true,
1200
1412
  stdio: "inherit"
@@ -1202,13 +1414,13 @@ var DepsService = class {
1202
1414
  }
1203
1415
  async checkDependencies(dependencies) {
1204
1416
  try {
1205
- const packageJsonPath = path2.join(process.cwd(), "package.json");
1417
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1206
1418
  try {
1207
- await fs4.access(packageJsonPath);
1419
+ await fs5.access(packageJsonPath);
1208
1420
  } catch {
1209
1421
  return "No package.json file found in the current directory";
1210
1422
  }
1211
- const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
1423
+ const packageJson = JSON.parse(await fs5.readFile(packageJsonPath, "utf-8"));
1212
1424
  for (const dependency of dependencies) {
1213
1425
  if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
1214
1426
  return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
@@ -1222,65 +1434,23 @@ var DepsService = class {
1222
1434
  }
1223
1435
  async getProjectName() {
1224
1436
  try {
1225
- const packageJsonPath = path2.join(process.cwd(), "package.json");
1226
- const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
1437
+ const packageJsonPath = path3.join(process.cwd(), "package.json");
1438
+ const packageJson = await fs5.readFile(packageJsonPath, "utf-8");
1227
1439
  const pkg = JSON.parse(packageJson);
1228
1440
  return pkg.name;
1229
1441
  } catch (err) {
1230
1442
  throw err;
1231
1443
  }
1232
1444
  }
1233
- async getPackageVersion() {
1234
- const __filename = fileURLToPath(import.meta.url);
1235
- const __dirname = dirname(__filename);
1236
- const pkgJsonPath = path2.join(__dirname, "..", "package.json");
1237
- const content = await fsExtra3.readJSON(pkgJsonPath);
1238
- return content.version;
1239
- }
1240
1445
  async addScriptsToPackageJson(scripts) {
1241
- const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
1446
+ const packageJson = JSON.parse(await fs5.readFile("package.json", "utf-8"));
1242
1447
  packageJson.scripts = {
1243
1448
  ...packageJson.scripts,
1244
1449
  ...scripts
1245
1450
  };
1246
- await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1451
+ await fs5.writeFile("package.json", JSON.stringify(packageJson, null, 2));
1247
1452
  }
1248
1453
  };
1249
- function getPackageManager() {
1250
- const userAgent = process.env.npm_config_user_agent || "";
1251
- const execPath = process.env.npm_execpath || "";
1252
- if (userAgent.includes("yarn")) {
1253
- return "yarn";
1254
- }
1255
- if (userAgent.includes("pnpm")) {
1256
- return "pnpm";
1257
- }
1258
- if (userAgent.includes("npm")) {
1259
- return "npm";
1260
- }
1261
- if (execPath.includes("yarn")) {
1262
- return "yarn";
1263
- }
1264
- if (execPath.includes("pnpm")) {
1265
- return "pnpm";
1266
- }
1267
- if (execPath.includes("npm")) {
1268
- return "npm";
1269
- }
1270
- return "npm";
1271
- }
1272
- function getPackageManagerInstallCommand(pm) {
1273
- switch (pm) {
1274
- case "npm":
1275
- return "install";
1276
- case "yarn":
1277
- return "add";
1278
- case "pnpm":
1279
- return "add";
1280
- default:
1281
- return "install";
1282
- }
1283
- }
1284
1454
  var args = ["-y", "@mastra/mcp-docs-server"];
1285
1455
  var createMcpConfig = (editor) => {
1286
1456
  if (editor === "vscode") {
@@ -1333,19 +1503,19 @@ async function writeMergedConfig(configPath, editor) {
1333
1503
  spaces: 2
1334
1504
  });
1335
1505
  }
1336
- var windsurfGlobalMCPConfigPath = path2.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1337
- var cursorGlobalMCPConfigPath = path2.join(os.homedir(), ".cursor", "mcp.json");
1338
- path2.join(process.cwd(), ".vscode", "mcp.json");
1339
- var vscodeGlobalMCPConfigPath = path2.join(
1506
+ var windsurfGlobalMCPConfigPath = path3.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
1507
+ var cursorGlobalMCPConfigPath = path3.join(os.homedir(), ".cursor", "mcp.json");
1508
+ path3.join(process.cwd(), ".vscode", "mcp.json");
1509
+ var vscodeGlobalMCPConfigPath = path3.join(
1340
1510
  os.homedir(),
1341
- process.platform === "win32" ? path2.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path2.join("Library", "Application Support", "Code", "User", "settings.json") : path2.join(".config", "Code", "User", "settings.json")
1511
+ 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")
1342
1512
  );
1343
1513
  async function installMastraDocsMCPServer({ editor, directory }) {
1344
1514
  if (editor === `cursor`) {
1345
- await writeMergedConfig(path2.join(directory, ".cursor", "mcp.json"), "cursor");
1515
+ await writeMergedConfig(path3.join(directory, ".cursor", "mcp.json"), "cursor");
1346
1516
  }
1347
1517
  if (editor === `vscode`) {
1348
- await writeMergedConfig(path2.join(directory, ".vscode", "mcp.json"), "vscode");
1518
+ await writeMergedConfig(path3.join(directory, ".vscode", "mcp.json"), "vscode");
1349
1519
  }
1350
1520
  if (editor === `cursor-global`) {
1351
1521
  const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
@@ -1403,7 +1573,7 @@ var FileEnvService = class extends EnvService {
1403
1573
  }
1404
1574
  readFile(filePath) {
1405
1575
  return new Promise((resolve, reject) => {
1406
- fs3__default.readFile(filePath, "utf8", (err, data) => {
1576
+ fs4__default.readFile(filePath, "utf8", (err, data) => {
1407
1577
  if (err) reject(err);
1408
1578
  else resolve(data);
1409
1579
  });
@@ -1411,7 +1581,7 @@ var FileEnvService = class extends EnvService {
1411
1581
  }
1412
1582
  writeFile({ filePath, data }) {
1413
1583
  return new Promise((resolve, reject) => {
1414
- fs3__default.writeFile(filePath, data, "utf8", (err) => {
1584
+ fs4__default.writeFile(filePath, data, "utf8", (err) => {
1415
1585
  if (err) reject(err);
1416
1586
  else resolve();
1417
1587
  });
@@ -1431,7 +1601,7 @@ var FileEnvService = class extends EnvService {
1431
1601
  ${key}=${value}`;
1432
1602
  }
1433
1603
  await this.writeFile({ filePath, data });
1434
- console.log(`${key} set to ${value} in ENV file.`);
1604
+ console.info(`${key} set to ${value} in ENV file.`);
1435
1605
  return data;
1436
1606
  }
1437
1607
  async getEnvValue(key) {
@@ -1464,25 +1634,25 @@ var FileService = class {
1464
1634
  */
1465
1635
  async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
1466
1636
  const __filename = fileURLToPath(import.meta.url);
1467
- const __dirname = path2.dirname(__filename);
1468
- const filePath = path2.resolve(__dirname, "starter-files", inputFile);
1469
- const fileString = fs3__default__default.readFileSync(filePath, "utf8");
1470
- if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1471
- console.log(`${outputFilePath} already exists`);
1637
+ const __dirname = path3.dirname(__filename);
1638
+ const filePath = path3.resolve(__dirname, "starter-files", inputFile);
1639
+ const fileString = fs4__default__default.readFileSync(filePath, "utf8");
1640
+ if (fs4__default__default.existsSync(outputFilePath) && !replaceIfExists) {
1641
+ console.info(`${outputFilePath} already exists`);
1472
1642
  return false;
1473
1643
  }
1474
- await fsExtra3.outputFile(outputFilePath, fileString);
1644
+ await fsExtra.outputFile(outputFilePath, fileString);
1475
1645
  return true;
1476
1646
  }
1477
1647
  async setupEnvFile({ dbUrl }) {
1478
- const envPath = path2.join(process.cwd(), ".env.development");
1479
- await fsExtra3.ensureFile(envPath);
1648
+ const envPath = path3.join(process.cwd(), ".env.development");
1649
+ await fsExtra.ensureFile(envPath);
1480
1650
  const fileEnvService = new FileEnvService(envPath);
1481
1651
  await fileEnvService.setEnvValue("DB_URL", dbUrl);
1482
1652
  }
1483
1653
  getFirstExistingFile(files) {
1484
1654
  for (const f of files) {
1485
- if (fs3__default__default.existsSync(f)) {
1655
+ if (fs4__default__default.existsSync(f)) {
1486
1656
  return f;
1487
1657
  }
1488
1658
  }
@@ -1492,57 +1662,31 @@ var FileService = class {
1492
1662
  filePath,
1493
1663
  replacements
1494
1664
  }) {
1495
- let fileContent = fs3__default__default.readFileSync(filePath, "utf8");
1665
+ let fileContent = fs4__default__default.readFileSync(filePath, "utf8");
1496
1666
  replacements.forEach(({ search, replace }) => {
1497
1667
  fileContent = fileContent.replaceAll(search, replace);
1498
1668
  });
1499
- fs3__default__default.writeFileSync(filePath, fileContent);
1500
- }
1501
- };
1502
- new PinoLogger({
1503
- name: "Mastra CLI",
1504
- level: "info"
1505
- });
1506
- var exec = util.promisify(child_process.exec);
1507
- var getAISDKPackage = (llmProvider) => {
1508
- switch (llmProvider) {
1509
- case "openai":
1510
- return "@ai-sdk/openai";
1511
- case "anthropic":
1512
- return "@ai-sdk/anthropic";
1513
- case "groq":
1514
- return "@ai-sdk/groq";
1515
- case "google":
1516
- return "@ai-sdk/google";
1517
- case "cerebras":
1518
- return "@ai-sdk/cerebras";
1519
- default:
1520
- return "@ai-sdk/openai";
1669
+ fs4__default__default.writeFileSync(filePath, fileContent);
1521
1670
  }
1522
1671
  };
1523
- var getProviderImportAndModelItem = (llmProvider) => {
1524
- let providerImport = "";
1525
- let modelItem = "";
1672
+ var exec2 = util.promisify(child_process.exec);
1673
+ var getModelIdentifier = (llmProvider) => {
1526
1674
  if (llmProvider === "openai") {
1527
- providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
1528
- modelItem = `openai('gpt-4o-mini')`;
1675
+ return `'openai/gpt-4o-mini'`;
1529
1676
  } else if (llmProvider === "anthropic") {
1530
- providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
1531
- modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
1677
+ return `'anthropic/claude-3-5-sonnet-20241022'`;
1532
1678
  } else if (llmProvider === "groq") {
1533
- providerImport = `import { groq } from '${getAISDKPackage(llmProvider)}';`;
1534
- modelItem = `groq('llama-3.3-70b-versatile')`;
1679
+ return `'groq/llama-3.3-70b-versatile'`;
1535
1680
  } else if (llmProvider === "google") {
1536
- providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
1537
- modelItem = `google('gemini-2.5-pro-exp-03-25')`;
1681
+ return `'google/gemini-2.5-pro'`;
1538
1682
  } else if (llmProvider === "cerebras") {
1539
- providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
1540
- modelItem = `cerebras('llama-3.3-70b')`;
1683
+ return `'cerebras/llama-3.3-70b'`;
1684
+ } else if (llmProvider === "mistral") {
1685
+ return `'mistral/mistral-medium-2508'`;
1541
1686
  }
1542
- return { providerImport, modelItem };
1543
1687
  };
1544
1688
  async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1545
- const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
1689
+ const modelString = getModelIdentifier(llmProvider);
1546
1690
  const instructions = `
1547
1691
  You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
1548
1692
 
@@ -1558,7 +1702,6 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
1558
1702
  ${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
1559
1703
  `;
1560
1704
  const content = `
1561
- ${providerImport}
1562
1705
  import { Agent } from '@mastra/core/agent';
1563
1706
  import { Memory } from '@mastra/memory';
1564
1707
  import { LibSQLStore } from '@mastra/libsql';
@@ -1567,7 +1710,7 @@ ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
1567
1710
  export const weatherAgent = new Agent({
1568
1711
  name: 'Weather Agent',
1569
1712
  instructions: \`${instructions}\`,
1570
- model: ${modelItem},
1713
+ model: ${modelString},
1571
1714
  ${addExampleTool ? "tools: { weatherTool }," : ""}
1572
1715
  memory: new Memory({
1573
1716
  storage: new LibSQLStore({
@@ -1580,8 +1723,8 @@ export const weatherAgent = new Agent({
1580
1723
  parser: "typescript",
1581
1724
  singleQuote: true
1582
1725
  });
1583
- await fs4.writeFile(destPath, "");
1584
- await fs4.writeFile(destPath, formattedContent);
1726
+ await fs5.writeFile(destPath, "");
1727
+ await fs5.writeFile(destPath, formattedContent);
1585
1728
  }
1586
1729
  async function writeWorkflowSample(destPath) {
1587
1730
  const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
@@ -1774,7 +1917,7 @@ export { weatherWorkflow };`;
1774
1917
  semi: true,
1775
1918
  singleQuote: true
1776
1919
  });
1777
- await fs4.writeFile(destPath, formattedContent);
1920
+ await fs5.writeFile(destPath, formattedContent);
1778
1921
  }
1779
1922
  async function writeToolSample(destPath) {
1780
1923
  const fileService = new FileService();
@@ -1794,7 +1937,7 @@ async function writeCodeSampleForComponents(llmprovider, component, destPath, im
1794
1937
  }
1795
1938
  var createComponentsDir = async (dirPath, component) => {
1796
1939
  const componentPath = dirPath + `/${component}`;
1797
- await fsExtra3.ensureDir(componentPath);
1940
+ await fsExtra.ensureDir(componentPath);
1798
1941
  };
1799
1942
  var writeIndexFile = async ({
1800
1943
  dirPath,
@@ -1803,15 +1946,15 @@ var writeIndexFile = async ({
1803
1946
  addWorkflow
1804
1947
  }) => {
1805
1948
  const indexPath = dirPath + "/index.ts";
1806
- const destPath = path2.join(indexPath);
1949
+ const destPath = path3.join(indexPath);
1807
1950
  try {
1808
- await fs4.writeFile(destPath, "");
1951
+ await fs5.writeFile(destPath, "");
1809
1952
  const filteredExports = [
1810
1953
  addWorkflow ? `workflows: { weatherWorkflow },` : "",
1811
1954
  addAgent ? `agents: { weatherAgent },` : ""
1812
1955
  ].filter(Boolean);
1813
1956
  if (!addExample) {
1814
- await fs4.writeFile(
1957
+ await fs5.writeFile(
1815
1958
  destPath,
1816
1959
  `
1817
1960
  import { Mastra } from '@mastra/core';
@@ -1821,7 +1964,7 @@ export const mastra = new Mastra()
1821
1964
  );
1822
1965
  return;
1823
1966
  }
1824
- await fs4.writeFile(
1967
+ await fs5.writeFile(
1825
1968
  destPath,
1826
1969
  `
1827
1970
  import { Mastra } from '@mastra/core/mastra';
@@ -1833,13 +1976,21 @@ ${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
1833
1976
  export const mastra = new Mastra({
1834
1977
  ${filteredExports.join("\n ")}
1835
1978
  storage: new LibSQLStore({
1836
- // stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
1979
+ // stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
1837
1980
  url: ":memory:",
1838
1981
  }),
1839
1982
  logger: new PinoLogger({
1840
1983
  name: 'Mastra',
1841
1984
  level: 'info',
1842
1985
  }),
1986
+ telemetry: {
1987
+ // Telemetry is deprecated and will be removed in the Nov 4th release
1988
+ enabled: false,
1989
+ },
1990
+ observability: {
1991
+ // Enables DefaultExporter and CloudExporter for AI tracing
1992
+ default: { enabled: true },
1993
+ },
1843
1994
  });
1844
1995
  `
1845
1996
  );
@@ -1863,27 +2014,28 @@ var getAPIKey = async (provider) => {
1863
2014
  case "cerebras":
1864
2015
  key = "CEREBRAS_API_KEY";
1865
2016
  return key;
2017
+ case "mistral":
2018
+ key = "MISTRAL_API_KEY";
2019
+ return key;
1866
2020
  default:
1867
2021
  return key;
1868
2022
  }
1869
2023
  };
1870
- var writeAPIKey = async ({
1871
- provider,
1872
- apiKey = "your-api-key"
1873
- }) => {
2024
+ var writeAPIKey = async ({ provider, apiKey }) => {
2025
+ const envFileName = apiKey ? ".env" : ".env.example";
1874
2026
  const key = await getAPIKey(provider);
1875
2027
  const escapedKey = shellQuote.quote([key]);
1876
- const escapedApiKey = shellQuote.quote([apiKey]);
1877
- await exec(`echo ${escapedKey}=${escapedApiKey} >> .env`);
2028
+ const escapedApiKey = shellQuote.quote([apiKey ? apiKey : "your-api-key"]);
2029
+ await exec2(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
1878
2030
  };
1879
2031
  var createMastraDir = async (directory) => {
1880
2032
  let dir = directory.trim().split("/").filter((item) => item !== "");
1881
- const dirPath = path2.join(process.cwd(), ...dir, "mastra");
2033
+ const dirPath = path3.join(process.cwd(), ...dir, "mastra");
1882
2034
  try {
1883
- await fs4.access(dirPath);
2035
+ await fs5.access(dirPath);
1884
2036
  return { ok: false };
1885
2037
  } catch {
1886
- await fsExtra3.ensureDir(dirPath);
2038
+ await fsExtra.ensureDir(dirPath);
1887
2039
  return { ok: true, dirPath };
1888
2040
  }
1889
2041
  };
@@ -1895,8 +2047,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
1895
2047
  throw err;
1896
2048
  }
1897
2049
  };
1898
- var interactivePrompt = async () => {
1899
- Ie(color2.inverse(" Mastra Init "));
2050
+ var LLM_PROVIDERS = [
2051
+ { value: "openai", label: "OpenAI", hint: "recommended" },
2052
+ { value: "anthropic", label: "Anthropic" },
2053
+ { value: "groq", label: "Groq" },
2054
+ { value: "google", label: "Google" },
2055
+ { value: "cerebras", label: "Cerebras" },
2056
+ { value: "mistral", label: "Mistral" }
2057
+ ];
2058
+ var interactivePrompt = async (args2 = {}) => {
2059
+ const { skip = {}, options: { showBanner = true } = {} } = args2;
2060
+ if (showBanner) {
2061
+ Ie(color2.inverse(" Mastra Init "));
2062
+ }
1900
2063
  const mastraProject = await Ce(
1901
2064
  {
1902
2065
  directory: () => he({
@@ -1904,19 +2067,15 @@ var interactivePrompt = async () => {
1904
2067
  placeholder: "src/",
1905
2068
  defaultValue: "src/"
1906
2069
  }),
1907
- llmProvider: () => ve({
1908
- message: "Select default provider:",
1909
- options: [
1910
- { value: "openai", label: "OpenAI", hint: "recommended" },
1911
- { value: "anthropic", label: "Anthropic" },
1912
- { value: "groq", label: "Groq" },
1913
- { value: "google", label: "Google" },
1914
- { value: "cerebras", label: "Cerebras" }
1915
- ]
2070
+ llmProvider: () => skip?.llmProvider ? void 0 : ve({
2071
+ message: "Select a default provider:",
2072
+ options: LLM_PROVIDERS
1916
2073
  }),
1917
2074
  llmApiKey: async ({ results: { llmProvider } }) => {
2075
+ if (skip?.llmApiKey) return void 0;
2076
+ const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
1918
2077
  const keyChoice = await ve({
1919
- message: `Enter your ${llmProvider} API key?`,
2078
+ message: `Enter your ${llmName} API key?`,
1920
2079
  options: [
1921
2080
  { value: "skip", label: "Skip for now", hint: "default" },
1922
2081
  { value: "enter", label: "Enter API key" }
@@ -1926,7 +2085,10 @@ var interactivePrompt = async () => {
1926
2085
  if (keyChoice === "enter") {
1927
2086
  return he({
1928
2087
  message: "Enter your API key:",
1929
- placeholder: "sk-..."
2088
+ placeholder: "sk-...",
2089
+ validate: (value) => {
2090
+ if (value.length === 0) return "API key cannot be empty";
2091
+ }
1930
2092
  });
1931
2093
  }
1932
2094
  return void 0;
@@ -1936,7 +2098,7 @@ var interactivePrompt = async () => {
1936
2098
  const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
1937
2099
  const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
1938
2100
  const editor = await ve({
1939
- message: `Make your AI IDE into a Mastra expert? (installs Mastra docs MCP server)`,
2101
+ message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
1940
2102
  options: [
1941
2103
  { value: "skip", label: "Skip for now", hint: "default" },
1942
2104
  {
@@ -2017,7 +2179,6 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
2017
2179
  return mastraProject;
2018
2180
  };
2019
2181
  var s = Y();
2020
- var exec2 = util.promisify(child_process.exec);
2021
2182
  var init = async ({
2022
2183
  directory,
2023
2184
  addExample = false,
@@ -2065,11 +2226,6 @@ var init = async ({
2065
2226
  }
2066
2227
  }
2067
2228
  const key = await getAPIKey(llmProvider || "openai");
2068
- const aiSdkPackage = getAISDKPackage(llmProvider);
2069
- const depsService = new DepsService();
2070
- const pm = depsService.packageManager;
2071
- const installCommand = getPackageManagerInstallCommand(pm);
2072
- await exec2(`${pm} ${installCommand} ${aiSdkPackage}`);
2073
2229
  if (configureEditorWithDocsMCP) {
2074
2230
  await installMastraDocsMCPServer({
2075
2231
  editor: configureEditorWithDocsMCP,
@@ -2123,9 +2279,9 @@ var execWithTimeout = async (command, timeoutMs) => {
2123
2279
  }
2124
2280
  };
2125
2281
  async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
2126
- let installCommand = getPackageManagerInstallCommand(pm);
2282
+ let installCommand = getPackageManagerAddCommand(pm);
2127
2283
  if (isDev) {
2128
- installCommand = `${installCommand} --save-dev`;
2284
+ installCommand = `${installCommand} -D`;
2129
2285
  }
2130
2286
  try {
2131
2287
  await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
@@ -2147,23 +2303,39 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
2147
2303
  var createMastraProject = async ({
2148
2304
  projectName: name,
2149
2305
  createVersionTag,
2150
- timeout
2306
+ timeout,
2307
+ llmProvider,
2308
+ llmApiKey,
2309
+ needsInteractive
2151
2310
  }) => {
2152
2311
  Ie(color2.inverse(" Mastra Create "));
2153
2312
  const projectName = name ?? await he({
2154
2313
  message: "What do you want to name your project?",
2155
2314
  placeholder: "my-mastra-app",
2156
- defaultValue: "my-mastra-app"
2315
+ defaultValue: "my-mastra-app",
2316
+ validate: (value) => {
2317
+ if (value.length === 0) return "Project name cannot be empty";
2318
+ if (fs4__default__default.existsSync(value)) {
2319
+ return `A directory named "${value}" already exists. Please choose a different name.`;
2320
+ }
2321
+ }
2157
2322
  });
2158
2323
  if (pD(projectName)) {
2159
2324
  xe("Operation cancelled");
2160
2325
  process.exit(0);
2161
2326
  }
2327
+ let result;
2328
+ if (needsInteractive) {
2329
+ result = await interactivePrompt({
2330
+ options: { showBanner: false },
2331
+ skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
2332
+ });
2333
+ }
2162
2334
  const s2 = Y();
2163
2335
  try {
2164
2336
  s2.start("Creating project");
2165
2337
  try {
2166
- await fs4.mkdir(projectName);
2338
+ await fs5.mkdir(projectName);
2167
2339
  } catch (error) {
2168
2340
  if (error instanceof Error && "code" in error && error.code === "EEXIST") {
2169
2341
  s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
@@ -2175,7 +2347,7 @@ var createMastraProject = async ({
2175
2347
  }
2176
2348
  process.chdir(projectName);
2177
2349
  const pm = getPackageManager();
2178
- const installCommand = getPackageManagerInstallCommand(pm);
2350
+ const installCommand = getPackageManagerAddCommand(pm);
2179
2351
  s2.message("Initializing project structure");
2180
2352
  try {
2181
2353
  await exec3(`npm init -y`);
@@ -2219,15 +2391,15 @@ var createMastraProject = async ({
2219
2391
  );
2220
2392
  }
2221
2393
  s2.stop(`${pm} dependencies installed`);
2222
- s2.start("Installing mastra");
2394
+ s2.start("Installing Mastra CLI");
2223
2395
  const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
2224
2396
  try {
2225
2397
  await installMastraDependency(pm, "mastra", versionTag, true, timeout);
2226
2398
  } catch (error) {
2227
2399
  throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
2228
2400
  }
2229
- s2.stop("mastra installed");
2230
- s2.start("Installing dependencies");
2401
+ s2.stop("Mastra CLI installed");
2402
+ s2.start("Installing Mastra dependencies");
2231
2403
  try {
2232
2404
  await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
2233
2405
  await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
@@ -2253,8 +2425,8 @@ var createMastraProject = async ({
2253
2425
  }
2254
2426
  s2.stop(".gitignore added");
2255
2427
  Se("Project created successfully");
2256
- console.log("");
2257
- return { projectName };
2428
+ console.info("");
2429
+ return { projectName, result };
2258
2430
  } catch (error) {
2259
2431
  s2.stop();
2260
2432
  const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
@@ -2263,14 +2435,21 @@ var createMastraProject = async ({
2263
2435
  }
2264
2436
  };
2265
2437
  var create = async (args2) => {
2266
- const { projectName } = await createMastraProject({
2438
+ if (args2.template !== void 0) {
2439
+ await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
2440
+ return;
2441
+ }
2442
+ const needsInteractive = args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0;
2443
+ const { projectName, result } = await createMastraProject({
2267
2444
  projectName: args2?.projectName,
2268
2445
  createVersionTag: args2?.createVersionTag,
2269
- timeout: args2?.timeout
2446
+ timeout: args2?.timeout,
2447
+ llmProvider: args2?.llmProvider,
2448
+ llmApiKey: args2?.llmApiKey,
2449
+ needsInteractive
2270
2450
  });
2271
2451
  const directory = args2.directory || "src/";
2272
- if (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
2273
- const result = await interactivePrompt();
2452
+ if (needsInteractive && result) {
2274
2453
  await init({
2275
2454
  ...result,
2276
2455
  llmApiKey: result?.llmApiKey,
@@ -2300,18 +2479,172 @@ var postCreate = ({ projectName }) => {
2300
2479
  ${color2.cyan(`${packageManager} run dev`)}
2301
2480
  `);
2302
2481
  };
2482
+ function isGitHubUrl(url) {
2483
+ try {
2484
+ const parsedUrl = new URL(url);
2485
+ return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
2486
+ } catch {
2487
+ return false;
2488
+ }
2489
+ }
2490
+ async function validateGitHubProject(githubUrl) {
2491
+ const errors = [];
2492
+ try {
2493
+ const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
2494
+ const owner = urlParts[0];
2495
+ const repo = urlParts[1]?.replace(".git", "");
2496
+ if (!owner || !repo) {
2497
+ throw new Error("Invalid GitHub URL format");
2498
+ }
2499
+ const branches = ["main", "master"];
2500
+ let packageJsonContent = null;
2501
+ let indexContent = null;
2502
+ for (const branch of branches) {
2503
+ try {
2504
+ const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
2505
+ const packageJsonResponse = await fetch(packageJsonUrl);
2506
+ if (packageJsonResponse.ok) {
2507
+ packageJsonContent = await packageJsonResponse.text();
2508
+ const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
2509
+ const indexResponse = await fetch(indexUrl);
2510
+ if (indexResponse.ok) {
2511
+ indexContent = await indexResponse.text();
2512
+ }
2513
+ break;
2514
+ }
2515
+ } catch {
2516
+ }
2517
+ }
2518
+ if (!packageJsonContent) {
2519
+ errors.push("Could not fetch package.json from repository");
2520
+ return { isValid: false, errors };
2521
+ }
2522
+ try {
2523
+ const packageJson = JSON.parse(packageJsonContent);
2524
+ const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
2525
+ if (!hasMastraCore) {
2526
+ errors.push("Missing @mastra/core dependency in package.json");
2527
+ }
2528
+ } catch {
2529
+ errors.push("Invalid package.json format");
2530
+ }
2531
+ if (!indexContent) {
2532
+ errors.push("Missing src/mastra/index.ts file");
2533
+ } else {
2534
+ const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
2535
+ if (!hasMastraExport) {
2536
+ errors.push("src/mastra/index.ts does not export a Mastra instance");
2537
+ }
2538
+ }
2539
+ return { isValid: errors.length === 0, errors };
2540
+ } catch (error) {
2541
+ errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
2542
+ return { isValid: false, errors };
2543
+ }
2544
+ }
2545
+ async function createFromGitHubUrl(url) {
2546
+ const urlParts = new URL(url).pathname.split("/").filter(Boolean);
2547
+ const owner = urlParts[0] || "unknown";
2548
+ const repo = urlParts[1] || "unknown";
2549
+ return {
2550
+ githubUrl: url,
2551
+ title: `${owner}/${repo}`,
2552
+ slug: repo,
2553
+ agents: [],
2554
+ mcp: [],
2555
+ tools: [],
2556
+ networks: [],
2557
+ workflows: []
2558
+ };
2559
+ }
2560
+ async function createFromTemplate(args2) {
2561
+ let selectedTemplate;
2562
+ if (args2.template === true) {
2563
+ const templates = await loadTemplates();
2564
+ const selected = await selectTemplate(templates);
2565
+ if (!selected) {
2566
+ M.info("No template selected. Exiting.");
2567
+ return;
2568
+ }
2569
+ selectedTemplate = selected;
2570
+ } else if (args2.template && typeof args2.template === "string") {
2571
+ if (isGitHubUrl(args2.template)) {
2572
+ const spinner5 = Y();
2573
+ spinner5.start("Validating GitHub repository...");
2574
+ const validation = await validateGitHubProject(args2.template);
2575
+ if (!validation.isValid) {
2576
+ spinner5.stop("Validation failed");
2577
+ M.error("This does not appear to be a valid Mastra project:");
2578
+ validation.errors.forEach((error) => M.error(` - ${error}`));
2579
+ throw new Error("Invalid Mastra project");
2580
+ }
2581
+ spinner5.stop("Valid Mastra project \u2713");
2582
+ selectedTemplate = await createFromGitHubUrl(args2.template);
2583
+ } else {
2584
+ const templates = await loadTemplates();
2585
+ const found = findTemplateByName(templates, args2.template);
2586
+ if (!found) {
2587
+ M.error(`Template "${args2.template}" not found. Available templates:`);
2588
+ templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
2589
+ throw new Error(`Template "${args2.template}" not found`);
2590
+ }
2591
+ selectedTemplate = found;
2592
+ }
2593
+ }
2594
+ if (!selectedTemplate) {
2595
+ throw new Error("No template selected");
2596
+ }
2597
+ let projectName = args2.projectName;
2598
+ if (!projectName) {
2599
+ const defaultName = getDefaultProjectName(selectedTemplate);
2600
+ const response = await he({
2601
+ message: "What is your project name?",
2602
+ defaultValue: defaultName,
2603
+ placeholder: defaultName
2604
+ });
2605
+ if (pD(response)) {
2606
+ M.info("Project creation cancelled.");
2607
+ return;
2608
+ }
2609
+ projectName = response;
2610
+ }
2611
+ try {
2612
+ const analytics = args2.injectedAnalytics || getAnalytics();
2613
+ if (analytics) {
2614
+ analytics.trackEvent("cli_template_used", {
2615
+ template_slug: selectedTemplate.slug,
2616
+ template_title: selectedTemplate.title
2617
+ });
2618
+ }
2619
+ const projectPath = await cloneTemplate({
2620
+ template: selectedTemplate,
2621
+ projectName
2622
+ });
2623
+ await installDependencies(projectPath);
2624
+ Me(`
2625
+ ${color2.green("Mastra template installed!")}
2626
+
2627
+ Add the necessary environment
2628
+ variables in your ${color2.cyan(".env")} file
2629
+ `);
2630
+ postCreate({ projectName });
2631
+ } catch (error) {
2632
+ M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
2633
+ throw error;
2634
+ }
2635
+ }
2303
2636
 
2304
2637
  async function getPackageVersion() {
2305
2638
  const __filename = fileURLToPath(import.meta.url);
2306
2639
  const __dirname = dirname(__filename);
2307
- const pkgJsonPath = path2.join(__dirname, "..", "package.json");
2308
- const content = await fsExtra.readJSON(pkgJsonPath);
2640
+ const pkgJsonPath = path3.join(__dirname, "..", "package.json");
2641
+ const content = await fsExtra$1.readJSON(pkgJsonPath);
2309
2642
  return content.version;
2310
2643
  }
2311
2644
  async function getCreateVersionTag() {
2312
2645
  try {
2313
2646
  const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
2314
- const json = await fsExtra.readJSON(pkgPath);
2647
+ const json = await fsExtra$1.readJSON(pkgPath);
2315
2648
  const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
2316
2649
  const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
2317
2650
  const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
@@ -2335,14 +2668,17 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
2335
2668
  analytics.trackCommand({
2336
2669
  command: "version"
2337
2670
  });
2338
- console.log(`create-mastra ${version}`);
2671
+ console.info(`create-mastra ${version}`);
2339
2672
  } catch {
2340
2673
  }
2341
2674
  });
2342
2675
  program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
2343
2676
  "-p, --project-name <string>",
2344
2677
  "Project name that will be used in package.json and as the project directory name."
2345
- ).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)").action(async (projectNameArg, args) => {
2678
+ ).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(
2679
+ "--template [template-name]",
2680
+ "Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
2681
+ ).action(async (projectNameArg, args) => {
2346
2682
  const projectName = projectNameArg || args.projectName;
2347
2683
  const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
2348
2684
  if (args.default) {
@@ -2353,7 +2689,9 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2353
2689
  createVersionTag,
2354
2690
  timeout,
2355
2691
  mcpServer: args.mcp,
2356
- directory: "src/"
2692
+ directory: "src/",
2693
+ template: args.template,
2694
+ analytics
2357
2695
  });
2358
2696
  return;
2359
2697
  }
@@ -2361,12 +2699,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
2361
2699
  components: args.components ? args.components.split(",") : [],
2362
2700
  llmProvider: args.llm,
2363
2701
  addExample: args.example,
2364
- llmApiKey: args["llm-api-key"],
2702
+ llmApiKey: args.llmApiKey,
2365
2703
  createVersionTag,
2366
2704
  timeout,
2367
2705
  projectName,
2368
2706
  directory: args.dir,
2369
- mcpServer: args.mcp
2707
+ mcpServer: args.mcp,
2708
+ template: args.template,
2709
+ analytics
2370
2710
  });
2371
2711
  });
2372
2712
  program.parse(process.argv);