mastra 0.10.14-alpha.1 → 0.10.14-alpha.2

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.
@@ -62,10 +62,10 @@ var exec = util.promisify(child_process.exec);
62
62
  async function cloneTemplate(options) {
63
63
  const { template, projectName, targetDir } = options;
64
64
  const projectPath = targetDir ? path3.resolve(targetDir, projectName) : path3.resolve(projectName);
65
- const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
65
+ const spinner5 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
66
66
  try {
67
67
  if (await directoryExists(projectPath)) {
68
- spinner4.error(`Directory ${projectName} already exists`);
68
+ spinner5.error(`Directory ${projectName} already exists`);
69
69
  throw new Error(`Directory ${projectName} already exists`);
70
70
  }
71
71
  await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
@@ -74,10 +74,10 @@ async function cloneTemplate(options) {
74
74
  if (await fileExists(envExamplePath)) {
75
75
  await fs.copyFile(envExamplePath, path3.join(projectPath, ".env"));
76
76
  }
77
- spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
77
+ spinner5.success(`Template "${template.title}" cloned successfully to ${projectName}`);
78
78
  return projectPath;
79
79
  } catch (error) {
80
- spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
80
+ spinner5.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
81
81
  throw error;
82
82
  }
83
83
  }
@@ -132,16 +132,16 @@ async function updatePackageJson(projectPath, projectName) {
132
132
  }
133
133
  }
134
134
  async function installDependencies(projectPath, packageManager) {
135
- const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
135
+ const spinner5 = yoctoSpinner({ text: "Installing dependencies..." }).start();
136
136
  try {
137
137
  const pm = packageManager || getPackageManager();
138
138
  const installCommand = shellQuote.quote([pm, "install"]);
139
139
  await exec(installCommand, {
140
140
  cwd: projectPath
141
141
  });
142
- spinner4.success("Dependencies installed successfully");
142
+ spinner5.success("Dependencies installed successfully");
143
143
  } catch (error) {
144
- spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
144
+ spinner5.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
145
145
  throw error;
146
146
  }
147
147
  }
