create-mastra 0.0.0-tsconfig-compile-20250703214351 → 0.0.0-usechat-duplicate-20251016110554
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 +2035 -0
- package/LICENSE.md +11 -42
- package/README.md +11 -39
- package/dist/index.js +589 -251
- package/dist/index.js.map +1 -1
- package/dist/templates/dev.entry.js +12 -2
- package/package.json +20 -12
- package/dist/starter-files/config.ts +0 -25
- package/dist/starter-files/mastra-pg.docker-compose.yaml +0 -15
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { randomUUID } from 'node:crypto';
|
|
|
4
4
|
import * as fs3__default from 'node:fs';
|
|
5
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,22 @@ import y$1, { stdout, stdin } from 'node:process';
|
|
|
12
12
|
import * as g from 'node:readline';
|
|
13
13
|
import g__default from 'node:readline';
|
|
14
14
|
import { Writable } from 'node:stream';
|
|
15
|
-
import child_process from 'node:child_process';
|
|
16
15
|
import fs4 from 'node:fs/promises';
|
|
17
|
-
import
|
|
18
|
-
import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
19
|
-
import prettier from 'prettier';
|
|
16
|
+
import child_process from 'node:child_process';
|
|
20
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';
|
|
21
21
|
import pino from 'pino';
|
|
22
22
|
import pretty from 'pino-pretty';
|
|
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
|
+
var analyticsInstance = null;
|
|
28
|
+
function getAnalytics() {
|
|
29
|
+
return analyticsInstance;
|
|
30
|
+
}
|
|
27
31
|
var PosthogAnalytics = class {
|
|
28
32
|
sessionId;
|
|
29
33
|
client;
|
|
@@ -35,7 +39,7 @@ var PosthogAnalytics = class {
|
|
|
35
39
|
host = "https://app.posthog.com"
|
|
36
40
|
}) {
|
|
37
41
|
this.version = version;
|
|
38
|
-
const cliConfigPath =
|
|
42
|
+
const cliConfigPath = path.join(__dirname, "mastra-cli.json");
|
|
39
43
|
if (existsSync(cliConfigPath)) {
|
|
40
44
|
try {
|
|
41
45
|
const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
|
|
@@ -63,7 +67,7 @@ var PosthogAnalytics = class {
|
|
|
63
67
|
}
|
|
64
68
|
writeCliConfig({ distinctId, sessionId }) {
|
|
65
69
|
try {
|
|
66
|
-
writeFileSync(
|
|
70
|
+
writeFileSync(path.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
|
|
67
71
|
} catch {
|
|
68
72
|
}
|
|
69
73
|
}
|
|
@@ -113,6 +117,22 @@ var PosthogAnalytics = class {
|
|
|
113
117
|
}
|
|
114
118
|
});
|
|
115
119
|
}
|
|
120
|
+
trackEvent(eventName, properties) {
|
|
121
|
+
try {
|
|
122
|
+
if (!this.client) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
this.client.capture({
|
|
126
|
+
distinctId: this.distinctId,
|
|
127
|
+
event: eventName,
|
|
128
|
+
properties: {
|
|
129
|
+
...this.getSystemProperties(),
|
|
130
|
+
...properties
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
}
|
|
116
136
|
trackCommand(options) {
|
|
117
137
|
try {
|
|
118
138
|
if (!this.client) {
|
|
@@ -402,7 +422,7 @@ ${color2.gray(d)} ${t}
|
|
|
402
422
|
`):process.stdout.write(`${w} ${l}
|
|
403
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};
|
|
404
424
|
|
|
405
|
-
var shellQuote
|
|
425
|
+
var shellQuote = {};
|
|
406
426
|
|
|
407
427
|
var quote;
|
|
408
428
|
var hasRequiredQuote;
|
|
@@ -668,16 +688,16 @@ function requireParse () {
|
|
|
668
688
|
var hasRequiredShellQuote;
|
|
669
689
|
|
|
670
690
|
function requireShellQuote () {
|
|
671
|
-
if (hasRequiredShellQuote) return shellQuote
|
|
691
|
+
if (hasRequiredShellQuote) return shellQuote;
|
|
672
692
|
hasRequiredShellQuote = 1;
|
|
673
693
|
|
|
674
|
-
shellQuote
|
|
675
|
-
shellQuote
|
|
676
|
-
return shellQuote
|
|
694
|
+
shellQuote.quote = requireQuote();
|
|
695
|
+
shellQuote.parse = requireParse();
|
|
696
|
+
return shellQuote;
|
|
677
697
|
}
|
|
678
698
|
|
|
679
699
|
var shellQuoteExports = requireShellQuote();
|
|
680
|
-
var
|
|
700
|
+
var shellQuote2 = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
|
|
681
701
|
|
|
682
702
|
// eslint-disable-next-line no-warning-comments
|
|
683
703
|
// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
|
|
@@ -1153,134 +1173,6 @@ var PinoLogger = class extends MastraLogger {
|
|
|
1153
1173
|
}
|
|
1154
1174
|
};
|
|
1155
1175
|
|
|
1156
|
-
var DepsService = class {
|
|
1157
|
-
packageManager;
|
|
1158
|
-
constructor() {
|
|
1159
|
-
this.packageManager = this.getPackageManager();
|
|
1160
|
-
}
|
|
1161
|
-
findLockFile(dir) {
|
|
1162
|
-
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1163
|
-
for (const file of lockFiles) {
|
|
1164
|
-
if (fs3__default__default.existsSync(path2.join(dir, file))) {
|
|
1165
|
-
return file;
|
|
1166
|
-
}
|
|
1167
|
-
}
|
|
1168
|
-
const parentDir = path2.resolve(dir, "..");
|
|
1169
|
-
if (parentDir !== dir) {
|
|
1170
|
-
return this.findLockFile(parentDir);
|
|
1171
|
-
}
|
|
1172
|
-
return null;
|
|
1173
|
-
}
|
|
1174
|
-
getPackageManager() {
|
|
1175
|
-
const lockFile = this.findLockFile(process.cwd());
|
|
1176
|
-
switch (lockFile) {
|
|
1177
|
-
case "pnpm-lock.yaml":
|
|
1178
|
-
return "pnpm";
|
|
1179
|
-
case "package-lock.json":
|
|
1180
|
-
return "npm";
|
|
1181
|
-
case "yarn.lock":
|
|
1182
|
-
return "yarn";
|
|
1183
|
-
case "bun.lock":
|
|
1184
|
-
return "bun";
|
|
1185
|
-
default:
|
|
1186
|
-
return "npm";
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
async installPackages(packages) {
|
|
1190
|
-
let runCommand = this.packageManager;
|
|
1191
|
-
if (this.packageManager === "npm") {
|
|
1192
|
-
runCommand = `${this.packageManager} i`;
|
|
1193
|
-
} else {
|
|
1194
|
-
runCommand = `${this.packageManager} add`;
|
|
1195
|
-
}
|
|
1196
|
-
const packageList = packages.join(" ");
|
|
1197
|
-
return execa(`${runCommand} ${packageList}`, {
|
|
1198
|
-
all: true,
|
|
1199
|
-
shell: true,
|
|
1200
|
-
stdio: "inherit"
|
|
1201
|
-
});
|
|
1202
|
-
}
|
|
1203
|
-
async checkDependencies(dependencies) {
|
|
1204
|
-
try {
|
|
1205
|
-
const packageJsonPath = path2.join(process.cwd(), "package.json");
|
|
1206
|
-
try {
|
|
1207
|
-
await fs4.access(packageJsonPath);
|
|
1208
|
-
} catch {
|
|
1209
|
-
return "No package.json file found in the current directory";
|
|
1210
|
-
}
|
|
1211
|
-
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
1212
|
-
for (const dependency of dependencies) {
|
|
1213
|
-
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
1214
|
-
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
return "ok";
|
|
1218
|
-
} catch (err) {
|
|
1219
|
-
console.error(err);
|
|
1220
|
-
return "Could not check dependencies";
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
async getProjectName() {
|
|
1224
|
-
try {
|
|
1225
|
-
const packageJsonPath = path2.join(process.cwd(), "package.json");
|
|
1226
|
-
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1227
|
-
const pkg = JSON.parse(packageJson);
|
|
1228
|
-
return pkg.name;
|
|
1229
|
-
} catch (err) {
|
|
1230
|
-
throw err;
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
async getPackageVersion() {
|
|
1234
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
1235
|
-
const __dirname = dirname(__filename);
|
|
1236
|
-
const pkgJsonPath = path2.join(__dirname, "..", "package.json");
|
|
1237
|
-
const content = await fsExtra3.readJSON(pkgJsonPath);
|
|
1238
|
-
return content.version;
|
|
1239
|
-
}
|
|
1240
|
-
async addScriptsToPackageJson(scripts) {
|
|
1241
|
-
const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
|
|
1242
|
-
packageJson.scripts = {
|
|
1243
|
-
...packageJson.scripts,
|
|
1244
|
-
...scripts
|
|
1245
|
-
};
|
|
1246
|
-
await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
|
|
1247
|
-
}
|
|
1248
|
-
};
|
|
1249
|
-
function getPackageManager() {
|
|
1250
|
-
const userAgent = process.env.npm_config_user_agent || "";
|
|
1251
|
-
const execPath = process.env.npm_execpath || "";
|
|
1252
|
-
if (userAgent.includes("yarn")) {
|
|
1253
|
-
return "yarn";
|
|
1254
|
-
}
|
|
1255
|
-
if (userAgent.includes("pnpm")) {
|
|
1256
|
-
return "pnpm";
|
|
1257
|
-
}
|
|
1258
|
-
if (userAgent.includes("npm")) {
|
|
1259
|
-
return "npm";
|
|
1260
|
-
}
|
|
1261
|
-
if (execPath.includes("yarn")) {
|
|
1262
|
-
return "yarn";
|
|
1263
|
-
}
|
|
1264
|
-
if (execPath.includes("pnpm")) {
|
|
1265
|
-
return "pnpm";
|
|
1266
|
-
}
|
|
1267
|
-
if (execPath.includes("npm")) {
|
|
1268
|
-
return "npm";
|
|
1269
|
-
}
|
|
1270
|
-
return "npm";
|
|
1271
|
-
}
|
|
1272
|
-
function getPackageManagerInstallCommand(pm) {
|
|
1273
|
-
switch (pm) {
|
|
1274
|
-
case "npm":
|
|
1275
|
-
return "install";
|
|
1276
|
-
case "yarn":
|
|
1277
|
-
return "add";
|
|
1278
|
-
case "pnpm":
|
|
1279
|
-
return "add";
|
|
1280
|
-
default:
|
|
1281
|
-
return "install";
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
1176
|
var args = ["-y", "@mastra/mcp-docs-server"];
|
|
1285
1177
|
var createMcpConfig = (editor) => {
|
|
1286
1178
|
if (editor === "vscode") {
|
|
@@ -1333,19 +1225,19 @@ async function writeMergedConfig(configPath, editor) {
|
|
|
1333
1225
|
spaces: 2
|
|
1334
1226
|
});
|
|
1335
1227
|
}
|
|
1336
|
-
var windsurfGlobalMCPConfigPath =
|
|
1337
|
-
var cursorGlobalMCPConfigPath =
|
|
1338
|
-
|
|
1339
|
-
var vscodeGlobalMCPConfigPath =
|
|
1228
|
+
var windsurfGlobalMCPConfigPath = path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1229
|
+
var cursorGlobalMCPConfigPath = path.join(os.homedir(), ".cursor", "mcp.json");
|
|
1230
|
+
path.join(process.cwd(), ".vscode", "mcp.json");
|
|
1231
|
+
var vscodeGlobalMCPConfigPath = path.join(
|
|
1340
1232
|
os.homedir(),
|
|
1341
|
-
process.platform === "win32" ?
|
|
1233
|
+
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")
|
|
1342
1234
|
);
|
|
1343
1235
|
async function installMastraDocsMCPServer({ editor, directory }) {
|
|
1344
1236
|
if (editor === `cursor`) {
|
|
1345
|
-
await writeMergedConfig(
|
|
1237
|
+
await writeMergedConfig(path.join(directory, ".cursor", "mcp.json"), "cursor");
|
|
1346
1238
|
}
|
|
1347
1239
|
if (editor === `vscode`) {
|
|
1348
|
-
await writeMergedConfig(
|
|
1240
|
+
await writeMergedConfig(path.join(directory, ".vscode", "mcp.json"), "vscode");
|
|
1349
1241
|
}
|
|
1350
1242
|
if (editor === `cursor-global`) {
|
|
1351
1243
|
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
@@ -1393,6 +1285,102 @@ async function globalMCPIsAlreadyInstalled(editor) {
|
|
|
1393
1285
|
return false;
|
|
1394
1286
|
}
|
|
1395
1287
|
}
|
|
1288
|
+
function getPackageManagerAddCommand(pm) {
|
|
1289
|
+
switch (pm) {
|
|
1290
|
+
case "npm":
|
|
1291
|
+
return "install --audit=false --fund=false --loglevel=error --progress=false --update-notifier=false";
|
|
1292
|
+
case "yarn":
|
|
1293
|
+
return "add";
|
|
1294
|
+
case "pnpm":
|
|
1295
|
+
return "add --loglevel=error";
|
|
1296
|
+
case "bun":
|
|
1297
|
+
return "add";
|
|
1298
|
+
default:
|
|
1299
|
+
return "add";
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
var DepsService = class {
|
|
1303
|
+
packageManager;
|
|
1304
|
+
constructor() {
|
|
1305
|
+
this.packageManager = this.getPackageManager();
|
|
1306
|
+
}
|
|
1307
|
+
findLockFile(dir) {
|
|
1308
|
+
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
1309
|
+
for (const file of lockFiles) {
|
|
1310
|
+
if (fs3__default__default.existsSync(path.join(dir, file))) {
|
|
1311
|
+
return file;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
const parentDir = path.resolve(dir, "..");
|
|
1315
|
+
if (parentDir !== dir) {
|
|
1316
|
+
return this.findLockFile(parentDir);
|
|
1317
|
+
}
|
|
1318
|
+
return null;
|
|
1319
|
+
}
|
|
1320
|
+
getPackageManager() {
|
|
1321
|
+
const lockFile = this.findLockFile(process.cwd());
|
|
1322
|
+
switch (lockFile) {
|
|
1323
|
+
case "pnpm-lock.yaml":
|
|
1324
|
+
return "pnpm";
|
|
1325
|
+
case "package-lock.json":
|
|
1326
|
+
return "npm";
|
|
1327
|
+
case "yarn.lock":
|
|
1328
|
+
return "yarn";
|
|
1329
|
+
case "bun.lock":
|
|
1330
|
+
return "bun";
|
|
1331
|
+
default:
|
|
1332
|
+
return "npm";
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
async installPackages(packages) {
|
|
1336
|
+
const pm = this.packageManager;
|
|
1337
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
1338
|
+
const packageList = packages.join(" ");
|
|
1339
|
+
return execa(`${pm} ${installCommand} ${packageList}`, {
|
|
1340
|
+
all: true,
|
|
1341
|
+
shell: true,
|
|
1342
|
+
stdio: "inherit"
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
async checkDependencies(dependencies) {
|
|
1346
|
+
try {
|
|
1347
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1348
|
+
try {
|
|
1349
|
+
await fs4.access(packageJsonPath);
|
|
1350
|
+
} catch {
|
|
1351
|
+
return "No package.json file found in the current directory";
|
|
1352
|
+
}
|
|
1353
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
1354
|
+
for (const dependency of dependencies) {
|
|
1355
|
+
if (!packageJson.dependencies || !packageJson.dependencies[dependency]) {
|
|
1356
|
+
return `Please install ${dependency} before running this command (${this.packageManager} install ${dependency})`;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
return "ok";
|
|
1360
|
+
} catch (err) {
|
|
1361
|
+
console.error(err);
|
|
1362
|
+
return "Could not check dependencies";
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
async getProjectName() {
|
|
1366
|
+
try {
|
|
1367
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
1368
|
+
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
1369
|
+
const pkg = JSON.parse(packageJson);
|
|
1370
|
+
return pkg.name;
|
|
1371
|
+
} catch (err) {
|
|
1372
|
+
throw err;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
async addScriptsToPackageJson(scripts) {
|
|
1376
|
+
const packageJson = JSON.parse(await fs4.readFile("package.json", "utf-8"));
|
|
1377
|
+
packageJson.scripts = {
|
|
1378
|
+
...packageJson.scripts,
|
|
1379
|
+
...scripts
|
|
1380
|
+
};
|
|
1381
|
+
await fs4.writeFile("package.json", JSON.stringify(packageJson, null, 2));
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1396
1384
|
var EnvService = class {
|
|
1397
1385
|
};
|
|
1398
1386
|
var FileEnvService = class extends EnvService {
|
|
@@ -1431,7 +1419,7 @@ var FileEnvService = class extends EnvService {
|
|
|
1431
1419
|
${key}=${value}`;
|
|
1432
1420
|
}
|
|
1433
1421
|
await this.writeFile({ filePath, data });
|
|
1434
|
-
console.
|
|
1422
|
+
console.info(`${key} set to ${value} in ENV file.`);
|
|
1435
1423
|
return data;
|
|
1436
1424
|
}
|
|
1437
1425
|
async getEnvValue(key) {
|
|
@@ -1464,19 +1452,19 @@ var FileService = class {
|
|
|
1464
1452
|
*/
|
|
1465
1453
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1466
1454
|
const __filename = fileURLToPath(import.meta.url);
|
|
1467
|
-
const __dirname =
|
|
1468
|
-
const filePath =
|
|
1455
|
+
const __dirname = path.dirname(__filename);
|
|
1456
|
+
const filePath = path.resolve(__dirname, "starter-files", inputFile);
|
|
1469
1457
|
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1470
1458
|
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1471
|
-
console.
|
|
1459
|
+
console.info(`${outputFilePath} already exists`);
|
|
1472
1460
|
return false;
|
|
1473
1461
|
}
|
|
1474
|
-
await
|
|
1462
|
+
await fsExtra.outputFile(outputFilePath, fileString);
|
|
1475
1463
|
return true;
|
|
1476
1464
|
}
|
|
1477
1465
|
async setupEnvFile({ dbUrl }) {
|
|
1478
|
-
const envPath =
|
|
1479
|
-
await
|
|
1466
|
+
const envPath = path.join(process.cwd(), ".env.development");
|
|
1467
|
+
await fsExtra.ensureFile(envPath);
|
|
1480
1468
|
const fileEnvService = new FileEnvService(envPath);
|
|
1481
1469
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
1482
1470
|
}
|
|
@@ -1499,50 +1487,24 @@ var FileService = class {
|
|
|
1499
1487
|
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1500
1488
|
}
|
|
1501
1489
|
};
|
|
1502
|
-
new PinoLogger({
|
|
1503
|
-
name: "Mastra CLI",
|
|
1504
|
-
level: "info"
|
|
1505
|
-
});
|
|
1506
1490
|
var exec = util.promisify(child_process.exec);
|
|
1507
|
-
var
|
|
1508
|
-
switch (llmProvider) {
|
|
1509
|
-
case "openai":
|
|
1510
|
-
return "@ai-sdk/openai";
|
|
1511
|
-
case "anthropic":
|
|
1512
|
-
return "@ai-sdk/anthropic";
|
|
1513
|
-
case "groq":
|
|
1514
|
-
return "@ai-sdk/groq";
|
|
1515
|
-
case "google":
|
|
1516
|
-
return "@ai-sdk/google";
|
|
1517
|
-
case "cerebras":
|
|
1518
|
-
return "@ai-sdk/cerebras";
|
|
1519
|
-
default:
|
|
1520
|
-
return "@ai-sdk/openai";
|
|
1521
|
-
}
|
|
1522
|
-
};
|
|
1523
|
-
var getProviderImportAndModelItem = (llmProvider) => {
|
|
1524
|
-
let providerImport = "";
|
|
1525
|
-
let modelItem = "";
|
|
1491
|
+
var getModelIdentifier = (llmProvider) => {
|
|
1526
1492
|
if (llmProvider === "openai") {
|
|
1527
|
-
|
|
1528
|
-
modelItem = `openai('gpt-4o-mini')`;
|
|
1493
|
+
return `'openai/gpt-4o-mini'`;
|
|
1529
1494
|
} else if (llmProvider === "anthropic") {
|
|
1530
|
-
|
|
1531
|
-
modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
|
|
1495
|
+
return `'anthropic/claude-3-5-sonnet-20241022'`;
|
|
1532
1496
|
} else if (llmProvider === "groq") {
|
|
1533
|
-
|
|
1534
|
-
modelItem = `groq('llama-3.3-70b-versatile')`;
|
|
1497
|
+
return `'groq/llama-3.3-70b-versatile'`;
|
|
1535
1498
|
} else if (llmProvider === "google") {
|
|
1536
|
-
|
|
1537
|
-
modelItem = `google('gemini-2.5-pro-exp-03-25')`;
|
|
1499
|
+
return `'google/gemini-2.5-pro'`;
|
|
1538
1500
|
} else if (llmProvider === "cerebras") {
|
|
1539
|
-
|
|
1540
|
-
|
|
1501
|
+
return `'cerebras/llama-3.3-70b'`;
|
|
1502
|
+
} else if (llmProvider === "mistral") {
|
|
1503
|
+
return `'mistral/mistral-medium-2508'`;
|
|
1541
1504
|
}
|
|
1542
|
-
return { providerImport, modelItem };
|
|
1543
1505
|
};
|
|
1544
1506
|
async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
1545
|
-
const
|
|
1507
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1546
1508
|
const instructions = `
|
|
1547
1509
|
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
|
|
1548
1510
|
|
|
@@ -1558,7 +1520,6 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
|
1558
1520
|
${addExampleTool ? "Use the weatherTool to fetch current weather data." : ""}
|
|
1559
1521
|
`;
|
|
1560
1522
|
const content = `
|
|
1561
|
-
${providerImport}
|
|
1562
1523
|
import { Agent } from '@mastra/core/agent';
|
|
1563
1524
|
import { Memory } from '@mastra/memory';
|
|
1564
1525
|
import { LibSQLStore } from '@mastra/libsql';
|
|
@@ -1567,7 +1528,7 @@ ${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
|
1567
1528
|
export const weatherAgent = new Agent({
|
|
1568
1529
|
name: 'Weather Agent',
|
|
1569
1530
|
instructions: \`${instructions}\`,
|
|
1570
|
-
model: ${
|
|
1531
|
+
model: ${modelString},
|
|
1571
1532
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1572
1533
|
memory: new Memory({
|
|
1573
1534
|
storage: new LibSQLStore({
|
|
@@ -1794,7 +1755,7 @@ async function writeCodeSampleForComponents(llmprovider, component, destPath, im
|
|
|
1794
1755
|
}
|
|
1795
1756
|
var createComponentsDir = async (dirPath, component) => {
|
|
1796
1757
|
const componentPath = dirPath + `/${component}`;
|
|
1797
|
-
await
|
|
1758
|
+
await fsExtra.ensureDir(componentPath);
|
|
1798
1759
|
};
|
|
1799
1760
|
var writeIndexFile = async ({
|
|
1800
1761
|
dirPath,
|
|
@@ -1803,7 +1764,7 @@ var writeIndexFile = async ({
|
|
|
1803
1764
|
addWorkflow
|
|
1804
1765
|
}) => {
|
|
1805
1766
|
const indexPath = dirPath + "/index.ts";
|
|
1806
|
-
const destPath =
|
|
1767
|
+
const destPath = path.join(indexPath);
|
|
1807
1768
|
try {
|
|
1808
1769
|
await fs4.writeFile(destPath, "");
|
|
1809
1770
|
const filteredExports = [
|
|
@@ -1833,13 +1794,21 @@ ${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
|
1833
1794
|
export const mastra = new Mastra({
|
|
1834
1795
|
${filteredExports.join("\n ")}
|
|
1835
1796
|
storage: new LibSQLStore({
|
|
1836
|
-
// stores
|
|
1797
|
+
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1837
1798
|
url: ":memory:",
|
|
1838
1799
|
}),
|
|
1839
1800
|
logger: new PinoLogger({
|
|
1840
1801
|
name: 'Mastra',
|
|
1841
1802
|
level: 'info',
|
|
1842
1803
|
}),
|
|
1804
|
+
telemetry: {
|
|
1805
|
+
// Telemetry is deprecated and will be removed in the Nov 4th release
|
|
1806
|
+
enabled: false,
|
|
1807
|
+
},
|
|
1808
|
+
observability: {
|
|
1809
|
+
// Enables DefaultExporter and CloudExporter for AI tracing
|
|
1810
|
+
default: { enabled: true },
|
|
1811
|
+
},
|
|
1843
1812
|
});
|
|
1844
1813
|
`
|
|
1845
1814
|
);
|
|
@@ -1863,27 +1832,28 @@ var getAPIKey = async (provider) => {
|
|
|
1863
1832
|
case "cerebras":
|
|
1864
1833
|
key = "CEREBRAS_API_KEY";
|
|
1865
1834
|
return key;
|
|
1835
|
+
case "mistral":
|
|
1836
|
+
key = "MISTRAL_API_KEY";
|
|
1837
|
+
return key;
|
|
1866
1838
|
default:
|
|
1867
1839
|
return key;
|
|
1868
1840
|
}
|
|
1869
1841
|
};
|
|
1870
|
-
var writeAPIKey = async ({
|
|
1871
|
-
|
|
1872
|
-
apiKey = "your-api-key"
|
|
1873
|
-
}) => {
|
|
1842
|
+
var writeAPIKey = async ({ provider, apiKey }) => {
|
|
1843
|
+
const envFileName = apiKey ? ".env" : ".env.example";
|
|
1874
1844
|
const key = await getAPIKey(provider);
|
|
1875
|
-
const escapedKey =
|
|
1876
|
-
const escapedApiKey =
|
|
1877
|
-
await exec(`echo ${escapedKey}=${escapedApiKey} >>
|
|
1845
|
+
const escapedKey = shellQuote2.quote([key]);
|
|
1846
|
+
const escapedApiKey = shellQuote2.quote([apiKey ? apiKey : "your-api-key"]);
|
|
1847
|
+
await exec(`echo ${escapedKey}=${escapedApiKey} >> ${envFileName}`);
|
|
1878
1848
|
};
|
|
1879
1849
|
var createMastraDir = async (directory) => {
|
|
1880
1850
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1881
|
-
const dirPath =
|
|
1851
|
+
const dirPath = path.join(process.cwd(), ...dir, "mastra");
|
|
1882
1852
|
try {
|
|
1883
1853
|
await fs4.access(dirPath);
|
|
1884
1854
|
return { ok: false };
|
|
1885
1855
|
} catch {
|
|
1886
|
-
await
|
|
1856
|
+
await fsExtra.ensureDir(dirPath);
|
|
1887
1857
|
return { ok: true, dirPath };
|
|
1888
1858
|
}
|
|
1889
1859
|
};
|
|
@@ -1895,8 +1865,19 @@ var writeCodeSample = async (dirPath, component, llmProvider, importComponents)
|
|
|
1895
1865
|
throw err;
|
|
1896
1866
|
}
|
|
1897
1867
|
};
|
|
1898
|
-
var
|
|
1899
|
-
|
|
1868
|
+
var LLM_PROVIDERS = [
|
|
1869
|
+
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
1870
|
+
{ value: "anthropic", label: "Anthropic" },
|
|
1871
|
+
{ value: "groq", label: "Groq" },
|
|
1872
|
+
{ value: "google", label: "Google" },
|
|
1873
|
+
{ value: "cerebras", label: "Cerebras" },
|
|
1874
|
+
{ value: "mistral", label: "Mistral" }
|
|
1875
|
+
];
|
|
1876
|
+
var interactivePrompt = async (args2 = {}) => {
|
|
1877
|
+
const { skip = {}, options: { showBanner = true } = {} } = args2;
|
|
1878
|
+
if (showBanner) {
|
|
1879
|
+
Ie(color2.inverse(" Mastra Init "));
|
|
1880
|
+
}
|
|
1900
1881
|
const mastraProject = await Ce(
|
|
1901
1882
|
{
|
|
1902
1883
|
directory: () => he({
|
|
@@ -1904,19 +1885,15 @@ var interactivePrompt = async () => {
|
|
|
1904
1885
|
placeholder: "src/",
|
|
1905
1886
|
defaultValue: "src/"
|
|
1906
1887
|
}),
|
|
1907
|
-
llmProvider: () => ve({
|
|
1908
|
-
message: "Select default provider:",
|
|
1909
|
-
options:
|
|
1910
|
-
{ value: "openai", label: "OpenAI", hint: "recommended" },
|
|
1911
|
-
{ value: "anthropic", label: "Anthropic" },
|
|
1912
|
-
{ value: "groq", label: "Groq" },
|
|
1913
|
-
{ value: "google", label: "Google" },
|
|
1914
|
-
{ value: "cerebras", label: "Cerebras" }
|
|
1915
|
-
]
|
|
1888
|
+
llmProvider: () => skip?.llmProvider ? void 0 : ve({
|
|
1889
|
+
message: "Select a default provider:",
|
|
1890
|
+
options: LLM_PROVIDERS
|
|
1916
1891
|
}),
|
|
1917
1892
|
llmApiKey: async ({ results: { llmProvider } }) => {
|
|
1893
|
+
if (skip?.llmApiKey) return void 0;
|
|
1894
|
+
const llmName = LLM_PROVIDERS.find((p6) => p6.value === llmProvider)?.label || "provider";
|
|
1918
1895
|
const keyChoice = await ve({
|
|
1919
|
-
message: `Enter your ${
|
|
1896
|
+
message: `Enter your ${llmName} API key?`,
|
|
1920
1897
|
options: [
|
|
1921
1898
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
1922
1899
|
{ value: "enter", label: "Enter API key" }
|
|
@@ -1926,7 +1903,10 @@ var interactivePrompt = async () => {
|
|
|
1926
1903
|
if (keyChoice === "enter") {
|
|
1927
1904
|
return he({
|
|
1928
1905
|
message: "Enter your API key:",
|
|
1929
|
-
placeholder: "sk-..."
|
|
1906
|
+
placeholder: "sk-...",
|
|
1907
|
+
validate: (value) => {
|
|
1908
|
+
if (value.length === 0) return "API key cannot be empty";
|
|
1909
|
+
}
|
|
1930
1910
|
});
|
|
1931
1911
|
}
|
|
1932
1912
|
return void 0;
|
|
@@ -1936,7 +1916,7 @@ var interactivePrompt = async () => {
|
|
|
1936
1916
|
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
1937
1917
|
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
1938
1918
|
const editor = await ve({
|
|
1939
|
-
message: `Make your
|
|
1919
|
+
message: `Make your IDE into a Mastra expert? (Installs Mastra's MCP server)`,
|
|
1940
1920
|
options: [
|
|
1941
1921
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
1942
1922
|
{
|
|
@@ -2016,14 +1996,193 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
2016
1996
|
);
|
|
2017
1997
|
return mastraProject;
|
|
2018
1998
|
};
|
|
2019
|
-
|
|
1999
|
+
function getPackageManager() {
|
|
2000
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
2001
|
+
const execPath = process.env.npm_execpath || "";
|
|
2002
|
+
if (userAgent.includes("yarn")) {
|
|
2003
|
+
return "yarn";
|
|
2004
|
+
}
|
|
2005
|
+
if (userAgent.includes("pnpm")) {
|
|
2006
|
+
return "pnpm";
|
|
2007
|
+
}
|
|
2008
|
+
if (userAgent.includes("npm")) {
|
|
2009
|
+
return "npm";
|
|
2010
|
+
}
|
|
2011
|
+
if (execPath.includes("yarn")) {
|
|
2012
|
+
return "yarn";
|
|
2013
|
+
}
|
|
2014
|
+
if (execPath.includes("pnpm")) {
|
|
2015
|
+
return "pnpm";
|
|
2016
|
+
}
|
|
2017
|
+
if (execPath.includes("npm")) {
|
|
2018
|
+
return "npm";
|
|
2019
|
+
}
|
|
2020
|
+
return "npm";
|
|
2021
|
+
}
|
|
2022
|
+
var logger = createLogger(false);
|
|
2023
|
+
function createLogger(debug = false) {
|
|
2024
|
+
return new PinoLogger({
|
|
2025
|
+
name: "Mastra CLI",
|
|
2026
|
+
level: debug ? "debug" : "info"
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2020
2029
|
var exec2 = util.promisify(child_process.exec);
|
|
2030
|
+
async function cloneTemplate(options) {
|
|
2031
|
+
const { template, projectName, targetDir } = options;
|
|
2032
|
+
const projectPath = targetDir ? path.resolve(targetDir, projectName) : path.resolve(projectName);
|
|
2033
|
+
const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2034
|
+
try {
|
|
2035
|
+
if (await directoryExists(projectPath)) {
|
|
2036
|
+
spinner5.error(`Directory ${projectName} already exists`);
|
|
2037
|
+
throw new Error(`Directory ${projectName} already exists`);
|
|
2038
|
+
}
|
|
2039
|
+
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
2040
|
+
await updatePackageJson(projectPath, projectName);
|
|
2041
|
+
const envExamplePath = path.join(projectPath, ".env.example");
|
|
2042
|
+
if (await fileExists(envExamplePath)) {
|
|
2043
|
+
await fs4.copyFile(envExamplePath, path.join(projectPath, ".env"));
|
|
2044
|
+
}
|
|
2045
|
+
spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2046
|
+
return projectPath;
|
|
2047
|
+
} catch (error) {
|
|
2048
|
+
spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2049
|
+
throw error;
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
async function directoryExists(dirPath) {
|
|
2053
|
+
try {
|
|
2054
|
+
const stat = await fs4.stat(dirPath);
|
|
2055
|
+
return stat.isDirectory();
|
|
2056
|
+
} catch {
|
|
2057
|
+
return false;
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
async function fileExists(filePath) {
|
|
2061
|
+
try {
|
|
2062
|
+
const stat = await fs4.stat(filePath);
|
|
2063
|
+
return stat.isFile();
|
|
2064
|
+
} catch {
|
|
2065
|
+
return false;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
async function cloneRepositoryWithoutGit(repoUrl, targetPath) {
|
|
2069
|
+
await fs4.mkdir(targetPath, { recursive: true });
|
|
2070
|
+
try {
|
|
2071
|
+
const degitRepo = repoUrl.replace("https://github.com/", "");
|
|
2072
|
+
const degitCommand = shellQuote2.quote(["npx", "degit", degitRepo, targetPath]);
|
|
2073
|
+
await exec2(degitCommand, {
|
|
2074
|
+
cwd: process.cwd()
|
|
2075
|
+
});
|
|
2076
|
+
} catch {
|
|
2077
|
+
try {
|
|
2078
|
+
const gitCommand = shellQuote2.quote(["git", "clone", repoUrl, targetPath]);
|
|
2079
|
+
await exec2(gitCommand, {
|
|
2080
|
+
cwd: process.cwd()
|
|
2081
|
+
});
|
|
2082
|
+
const gitDir = path.join(targetPath, ".git");
|
|
2083
|
+
if (await directoryExists(gitDir)) {
|
|
2084
|
+
await fs4.rm(gitDir, { recursive: true, force: true });
|
|
2085
|
+
}
|
|
2086
|
+
} catch (gitError) {
|
|
2087
|
+
throw new Error(`Failed to clone repository: ${gitError instanceof Error ? gitError.message : "Unknown error"}`);
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
async function updatePackageJson(projectPath, projectName) {
|
|
2092
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
2093
|
+
try {
|
|
2094
|
+
const packageJsonContent = await fs4.readFile(packageJsonPath, "utf-8");
|
|
2095
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2096
|
+
packageJson.name = projectName;
|
|
2097
|
+
await fs4.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
2098
|
+
} catch (error) {
|
|
2099
|
+
logger.warn(`Could not update package.json: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
async function installDependencies(projectPath, packageManager) {
|
|
2103
|
+
const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2104
|
+
try {
|
|
2105
|
+
const pm = packageManager || getPackageManager();
|
|
2106
|
+
const installCommand = shellQuote2.quote([pm, "install"]);
|
|
2107
|
+
await exec2(installCommand, {
|
|
2108
|
+
cwd: projectPath
|
|
2109
|
+
});
|
|
2110
|
+
spinner5.success("Dependencies installed successfully");
|
|
2111
|
+
} catch (error) {
|
|
2112
|
+
spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2113
|
+
throw error;
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
var TEMPLATES_API_URL = process.env.MASTRA_TEMPLATES_API_URL || "https://mastra.ai/api/templates.json";
|
|
2117
|
+
async function loadTemplates() {
|
|
2118
|
+
try {
|
|
2119
|
+
const response = await fetch(TEMPLATES_API_URL);
|
|
2120
|
+
if (!response.ok) {
|
|
2121
|
+
throw new Error(`Failed to fetch templates: ${response.statusText}`);
|
|
2122
|
+
}
|
|
2123
|
+
const templates = await response.json();
|
|
2124
|
+
return templates;
|
|
2125
|
+
} catch (error) {
|
|
2126
|
+
console.error("Error loading templates:", error);
|
|
2127
|
+
throw new Error("Failed to load templates. Please check your internet connection and try again.");
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
function pluralize(count, singular, plural) {
|
|
2131
|
+
return count === 1 ? singular : plural || `${singular}s`;
|
|
2132
|
+
}
|
|
2133
|
+
async function selectTemplate(templates) {
|
|
2134
|
+
const choices = templates.map((template) => {
|
|
2135
|
+
const parts = [];
|
|
2136
|
+
if (template.agents?.length) {
|
|
2137
|
+
parts.push(`${template.agents.length} ${pluralize(template.agents.length, "agent")}`);
|
|
2138
|
+
}
|
|
2139
|
+
if (template.tools?.length) {
|
|
2140
|
+
parts.push(`${template.tools.length} ${pluralize(template.tools.length, "tool")}`);
|
|
2141
|
+
}
|
|
2142
|
+
if (template.workflows?.length) {
|
|
2143
|
+
parts.push(`${template.workflows.length} ${pluralize(template.workflows.length, "workflow")}`);
|
|
2144
|
+
}
|
|
2145
|
+
if (template.mcp?.length) {
|
|
2146
|
+
parts.push(`${template.mcp.length} ${pluralize(template.mcp.length, "MCP server")}`);
|
|
2147
|
+
}
|
|
2148
|
+
if (template.networks?.length) {
|
|
2149
|
+
parts.push(`${template.networks.length} ${pluralize(template.networks.length, "agent network")}`);
|
|
2150
|
+
}
|
|
2151
|
+
return {
|
|
2152
|
+
value: template,
|
|
2153
|
+
label: template.title,
|
|
2154
|
+
hint: parts.join(", ") || "Template components"
|
|
2155
|
+
};
|
|
2156
|
+
});
|
|
2157
|
+
const selected = await ve({
|
|
2158
|
+
message: "Select a template:",
|
|
2159
|
+
options: choices
|
|
2160
|
+
});
|
|
2161
|
+
if (pD(selected)) {
|
|
2162
|
+
return null;
|
|
2163
|
+
}
|
|
2164
|
+
return selected;
|
|
2165
|
+
}
|
|
2166
|
+
function findTemplateByName(templates, templateName) {
|
|
2167
|
+
let template = templates.find((t) => t.slug === templateName);
|
|
2168
|
+
if (template) return template;
|
|
2169
|
+
const slugWithPrefix = `template-${templateName}`;
|
|
2170
|
+
template = templates.find((t) => t.slug === slugWithPrefix);
|
|
2171
|
+
if (template) return template;
|
|
2172
|
+
template = templates.find((t) => t.title.toLowerCase() === templateName.toLowerCase());
|
|
2173
|
+
if (template) return template;
|
|
2174
|
+
return null;
|
|
2175
|
+
}
|
|
2176
|
+
function getDefaultProjectName(template) {
|
|
2177
|
+
return template.slug.replace(/^template-/, "");
|
|
2178
|
+
}
|
|
2179
|
+
var s = Y();
|
|
2021
2180
|
var init = async ({
|
|
2022
|
-
directory,
|
|
2023
|
-
addExample = false,
|
|
2181
|
+
directory = "src/",
|
|
2024
2182
|
components,
|
|
2025
2183
|
llmProvider = "openai",
|
|
2026
2184
|
llmApiKey,
|
|
2185
|
+
addExample = false,
|
|
2027
2186
|
configureEditorWithDocsMCP
|
|
2028
2187
|
}) => {
|
|
2029
2188
|
s.start("Initializing Mastra");
|
|
@@ -2065,11 +2224,6 @@ var init = async ({
|
|
|
2065
2224
|
}
|
|
2066
2225
|
}
|
|
2067
2226
|
const key = await getAPIKey(llmProvider || "openai");
|
|
2068
|
-
const aiSdkPackage = getAISDKPackage(llmProvider);
|
|
2069
|
-
const depsService = new DepsService();
|
|
2070
|
-
const pm = depsService.packageManager;
|
|
2071
|
-
const installCommand = getPackageManagerInstallCommand(pm);
|
|
2072
|
-
await exec2(`${pm} ${installCommand} ${aiSdkPackage}`);
|
|
2073
2227
|
if (configureEditorWithDocsMCP) {
|
|
2074
2228
|
await installMastraDocsMCPServer({
|
|
2075
2229
|
editor: configureEditorWithDocsMCP,
|
|
@@ -2123,9 +2277,9 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
2123
2277
|
}
|
|
2124
2278
|
};
|
|
2125
2279
|
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2126
|
-
let installCommand =
|
|
2280
|
+
let installCommand = getPackageManagerAddCommand(pm);
|
|
2127
2281
|
if (isDev) {
|
|
2128
|
-
installCommand = `${installCommand}
|
|
2282
|
+
installCommand = `${installCommand} -D`;
|
|
2129
2283
|
}
|
|
2130
2284
|
try {
|
|
2131
2285
|
await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
|
|
@@ -2147,18 +2301,34 @@ async function installMastraDependency(pm, dependency, versionTag, isDev, timeou
|
|
|
2147
2301
|
var createMastraProject = async ({
|
|
2148
2302
|
projectName: name,
|
|
2149
2303
|
createVersionTag,
|
|
2150
|
-
timeout
|
|
2304
|
+
timeout,
|
|
2305
|
+
llmProvider,
|
|
2306
|
+
llmApiKey,
|
|
2307
|
+
needsInteractive
|
|
2151
2308
|
}) => {
|
|
2152
2309
|
Ie(color2.inverse(" Mastra Create "));
|
|
2153
2310
|
const projectName = name ?? await he({
|
|
2154
2311
|
message: "What do you want to name your project?",
|
|
2155
2312
|
placeholder: "my-mastra-app",
|
|
2156
|
-
defaultValue: "my-mastra-app"
|
|
2313
|
+
defaultValue: "my-mastra-app",
|
|
2314
|
+
validate: (value) => {
|
|
2315
|
+
if (value.length === 0) return "Project name cannot be empty";
|
|
2316
|
+
if (fs3__default__default.existsSync(value)) {
|
|
2317
|
+
return `A directory named "${value}" already exists. Please choose a different name.`;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2157
2320
|
});
|
|
2158
2321
|
if (pD(projectName)) {
|
|
2159
2322
|
xe("Operation cancelled");
|
|
2160
2323
|
process.exit(0);
|
|
2161
2324
|
}
|
|
2325
|
+
let result;
|
|
2326
|
+
if (needsInteractive) {
|
|
2327
|
+
result = await interactivePrompt({
|
|
2328
|
+
options: { showBanner: false },
|
|
2329
|
+
skip: { llmProvider: llmProvider !== void 0, llmApiKey: llmApiKey !== void 0 }
|
|
2330
|
+
});
|
|
2331
|
+
}
|
|
2162
2332
|
const s2 = Y();
|
|
2163
2333
|
try {
|
|
2164
2334
|
s2.start("Creating project");
|
|
@@ -2175,7 +2345,7 @@ var createMastraProject = async ({
|
|
|
2175
2345
|
}
|
|
2176
2346
|
process.chdir(projectName);
|
|
2177
2347
|
const pm = getPackageManager();
|
|
2178
|
-
const installCommand =
|
|
2348
|
+
const installCommand = getPackageManagerAddCommand(pm);
|
|
2179
2349
|
s2.message("Initializing project structure");
|
|
2180
2350
|
try {
|
|
2181
2351
|
await exec3(`npm init -y`);
|
|
@@ -2195,7 +2365,7 @@ var createMastraProject = async ({
|
|
|
2195
2365
|
s2.stop("Project structure created");
|
|
2196
2366
|
s2.start(`Installing ${pm} dependencies`);
|
|
2197
2367
|
try {
|
|
2198
|
-
await exec3(`${pm} ${installCommand} zod`);
|
|
2368
|
+
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2199
2369
|
await exec3(`${pm} ${installCommand} typescript @types/node --save-dev`);
|
|
2200
2370
|
await exec3(`echo '{
|
|
2201
2371
|
"compilerOptions": {
|
|
@@ -2219,15 +2389,15 @@ var createMastraProject = async ({
|
|
|
2219
2389
|
);
|
|
2220
2390
|
}
|
|
2221
2391
|
s2.stop(`${pm} dependencies installed`);
|
|
2222
|
-
s2.start("Installing
|
|
2392
|
+
s2.start("Installing Mastra CLI");
|
|
2223
2393
|
const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
|
|
2224
2394
|
try {
|
|
2225
2395
|
await installMastraDependency(pm, "mastra", versionTag, true, timeout);
|
|
2226
2396
|
} catch (error) {
|
|
2227
2397
|
throw new Error(`Failed to install Mastra CLI: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2228
2398
|
}
|
|
2229
|
-
s2.stop("
|
|
2230
|
-
s2.start("Installing dependencies");
|
|
2399
|
+
s2.stop("Mastra CLI installed");
|
|
2400
|
+
s2.start("Installing Mastra dependencies");
|
|
2231
2401
|
try {
|
|
2232
2402
|
await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
|
|
2233
2403
|
await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
|
|
@@ -2253,8 +2423,8 @@ var createMastraProject = async ({
|
|
|
2253
2423
|
}
|
|
2254
2424
|
s2.stop(".gitignore added");
|
|
2255
2425
|
Se("Project created successfully");
|
|
2256
|
-
console.
|
|
2257
|
-
return { projectName };
|
|
2426
|
+
console.info("");
|
|
2427
|
+
return { projectName, result };
|
|
2258
2428
|
} catch (error) {
|
|
2259
2429
|
s2.stop();
|
|
2260
2430
|
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
@@ -2263,14 +2433,21 @@ var createMastraProject = async ({
|
|
|
2263
2433
|
}
|
|
2264
2434
|
};
|
|
2265
2435
|
var create = async (args2) => {
|
|
2266
|
-
|
|
2436
|
+
if (args2.template !== void 0) {
|
|
2437
|
+
await createFromTemplate({ ...args2, injectedAnalytics: args2.analytics });
|
|
2438
|
+
return;
|
|
2439
|
+
}
|
|
2440
|
+
const needsInteractive = args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0;
|
|
2441
|
+
const { projectName, result } = await createMastraProject({
|
|
2267
2442
|
projectName: args2?.projectName,
|
|
2268
2443
|
createVersionTag: args2?.createVersionTag,
|
|
2269
|
-
timeout: args2?.timeout
|
|
2444
|
+
timeout: args2?.timeout,
|
|
2445
|
+
llmProvider: args2?.llmProvider,
|
|
2446
|
+
llmApiKey: args2?.llmApiKey,
|
|
2447
|
+
needsInteractive
|
|
2270
2448
|
});
|
|
2271
2449
|
const directory = args2.directory || "src/";
|
|
2272
|
-
if (
|
|
2273
|
-
const result = await interactivePrompt();
|
|
2450
|
+
if (needsInteractive && result) {
|
|
2274
2451
|
await init({
|
|
2275
2452
|
...result,
|
|
2276
2453
|
llmApiKey: result?.llmApiKey,
|
|
@@ -2300,18 +2477,172 @@ var postCreate = ({ projectName }) => {
|
|
|
2300
2477
|
${color2.cyan(`${packageManager} run dev`)}
|
|
2301
2478
|
`);
|
|
2302
2479
|
};
|
|
2480
|
+
function isGitHubUrl(url) {
|
|
2481
|
+
try {
|
|
2482
|
+
const parsedUrl = new URL(url);
|
|
2483
|
+
return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
|
|
2484
|
+
} catch {
|
|
2485
|
+
return false;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
async function validateGitHubProject(githubUrl) {
|
|
2489
|
+
const errors = [];
|
|
2490
|
+
try {
|
|
2491
|
+
const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
|
|
2492
|
+
const owner = urlParts[0];
|
|
2493
|
+
const repo = urlParts[1]?.replace(".git", "");
|
|
2494
|
+
if (!owner || !repo) {
|
|
2495
|
+
throw new Error("Invalid GitHub URL format");
|
|
2496
|
+
}
|
|
2497
|
+
const branches = ["main", "master"];
|
|
2498
|
+
let packageJsonContent = null;
|
|
2499
|
+
let indexContent = null;
|
|
2500
|
+
for (const branch of branches) {
|
|
2501
|
+
try {
|
|
2502
|
+
const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
|
|
2503
|
+
const packageJsonResponse = await fetch(packageJsonUrl);
|
|
2504
|
+
if (packageJsonResponse.ok) {
|
|
2505
|
+
packageJsonContent = await packageJsonResponse.text();
|
|
2506
|
+
const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
|
|
2507
|
+
const indexResponse = await fetch(indexUrl);
|
|
2508
|
+
if (indexResponse.ok) {
|
|
2509
|
+
indexContent = await indexResponse.text();
|
|
2510
|
+
}
|
|
2511
|
+
break;
|
|
2512
|
+
}
|
|
2513
|
+
} catch {
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
if (!packageJsonContent) {
|
|
2517
|
+
errors.push("Could not fetch package.json from repository");
|
|
2518
|
+
return { isValid: false, errors };
|
|
2519
|
+
}
|
|
2520
|
+
try {
|
|
2521
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
2522
|
+
const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
|
|
2523
|
+
if (!hasMastraCore) {
|
|
2524
|
+
errors.push("Missing @mastra/core dependency in package.json");
|
|
2525
|
+
}
|
|
2526
|
+
} catch {
|
|
2527
|
+
errors.push("Invalid package.json format");
|
|
2528
|
+
}
|
|
2529
|
+
if (!indexContent) {
|
|
2530
|
+
errors.push("Missing src/mastra/index.ts file");
|
|
2531
|
+
} else {
|
|
2532
|
+
const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
|
|
2533
|
+
if (!hasMastraExport) {
|
|
2534
|
+
errors.push("src/mastra/index.ts does not export a Mastra instance");
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
return { isValid: errors.length === 0, errors };
|
|
2538
|
+
} catch (error) {
|
|
2539
|
+
errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2540
|
+
return { isValid: false, errors };
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
async function createFromGitHubUrl(url) {
|
|
2544
|
+
const urlParts = new URL(url).pathname.split("/").filter(Boolean);
|
|
2545
|
+
const owner = urlParts[0] || "unknown";
|
|
2546
|
+
const repo = urlParts[1] || "unknown";
|
|
2547
|
+
return {
|
|
2548
|
+
githubUrl: url,
|
|
2549
|
+
title: `${owner}/${repo}`,
|
|
2550
|
+
slug: repo,
|
|
2551
|
+
agents: [],
|
|
2552
|
+
mcp: [],
|
|
2553
|
+
tools: [],
|
|
2554
|
+
networks: [],
|
|
2555
|
+
workflows: []
|
|
2556
|
+
};
|
|
2557
|
+
}
|
|
2558
|
+
async function createFromTemplate(args2) {
|
|
2559
|
+
let selectedTemplate;
|
|
2560
|
+
if (args2.template === true) {
|
|
2561
|
+
const templates = await loadTemplates();
|
|
2562
|
+
const selected = await selectTemplate(templates);
|
|
2563
|
+
if (!selected) {
|
|
2564
|
+
M.info("No template selected. Exiting.");
|
|
2565
|
+
return;
|
|
2566
|
+
}
|
|
2567
|
+
selectedTemplate = selected;
|
|
2568
|
+
} else if (args2.template && typeof args2.template === "string") {
|
|
2569
|
+
if (isGitHubUrl(args2.template)) {
|
|
2570
|
+
const spinner5 = Y();
|
|
2571
|
+
spinner5.start("Validating GitHub repository...");
|
|
2572
|
+
const validation = await validateGitHubProject(args2.template);
|
|
2573
|
+
if (!validation.isValid) {
|
|
2574
|
+
spinner5.stop("Validation failed");
|
|
2575
|
+
M.error("This does not appear to be a valid Mastra project:");
|
|
2576
|
+
validation.errors.forEach((error) => M.error(` - ${error}`));
|
|
2577
|
+
throw new Error("Invalid Mastra project");
|
|
2578
|
+
}
|
|
2579
|
+
spinner5.stop("Valid Mastra project \u2713");
|
|
2580
|
+
selectedTemplate = await createFromGitHubUrl(args2.template);
|
|
2581
|
+
} else {
|
|
2582
|
+
const templates = await loadTemplates();
|
|
2583
|
+
const found = findTemplateByName(templates, args2.template);
|
|
2584
|
+
if (!found) {
|
|
2585
|
+
M.error(`Template "${args2.template}" not found. Available templates:`);
|
|
2586
|
+
templates.forEach((t) => M.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
|
|
2587
|
+
throw new Error(`Template "${args2.template}" not found`);
|
|
2588
|
+
}
|
|
2589
|
+
selectedTemplate = found;
|
|
2590
|
+
}
|
|
2591
|
+
}
|
|
2592
|
+
if (!selectedTemplate) {
|
|
2593
|
+
throw new Error("No template selected");
|
|
2594
|
+
}
|
|
2595
|
+
let projectName = args2.projectName;
|
|
2596
|
+
if (!projectName) {
|
|
2597
|
+
const defaultName = getDefaultProjectName(selectedTemplate);
|
|
2598
|
+
const response = await he({
|
|
2599
|
+
message: "What is your project name?",
|
|
2600
|
+
defaultValue: defaultName,
|
|
2601
|
+
placeholder: defaultName
|
|
2602
|
+
});
|
|
2603
|
+
if (pD(response)) {
|
|
2604
|
+
M.info("Project creation cancelled.");
|
|
2605
|
+
return;
|
|
2606
|
+
}
|
|
2607
|
+
projectName = response;
|
|
2608
|
+
}
|
|
2609
|
+
try {
|
|
2610
|
+
const analytics = args2.injectedAnalytics || getAnalytics();
|
|
2611
|
+
if (analytics) {
|
|
2612
|
+
analytics.trackEvent("cli_template_used", {
|
|
2613
|
+
template_slug: selectedTemplate.slug,
|
|
2614
|
+
template_title: selectedTemplate.title
|
|
2615
|
+
});
|
|
2616
|
+
}
|
|
2617
|
+
const projectPath = await cloneTemplate({
|
|
2618
|
+
template: selectedTemplate,
|
|
2619
|
+
projectName
|
|
2620
|
+
});
|
|
2621
|
+
await installDependencies(projectPath);
|
|
2622
|
+
Me(`
|
|
2623
|
+
${color2.green("Mastra template installed!")}
|
|
2624
|
+
|
|
2625
|
+
Add the necessary environment
|
|
2626
|
+
variables in your ${color2.cyan(".env")} file
|
|
2627
|
+
`);
|
|
2628
|
+
postCreate({ projectName });
|
|
2629
|
+
} catch (error) {
|
|
2630
|
+
M.error(`Failed to create project from template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2631
|
+
throw error;
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2303
2634
|
|
|
2304
2635
|
async function getPackageVersion() {
|
|
2305
2636
|
const __filename = fileURLToPath(import.meta.url);
|
|
2306
2637
|
const __dirname = dirname(__filename);
|
|
2307
|
-
const pkgJsonPath =
|
|
2308
|
-
const content = await fsExtra.readJSON(pkgJsonPath);
|
|
2638
|
+
const pkgJsonPath = path.join(__dirname, "..", "package.json");
|
|
2639
|
+
const content = await fsExtra$1.readJSON(pkgJsonPath);
|
|
2309
2640
|
return content.version;
|
|
2310
2641
|
}
|
|
2311
2642
|
async function getCreateVersionTag() {
|
|
2312
2643
|
try {
|
|
2313
2644
|
const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
|
|
2314
|
-
const json = await fsExtra.readJSON(pkgPath);
|
|
2645
|
+
const json = await fsExtra$1.readJSON(pkgPath);
|
|
2315
2646
|
const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
|
|
2316
2647
|
const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
|
|
2317
2648
|
const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
|
|
@@ -2335,14 +2666,17 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
2335
2666
|
analytics.trackCommand({
|
|
2336
2667
|
command: "version"
|
|
2337
2668
|
});
|
|
2338
|
-
console.
|
|
2669
|
+
console.info(`create-mastra ${version}`);
|
|
2339
2670
|
} catch {
|
|
2340
2671
|
}
|
|
2341
2672
|
});
|
|
2342
2673
|
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2343
2674
|
"-p, --project-name <string>",
|
|
2344
2675
|
"Project name that will be used in package.json and as the project directory name."
|
|
2345
|
-
).option("--default", "Quick start with defaults(src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").
|
|
2676
|
+
).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(
|
|
2677
|
+
"--template [template-name]",
|
|
2678
|
+
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2679
|
+
).action(async (projectNameArg, args) => {
|
|
2346
2680
|
const projectName = projectNameArg || args.projectName;
|
|
2347
2681
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
2348
2682
|
if (args.default) {
|
|
@@ -2353,7 +2687,9 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2353
2687
|
createVersionTag,
|
|
2354
2688
|
timeout,
|
|
2355
2689
|
mcpServer: args.mcp,
|
|
2356
|
-
directory: "src/"
|
|
2690
|
+
directory: "src/",
|
|
2691
|
+
template: args.template,
|
|
2692
|
+
analytics
|
|
2357
2693
|
});
|
|
2358
2694
|
return;
|
|
2359
2695
|
}
|
|
@@ -2361,12 +2697,14 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2361
2697
|
components: args.components ? args.components.split(",") : [],
|
|
2362
2698
|
llmProvider: args.llm,
|
|
2363
2699
|
addExample: args.example,
|
|
2364
|
-
llmApiKey: args
|
|
2700
|
+
llmApiKey: args.llmApiKey,
|
|
2365
2701
|
createVersionTag,
|
|
2366
2702
|
timeout,
|
|
2367
2703
|
projectName,
|
|
2368
2704
|
directory: args.dir,
|
|
2369
|
-
mcpServer: args.mcp
|
|
2705
|
+
mcpServer: args.mcp,
|
|
2706
|
+
template: args.template,
|
|
2707
|
+
analytics
|
|
2370
2708
|
});
|
|
2371
2709
|
});
|
|
2372
2710
|
program.parse(process.argv);
|