create-mastra 0.0.0-share-agent-metadata-with-cloud-20250718123411 → 0.0.0-stream-vnext-usage-20250908171242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1651 -0
- package/README.md +2 -8
- package/dist/index.js +172 -61
- package/dist/index.js.map +1 -1
- package/dist/templates/dev.entry.js +7 -2
- package/dist/templates/scorers/answer-relevancy-scorer.ts +15 -0
- package/dist/templates/scorers/bias-detection-scorer.ts +16 -0
- package/dist/templates/scorers/completeness-scorer.ts +16 -0
- package/dist/templates/scorers/content-similarity-scorer.ts +15 -0
- package/dist/templates/scorers/faithfulness-scorer.ts +21 -0
- package/dist/templates/scorers/hallucination-scorer.ts +21 -0
- package/dist/templates/scorers/keyword-coverage-scorer.ts +15 -0
- package/dist/templates/scorers/textual-difference-scorer.ts +16 -0
- package/dist/templates/scorers/tone-consistency-scorer.ts +16 -0
- package/dist/templates/scorers/toxicity-detection-scorer.ts +16 -0
- package/package.json +15 -7
- package/dist/starter-files/config.ts +0 -25
- package/dist/starter-files/mastra-pg.docker-compose.yaml +0 -15
package/README.md
CHANGED
|
@@ -4,22 +4,16 @@ The easiest way to get started with Mastra is by using `create-mastra`. This CLI
|
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
|
-
Using npx:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npx create-mastra@latest
|
|
11
|
-
```
|
|
12
|
-
|
|
13
7
|
Using npm:
|
|
14
8
|
|
|
15
9
|
```bash
|
|
16
|
-
|
|
10
|
+
npx create-mastra@latest
|
|
17
11
|
```
|
|
18
12
|
|
|
19
13
|
Using yarn:
|
|
20
14
|
|
|
21
15
|
```bash
|
|
22
|
-
yarn create
|
|
16
|
+
yarn dlx create-mastra@latest
|
|
23
17
|
```
|
|
24
18
|
|
|
25
19
|
Using pnpm:
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import tty from 'node:tty';
|
|
|
18
18
|
import pino from 'pino';
|
|
19
19
|
import pretty from 'pino-pretty';
|
|
20
20
|
import { execa } from 'execa';
|
|
21
|
-
import
|
|
21
|
+
import fsExtra2, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
22
22
|
import prettier from 'prettier';
|
|
23
23
|
import fsExtra from 'fs-extra';
|
|
24
24
|
|
|
@@ -1196,18 +1196,6 @@ function getPackageManager() {
|
|
|
1196
1196
|
}
|
|
1197
1197
|
return "npm";
|
|
1198
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
1199
|
var logger = new PinoLogger({
|
|
1212
1200
|
name: "Mastra CLI",
|
|
1213
1201
|
level: "info"
|
|
@@ -1216,10 +1204,10 @@ var exec = util.promisify(child_process.exec);
|
|
|
1216
1204
|
async function cloneTemplate(options) {
|
|
1217
1205
|
const { template, projectName, targetDir } = options;
|
|
1218
1206
|
const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
|
|
1219
|
-
const
|
|
1207
|
+
const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
1220
1208
|
try {
|
|
1221
1209
|
if (await directoryExists(projectPath)) {
|
|
1222
|
-
|
|
1210
|
+
spinner5.error(`Directory ${projectName} already exists`);
|
|
1223
1211
|
throw new Error(`Directory ${projectName} already exists`);
|
|
1224
1212
|
}
|
|
1225
1213
|
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
@@ -1228,10 +1216,10 @@ async function cloneTemplate(options) {
|
|
|
1228
1216
|
if (await fileExists(envExamplePath)) {
|
|
1229
1217
|
await fs.copyFile(envExamplePath, path3.join(projectPath, ".env"));
|
|
1230
1218
|
}
|
|
1231
|
-
|
|
1219
|
+
spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
1232
1220
|
return projectPath;
|
|
1233
1221
|
} catch (error) {
|
|
1234
|
-
|
|
1222
|
+
spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1235
1223
|
throw error;
|
|
1236
1224
|
}
|
|
1237
1225
|
}
|
|
@@ -1286,16 +1274,16 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
1286
1274
|
}
|
|
1287
1275
|
}
|
|
1288
1276
|
async function installDependencies(projectPath, packageManager) {
|
|
1289
|
-
const
|
|
1277
|
+
const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
1290
1278
|
try {
|
|
1291
1279
|
const pm = packageManager || getPackageManager();
|
|
1292
1280
|
const installCommand = shellQuote.quote([pm, "install"]);
|
|
1293
1281
|
await exec(installCommand, {
|
|
1294
1282
|
cwd: projectPath
|
|
1295
1283
|
});
|
|
1296
|
-
|
|
1284
|
+
spinner5.success("Dependencies installed successfully");
|
|
1297
1285
|
} catch (error) {
|
|
1298
|
-
|
|
1286
|
+
spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1299
1287
|
throw error;
|
|
1300
1288
|
}
|
|
1301
1289
|
}
|
|
@@ -1362,6 +1350,20 @@ function findTemplateByName(templates, templateName) {
|
|
|
1362
1350
|
function getDefaultProjectName(template) {
|
|
1363
1351
|
return template.slug.replace(/^template-/, "");
|
|
1364
1352
|
}
|
|
1353
|
+
function getPackageManagerAddCommand(pm) {
|
|
1354
|
+
switch (pm) {
|
|
1355
|
+
case "npm":
|
|
1356
|
+
return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
|
|
1357
|
+
case "yarn":
|
|
1358
|
+
return "add";
|
|
1359
|
+
case "pnpm":
|
|
1360
|
+
return "add --loglevel=error";
|
|
1361
|
+
case "bun":
|
|
1362
|
+
return "add";
|
|
1363
|
+
default:
|
|
1364
|
+
return "add";
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1365
1367
|
var DepsService = class {
|
|
1366
1368
|
packageManager;
|
|
1367
1369
|
constructor() {
|
|
@@ -1396,14 +1398,10 @@ var DepsService = class {
|
|
|
1396
1398
|
}
|
|
1397
1399
|
}
|
|
1398
1400
|
async installPackages(packages) {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
runCommand = `${this.packageManager} i`;
|
|
1402
|
-
} else {
|
|
1403
|
-
runCommand = `${this.packageManager} add`;
|
|
1404
|
-
}
|
|
1401
|
+
const pm = this.packageManager;
|
|
1402
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
1405
1403
|
const packageList = packages.join(" ");
|
|
1406
|
-
return execa(`${
|
|
1404
|
+
return execa(`${pm} ${installCommand} ${packageList}`, {
|
|
1407
1405
|
all: true,
|
|
1408
1406
|
shell: true,
|
|
1409
1407
|
stdio: "inherit"
|
|
@@ -1439,13 +1437,6 @@ var DepsService = class {
|
|
|
1439
1437
|
throw err;
|
|
1440
1438
|
}
|
|
1441
1439
|
}
|
|
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
1440
|
async addScriptsToPackageJson(scripts) {
|
|
1450
1441
|
const packageJson = JSON.parse(await fs.readFile("package.json", "utf-8"));
|
|
1451
1442
|
packageJson.scripts = {
|
|
@@ -1645,12 +1636,12 @@ var FileService = class {
|
|
|
1645
1636
|
console.log(`${outputFilePath} already exists`);
|
|
1646
1637
|
return false;
|
|
1647
1638
|
}
|
|
1648
|
-
await
|
|
1639
|
+
await fsExtra2.outputFile(outputFilePath, fileString);
|
|
1649
1640
|
return true;
|
|
1650
1641
|
}
|
|
1651
1642
|
async setupEnvFile({ dbUrl }) {
|
|
1652
1643
|
const envPath = path3.join(process.cwd(), ".env.development");
|
|
1653
|
-
await
|
|
1644
|
+
await fsExtra2.ensureFile(envPath);
|
|
1654
1645
|
const fileEnvService = new FileEnvService(envPath);
|
|
1655
1646
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
1656
1647
|
}
|
|
@@ -1674,6 +1665,14 @@ var FileService = class {
|
|
|
1674
1665
|
}
|
|
1675
1666
|
};
|
|
1676
1667
|
var exec2 = util.promisify(child_process.exec);
|
|
1668
|
+
var getAISDKPackageVersion = (llmProvider) => {
|
|
1669
|
+
switch (llmProvider) {
|
|
1670
|
+
case "cerebras":
|
|
1671
|
+
return "^0.2.14";
|
|
1672
|
+
default:
|
|
1673
|
+
return "^1.0.0";
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1677
1676
|
var getAISDKPackage = (llmProvider) => {
|
|
1678
1677
|
switch (llmProvider) {
|
|
1679
1678
|
case "openai":
|
|
@@ -1686,6 +1685,8 @@ var getAISDKPackage = (llmProvider) => {
|
|
|
1686
1685
|
return "@ai-sdk/google";
|
|
1687
1686
|
case "cerebras":
|
|
1688
1687
|
return "@ai-sdk/cerebras";
|
|
1688
|
+
case "mistral":
|
|
1689
|
+
return "@ai-sdk/mistral";
|
|
1689
1690
|
default:
|
|
1690
1691
|
return "@ai-sdk/openai";
|
|
1691
1692
|
}
|
|
@@ -1704,10 +1705,13 @@ var getProviderImportAndModelItem = (llmProvider) => {
|
|
|
1704
1705
|
modelItem = `groq('llama-3.3-70b-versatile')`;
|
|
1705
1706
|
} else if (llmProvider === "google") {
|
|
1706
1707
|
providerImport = `import { google } from '${getAISDKPackage(llmProvider)}';`;
|
|
1707
|
-
modelItem = `google('gemini-2.5-pro
|
|
1708
|
+
modelItem = `google('gemini-2.5-pro')`;
|
|
1708
1709
|
} else if (llmProvider === "cerebras") {
|
|
1709
1710
|
providerImport = `import { cerebras } from '${getAISDKPackage(llmProvider)}';`;
|
|
1710
1711
|
modelItem = `cerebras('llama-3.3-70b')`;
|
|
1712
|
+
} else if (llmProvider === "mistral") {
|
|
1713
|
+
providerImport = `import { mistral } from '${getAISDKPackage(llmProvider)}';`;
|
|
1714
|
+
modelItem = `mistral('mistral-medium-2508')`;
|
|
1711
1715
|
}
|
|
1712
1716
|
return { providerImport, modelItem };
|
|
1713
1717
|
};
|
|
@@ -1964,7 +1968,7 @@ async function writeCodeSampleForComponents(llmprovider, component, destPath, im
|
|
|
1964
1968
|
}
|
|
1965
1969
|
var createComponentsDir = async (dirPath, component) => {
|
|
1966
1970
|
const componentPath = dirPath + `/${component}`;
|
|
1967
|
-
await
|
|
1971
|
+
await fsExtra2.ensureDir(componentPath);
|
|
1968
1972
|
};
|
|
1969
1973
|
var writeIndexFile = async ({
|
|
1970
1974
|
dirPath,
|
|
@@ -2033,6 +2037,9 @@ var getAPIKey = async (provider) => {
|
|
|
2033
2037
|
case "cerebras":
|
|
2034
2038
|
key = "CEREBRAS_API_KEY";
|
|
2035
2039
|
return key;
|
|
2040
|
+
case "mistral":
|
|
2041
|
+
key = "MISTRAL_API_KEY";
|
|
2042
|
+
return key;
|
|
2036
2043
|
default:
|
|
2037
2044
|
return key;
|
|
2038
2045
|
}
|
|
@@ -2053,7 +2060,7 @@ var createMastraDir = async (directory) => {
|
|
|
2053
2060
|
await fs.access(dirPath);
|
|
2054
2061
|
return { ok: false };
|
|
2055
2062
|
} catch {
|
|
2056
|
-
await
|
|
2063
|
+
await fsExtra2.ensureDir(dirPath);
|
|
2057
2064
|
return { ok: true, dirPath };
|
|
2058
2065
|
}
|
|
2059
2066
|
};
|
|
@@ -2081,7 +2088,8 @@ var interactivePrompt = async () => {
|
|
|
2081
2088
|
{ value: "anthropic", label: "Anthropic" },
|
|
2082
2089
|
{ value: "groq", label: "Groq" },
|
|
2083
2090
|
{ value: "google", label: "Google" },
|
|
2084
|
-
{ value: "cerebras", label: "Cerebras" }
|
|
2091
|
+
{ value: "cerebras", label: "Cerebras" },
|
|
2092
|
+
{ value: "mistral", label: "Mistral" }
|
|
2085
2093
|
]
|
|
2086
2094
|
}),
|
|
2087
2095
|
llmApiKey: async ({ results: { llmProvider } }) => {
|
|
@@ -2236,10 +2244,11 @@ var init = async ({
|
|
|
2236
2244
|
}
|
|
2237
2245
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2238
2246
|
const aiSdkPackage = getAISDKPackage(llmProvider);
|
|
2247
|
+
const aiSdkPackageVersion = getAISDKPackageVersion(llmProvider);
|
|
2239
2248
|
const depsService = new DepsService();
|
|
2240
2249
|
const pm = depsService.packageManager;
|
|
2241
|
-
const installCommand =
|
|
2242
|
-
await exec3(`${pm} ${installCommand} ${aiSdkPackage}`);
|
|
2250
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
2251
|
+
await exec3(`${pm} ${installCommand} ${aiSdkPackage}@${aiSdkPackageVersion}`);
|
|
2243
2252
|
if (configureEditorWithDocsMCP) {
|
|
2244
2253
|
await installMastraDocsMCPServer({
|
|
2245
2254
|
editor: configureEditorWithDocsMCP,
|
|
@@ -2293,9 +2302,9 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2293
2302
|
}
|
|
2294
2303
|
};
|
|
2295
2304
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2296
|
-
let installCommand =
|
|
2305
|
+
let installCommand = getPackageManagerAddCommand(pm);
|
|
2297
2306
|
if (isDev) {
|
|
2298
|
-
installCommand = `${installCommand}
|
|
2307
|
+
installCommand = `${installCommand} -D`;
|
|
2299
2308
|
}
|
|
2300
2309
|
try {
|
|
2301
2310
|
await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
|
|
@@ -2345,7 +2354,7 @@ var createMastraProject = async ({
|
|
|
2345
2354
|
}
|
|
2346
2355
|
process.chdir(projectName);
|
|
2347
2356
|
const pm = getPackageManager();
|
|
2348
|
-
const installCommand =
|
|
2357
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
2349
2358
|
s2.message("Initializing project structure");
|
|
2350
2359
|
try {
|
|
2351
2360
|
await exec4(`npm init -y`);
|
|
@@ -2434,7 +2443,7 @@ var createMastraProject = async ({
|
|
|
2434
2443
|
};
|
|
2435
2444
|
var create = async (args2) => {
|
|
2436
2445
|
if (args2.template !== void 0) {
|
|
2437
|
-
await createFromTemplate(args2);
|
|
2446
|
+
await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
|
|
2438
2447
|
return;
|
|
2439
2448
|
}
|
|
2440
2449
|
const { projectName } = await createMastraProject({
|
|
@@ -2474,21 +2483,116 @@ var postCreate = ({ projectName }) => {
|
|
|
2474
2483
|
${color2.cyan(`${packageManager} run dev`)}
|
|
2475
2484
|
`);
|
|
2476
2485
|
};
|
|
2486
|
+
function isGitHubUrl(url) {
|
|
2487
|
+
try {
|
|
2488
|
+
const parsedUrl = new URL(url);
|
|
2489
|
+
return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
|
|
2490
|
+
} catch {
|
|
2491
|
+
return false;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
async function validateGitHubProject(githubUrl) {
|
|
2495
|
+
const errors = [];
|
|
2496
|
+
try {
|
|
2497
|
+
const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
|
|
2498
|
+
const owner = urlParts[0];
|
|
2499
|
+
const repo = urlParts[1]?.replace(".git", "");
|
|
2500
|
+
if (!owner || !repo) {
|
|
2501
|
+
throw new Error("Invalid GitHub URL format");
|
|
2502
|
+
}
|
|
2503
|
+
const branches = ["main", "master"];
|
|
2504
|
+
let packageJsonContent = null;
|
|
2505
|
+
let indexContent = null;
|
|
2506
|
+
for (const branch of branches) {
|
|
2507
|
+
try {
|
|
2508
|
+
const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
|
|
2509
|
+
const packageJsonResponse = await fetch(packageJsonUrl);
|
|
2510
|
+
if (packageJsonResponse.ok) {
|
|
2511
|
+
packageJsonContent = await packageJsonResponse.text();
|
|
2512
|
+
const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
|
|
2513
|
+
const indexResponse = await fetch(indexUrl);
|
|
2514
|
+
if (indexResponse.ok) {
|
|
2515
|
+
indexContent = await indexResponse.text();
|
|
2516
|
+
}
|
|
2517
|
+
break;
|
|
2518
|
+
}
|
|
2519
|
+
} catch {
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
if (!packageJsonContent) {
|
|
2523
|
+
errors.push("Could not fetch package.json from repository");
|
|
2524
|
+
return { isValid: false, errors };
|
|
2525
|
+
}
|
|
2526
|
+
try {
|
|
2527
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2528
|
+
const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
|
|
2529
|
+
if (!hasMastraCore) {
|
|
2530
|
+
errors.push("Missing @mastra/core dependency in package.json");
|
|
2531
|
+
}
|
|
2532
|
+
} catch {
|
|
2533
|
+
errors.push("Invalid package.json format");
|
|
2534
|
+
}
|
|
2535
|
+
if (!indexContent) {
|
|
2536
|
+
errors.push("Missing src/mastra/index.ts file");
|
|
2537
|
+
} else {
|
|
2538
|
+
const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
|
|
2539
|
+
if (!hasMastraExport) {
|
|
2540
|
+
errors.push("src/mastra/index.ts does not export a Mastra instance");
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
return { isValid: errors.length === 0, errors };
|
|
2544
|
+
} catch (error) {
|
|
2545
|
+
errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2546
|
+
return { isValid: false, errors };
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
async function createFromGitHubUrl(url) {
|
|
2550
|
+
const urlParts = new URL(url).pathname.split("/").filter(Boolean);
|
|
2551
|
+
const owner = urlParts[0] || "unknown";
|
|
2552
|
+
const repo = urlParts[1] || "unknown";
|
|
2553
|
+
return {
|
|
2554
|
+
githubUrl: url,
|
|
2555
|
+
title: `${owner}/${repo}`,
|
|
2556
|
+
slug: repo,
|
|
2557
|
+
agents: [],
|
|
2558
|
+
mcp: [],
|
|
2559
|
+
tools: [],
|
|
2560
|
+
networks: [],
|
|
2561
|
+
workflows: []
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2477
2564
|
async function createFromTemplate(args2) {
|
|
2478
|
-
const templates = await loadTemplates();
|
|
2479
2565
|
let selectedTemplate;
|
|
2480
2566
|
if (args2.template === true) {
|
|
2481
|
-
|
|
2482
|
-
|
|
2567
|
+
const templates = await loadTemplates();
|
|
2568
|
+
const selected = await selectTemplate(templates);
|
|
2569
|
+
if (!selected) {
|
|
2483
2570
|
M.info("No template selected. Exiting.");
|
|
2484
2571
|
return;
|
|
2485
2572
|
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
if (
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2573
|
+
selectedTemplate = selected;
|
|
2574
|
+
} else if (args2.template && typeof args2.template === "string") {
|
|
2575
|
+
if (isGitHubUrl(args2.template)) {
|
|
2576
|
+
const spinner5 = Y();
|
|
2577
|
+
spinner5.start("Validating GitHub repository...");
|
|
2578
|
+
const validation = await validateGitHubProject(args2.template);
|
|
2579
|
+
if (!validation.isValid) {
|
|
2580
|
+
spinner5.stop("Validation failed");
|
|
2581
|
+
M.error("This does not appear to be a valid Mastra project:");
|
|
2582
|
+
validation.errors.forEach((error) => M.error(` - ${error}`));
|
|
2583
|
+
throw new Error("Invalid Mastra project");
|
|
2584
|
+
}
|
|
2585
|
+
spinner5.stop("Valid Mastra project \u2713");
|
|
2586
|
+
selectedTemplate = await createFromGitHubUrl(args2.template);
|
|
2587
|
+
} else {
|
|
2588
|
+
const templates = await loadTemplates();
|
|
2589
|
+
const found = findTemplateByName(templates, args2.template);
|
|
2590
|
+
if (!found) {
|
|
2591
|
+
M.error(`Template "${args2.template}" not found. Available templates:`);
|
|
2592
|
+
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2593
|
+
throw new Error(`Template "${args2.template}" not found`);
|
|
2594
|
+
}
|
|
2595
|
+
selectedTemplate = found;
|
|
2492
2596
|
}
|
|
2493
2597
|
}
|
|
2494
2598
|
if (!selectedTemplate) {
|
|
@@ -2509,8 +2613,13 @@ async function createFromTemplate(args2) {
|
|
|
2509
2613
|
projectName = response;
|
|
2510
2614
|
}
|
|
2511
2615
|
try {
|
|
2512
|
-
const analytics = getAnalytics();
|
|
2513
|
-
if (analytics)
|
|
2616
|
+
const analytics = args2.injectedAnalytics || getAnalytics();
|
|
2617
|
+
if (analytics) {
|
|
2618
|
+
analytics.trackEvent("cli_template_used", {
|
|
2619
|
+
template_slug: selectedTemplate.slug,
|
|
2620
|
+
template_title: selectedTemplate.title
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2514
2623
|
const projectPath = await cloneTemplate({
|
|
2515
2624
|
template: selectedTemplate,
|
|
2516
2625
|
projectName
|
|
@@ -2519,7 +2628,7 @@ async function createFromTemplate(args2) {
|
|
|
2519
2628
|
Me(`
|
|
2520
2629
|
${color2.green("Mastra template installed!")}
|
|
2521
2630
|
|
|
2522
|
-
Add the necessary environment
|
|
2631
|
+
Add the necessary environment
|
|
2523
2632
|
variables in your ${color2.cyan(".env")} file
|
|
2524
2633
|
`);
|
|
2525
2634
|
postCreate({ projectName });
|
|
@@ -2572,7 +2681,7 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2572
2681
|
"Project name that will be used in package.json and as the project directory name."
|
|
2573
2682
|
).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(
|
|
2574
2683
|
"--template [template-name]",
|
|
2575
|
-
"Create project from a template (use template name or leave blank to select from list)"
|
|
2684
|
+
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2576
2685
|
).action(async (projectNameArg, args) => {
|
|
2577
2686
|
const projectName = projectNameArg || args.projectName;
|
|
2578
2687
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
@@ -2585,7 +2694,8 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2585
2694
|
timeout,
|
|
2586
2695
|
mcpServer: args.mcp,
|
|
2587
2696
|
directory: "src/",
|
|
2588
|
-
template: args.template
|
|
2697
|
+
template: args.template,
|
|
2698
|
+
analytics
|
|
2589
2699
|
});
|
|
2590
2700
|
return;
|
|
2591
2701
|
}
|
|
@@ -2599,7 +2709,8 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2599
2709
|
projectName,
|
|
2600
2710
|
directory: args.dir,
|
|
2601
2711
|
mcpServer: args.mcp,
|
|
2602
|
-
template: args.template
|
|
2712
|
+
template: args.template,
|
|
2713
|
+
analytics
|
|
2603
2714
|
});
|
|
2604
2715
|
});
|
|
2605
2716
|
program.parse(process.argv);
|