create-mastra 0.0.0-experimental-agent-builder-20250815195917 → 0.0.0-export-agent-memory-from-local-studio-20251112153946
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 +2111 -0
- package/README.md +11 -39
- package/dist/index.js +645 -496
- package/dist/index.js.map +1 -1
- package/dist/starter-files/tools.ts +2 -2
- package/dist/templates/dev.entry.js +4 -42
- package/package.json +22 -14
- package/dist/starter-files/tools.d.ts +0 -79
- package/dist/starter-files/tools.d.ts.map +0 -1
- package/dist/templates/dev.entry.d.ts +0 -2
- package/dist/templates/dev.entry.d.ts.map +0 -1
- package/dist/templates/scorers/answer-relevancy-scorer.d.ts +0 -2
- package/dist/templates/scorers/answer-relevancy-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/answer-relevancy-scorer.ts +0 -15
- package/dist/templates/scorers/bias-detection-scorer.d.ts +0 -2
- package/dist/templates/scorers/bias-detection-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/bias-detection-scorer.ts +0 -16
- package/dist/templates/scorers/completeness-scorer.d.ts +0 -2
- package/dist/templates/scorers/completeness-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/completeness-scorer.ts +0 -16
- package/dist/templates/scorers/content-similarity-scorer.d.ts +0 -2
- package/dist/templates/scorers/content-similarity-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/content-similarity-scorer.ts +0 -15
- package/dist/templates/scorers/faithfulness-scorer.d.ts +0 -2
- package/dist/templates/scorers/faithfulness-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/faithfulness-scorer.ts +0 -21
- package/dist/templates/scorers/hallucination-scorer.d.ts +0 -2
- package/dist/templates/scorers/hallucination-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/hallucination-scorer.ts +0 -21
- package/dist/templates/scorers/keyword-coverage-scorer.d.ts +0 -2
- package/dist/templates/scorers/keyword-coverage-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/keyword-coverage-scorer.ts +0 -15
- package/dist/templates/scorers/textual-difference-scorer.d.ts +0 -2
- package/dist/templates/scorers/textual-difference-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/textual-difference-scorer.ts +0 -16
- package/dist/templates/scorers/tone-consistency-scorer.d.ts +0 -2
- package/dist/templates/scorers/tone-consistency-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/tone-consistency-scorer.ts +0 -16
- package/dist/templates/scorers/toxicity-detection-scorer.d.ts +0 -2
- package/dist/templates/scorers/toxicity-detection-scorer.d.ts.map +0 -1
- package/dist/templates/scorers/toxicity-detection-scorer.ts +0 -16
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import * as
|
|
5
|
-
import
|
|
4
|
+
import * as fs3__default from 'node:fs';
|
|
5
|
+
import fs3__default__default, { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import os from 'node:os';
|
|
7
|
-
import
|
|
7
|
+
import path, { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { PostHog } from 'posthog-node';
|
|
10
10
|
import util, { stripVTControlCharacters } from 'node:util';
|
|
@@ -12,18 +12,18 @@ import y$1, { stdout, stdin } from 'node:process';
|
|
|
12
12
|
import * as g from 'node:readline';
|
|
13
13
|
import g__default from 'node:readline';
|
|
14
14
|
import { Writable } from 'node:stream';
|
|
15
|
-
import
|
|
15
|
+
import fs4 from 'node:fs/promises';
|
|
16
16
|
import child_process from 'node:child_process';
|
|
17
17
|
import tty from 'node:tty';
|
|
18
|
+
import fsExtra, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
19
|
+
import prettier from 'prettier';
|
|
20
|
+
import { execa } from 'execa';
|
|
18
21
|
import pino from 'pino';
|
|
19
22
|
import pretty from 'pino-pretty';
|
|
20
|
-
import
|
|
21
|
-
import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
22
|
-
import prettier from 'prettier';
|
|
23
|
-
import fsExtra from 'fs-extra';
|
|
23
|
+
import fsExtra$1 from 'fs-extra';
|
|
24
24
|
|
|
25
25
|
var __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
var __dirname =
|
|
26
|
+
var __dirname = path.dirname(__filename);
|
|
27
27
|
var analyticsInstance = null;
|
|
28
28
|
function getAnalytics() {
|
|
29
29
|
return analyticsInstance;
|
|
@@ -39,7 +39,7 @@ var PosthogAnalytics = class {
|
|
|
39
39
|
host = "https://app.posthog.com"
|
|
40
40
|
}) {
|
|
41
41
|
this.version = version;
|
|
42
|
-
const cliConfigPath =
|
|
42
|
+
const cliConfigPath = path.join(__dirname, "mastra-cli.json");
|
|
43
43
|
if (existsSync(cliConfigPath)) {
|
|
44
44
|
try {
|
|
45
45
|
const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
|
|
@@ -67,7 +67,7 @@ var PosthogAnalytics = class {
|
|
|
67
67
|
}
|
|
68
68
|
writeCliConfig({ distinctId, sessionId }) {
|
|
69
69
|
try {
|
|
70
|
-
writeFileSync(
|
|
70
|
+
writeFileSync(path.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
|
|
71
71
|
} catch {
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -422,7 +422,7 @@ ${color2.gray(d)} ${t}
|
|
|
422
422
|
`):process.stdout.write(`${w} ${l}
|
|
423
423
|
`),E(),s();};return {start:H,stop:N,message:(m="")=>{l=R(m??l);}}},Ce=async(t,n)=>{const r={},i=Object.keys(t);for(const s of i){const c=t[s],a=await c({results:r})?.catch(l=>{throw l});if(typeof n?.onCancel=="function"&&pD(a)){r[s]="canceled",n.onCancel({results:r});continue}r[s]=a;}return r};
|
|
424
424
|
|
|
425
|
-
var shellQuote
|
|
425
|
+
var shellQuote = {};
|
|
426
426
|
|
|
427
427
|
var quote;
|
|
428
428
|
var hasRequiredQuote;
|
|
@@ -688,16 +688,16 @@ function requireParse () {
|
|
|
688
688
|
var hasRequiredShellQuote;
|
|
689
689
|
|
|
690
690
|
function requireShellQuote () {
|
|
691
|
-
if (hasRequiredShellQuote) return shellQuote
|
|
691
|
+
if (hasRequiredShellQuote) return shellQuote;
|
|
692
692
|
hasRequiredShellQuote = 1;
|
|
693
693
|
|
|
694
|
-
shellQuote
|
|
695
|
-
shellQuote
|
|
696
|
-
return shellQuote
|
|
694
|
+
shellQuote.quote = requireQuote();
|
|
695
|
+
shellQuote.parse = requireParse();
|
|
696
|
+
return shellQuote;
|
|
697
697
|
}
|
|
698
698
|
|
|
699
699
|
var shellQuoteExports = requireShellQuote();
|
|
700
|
-
var
|
|
700
|
+
var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
|
|
701
701
|
|
|
702
702
|
// eslint-disable-next-line no-warning-comments
|
|
703
703
|
// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
|
|
@@ -724,13 +724,18 @@ const format = (open, close) => {
|
|
|
724
724
|
// Handle nested colors.
|
|
725
725
|
|
|
726
726
|
// We could have done this, but it's too slow (as of Node.js 22).
|
|
727
|
-
// return openCode + string.replaceAll(closeCode, openCode) + closeCode;
|
|
727
|
+
// return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
|
|
728
728
|
|
|
729
729
|
let result = openCode;
|
|
730
730
|
let lastIndex = 0;
|
|
731
731
|
|
|
732
|
+
// SGR 22 resets both bold (1) and dim (2). When we encounter a nested
|
|
733
|
+
// close for styles that use 22, we need to re-open the outer style.
|
|
734
|
+
const reopenOnNestedClose = close === 22;
|
|
735
|
+
const replaceCode = (reopenOnNestedClose ? closeCode : '') + openCode;
|
|
736
|
+
|
|
732
737
|
while (index !== -1) {
|
|
733
|
-
result += string.slice(lastIndex, index) +
|
|
738
|
+
result += string.slice(lastIndex, index) + replaceCode;
|
|
734
739
|
lastIndex = index + closeCode.length;
|
|
735
740
|
index = string.indexOf(closeCode, lastIndex);
|
|
736
741
|
}
|
|
@@ -882,6 +887,7 @@ class YoctoSpinner {
|
|
|
882
887
|
#exitHandlerBound;
|
|
883
888
|
#isInteractive;
|
|
884
889
|
#lastSpinnerFrameTime = 0;
|
|
890
|
+
#isSpinning = false;
|
|
885
891
|
|
|
886
892
|
constructor(options = {}) {
|
|
887
893
|
const spinner = options.spinner ?? defaultSpinner;
|
|
@@ -903,13 +909,17 @@ class YoctoSpinner {
|
|
|
903
909
|
return this;
|
|
904
910
|
}
|
|
905
911
|
|
|
912
|
+
this.#isSpinning = true;
|
|
906
913
|
this.#hideCursor();
|
|
907
914
|
this.#render();
|
|
908
915
|
this.#subscribeToProcessEvents();
|
|
909
916
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
917
|
+
// Only start the timer in interactive mode
|
|
918
|
+
if (this.#isInteractive) {
|
|
919
|
+
this.#timer = setInterval(() => {
|
|
920
|
+
this.#render();
|
|
921
|
+
}, this.#interval);
|
|
922
|
+
}
|
|
913
923
|
|
|
914
924
|
return this;
|
|
915
925
|
}
|
|
@@ -919,8 +929,12 @@ class YoctoSpinner {
|
|
|
919
929
|
return this;
|
|
920
930
|
}
|
|
921
931
|
|
|
922
|
-
|
|
923
|
-
this.#timer
|
|
932
|
+
this.#isSpinning = false;
|
|
933
|
+
if (this.#timer) {
|
|
934
|
+
clearInterval(this.#timer);
|
|
935
|
+
this.#timer = undefined;
|
|
936
|
+
}
|
|
937
|
+
|
|
924
938
|
this.#showCursor();
|
|
925
939
|
this.clear();
|
|
926
940
|
this.#unsubscribeFromProcessEvents();
|
|
@@ -953,7 +967,7 @@ class YoctoSpinner {
|
|
|
953
967
|
}
|
|
954
968
|
|
|
955
969
|
get isSpinning() {
|
|
956
|
-
return this.#
|
|
970
|
+
return this.#isSpinning;
|
|
957
971
|
}
|
|
958
972
|
|
|
959
973
|
get text() {
|
|
@@ -1090,11 +1104,11 @@ var MastraLogger = class {
|
|
|
1090
1104
|
}
|
|
1091
1105
|
trackException(_error) {
|
|
1092
1106
|
}
|
|
1093
|
-
async
|
|
1107
|
+
async listLogs(transportId, params) {
|
|
1094
1108
|
if (!transportId || !this.transports.has(transportId)) {
|
|
1095
1109
|
return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
|
|
1096
1110
|
}
|
|
1097
|
-
return this.transports.get(transportId).
|
|
1111
|
+
return this.transports.get(transportId).listLogs(params) ?? {
|
|
1098
1112
|
logs: [],
|
|
1099
1113
|
total: 0,
|
|
1100
1114
|
page: params?.page ?? 1,
|
|
@@ -1102,7 +1116,7 @@ var MastraLogger = class {
|
|
|
1102
1116
|
hasMore: false
|
|
1103
1117
|
};
|
|
1104
1118
|
}
|
|
1105
|
-
async
|
|
1119
|
+
async listLogsByRunId({
|
|
1106
1120
|
transportId,
|
|
1107
1121
|
runId,
|
|
1108
1122
|
fromDate,
|
|
@@ -1115,7 +1129,7 @@ var MastraLogger = class {
|
|
|
1115
1129
|
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1116
1130
|
return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
|
|
1117
1131
|
}
|
|
1118
|
-
return this.transports.get(transportId).
|
|
1132
|
+
return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
|
|
1119
1133
|
logs: [],
|
|
1120
1134
|
total: 0,
|
|
1121
1135
|
page: page ?? 1,
|
|
@@ -1173,288 +1187,6 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1173
1187
|
}
|
|
1174
1188
|
};
|
|
1175
1189
|
|
|
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 spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
1220
|
-
try {
|
|
1221
|
-
if (await directoryExists(projectPath)) {
|
|
1222
|
-
spinner5.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
|
-
spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
1232
|
-
return projectPath;
|
|
1233
|
-
} catch (error) {
|
|
1234
|
-
spinner5.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 spinner5 = 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
|
-
spinner5.success("Dependencies installed successfully");
|
|
1297
|
-
} catch (error) {
|
|
1298
|
-
spinner5.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
1190
|
var args = ["-y", "@mastra/mcp-docs-server"];
|
|
1459
1191
|
var createMcpConfig = (editor) => {
|
|
1460
1192
|
if (editor === "vscode") {
|
|
@@ -1507,19 +1239,19 @@ async function writeMergedConfig(configPath, editor) {
|
|
|
1507
1239
|
spaces: 2
|
|
1508
1240
|
});
|
|
1509
1241
|
}
|
|
1510
|
-
var windsurfGlobalMCPConfigPath =
|
|
1511
|
-
var cursorGlobalMCPConfigPath =
|
|
1512
|
-
|
|
1513
|
-
var vscodeGlobalMCPConfigPath =
|
|
1242
|
+
var windsurfGlobalMCPConfigPath = path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1243
|
+
var cursorGlobalMCPConfigPath = path.join(os.homedir(), ".cursor", "mcp.json");
|
|
1244
|
+
path.join(process.cwd(), ".vscode", "mcp.json");
|
|
1245
|
+
var vscodeGlobalMCPConfigPath = path.join(
|
|
1514
1246
|
os.homedir(),
|
|
1515
|
-
process.platform === "win32" ?
|
|
1247
|
+
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
1248
|
);
|
|
1517
1249
|
async function installMastraDocsMCPServer({ editor, directory }) {
|
|
1518
1250
|
if (editor === `cursor`) {
|
|
1519
|
-
await writeMergedConfig(
|
|
1251
|
+
await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
|
|
1520
1252
|
}
|
|
1521
1253
|
if (editor === `vscode`) {
|
|
1522
|
-
await writeMergedConfig(
|
|
1254
|
+
await writeMergedConfig(path.join(directory, ".vscode", "mcp.json"), "vscode");
|
|
1523
1255
|
}
|
|
1524
1256
|
if (editor === `cursor-global`) {
|
|
1525
1257
|
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
@@ -1567,25 +1299,121 @@ async function globalMCPIsAlreadyInstalled(editor) {
|
|
|
1567
1299
|
return false;
|
|
1568
1300
|
}
|
|
1569
1301
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1302
|
+
function getPackageManagerAddCommand(pm) {
|
|
1303
|
+
switch (pm) {
|
|
1304
|
+
case "npm":
|
|
1305
|
+
return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
|
|
1306
|
+
case "yarn":
|
|
1307
|
+
return "add";
|
|
1308
|
+
case "pnpm":
|
|
1309
|
+
return "add --loglevel=error";
|
|
1310
|
+
case "bun":
|
|
1311
|
+
return "add";
|
|
1312
|
+
default:
|
|
1313
|
+
return "add";
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
var DepsService = class {
|
|
1317
|
+
packageManager;
|
|
1318
|
+
constructor() {
|
|
1319
|
+
this.packageManager = this.getPackageManager();
|
|
1320
|
+
}
|
|
1321
|
+
findLockFile(dir) {
|
|
1322
|
+
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1323
|
+
for (const file of lockFiles) {
|
|
1324
|
+
if (fs3__default__default.existsSync(path.join(dir, file))) {
|
|
1325
|
+
return file;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
const parentDir = path.resolve(dir, "..");
|
|
1329
|
+
if (parentDir !== dir) {
|
|
1330
|
+
return this.findLockFile(parentDir);
|
|
1331
|
+
}
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
getPackageManager() {
|
|
1335
|
+
const lockFile = this.findLockFile(process.cwd());
|
|
1336
|
+
switch (lockFile) {
|
|
1337
|
+
case "pnpm-lock.yaml":
|
|
1338
|
+
return "pnpm";
|
|
1339
|
+
case "package-lock.json":
|
|
1340
|
+
return "npm";
|
|
1341
|
+
case "yarn.lock":
|
|
1342
|
+
return "yarn";
|
|
1343
|
+
case "bun.lock":
|
|
1344
|
+
return "bun";
|
|
1345
|
+
default:
|
|
1346
|
+
return "npm";
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
async installPackages(packages) {
|
|
1350
|
+
const pm = this.packageManager;
|
|
1351
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
1352
|
+
const packageList = packages.join(" ");
|
|
1353
|
+
return execa(`${pm} ${installCommand} ${packageList}`, {
|
|
1354
|
+
all: true,
|
|
1355
|
+
shell: true,
|
|
1356
|
+
stdio: "inherit"
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
async checkDependencies(dependencies) {
|
|
1360
|
+
try {
|
|
1361
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1362
|
+
try {
|
|
1363
|
+
await fs4.access(packageJsonPath);
|
|
1364
|
+
} catch {
|
|
1365
|
+
return "No package.json file found in the current directory";
|
|
1366
|
+
}
|
|
1367
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
1368
|
+
for (const dependency of dependencies) {
|
|
1369
|
+
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
1370
|
+
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
return "ok";
|
|
1374
|
+
} catch (err) {
|
|
1375
|
+
console.error(err);
|
|
1376
|
+
return "Could not check dependencies";
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
async getProjectName() {
|
|
1380
|
+
try {
|
|
1381
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1382
|
+
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1383
|
+
const pkg = JSON.parse(packageJson);
|
|
1384
|
+
return pkg.name;
|
|
1385
|
+
} catch (err) {
|
|
1386
|
+
throw err;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
async addScriptsToPackageJson(scripts) {
|
|
1390
|
+
const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
|
|
1391
|
+
packageJson.scripts = {
|
|
1392
|
+
...packageJson.scripts,
|
|
1393
|
+
...scripts
|
|
1394
|
+
};
|
|
1395
|
+
await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1398
|
+
var EnvService = class {
|
|
1399
|
+
};
|
|
1400
|
+
var FileEnvService = class extends EnvService {
|
|
1401
|
+
filePath;
|
|
1402
|
+
constructor(filePath) {
|
|
1403
|
+
super();
|
|
1404
|
+
this.filePath = filePath;
|
|
1405
|
+
}
|
|
1406
|
+
readFile(filePath) {
|
|
1407
|
+
return new Promise((resolve, reject) => {
|
|
1408
|
+
fs3__default.readFile(filePath, "utf8", (err, data) => {
|
|
1409
|
+
if (err) reject(err);
|
|
1410
|
+
else resolve(data);
|
|
1411
|
+
});
|
|
1412
|
+
});
|
|
1585
1413
|
}
|
|
1586
1414
|
writeFile({ filePath, data }) {
|
|
1587
1415
|
return new Promise((resolve, reject) => {
|
|
1588
|
-
|
|
1416
|
+
fs3__default.writeFile(filePath, data, "utf8", (err) => {
|
|
1589
1417
|
if (err) reject(err);
|
|
1590
1418
|
else resolve();
|
|
1591
1419
|
});
|
|
@@ -1605,7 +1433,7 @@ var FileEnvService = class extends EnvService {
|
|
|
1605
1433
|
${key}=${value}`;
|
|
1606
1434
|
}
|
|
1607
1435
|
await this.writeFile({ filePath, data });
|
|
1608
|
-
console.
|
|
1436
|
+
console.info(`${key} set to ${value} in ENV file.`);
|
|
1609
1437
|
return data;
|
|
1610
1438
|
}
|
|
1611
1439
|
async getEnvValue(key) {
|
|
@@ -1638,25 +1466,25 @@ var FileService = class {
|
|
|
1638
1466
|
*/
|
|
1639
1467
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1640
1468
|
const __filename = fileURLToPath(import.meta.url);
|
|
1641
|
-
const __dirname =
|
|
1642
|
-
const filePath =
|
|
1643
|
-
const fileString =
|
|
1644
|
-
if (
|
|
1645
|
-
console.
|
|
1469
|
+
const __dirname = path.dirname(__filename);
|
|
1470
|
+
const filePath = path.resolve(__dirname, "starter-files", inputFile);
|
|
1471
|
+
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1472
|
+
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1473
|
+
console.info(`${outputFilePath} already exists`);
|
|
1646
1474
|
return false;
|
|
1647
1475
|
}
|
|
1648
|
-
await
|
|
1476
|
+
await fsExtra.outputFile(outputFilePath, fileString);
|
|
1649
1477
|
return true;
|
|
1650
1478
|
}
|
|
1651
1479
|
async setupEnvFile({ dbUrl }) {
|
|
1652
|
-
const envPath =
|
|
1653
|
-
await
|
|
1480
|
+
const envPath = path.join(process.cwd(), ".env.development");
|
|
1481
|
+
await fsExtra.ensureFile(envPath);
|
|
1654
1482
|
const fileEnvService = new FileEnvService(envPath);
|
|
1655
1483
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
1656
1484
|
}
|
|
1657
1485
|
getFirstExistingFile(files) {
|
|
1658
1486
|
for (const f of files) {
|
|
1659
|
-
if (
|
|
1487
|
+
if (fs3__default__default.existsSync(f)) {
|
|
1660
1488
|
return f;
|
|
1661
1489
|
}
|
|
1662
1490
|
}
|
|
@@ -1666,61 +1494,31 @@ var FileService = class {
|
|
|
1666
1494
|
filePath,
|
|
1667
1495
|
replacements
|
|
1668
1496
|
}) {
|
|
1669
|
-
let fileContent =
|
|
1497
|
+
let fileContent = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1670
1498
|
replacements.forEach(({ search, replace }) => {
|
|
1671
1499
|
fileContent = fileContent.replaceAll(search, replace);
|
|
1672
1500
|
});
|
|
1673
|
-
|
|
1674
|
-
}
|
|
1675
|
-
};
|
|
1676
|
-
var exec2 = util.promisify(child_process.exec);
|
|
1677
|
-
var getAISDKPackageVersion = (llmProvider) => {
|
|
1678
|
-
switch (llmProvider) {
|
|
1679
|
-
case "cerebras":
|
|
1680
|
-
return "^0.2.14";
|
|
1681
|
-
default:
|
|
1682
|
-
return "^1.0.0";
|
|
1501
|
+
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1683
1502
|
}
|
|
1684
1503
|
};
|
|
1685
|
-
var
|
|
1686
|
-
|
|
1687
|
-
case "openai":
|
|
1688
|
-
return "@ai-sdk/openai";
|
|
1689
|
-
case "anthropic":
|
|
1690
|
-
return "@ai-sdk/anthropic";
|
|
1691
|
-
case "groq":
|
|
1692
|
-
return "@ai-sdk/groq";
|
|
1693
|
-
case "google":
|
|
1694
|
-
return "@ai-sdk/google";
|
|
1695
|
-
case "cerebras":
|
|
1696
|
-
return "@ai-sdk/cerebras";
|
|
1697
|
-
default:
|
|
1698
|
-
return "@ai-sdk/openai";
|
|
1699
|
-
}
|
|
1700
|
-
};
|
|
1701
|
-
var getProviderImportAndModelItem = (llmProvider) => {
|
|
1702
|
-
let providerImport = "";
|
|
1703
|
-
let modelItem = "";
|
|
1504
|
+
var exec = util.promisify(child_process.exec);
|
|
1505
|
+
var getModelIdentifier = (llmProvider) => {
|
|
1704
1506
|
if (llmProvider === "openai") {
|
|
1705
|
-
|
|
1706
|
-
modelItem = `openai('gpt-4o-mini')`;
|
|
1507
|
+
return `'openai/gpt-4o-mini'`;
|
|
1707
1508
|
} else if (llmProvider === "anthropic") {
|
|
1708
|
-
|
|
1709
|
-
modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
|
|
1509
|
+
return `'anthropic/claude-sonnet-4-5-20250929'`;
|
|
1710
1510
|
} else if (llmProvider === "groq") {
|
|
1711
|
-
|
|
1712
|
-
modelItem = `groq('llama-3.3-70b-versatile')`;
|
|
1511
|
+
return `'groq/llama-3.3-70b-versatile'`;
|
|
1713
1512
|
} else if (llmProvider === "google") {
|
|
1714
|
-
|
|
1715
|
-
modelItem = `google('gemini-2.5-pro')`;
|
|
1513
|
+
return `'google/gemini-2.5-pro'`;
|
|
1716
1514
|
} else if (llmProvider === "cerebras") {
|
|
1717
|
-
|
|
1718
|
-
|
|
1515
|
+
return `'cerebras/llama-3.3-70b'`;
|
|
1516
|
+
} else if (llmProvider === "mistral") {
|
|
1517
|
+
return `'mistral/mistral-medium-2508'`;
|
|
1719
1518
|
}
|
|
1720
|
-
return { providerImport, modelItem };
|
|
1721
1519
|
};
|
|
1722
|
-
async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
1723
|
-
const
|
|
1520
|
+
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1521
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1724
1522
|
const instructions = `
|
|
1725
1523
|
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
|
|
1726
1524
|
|
|
@@ -1736,19 +1534,44 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
|
1736
1534
|
${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
|
|
1737
1535
|
`;
|
|
1738
1536
|
const content = `
|
|
1739
|
-
${providerImport}
|
|
1740
1537
|
import { Agent } from '@mastra/core/agent';
|
|
1741
1538
|
import { Memory } from '@mastra/memory';
|
|
1742
1539
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1743
1540
|
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1541
|
+
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1744
1542
|
|
|
1745
1543
|
export const weatherAgent = new Agent({
|
|
1544
|
+
id: 'weather-agent',
|
|
1746
1545
|
name: 'Weather Agent',
|
|
1747
1546
|
instructions: \`${instructions}\`,
|
|
1748
|
-
model: ${
|
|
1547
|
+
model: ${modelString},
|
|
1749
1548
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1549
|
+
${addScorers ? `scorers: {
|
|
1550
|
+
toolCallAppropriateness: {
|
|
1551
|
+
scorer: scorers.toolCallAppropriatenessScorer,
|
|
1552
|
+
sampling: {
|
|
1553
|
+
type: 'ratio',
|
|
1554
|
+
rate: 1,
|
|
1555
|
+
},
|
|
1556
|
+
},
|
|
1557
|
+
completeness: {
|
|
1558
|
+
scorer: scorers.completenessScorer,
|
|
1559
|
+
sampling: {
|
|
1560
|
+
type: 'ratio',
|
|
1561
|
+
rate: 1,
|
|
1562
|
+
},
|
|
1563
|
+
},
|
|
1564
|
+
translation: {
|
|
1565
|
+
scorer: scorers.translationScorer,
|
|
1566
|
+
sampling: {
|
|
1567
|
+
type: 'ratio',
|
|
1568
|
+
rate: 1,
|
|
1569
|
+
},
|
|
1570
|
+
},
|
|
1571
|
+
},` : ""}
|
|
1750
1572
|
memory: new Memory({
|
|
1751
1573
|
storage: new LibSQLStore({
|
|
1574
|
+
id: "memory-storage",
|
|
1752
1575
|
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1753
1576
|
})
|
|
1754
1577
|
})
|
|
@@ -1758,8 +1581,8 @@ export const weatherAgent = new Agent({
|
|
|
1758
1581
|
parser: "typescript",
|
|
1759
1582
|
singleQuote: true
|
|
1760
1583
|
});
|
|
1761
|
-
await
|
|
1762
|
-
await
|
|
1584
|
+
await fs4.writeFile(destPath, "");
|
|
1585
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1763
1586
|
}
|
|
1764
1587
|
async function writeWorkflowSample(destPath) {
|
|
1765
1588
|
const content = `import { createStep, createWorkflow } from '@mastra/core/workflows';
|
|
@@ -1952,72 +1775,176 @@ export { weatherWorkflow };`;
|
|
|
1952
1775
|
semi: true,
|
|
1953
1776
|
singleQuote: true
|
|
1954
1777
|
});
|
|
1955
|
-
await
|
|
1778
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1956
1779
|
}
|
|
1957
1780
|
async function writeToolSample(destPath) {
|
|
1958
1781
|
const fileService = new FileService();
|
|
1959
1782
|
await fileService.copyStarterFile("tools.ts", destPath);
|
|
1960
1783
|
}
|
|
1784
|
+
async function writeScorersSample(llmProvider, destPath) {
|
|
1785
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1786
|
+
const content = `import { z } from 'zod';
|
|
1787
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
1788
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
|
|
1789
|
+
import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
1790
|
+
import { createScorer } from '@mastra/core/evals';
|
|
1791
|
+
|
|
1792
|
+
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1793
|
+
expectedTool: 'weatherTool',
|
|
1794
|
+
strictMode: false,
|
|
1795
|
+
});
|
|
1796
|
+
|
|
1797
|
+
export const completenessScorer = createCompletenessScorer();
|
|
1798
|
+
|
|
1799
|
+
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1800
|
+
export const translationScorer = createScorer({
|
|
1801
|
+
id: 'translation-quality-scorer',
|
|
1802
|
+
name: 'Translation Quality',
|
|
1803
|
+
description: 'Checks that non-English location names are translated and used correctly',
|
|
1804
|
+
type: 'agent',
|
|
1805
|
+
judge: {
|
|
1806
|
+
model: ${modelString},
|
|
1807
|
+
instructions:
|
|
1808
|
+
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1809
|
+
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
1810
|
+
'Be lenient with transliteration differences and diacritics. ' +
|
|
1811
|
+
'Return only the structured JSON matching the provided schema.',
|
|
1812
|
+
},
|
|
1813
|
+
})
|
|
1814
|
+
.preprocess(({ run }) => {
|
|
1815
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1816
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1817
|
+
return { userText, assistantText };
|
|
1818
|
+
})
|
|
1819
|
+
.analyze({
|
|
1820
|
+
description: 'Extract location names and detect language/translation adequacy',
|
|
1821
|
+
outputSchema: z.object({
|
|
1822
|
+
nonEnglish: z.boolean(),
|
|
1823
|
+
translated: z.boolean(),
|
|
1824
|
+
confidence: z.number().min(0).max(1).default(1),
|
|
1825
|
+
explanation: z.string().default(''),
|
|
1826
|
+
}),
|
|
1827
|
+
createPrompt: ({ results }) => \`
|
|
1828
|
+
You are evaluating if a weather assistant correctly handled translation of a non-English location.
|
|
1829
|
+
User text:
|
|
1830
|
+
"""
|
|
1831
|
+
\${results.preprocessStepResult.userText}
|
|
1832
|
+
"""
|
|
1833
|
+
Assistant response:
|
|
1834
|
+
"""
|
|
1835
|
+
\${results.preprocessStepResult.assistantText}
|
|
1836
|
+
"""
|
|
1837
|
+
Tasks:
|
|
1838
|
+
1) Identify if the user mentioned a location that appears non-English.
|
|
1839
|
+
2) If non-English, check whether the assistant used a correct English translation of that location in its response.
|
|
1840
|
+
3) Be lenient with transliteration differences (e.g., accents/diacritics).
|
|
1841
|
+
Return JSON with fields:
|
|
1842
|
+
{
|
|
1843
|
+
"nonEnglish": boolean,
|
|
1844
|
+
"translated": boolean,
|
|
1845
|
+
"confidence": number, // 0-1
|
|
1846
|
+
"explanation": string
|
|
1847
|
+
}
|
|
1848
|
+
\`,
|
|
1849
|
+
})
|
|
1850
|
+
.generateScore(({ results }) => {
|
|
1851
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1852
|
+
if (!r.nonEnglish) return 1; // If not applicable, full credit
|
|
1853
|
+
if (r.translated) return Math.max(0, Math.min(1, 0.7 + 0.3 * (r.confidence ?? 1)));
|
|
1854
|
+
return 0; // Non-English but not translated
|
|
1855
|
+
})
|
|
1856
|
+
.generateReason(({ results, score }) => {
|
|
1857
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1858
|
+
return \`Translation scoring: nonEnglish=\${r.nonEnglish ?? false}, translated=\${r.translated ?? false}, confidence=\${r.confidence ?? 0}. Score=\${score}. \${r.explanation ?? ''}\`;
|
|
1859
|
+
});
|
|
1860
|
+
|
|
1861
|
+
export const scorers = {
|
|
1862
|
+
toolCallAppropriatenessScorer,
|
|
1863
|
+
completenessScorer,
|
|
1864
|
+
translationScorer,
|
|
1865
|
+
};`;
|
|
1866
|
+
const formattedContent = await prettier.format(content, {
|
|
1867
|
+
parser: "typescript",
|
|
1868
|
+
singleQuote: true
|
|
1869
|
+
});
|
|
1870
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1871
|
+
}
|
|
1961
1872
|
async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
|
|
1962
1873
|
switch (component) {
|
|
1963
1874
|
case "agents":
|
|
1964
|
-
return writeAgentSample(
|
|
1875
|
+
return writeAgentSample(
|
|
1876
|
+
llmprovider,
|
|
1877
|
+
destPath,
|
|
1878
|
+
importComponents.includes("tools"),
|
|
1879
|
+
importComponents.includes("scorers")
|
|
1880
|
+
);
|
|
1965
1881
|
case "tools":
|
|
1966
1882
|
return writeToolSample(destPath);
|
|
1967
1883
|
case "workflows":
|
|
1968
1884
|
return writeWorkflowSample(destPath);
|
|
1885
|
+
case "scorers":
|
|
1886
|
+
return writeScorersSample(llmprovider, destPath);
|
|
1969
1887
|
default:
|
|
1970
1888
|
return "";
|
|
1971
1889
|
}
|
|
1972
1890
|
}
|
|
1973
1891
|
var createComponentsDir = async (dirPath, component) => {
|
|
1974
1892
|
const componentPath = dirPath + `/${component}`;
|
|
1975
|
-
await
|
|
1893
|
+
await fsExtra.ensureDir(componentPath);
|
|
1976
1894
|
};
|
|
1977
1895
|
var writeIndexFile = async ({
|
|
1978
1896
|
dirPath,
|
|
1979
1897
|
addAgent,
|
|
1980
1898
|
addExample,
|
|
1981
|
-
addWorkflow
|
|
1899
|
+
addWorkflow,
|
|
1900
|
+
addScorers
|
|
1982
1901
|
}) => {
|
|
1983
1902
|
const indexPath = dirPath + "/index.ts";
|
|
1984
|
-
const destPath =
|
|
1903
|
+
const destPath = path.join(indexPath);
|
|
1985
1904
|
try {
|
|
1986
|
-
await
|
|
1905
|
+
await fs4.writeFile(destPath, "");
|
|
1987
1906
|
const filteredExports = [
|
|
1988
1907
|
addWorkflow ? `workflows: { weatherWorkflow },` : "",
|
|
1989
|
-
addAgent ? `agents: { weatherAgent },` : ""
|
|
1908
|
+
addAgent ? `agents: { weatherAgent },` : "",
|
|
1909
|
+
addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
|
|
1990
1910
|
].filter(Boolean);
|
|
1991
1911
|
if (!addExample) {
|
|
1992
|
-
await
|
|
1912
|
+
await fs4.writeFile(
|
|
1993
1913
|
destPath,
|
|
1994
1914
|
`
|
|
1995
|
-
import { Mastra } from '@mastra/core';
|
|
1915
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1996
1916
|
|
|
1997
1917
|
export const mastra = new Mastra()
|
|
1998
1918
|
`
|
|
1999
1919
|
);
|
|
2000
1920
|
return;
|
|
2001
1921
|
}
|
|
2002
|
-
await
|
|
1922
|
+
await fs4.writeFile(
|
|
2003
1923
|
destPath,
|
|
2004
1924
|
`
|
|
2005
1925
|
import { Mastra } from '@mastra/core/mastra';
|
|
2006
1926
|
import { PinoLogger } from '@mastra/loggers';
|
|
2007
1927
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1928
|
+
import { Observability } from '@mastra/observability';
|
|
2008
1929
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
2009
1930
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1931
|
+
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
2010
1932
|
|
|
2011
1933
|
export const mastra = new Mastra({
|
|
2012
1934
|
${filteredExports.join("\n ")}
|
|
2013
1935
|
storage: new LibSQLStore({
|
|
2014
|
-
|
|
1936
|
+
id: "mastra-storage",
|
|
1937
|
+
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
2015
1938
|
url: ":memory:",
|
|
2016
1939
|
}),
|
|
2017
1940
|
logger: new PinoLogger({
|
|
2018
1941
|
name: 'Mastra',
|
|
2019
1942
|
level: 'info',
|
|
2020
1943
|
}),
|
|
1944
|
+
observability: new Observability({
|
|
1945
|
+
// Enables DefaultExporter and CloudExporter for tracing
|
|
1946
|
+
default: { enabled: true },
|
|
1947
|
+
}),
|
|
2021
1948
|
});
|
|
2022
1949
|
`
|
|
2023
1950
|
);
|
|
@@ -2025,7 +1952,6 @@ export const mastra = new Mastra({
|
|
|
2025
1952
|
throw err;
|
|
2026
1953
|
}
|
|
2027
1954
|
};
|
|
2028
|
-
yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
|
|
2029
1955
|
var getAPIKey = async (provider) => {
|
|
2030
1956
|
let key = "OPENAI_API_KEY";
|
|
2031
1957
|
switch (provider) {
|
|
@@ -2041,27 +1967,28 @@ var getAPIKey = async (provider) => {
|
|
|
2041
1967
|
case "cerebras":
|
|
2042
1968
|
key = "CEREBRAS_API_KEY";
|
|
2043
1969
|
return key;
|
|
1970
|
+
case "mistral":
|
|
1971
|
+
key = "MISTRAL_API_KEY";
|
|
1972
|
+
return key;
|
|
2044
1973
|
default:
|
|
2045
1974
|
return key;
|
|
2046
1975
|
}
|
|
2047
1976
|
};
|
|
2048
|
-
var writeAPIKey = async ({
|
|
2049
|
-
|
|
2050
|
-
apiKey = "your-api-key"
|
|
2051
|
-
}) => {
|
|
1977
|
+
var writeAPIKey = async ({ provider, apiKey }) => {
|
|
1978
|
+
const envFileName = apiKey ? ".env" : ".env.example";
|
|
2052
1979
|
const key = await getAPIKey(provider);
|
|
2053
|
-
const escapedKey =
|
|
2054
|
-
const escapedApiKey =
|
|
2055
|
-
await
|
|
1980
|
+
const escapedKey = shellQuote2.quote([key]);
|
|
1981
|
+
const escapedApiKey = shellQuote2.quote([apiKey ? apiKey : "your-api-key"]);
|
|
1982
|
+
await exec(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
|
|
2056
1983
|
};
|
|
2057
1984
|
var createMastraDir = async (directory) => {
|
|
2058
1985
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
2059
|
-
const dirPath =
|
|
1986
|
+
const dirPath = path.join(process.cwd(), ...dir, "mastra");
|
|
2060
1987
|
try {
|
|
2061
|
-
await
|
|
1988
|
+
await fs4.access(dirPath);
|
|
2062
1989
|
return { ok: false };
|
|
2063
1990
|
} catch {
|
|
2064
|
-
await
|
|
1991
|
+
await fsExtra.ensureDir(dirPath);
|
|
2065
1992
|
return { ok: true, dirPath };
|
|
2066
1993
|
}
|
|
2067
1994
|
};
|
|
@@ -2073,8 +2000,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
|
|
|
2073
2000
|
throw err;
|
|
2074
2001
|
}
|
|
2075
2002
|
};
|
|
2076
|
-
var
|
|
2077
|
-
|
|
2003
|
+
var LLM_PROVIDERS = [
|
|
2004
|
+
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
2005
|
+
{ value: "anthropic", label: "Anthropic" },
|
|
2006
|
+
{ value: "groq", label: "Groq" },
|
|
2007
|
+
{ value: "google", label: "Google" },
|
|
2008
|
+
{ value: "cerebras", label: "Cerebras" },
|
|
2009
|
+
{ value: "mistral", label: "Mistral" }
|
|
2010
|
+
];
|
|
2011
|
+
var interactivePrompt = async (args2 = {}) => {
|
|
2012
|
+
const { skip = {}, options: { showBanner = true } = {} } = args2;
|
|
2013
|
+
if (showBanner) {
|
|
2014
|
+
Ie(color2.inverse(" Mastra Init "));
|
|
2015
|
+
}
|
|
2078
2016
|
const mastraProject = await Ce(
|
|
2079
2017
|
{
|
|
2080
2018
|
directory: () => he({
|
|
@@ -2082,19 +2020,15 @@ var interactivePrompt = async () => {
|
|
|
2082
2020
|
placeholder: "src/",
|
|
2083
2021
|
defaultValue: "src/"
|
|
2084
2022
|
}),
|
|
2085
|
-
llmProvider: () => ve({
|
|
2086
|
-
message: "Select default provider:",
|
|
2087
|
-
options:
|
|
2088
|
-
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
2089
|
-
{ value: "anthropic", label: "Anthropic" },
|
|
2090
|
-
{ value: "groq", label: "Groq" },
|
|
2091
|
-
{ value: "google", label: "Google" },
|
|
2092
|
-
{ value: "cerebras", label: "Cerebras" }
|
|
2093
|
-
]
|
|
2023
|
+
llmProvider: () => skip?.llmProvider ? void 0 : ve({
|
|
2024
|
+
message: "Select a default provider:",
|
|
2025
|
+
options: LLM_PROVIDERS
|
|
2094
2026
|
}),
|
|
2095
2027
|
llmApiKey: async ({ results: { llmProvider } }) => {
|
|
2028
|
+
if (skip?.llmApiKey) return void 0;
|
|
2029
|
+
const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
|
|
2096
2030
|
const keyChoice = await ve({
|
|
2097
|
-
message: `Enter your ${
|
|
2031
|
+
message: `Enter your ${llmName} API key?`,
|
|
2098
2032
|
options: [
|
|
2099
2033
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2100
2034
|
{ value: "enter", label: "Enter API key" }
|
|
@@ -2104,7 +2038,10 @@ var interactivePrompt = async () => {
|
|
|
2104
2038
|
if (keyChoice === "enter") {
|
|
2105
2039
|
return he({
|
|
2106
2040
|
message: "Enter your API key:",
|
|
2107
|
-
placeholder: "sk-..."
|
|
2041
|
+
placeholder: "sk-...",
|
|
2042
|
+
validate: (value) => {
|
|
2043
|
+
if (value.length === 0) return "API key cannot be empty";
|
|
2044
|
+
}
|
|
2108
2045
|
});
|
|
2109
2046
|
}
|
|
2110
2047
|
return void 0;
|
|
@@ -2114,7 +2051,7 @@ var interactivePrompt = async () => {
|
|
|
2114
2051
|
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
2115
2052
|
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
2116
2053
|
const editor = await ve({
|
|
2117
|
-
message: `Make your
|
|
2054
|
+
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
2118
2055
|
options: [
|
|
2119
2056
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
2120
2057
|
{
|
|
@@ -2158,19 +2095,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
2158
2095
|
);
|
|
2159
2096
|
}
|
|
2160
2097
|
if (editor === `cursor-global`) {
|
|
2161
|
-
const
|
|
2098
|
+
const confirm = await ve({
|
|
2162
2099
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2163
2100
|
options: [
|
|
2164
2101
|
{ value: "yes", label: "Yes, I understand" },
|
|
2165
2102
|
{ value: "skip", label: "No, skip for now" }
|
|
2166
2103
|
]
|
|
2167
2104
|
});
|
|
2168
|
-
if (
|
|
2105
|
+
if (confirm !== `yes`) {
|
|
2169
2106
|
return void 0;
|
|
2170
2107
|
}
|
|
2171
2108
|
}
|
|
2172
2109
|
if (editor === `windsurf`) {
|
|
2173
|
-
const
|
|
2110
|
+
const confirm = await ve({
|
|
2174
2111
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
2175
2112
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
2176
2113
|
options: [
|
|
@@ -2178,7 +2115,7 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2178
2115
|
{ value: "skip", label: "No, skip for now" }
|
|
2179
2116
|
]
|
|
2180
2117
|
});
|
|
2181
|
-
if (
|
|
2118
|
+
if (confirm !== `yes`) {
|
|
2182
2119
|
return void 0;
|
|
2183
2120
|
}
|
|
2184
2121
|
}
|
|
@@ -2194,17 +2131,198 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2194
2131
|
);
|
|
2195
2132
|
return mastraProject;
|
|
2196
2133
|
};
|
|
2134
|
+
function getPackageManager() {
|
|
2135
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
2136
|
+
const execPath = process.env.npm_execpath || "";
|
|
2137
|
+
if (userAgent.includes("yarn")) {
|
|
2138
|
+
return "yarn";
|
|
2139
|
+
}
|
|
2140
|
+
if (userAgent.includes("pnpm")) {
|
|
2141
|
+
return "pnpm";
|
|
2142
|
+
}
|
|
2143
|
+
if (userAgent.includes("npm")) {
|
|
2144
|
+
return "npm";
|
|
2145
|
+
}
|
|
2146
|
+
if (execPath.includes("yarn")) {
|
|
2147
|
+
return "yarn";
|
|
2148
|
+
}
|
|
2149
|
+
if (execPath.includes("pnpm")) {
|
|
2150
|
+
return "pnpm";
|
|
2151
|
+
}
|
|
2152
|
+
if (execPath.includes("npm")) {
|
|
2153
|
+
return "npm";
|
|
2154
|
+
}
|
|
2155
|
+
return "npm";
|
|
2156
|
+
}
|
|
2157
|
+
var logger = createLogger(false);
|
|
2158
|
+
function createLogger(debug = false) {
|
|
2159
|
+
return new PinoLogger({
|
|
2160
|
+
name: "Mastra CLI",
|
|
2161
|
+
level: debug ? "debug" : "info"
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
var exec2 = util.promisify(child_process.exec);
|
|
2165
|
+
async function cloneTemplate(options) {
|
|
2166
|
+
const { template, projectName, targetDir } = options;
|
|
2167
|
+
const projectPath = targetDir ? path.resolve(targetDir, projectName) : path.resolve(projectName);
|
|
2168
|
+
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2169
|
+
try {
|
|
2170
|
+
if (await directoryExists(projectPath)) {
|
|
2171
|
+
spinner4.error(`Directory ${projectName} already exists`);
|
|
2172
|
+
throw new Error(`Directory ${projectName} already exists`);
|
|
2173
|
+
}
|
|
2174
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2175
|
+
await updatePackageJson(projectPath, projectName);
|
|
2176
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
2177
|
+
if (await fileExists(envExamplePath)) {
|
|
2178
|
+
await fs4.copyFile(envExamplePath, path.join(projectPath, ".env"));
|
|
2179
|
+
}
|
|
2180
|
+
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2181
|
+
return projectPath;
|
|
2182
|
+
} catch (error) {
|
|
2183
|
+
spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2184
|
+
throw error;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
async function directoryExists(dirPath) {
|
|
2188
|
+
try {
|
|
2189
|
+
const stat = await fs4.stat(dirPath);
|
|
2190
|
+
return stat.isDirectory();
|
|
2191
|
+
} catch {
|
|
2192
|
+
return false;
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
async function fileExists(filePath) {
|
|
2196
|
+
try {
|
|
2197
|
+
const stat = await fs4.stat(filePath);
|
|
2198
|
+
return stat.isFile();
|
|
2199
|
+
} catch {
|
|
2200
|
+
return false;
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2204
|
+
await fs4.mkdir(targetPath, { recursive: true });
|
|
2205
|
+
try {
|
|
2206
|
+
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2207
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepo, targetPath]);
|
|
2208
|
+
await exec2(degitCommand, {
|
|
2209
|
+
cwd: process.cwd()
|
|
2210
|
+
});
|
|
2211
|
+
} catch {
|
|
2212
|
+
try {
|
|
2213
|
+
const gitCommand = shellQuote2.quote(["git", "clone", repoUrl, targetPath]);
|
|
2214
|
+
await exec2(gitCommand, {
|
|
2215
|
+
cwd: process.cwd()
|
|
2216
|
+
});
|
|
2217
|
+
const gitDir = path.join(targetPath, ".git");
|
|
2218
|
+
if (await directoryExists(gitDir)) {
|
|
2219
|
+
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2220
|
+
}
|
|
2221
|
+
} catch (gitError) {
|
|
2222
|
+
throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
async function updatePackageJson(projectPath, projectName) {
|
|
2227
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
2228
|
+
try {
|
|
2229
|
+
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2230
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2231
|
+
packageJson.name = projectName;
|
|
2232
|
+
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
2233
|
+
} catch (error) {
|
|
2234
|
+
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
async function installDependencies(projectPath, packageManager) {
|
|
2238
|
+
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2239
|
+
try {
|
|
2240
|
+
const pm = packageManager || getPackageManager();
|
|
2241
|
+
const installCommand = shellQuote2.quote([pm, "install"]);
|
|
2242
|
+
await exec2(installCommand, {
|
|
2243
|
+
cwd: projectPath
|
|
2244
|
+
});
|
|
2245
|
+
spinner4.success("Dependencies installed successfully");
|
|
2246
|
+
} catch (error) {
|
|
2247
|
+
spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2248
|
+
throw error;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
|
|
2252
|
+
async function loadTemplates() {
|
|
2253
|
+
try {
|
|
2254
|
+
const response = await fetch(TEMPLATES_API_URL);
|
|
2255
|
+
if (!response.ok) {
|
|
2256
|
+
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
2257
|
+
}
|
|
2258
|
+
const templates = await response.json();
|
|
2259
|
+
return templates;
|
|
2260
|
+
} catch (error) {
|
|
2261
|
+
console.error("Error loading templates:", error);
|
|
2262
|
+
throw new Error("Failed to load templates. Please check your internet connection and try again.");
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
function pluralize(count, singular, plural) {
|
|
2266
|
+
return count === 1 ? singular : plural || `${singular}s`;
|
|
2267
|
+
}
|
|
2268
|
+
async function selectTemplate(templates) {
|
|
2269
|
+
const choices = templates.map((template) => {
|
|
2270
|
+
const parts = [];
|
|
2271
|
+
if (template.agents?.length) {
|
|
2272
|
+
parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
|
|
2273
|
+
}
|
|
2274
|
+
if (template.tools?.length) {
|
|
2275
|
+
parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
|
|
2276
|
+
}
|
|
2277
|
+
if (template.workflows?.length) {
|
|
2278
|
+
parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
|
|
2279
|
+
}
|
|
2280
|
+
if (template.mcp?.length) {
|
|
2281
|
+
parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
|
|
2282
|
+
}
|
|
2283
|
+
if (template.networks?.length) {
|
|
2284
|
+
parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
|
|
2285
|
+
}
|
|
2286
|
+
return {
|
|
2287
|
+
value: template,
|
|
2288
|
+
label: template.title,
|
|
2289
|
+
hint: parts.join(", ") || "Template components"
|
|
2290
|
+
};
|
|
2291
|
+
});
|
|
2292
|
+
const selected = await ve({
|
|
2293
|
+
message: "Select a template:",
|
|
2294
|
+
options: choices
|
|
2295
|
+
});
|
|
2296
|
+
if (pD(selected)) {
|
|
2297
|
+
return null;
|
|
2298
|
+
}
|
|
2299
|
+
return selected;
|
|
2300
|
+
}
|
|
2301
|
+
function findTemplateByName(templates, templateName) {
|
|
2302
|
+
let template = templates.find((t) => t.slug === templateName);
|
|
2303
|
+
if (template) return template;
|
|
2304
|
+
const slugWithPrefix = `template-${templateName}`;
|
|
2305
|
+
template = templates.find((t) => t.slug === slugWithPrefix);
|
|
2306
|
+
if (template) return template;
|
|
2307
|
+
template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
|
|
2308
|
+
if (template) return template;
|
|
2309
|
+
return null;
|
|
2310
|
+
}
|
|
2311
|
+
function getDefaultProjectName(template) {
|
|
2312
|
+
return template.slug.replace(/^template-/, "");
|
|
2313
|
+
}
|
|
2197
2314
|
var s = Y();
|
|
2198
|
-
var exec3 = util.promisify(child_process.exec);
|
|
2199
2315
|
var init = async ({
|
|
2200
|
-
directory,
|
|
2201
|
-
addExample = false,
|
|
2316
|
+
directory = "src/",
|
|
2202
2317
|
components,
|
|
2203
2318
|
llmProvider = "openai",
|
|
2204
2319
|
llmApiKey,
|
|
2205
|
-
|
|
2320
|
+
addExample = false,
|
|
2321
|
+
configureEditorWithDocsMCP,
|
|
2322
|
+
versionTag
|
|
2206
2323
|
}) => {
|
|
2207
2324
|
s.start("Initializing Mastra");
|
|
2325
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2208
2326
|
try {
|
|
2209
2327
|
const result = await createMastraDir(directory);
|
|
2210
2328
|
if (!result.ok) {
|
|
@@ -2217,7 +2335,8 @@ var init = async ({
|
|
|
2217
2335
|
dirPath,
|
|
2218
2336
|
addExample,
|
|
2219
2337
|
addWorkflow: components.includes("workflows"),
|
|
2220
|
-
addAgent: components.includes("agents")
|
|
2338
|
+
addAgent: components.includes("agents"),
|
|
2339
|
+
addScorers: components.includes("scorers")
|
|
2221
2340
|
}),
|
|
2222
2341
|
...components.map((component) => createComponentsDir(dirPath, component)),
|
|
2223
2342
|
writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
|
|
@@ -2231,24 +2350,26 @@ var init = async ({
|
|
|
2231
2350
|
const depService = new DepsService();
|
|
2232
2351
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2233
2352
|
if (needsLibsql) {
|
|
2234
|
-
await depService.installPackages([
|
|
2353
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2235
2354
|
}
|
|
2236
2355
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2237
2356
|
if (needsMemory) {
|
|
2238
|
-
await depService.installPackages([
|
|
2357
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2239
2358
|
}
|
|
2240
2359
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2241
2360
|
if (needsLoggers) {
|
|
2242
|
-
await depService.installPackages([
|
|
2361
|
+
await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
|
|
2362
|
+
}
|
|
2363
|
+
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2364
|
+
if (needsObservability) {
|
|
2365
|
+
await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
|
|
2366
|
+
}
|
|
2367
|
+
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2368
|
+
if (needsEvals) {
|
|
2369
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2243
2370
|
}
|
|
2244
2371
|
}
|
|
2245
2372
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2246
|
-
const aiSdkPackage = getAISDKPackage(llmProvider);
|
|
2247
|
-
const aiSdkPackageVersion = getAISDKPackageVersion(llmProvider);
|
|
2248
|
-
const depsService = new DepsService();
|
|
2249
|
-
const pm = depsService.packageManager;
|
|
2250
|
-
const installCommand = getPackageManagerInstallCommand(pm);
|
|
2251
|
-
await exec3(`${pm} ${installCommand} ${aiSdkPackage}@${aiSdkPackageVersion}`);
|
|
2252
2373
|
if (configureEditorWithDocsMCP) {
|
|
2253
2374
|
await installMastraDocsMCPServer({
|
|
2254
2375
|
editor: configureEditorWithDocsMCP,
|
|
@@ -2275,10 +2396,10 @@ var init = async ({
|
|
|
2275
2396
|
return { success: false };
|
|
2276
2397
|
}
|
|
2277
2398
|
};
|
|
2278
|
-
var
|
|
2399
|
+
var exec3 = util.promisify(child_process.exec);
|
|
2279
2400
|
var execWithTimeout = async (command, timeoutMs) => {
|
|
2280
2401
|
try {
|
|
2281
|
-
const promise =
|
|
2402
|
+
const promise = exec3(command, { killSignal: "SIGTERM" });
|
|
2282
2403
|
if (!timeoutMs) {
|
|
2283
2404
|
return await promise;
|
|
2284
2405
|
}
|
|
@@ -2302,9 +2423,9 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2302
2423
|
}
|
|
2303
2424
|
};
|
|
2304
2425
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2305
|
-
let installCommand =
|
|
2426
|
+
let installCommand = getPackageManagerAddCommand(pm);
|
|
2306
2427
|
if (isDev) {
|
|
2307
|
-
installCommand = `${installCommand}
|
|
2428
|
+
installCommand = `${installCommand} -D`;
|
|
2308
2429
|
}
|
|
2309
2430
|
try {
|
|
2310
2431
|
await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
|
|
@@ -2326,23 +2447,39 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
|
|
|
2326
2447
|
var createMastraProject = async ({
|
|
2327
2448
|
projectName: name,
|
|
2328
2449
|
createVersionTag,
|
|
2329
|
-
timeout
|
|
2450
|
+
timeout,
|
|
2451
|
+
llmProvider,
|
|
2452
|
+
llmApiKey,
|
|
2453
|
+
needsInteractive
|
|
2330
2454
|
}) => {
|
|
2331
2455
|
Ie(color2.inverse(" Mastra Create "));
|
|
2332
2456
|
const projectName = name ?? await he({
|
|
2333
2457
|
message: "What do you want to name your project?",
|
|
2334
2458
|
placeholder: "my-mastra-app",
|
|
2335
|
-
defaultValue: "my-mastra-app"
|
|
2459
|
+
defaultValue: "my-mastra-app",
|
|
2460
|
+
validate: (value) => {
|
|
2461
|
+
if (value.length === 0) return "Project name cannot be empty";
|
|
2462
|
+
if (fs3__default__default.existsSync(value)) {
|
|
2463
|
+
return `A directory named "${value}" already exists. Please choose a different name.`;
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2336
2466
|
});
|
|
2337
2467
|
if (pD(projectName)) {
|
|
2338
2468
|
xe("Operation cancelled");
|
|
2339
2469
|
process.exit(0);
|
|
2340
2470
|
}
|
|
2471
|
+
let result;
|
|
2472
|
+
if (needsInteractive) {
|
|
2473
|
+
result = await interactivePrompt({
|
|
2474
|
+
options: { showBanner: false },
|
|
2475
|
+
skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2341
2478
|
const s2 = Y();
|
|
2342
2479
|
try {
|
|
2343
2480
|
s2.start("Creating project");
|
|
2344
2481
|
try {
|
|
2345
|
-
await
|
|
2482
|
+
await fs4.mkdir(projectName);
|
|
2346
2483
|
} catch (error) {
|
|
2347
2484
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
2348
2485
|
s2.stop(`A directory named "${projectName}" already exists. Please choose a different name.`);
|
|
@@ -2354,12 +2491,12 @@ var createMastraProject = async ({
|
|
|
2354
2491
|
}
|
|
2355
2492
|
process.chdir(projectName);
|
|
2356
2493
|
const pm = getPackageManager();
|
|
2357
|
-
const installCommand =
|
|
2494
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
2358
2495
|
s2.message("Initializing project structure");
|
|
2359
2496
|
try {
|
|
2360
|
-
await
|
|
2361
|
-
await
|
|
2362
|
-
await
|
|
2497
|
+
await exec3(`npm init -y`);
|
|
2498
|
+
await exec3(`npm pkg set type="module"`);
|
|
2499
|
+
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
2363
2500
|
const depsService = new DepsService();
|
|
2364
2501
|
await depsService.addScriptsToPackageJson({
|
|
2365
2502
|
dev: "mastra dev",
|
|
@@ -2374,9 +2511,9 @@ var createMastraProject = async ({
|
|
|
2374
2511
|
s2.stop("Project structure created");
|
|
2375
2512
|
s2.start(`Installing ${pm} dependencies`);
|
|
2376
2513
|
try {
|
|
2377
|
-
await
|
|
2378
|
-
await
|
|
2379
|
-
await
|
|
2514
|
+
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2515
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2516
|
+
await exec3(`echo '{
|
|
2380
2517
|
"compilerOptions": {
|
|
2381
2518
|
"target": "ES2022",
|
|
2382
2519
|
"module": "ES2022",
|
|
@@ -2398,15 +2535,15 @@ var createMastraProject = async ({
|
|
|
2398
2535
|
);
|
|
2399
2536
|
}
|
|
2400
2537
|
s2.stop(`${pm} dependencies installed`);
|
|
2401
|
-
s2.start("Installing
|
|
2538
|
+
s2.start("Installing Mastra CLI");
|
|
2402
2539
|
const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
|
|
2403
2540
|
try {
|
|
2404
2541
|
await installMastraDependency(pm, "mastra", versionTag, true, timeout);
|
|
2405
2542
|
} catch (error) {
|
|
2406
2543
|
throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2407
2544
|
}
|
|
2408
|
-
s2.stop("
|
|
2409
|
-
s2.start("Installing dependencies");
|
|
2545
|
+
s2.stop("Mastra CLI installed");
|
|
2546
|
+
s2.start("Installing Mastra dependencies");
|
|
2410
2547
|
try {
|
|
2411
2548
|
await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
|
|
2412
2549
|
await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
|
|
@@ -2419,21 +2556,21 @@ var createMastraProject = async ({
|
|
|
2419
2556
|
s2.stop("Mastra dependencies installed");
|
|
2420
2557
|
s2.start("Adding .gitignore");
|
|
2421
2558
|
try {
|
|
2422
|
-
await
|
|
2423
|
-
await
|
|
2424
|
-
await
|
|
2425
|
-
await
|
|
2426
|
-
await
|
|
2427
|
-
await
|
|
2428
|
-
await
|
|
2429
|
-
await
|
|
2559
|
+
await exec3(`echo output.txt >> .gitignore`);
|
|
2560
|
+
await exec3(`echo node_modules >> .gitignore`);
|
|
2561
|
+
await exec3(`echo dist >> .gitignore`);
|
|
2562
|
+
await exec3(`echo .mastra >> .gitignore`);
|
|
2563
|
+
await exec3(`echo .env.development >> .gitignore`);
|
|
2564
|
+
await exec3(`echo .env >> .gitignore`);
|
|
2565
|
+
await exec3(`echo *.db >> .gitignore`);
|
|
2566
|
+
await exec3(`echo *.db-* >> .gitignore`);
|
|
2430
2567
|
} catch (error) {
|
|
2431
2568
|
throw new Error(`Failed to create .gitignore: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2432
2569
|
}
|
|
2433
2570
|
s2.stop(".gitignore added");
|
|
2434
2571
|
Se("Project created successfully");
|
|
2435
|
-
console.
|
|
2436
|
-
return { projectName };
|
|
2572
|
+
console.info("");
|
|
2573
|
+
return { projectName, result };
|
|
2437
2574
|
} catch (error) {
|
|
2438
2575
|
s2.stop();
|
|
2439
2576
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
@@ -2443,22 +2580,26 @@ var createMastraProject = async ({
|
|
|
2443
2580
|
};
|
|
2444
2581
|
var create = async (args2) => {
|
|
2445
2582
|
if (args2.template !== void 0) {
|
|
2446
|
-
await createFromTemplate(args2);
|
|
2583
|
+
await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
|
|
2447
2584
|
return;
|
|
2448
2585
|
}
|
|
2449
|
-
const
|
|
2586
|
+
const needsInteractive = args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0;
|
|
2587
|
+
const { projectName, result } = await createMastraProject({
|
|
2450
2588
|
projectName: args2?.projectName,
|
|
2451
2589
|
createVersionTag: args2?.createVersionTag,
|
|
2452
|
-
timeout: args2?.timeout
|
|
2590
|
+
timeout: args2?.timeout,
|
|
2591
|
+
llmProvider: args2?.llmProvider,
|
|
2592
|
+
llmApiKey: args2?.llmApiKey,
|
|
2593
|
+
needsInteractive
|
|
2453
2594
|
});
|
|
2454
2595
|
const directory = args2.directory || "src/";
|
|
2455
|
-
if (
|
|
2456
|
-
const result = await interactivePrompt();
|
|
2596
|
+
if (needsInteractive && result) {
|
|
2457
2597
|
await init({
|
|
2458
2598
|
...result,
|
|
2459
2599
|
llmApiKey: result?.llmApiKey,
|
|
2460
|
-
components: ["agents", "tools", "workflows"],
|
|
2461
|
-
addExample: true
|
|
2600
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2601
|
+
addExample: true,
|
|
2602
|
+
versionTag: args2.createVersionTag
|
|
2462
2603
|
});
|
|
2463
2604
|
postCreate({ projectName });
|
|
2464
2605
|
return;
|
|
@@ -2470,7 +2611,8 @@ var create = async (args2) => {
|
|
|
2470
2611
|
llmProvider,
|
|
2471
2612
|
addExample,
|
|
2472
2613
|
llmApiKey,
|
|
2473
|
-
configureEditorWithDocsMCP: args2.mcpServer
|
|
2614
|
+
configureEditorWithDocsMCP: args2.mcpServer,
|
|
2615
|
+
versionTag: args2.createVersionTag
|
|
2474
2616
|
});
|
|
2475
2617
|
postCreate({ projectName });
|
|
2476
2618
|
};
|
|
@@ -2573,16 +2715,16 @@ async function createFromTemplate(args2) {
|
|
|
2573
2715
|
selectedTemplate = selected;
|
|
2574
2716
|
} else if (args2.template && typeof args2.template === "string") {
|
|
2575
2717
|
if (isGitHubUrl(args2.template)) {
|
|
2576
|
-
const
|
|
2577
|
-
|
|
2718
|
+
const spinner4 = Y();
|
|
2719
|
+
spinner4.start("Validating GitHub repository...");
|
|
2578
2720
|
const validation = await validateGitHubProject(args2.template);
|
|
2579
2721
|
if (!validation.isValid) {
|
|
2580
|
-
|
|
2722
|
+
spinner4.stop("Validation failed");
|
|
2581
2723
|
M.error("This does not appear to be a valid Mastra project:");
|
|
2582
2724
|
validation.errors.forEach((error) => M.error(` - ${error}`));
|
|
2583
2725
|
throw new Error("Invalid Mastra project");
|
|
2584
2726
|
}
|
|
2585
|
-
|
|
2727
|
+
spinner4.stop("Valid Mastra project \u2713");
|
|
2586
2728
|
selectedTemplate = await createFromGitHubUrl(args2.template);
|
|
2587
2729
|
} else {
|
|
2588
2730
|
const templates = await loadTemplates();
|
|
@@ -2613,8 +2755,13 @@ async function createFromTemplate(args2) {
|
|
|
2613
2755
|
projectName = response;
|
|
2614
2756
|
}
|
|
2615
2757
|
try {
|
|
2616
|
-
const analytics = getAnalytics();
|
|
2617
|
-
if (analytics)
|
|
2758
|
+
const analytics = args2.injectedAnalytics || getAnalytics();
|
|
2759
|
+
if (analytics) {
|
|
2760
|
+
analytics.trackEvent("cli_template_used", {
|
|
2761
|
+
template_slug: selectedTemplate.slug,
|
|
2762
|
+
template_title: selectedTemplate.title
|
|
2763
|
+
});
|
|
2764
|
+
}
|
|
2618
2765
|
const projectPath = await cloneTemplate({
|
|
2619
2766
|
template: selectedTemplate,
|
|
2620
2767
|
projectName
|
|
@@ -2623,7 +2770,7 @@ async function createFromTemplate(args2) {
|
|
|
2623
2770
|
Me(`
|
|
2624
2771
|
${color2.green("Mastra template installed!")}
|
|
2625
2772
|
|
|
2626
|
-
Add the necessary environment
|
|
2773
|
+
Add the necessary environment
|
|
2627
2774
|
variables in your ${color2.cyan(".env")} file
|
|
2628
2775
|
`);
|
|
2629
2776
|
postCreate({ projectName });
|
|
@@ -2636,14 +2783,14 @@ async function createFromTemplate(args2) {
|
|
|
2636
2783
|
async function getPackageVersion() {
|
|
2637
2784
|
const __filename = fileURLToPath(import.meta.url);
|
|
2638
2785
|
const __dirname = dirname(__filename);
|
|
2639
|
-
const pkgJsonPath =
|
|
2640
|
-
const content = await fsExtra.readJSON(pkgJsonPath);
|
|
2786
|
+
const pkgJsonPath = path.join(__dirname, "..", "package.json");
|
|
2787
|
+
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2641
2788
|
return content.version;
|
|
2642
2789
|
}
|
|
2643
2790
|
async function getCreateVersionTag() {
|
|
2644
2791
|
try {
|
|
2645
2792
|
const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
|
|
2646
|
-
const json = await fsExtra.readJSON(pkgPath);
|
|
2793
|
+
const json = await fsExtra$1.readJSON(pkgPath);
|
|
2647
2794
|
const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
|
|
2648
2795
|
const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
|
|
2649
2796
|
const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
|
|
@@ -2667,14 +2814,14 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
2667
2814
|
analytics.trackCommand({
|
|
2668
2815
|
command: "version"
|
|
2669
2816
|
});
|
|
2670
|
-
console.
|
|
2817
|
+
console.info(`create-mastra ${version}`);
|
|
2671
2818
|
} catch {
|
|
2672
2819
|
}
|
|
2673
2820
|
});
|
|
2674
2821
|
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2675
2822
|
"-p, --project-name <string>",
|
|
2676
2823
|
"Project name that will be used in package.json and as the project directory name."
|
|
2677
|
-
).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(
|
|
2824
|
+
).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(
|
|
2678
2825
|
"--template [template-name]",
|
|
2679
2826
|
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2680
2827
|
).action(async (projectNameArg, args) => {
|
|
@@ -2682,14 +2829,15 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2682
2829
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
2683
2830
|
if (args.default) {
|
|
2684
2831
|
await create({
|
|
2685
|
-
components: ["agents", "tools", "workflows"],
|
|
2832
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2686
2833
|
llmProvider: "openai",
|
|
2687
2834
|
addExample: true,
|
|
2688
2835
|
createVersionTag,
|
|
2689
2836
|
timeout,
|
|
2690
2837
|
mcpServer: args.mcp,
|
|
2691
2838
|
directory: "src/",
|
|
2692
|
-
template: args.template
|
|
2839
|
+
template: args.template,
|
|
2840
|
+
analytics
|
|
2693
2841
|
});
|
|
2694
2842
|
return;
|
|
2695
2843
|
}
|
|
@@ -2697,13 +2845,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2697
2845
|
components: args.components ? args.components.split(",") : [],
|
|
2698
2846
|
llmProvider: args.llm,
|
|
2699
2847
|
addExample: args.example,
|
|
2700
|
-
llmApiKey: args
|
|
2848
|
+
llmApiKey: args.llmApiKey,
|
|
2701
2849
|
createVersionTag,
|
|
2702
2850
|
timeout,
|
|
2703
2851
|
projectName,
|
|
2704
2852
|
directory: args.dir,
|
|
2705
2853
|
mcpServer: args.mcp,
|
|
2706
|
-
template: args.template
|
|
2854
|
+
template: args.template,
|
|
2855
|
+
analytics
|
|
2707
2856
|
});
|
|
2708
2857
|
});
|
|
2709
2858
|
program.parse(process.argv);
|