@@ -1397,21 +1397,116 @@ var postCreate = ({ projectName }) => {
1397
1397
  ${color2.cyan(`${packageManager} run dev`)}
1398
1398
  `);
1399
1399
  };
1400
+ function isGitHubUrl(url) {
1401
+ try {
1402
+ const parsedUrl = new URL(url);
1403
+ return parsedUrl.hostname === "github.com" && parsedUrl.pathname.split("/").length >= 3;
1404
+ } catch {
1405
+ return false;
1406
+ }
1407
+ }
1408
+ async function validateGitHubProject(githubUrl) {
1409
+ const errors = [];
1410
+ try {
1411
+ const urlParts = new URL(githubUrl).pathname.split("/").filter(Boolean);
1412
+ const owner = urlParts[0];
1413
+ const repo = urlParts[1]?.replace(".git", "");
1414
+ if (!owner || !repo) {
1415
+ throw new Error("Invalid GitHub URL format");
1416
+ }
1417
+ const branches = ["main", "master"];
1418
+ let packageJsonContent = null;
1419
+ let indexContent = null;
1420
+ for (const branch of branches) {
1421
+ try {
1422
+ const packageJsonUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/package.json`;
1423
+ const packageJsonResponse = await fetch(packageJsonUrl);
1424
+ if (packageJsonResponse.ok) {
1425
+ packageJsonContent = await packageJsonResponse.text();
1426
+ const indexUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/src/mastra/index.ts`;
1427
+ const indexResponse = await fetch(indexUrl);
1428
+ if (indexResponse.ok) {
1429
+ indexContent = await indexResponse.text();
1430
+ }
1431
+ break;
1432
+ }
1433
+ } catch {
1434
+ }
1435
+ }
1436
+ if (!packageJsonContent) {
1437
+ errors.push("Could not fetch package.json from repository");
1438
+ return { isValid: false, errors };
1439
+ }
1440
+ try {
1441
+ const packageJson = JSON.parse(packageJsonContent);
1442
+ const hasMastraCore = packageJson.dependencies?.["@mastra/core"] || packageJson.devDependencies?.["@mastra/core"] || packageJson.peerDependencies?.["@mastra/core"];
1443
+ if (!hasMastraCore) {
1444
+ errors.push("Missing @mastra/core dependency in package.json");
1445
+ }
1446
+ } catch {
1447
+ errors.push("Invalid package.json format");
1448
+ }
1449
+ if (!indexContent) {
1450
+ errors.push("Missing src/mastra/index.ts file");
1451
+ } else {
1452
+ const hasMastraExport = indexContent.includes("export") && (indexContent.includes("new Mastra") || indexContent.includes("Mastra("));
1453
+ if (!hasMastraExport) {
1454
+ errors.push("src/mastra/index.ts does not export a Mastra instance");
1455
+ }
1456
+ }
1457
+ return { isValid: errors.length === 0, errors };
1458
+ } catch (error) {
1459
+ errors.push(`Failed to validate GitHub repository: ${error instanceof Error ? error.message : "Unknown error"}`);
1460
+ return { isValid: false, errors };
1461
+ }
1462
+ }
1463
+ async function createFromGitHubUrl(url) {
1464
+ const urlParts = new URL(url).pathname.split("/").filter(Boolean);
1465
+ const owner = urlParts[0] || "unknown";
1466
+ const repo = urlParts[1] || "unknown";
1467
+ return {
1468
+ githubUrl: url,
1469
+ title: `${owner}/${repo}`,
1470
+ slug: repo,
1471
+ agents: [],
1472
+ mcp: [],
1473
+ tools: [],
1474
+ networks: [],
1475
+ workflows: []
1476
+ };
1477
+ }
1400
1478
  async function createFromTemplate(args2) {
1401
- const templates = await loadTemplates();
1402
1479
  let selectedTemplate;
1403
1480
  if (args2.template === true) {
1404
- selectedTemplate = await selectTemplate(templates);
1405
- if (!selectedTemplate) {
1481
+ const templates = await loadTemplates();
1482
+ const selected = await selectTemplate(templates);
1483
+ if (!selected) {
1406
1484
  p2.log.info("No template selected. Exiting.");
1407
1485
  return;
1408
1486
  }
1409
- } else if (args2.template) {
1410
- selectedTemplate = findTemplateByName(templates, args2.template);
1411
- if (!selectedTemplate) {
1412
- p2.log.error(`Template "${args2.template}" not found. Available templates:`);
1413
- templates.forEach((t) => p2.log.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
1414
- throw new Error(`Template "${args2.template}" not found`);
1487
+ selectedTemplate = selected;
1488
+ } else if (args2.template && typeof args2.template === "string") {
1489
+ if (isGitHubUrl(args2.template)) {
1490
+ const spinner5 = p2.spinner();
1491
+ spinner5.start("Validating GitHub repository...");
1492
+ const validation = await validateGitHubProject(args2.template);
1493
+ if (!validation.isValid) {
1494
+ spinner5.stop("Validation failed");
1495
+ p2.log.error("This does not appear to be a valid Mastra project:");
1496
+ validation.errors.forEach((error) => p2.log.error(` - ${error}`));
1497
+ throw new Error("Invalid Mastra project");
1498
+ }
1499
+ spinner5.stop("Valid Mastra project \u2713");
1500
+ selectedTemplate = await createFromGitHubUrl(args2.template);
1501
+ } else {
1502
+ const templates = await loadTemplates();
1503
+ const found = findTemplateByName(templates, args2.template);
1504
+ if (!found) {
1505
+ p2.log.error(`Template "${args2.template}" not found. Available templates:`);
1506
+ templates.forEach((t) => p2.log.info(` - ${t.title} (use: ${t.slug.replace("template-", "")})`));
1507
+ throw new Error(`Template "${args2.template}" not found`);
1508
+ }
1509
+ selectedTemplate = found;
1415
1510
  }
1416
1511
  }
1417
1512
  if (!selectedTemplate) {
@@ -1,2 +1,2 @@
1
- export { create } from '../../chunk-C56DSM55.js';
1
+ export { create } from '../../chunk-5PY7XHOW.js';
2
2
  import '../../chunk-US7IPLZ2.js';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #! /usr/bin/env node
2
- import { DepsService, create, checkPkgJson, checkAndInstallCoreDeps, interactivePrompt, init, logger, FileService } from './chunk-C56DSM55.js';
3
- export { create } from './chunk-C56DSM55.js';
2
+ import { DepsService, create, checkPkgJson, checkAndInstallCoreDeps, interactivePrompt, init, logger, FileService } from './chunk-5PY7XHOW.js';
3
+ export { create } from './chunk-5PY7XHOW.js';
4
4
  import { PosthogAnalytics, setAnalytics } from './chunk-US7IPLZ2.js';
5
5
  export { PosthogAnalytics } from './chunk-US7IPLZ2.js';
6
6
  import { Command } from 'commander';
@@ -53,9 +53,10 @@ var BuildBundler = class extends Bundler {
53
53
  import { TABLE_EVALS } from '@mastra/core/storage';
54
54
  import { checkEvalStorageFields } from '@mastra/core/utils';
55
55
  import { mastra } from '#mastra';
56
- import { createNodeServer } from '#server';
56
+ import { createNodeServer, getToolExports } from '#server';
57
+ import { tools } from '#tools';
57
58
  // @ts-ignore
58
- await createNodeServer(mastra);
59
+ await createNodeServer(mastra, { tools: getToolExports(tools) });
59
60
 
60
61
  registerHook(AvailableHooks.ON_GENERATION, ({ input, output, metric, runId, agentName, instructions }) => {
61
62
  evaluate({
@@ -211,7 +212,12 @@ var DevBundler = class extends Bundler {
211
212
  });
212
213
  const toolsInputOptions = await this.getToolsInputOptions(toolsPaths);
213
214
  const outputDir = join(outputDirectory, this.outputDir);
214
- await writeTelemetryConfig(entryFile, outputDir);
215
+ await writeTelemetryConfig({
216
+ entryFile,
217
+ outputDir,
218
+ options: {},
219
+ logger: this.logger
220
+ });
215
221
  const mastraFolder = dirname(entryFile);
216
222
  const fileService = new FileService$1();
217
223
  const customInstrumentation = fileService.getFirstExistingFileOrUndefined([
@@ -435,6 +441,9 @@ async function dev({
435
441
  await bundler.prepare(dotMastraPath);
436
442
  const watcher = await bundler.watch(entryFile, dotMastraPath, discoveredTools);
437
443
  const loadedEnv = await bundler.loadEnvVars();
444
+ for (const [key, value] of loadedEnv.entries()) {
445
+ process2.env[key] = value;
446
+ }
438
447
  const serverOptions = await getServerOptions(entryFile, join(dotMastraPath, "output"));
439
448
  let portToUse = port ?? serverOptions?.port ?? process2.env.PORT;
440
449
  if (!portToUse || isNaN(Number(portToUse))) {
@@ -702,7 +711,7 @@ program.command("create [project-name]").description("Create a new Mastra projec
702
711
  "Project name that will be used in package.json and as the project directory name."
703
712
  ).option("-m, --mcp <editor>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
704
713
  "--template [template-name]",
705
- "Create project from a template (use template name or leave blank to select from list)"
714
+ "Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
706
715
  ).action(async (projectNameArg, args) => {
707
716
  const projectName = projectNameArg || args.projectName;
708
717
  await analytics.trackCommandExecution({
@@ -5,9 +5,14 @@ import { AvailableHooks, registerHook } from '@mastra/core/hooks';
5
5
  import { TABLE_EVALS } from '@mastra/core/storage';
6
6
  import { checkEvalStorageFields } from '@mastra/core/utils';
7
7
  import { mastra } from '#mastra';
8
- import { createNodeServer } from '#server';
8
+ import { createNodeServer, getToolExports } from '#server';
9
+ import { tools } from '#tools';
9
10
  // @ts-ignore
10
- await createNodeServer(mastra, { playground: true, isDev: true });
11
+ await createNodeServer(mastra, {
12
+ playground: true,
13
+ isDev: true,
14
+ tools: getToolExports(tools),
15
+ });
11
16
 
12
17
  registerHook(AvailableHooks.ON_GENERATION, ({ input, output, metric, runId, agentName, instructions }) => {
13
18
  evaluate({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mastra",
3
- "version": "0.10.14-alpha.1",
3
+ "version": "0.10.14-alpha.2",
4
4
  "license": "Apache-2.0",
5
5
  "description": "cli for mastra",
6
6
  "type": "module",
@@ -75,9 +75,9 @@
75
75
  "yocto-spinner": "^0.2.3",
76
76
  "zod": "^3.25.67",
77
77
  "zod-to-json-schema": "^3.24.5",
78
- "@mastra/deployer": "^0.11.0-alpha.1",
79
- "@mastra/mcp": "^0.10.6",
80
- "@mastra/loggers": "^0.10.3"
78
+ "@mastra/deployer": "^0.11.0-alpha.2",
79
+ "@mastra/loggers": "^0.10.3",
80
+ "@mastra/mcp": "^0.10.6"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@microsoft/api-extractor": "^7.52.8",
@@ -96,9 +96,9 @@
96
96
  "typescript": "^5.8.3",
97
97
  "vitest": "^3.2.4",
98
98
  "@internal/lint": "0.0.20",
99
- "@mastra/core": "0.11.0-alpha.1",
100
- "@mastra/client-js": "0.10.15-alpha.1",
101
- "@mastra/playground-ui": "5.1.14-alpha.1"
99
+ "@mastra/client-js": "0.10.15-alpha.2",
100
+ "@mastra/core": "0.11.0-alpha.2",
101
+ "@mastra/playground-ui": "5.1.14-alpha.2"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "@mastra/core": "^0.10.2-alpha.0"