create-mastra 0.0.0-commonjs-20250414101718 → 0.0.0-course-20250527170450
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/README.md +0 -1
- package/dist/index.js +622 -232
- package/dist/index.js.map +1 -1
- package/dist/templates/dev.entry.js +7 -5
- package/package.json +5 -5
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 path2, { dirname } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { PostHog } from 'posthog-node';
|
|
10
10
|
import h, { stdin, stdout } from 'node:process';
|
|
@@ -17,13 +17,12 @@ import fs4 from 'node:fs/promises';
|
|
|
17
17
|
import { execa } from 'execa';
|
|
18
18
|
import fsExtra3, { readJSON, ensureFile, writeJSON } from 'fs-extra/esm';
|
|
19
19
|
import prettier from 'prettier';
|
|
20
|
-
import { Transform } from 'node:stream';
|
|
21
20
|
import pino from 'pino';
|
|
22
21
|
import pretty from 'pino-pretty';
|
|
23
22
|
import fsExtra from 'fs-extra';
|
|
24
23
|
|
|
25
24
|
var __filename = fileURLToPath(import.meta.url);
|
|
26
|
-
var __dirname =
|
|
25
|
+
var __dirname = path2.dirname(__filename);
|
|
27
26
|
var PosthogAnalytics = class {
|
|
28
27
|
sessionId;
|
|
29
28
|
client;
|
|
@@ -35,7 +34,7 @@ var PosthogAnalytics = class {
|
|
|
35
34
|
host = "https://app.posthog.com"
|
|
36
35
|
}) {
|
|
37
36
|
this.version = version;
|
|
38
|
-
const cliConfigPath =
|
|
37
|
+
const cliConfigPath = path2.join(__dirname, "mastra-cli.json");
|
|
39
38
|
if (existsSync(cliConfigPath)) {
|
|
40
39
|
try {
|
|
41
40
|
const { distinctId, sessionId } = JSON.parse(readFileSync(cliConfigPath, "utf-8"));
|
|
@@ -63,7 +62,7 @@ var PosthogAnalytics = class {
|
|
|
63
62
|
}
|
|
64
63
|
writeCliConfig({ distinctId, sessionId }) {
|
|
65
64
|
try {
|
|
66
|
-
writeFileSync(
|
|
65
|
+
writeFileSync(path2.join(__dirname, "mastra-cli.json"), JSON.stringify({ distinctId, sessionId }));
|
|
67
66
|
} catch {
|
|
68
67
|
}
|
|
69
68
|
}
|
|
@@ -71,7 +70,8 @@ var PosthogAnalytics = class {
|
|
|
71
70
|
this.client = new PostHog(apiKey, {
|
|
72
71
|
host,
|
|
73
72
|
flushAt: 1,
|
|
74
|
-
flushInterval: 0
|
|
73
|
+
flushInterval: 0,
|
|
74
|
+
disableGeoip: false
|
|
75
75
|
});
|
|
76
76
|
this.captureSessionStart();
|
|
77
77
|
process.on("exit", () => {
|
|
@@ -97,8 +97,7 @@ var PosthogAnalytics = class {
|
|
|
97
97
|
platform: process.arch,
|
|
98
98
|
session_id: this.sessionId,
|
|
99
99
|
cli_version: this.version || "unknown",
|
|
100
|
-
machine_id: os.hostname()
|
|
101
|
-
geoip_disable: false
|
|
100
|
+
machine_id: os.hostname()
|
|
102
101
|
};
|
|
103
102
|
}
|
|
104
103
|
captureSessionStart() {
|
|
@@ -416,6 +415,283 @@ ${color2.gray($)} ${s}
|
|
|
416
415
|
`);let m=0,w=0;p(),i=setInterval(()=>{const L=color2.magenta(s[m]),O=".".repeat(Math.floor(w)).slice(0,3);process.stdout.write(srcExports.cursor.move(-999,0)),process.stdout.write(srcExports.erase.down(1)),process.stdout.write(`${L} ${o}${O}`),m=m+1<s.length?m+1:0,w=w<s.length?w+.125:0;},n);},x=(g="",m=0)=>{o=g??o,r=false,clearInterval(i);const w=m===0?color2.green(M):m===1?color2.red(P):color2.red(V);process.stdout.write(srcExports.cursor.move(-999,0)),process.stdout.write(srcExports.erase.down(1)),process.stdout.write(`${w} ${o}
|
|
417
416
|
`),S(),t();};return {start:f,stop:x,message:(g="")=>{o=g??o;}}};function ye(){const s=["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)","(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");return new RegExp(s,"g")}const ve=async(s,n)=>{const t={},i=Object.keys(s);for(const r of i){const o=s[r],c=await o({results:t})?.catch(l=>{throw l});if(typeof n?.onCancel=="function"&&lD(c)){t[r]="canceled",n.onCancel({results:t});continue}t[r]=c;}return t};
|
|
418
417
|
|
|
418
|
+
var shellQuote$1 = {};
|
|
419
|
+
|
|
420
|
+
var quote;
|
|
421
|
+
var hasRequiredQuote;
|
|
422
|
+
|
|
423
|
+
function requireQuote () {
|
|
424
|
+
if (hasRequiredQuote) return quote;
|
|
425
|
+
hasRequiredQuote = 1;
|
|
426
|
+
|
|
427
|
+
quote = function quote(xs) {
|
|
428
|
+
return xs.map(function (s) {
|
|
429
|
+
if (s === '') {
|
|
430
|
+
return '\'\'';
|
|
431
|
+
}
|
|
432
|
+
if (s && typeof s === 'object') {
|
|
433
|
+
return s.op.replace(/(.)/g, '\\$1');
|
|
434
|
+
}
|
|
435
|
+
if ((/["\s]/).test(s) && !(/'/).test(s)) {
|
|
436
|
+
return "'" + s.replace(/(['\\])/g, '\\$1') + "'";
|
|
437
|
+
}
|
|
438
|
+
if ((/["'\s]/).test(s)) {
|
|
439
|
+
return '"' + s.replace(/(["\\$`!])/g, '\\$1') + '"';
|
|
440
|
+
}
|
|
441
|
+
return String(s).replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, '$1\\$2');
|
|
442
|
+
}).join(' ');
|
|
443
|
+
};
|
|
444
|
+
return quote;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
var parse;
|
|
448
|
+
var hasRequiredParse;
|
|
449
|
+
|
|
450
|
+
function requireParse () {
|
|
451
|
+
if (hasRequiredParse) return parse;
|
|
452
|
+
hasRequiredParse = 1;
|
|
453
|
+
|
|
454
|
+
// '<(' is process substitution operator and
|
|
455
|
+
// can be parsed the same as control operator
|
|
456
|
+
var CONTROL = '(?:' + [
|
|
457
|
+
'\\|\\|',
|
|
458
|
+
'\\&\\&',
|
|
459
|
+
';;',
|
|
460
|
+
'\\|\\&',
|
|
461
|
+
'\\<\\(',
|
|
462
|
+
'\\<\\<\\<',
|
|
463
|
+
'>>',
|
|
464
|
+
'>\\&',
|
|
465
|
+
'<\\&',
|
|
466
|
+
'[&;()|<>]'
|
|
467
|
+
].join('|') + ')';
|
|
468
|
+
var controlRE = new RegExp('^' + CONTROL + '$');
|
|
469
|
+
var META = '|&;()<> \\t';
|
|
470
|
+
var SINGLE_QUOTE = '"((\\\\"|[^"])*?)"';
|
|
471
|
+
var DOUBLE_QUOTE = '\'((\\\\\'|[^\'])*?)\'';
|
|
472
|
+
var hash = /^#$/;
|
|
473
|
+
|
|
474
|
+
var SQ = "'";
|
|
475
|
+
var DQ = '"';
|
|
476
|
+
var DS = '$';
|
|
477
|
+
|
|
478
|
+
var TOKEN = '';
|
|
479
|
+
var mult = 0x100000000; // Math.pow(16, 8);
|
|
480
|
+
for (var i = 0; i < 4; i++) {
|
|
481
|
+
TOKEN += (mult * Math.random()).toString(16);
|
|
482
|
+
}
|
|
483
|
+
var startsWithToken = new RegExp('^' + TOKEN);
|
|
484
|
+
|
|
485
|
+
function matchAll(s, r) {
|
|
486
|
+
var origIndex = r.lastIndex;
|
|
487
|
+
|
|
488
|
+
var matches = [];
|
|
489
|
+
var matchObj;
|
|
490
|
+
|
|
491
|
+
while ((matchObj = r.exec(s))) {
|
|
492
|
+
matches.push(matchObj);
|
|
493
|
+
if (r.lastIndex === matchObj.index) {
|
|
494
|
+
r.lastIndex += 1;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
r.lastIndex = origIndex;
|
|
499
|
+
|
|
500
|
+
return matches;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function getVar(env, pre, key) {
|
|
504
|
+
var r = typeof env === 'function' ? env(key) : env[key];
|
|
505
|
+
if (typeof r === 'undefined' && key != '') {
|
|
506
|
+
r = '';
|
|
507
|
+
} else if (typeof r === 'undefined') {
|
|
508
|
+
r = '$';
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (typeof r === 'object') {
|
|
512
|
+
return pre + TOKEN + JSON.stringify(r) + TOKEN;
|
|
513
|
+
}
|
|
514
|
+
return pre + r;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function parseInternal(string, env, opts) {
|
|
518
|
+
if (!opts) {
|
|
519
|
+
opts = {};
|
|
520
|
+
}
|
|
521
|
+
var BS = opts.escape || '\\';
|
|
522
|
+
var BAREWORD = '(\\' + BS + '[\'"' + META + ']|[^\\s\'"' + META + '])+';
|
|
523
|
+
|
|
524
|
+
var chunker = new RegExp([
|
|
525
|
+
'(' + CONTROL + ')', // control chars
|
|
526
|
+
'(' + BAREWORD + '|' + SINGLE_QUOTE + '|' + DOUBLE_QUOTE + ')+'
|
|
527
|
+
].join('|'), 'g');
|
|
528
|
+
|
|
529
|
+
var matches = matchAll(string, chunker);
|
|
530
|
+
|
|
531
|
+
if (matches.length === 0) {
|
|
532
|
+
return [];
|
|
533
|
+
}
|
|
534
|
+
if (!env) {
|
|
535
|
+
env = {};
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
var commented = false;
|
|
539
|
+
|
|
540
|
+
return matches.map(function (match) {
|
|
541
|
+
var s = match[0];
|
|
542
|
+
if (!s || commented) {
|
|
543
|
+
return void 0;
|
|
544
|
+
}
|
|
545
|
+
if (controlRE.test(s)) {
|
|
546
|
+
return { op: s };
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Hand-written scanner/parser for Bash quoting rules:
|
|
550
|
+
//
|
|
551
|
+
// 1. inside single quotes, all characters are printed literally.
|
|
552
|
+
// 2. inside double quotes, all characters are printed literally
|
|
553
|
+
// except variables prefixed by '$' and backslashes followed by
|
|
554
|
+
// either a double quote or another backslash.
|
|
555
|
+
// 3. outside of any quotes, backslashes are treated as escape
|
|
556
|
+
// characters and not printed (unless they are themselves escaped)
|
|
557
|
+
// 4. quote context can switch mid-token if there is no whitespace
|
|
558
|
+
// between the two quote contexts (e.g. all'one'"token" parses as
|
|
559
|
+
// "allonetoken")
|
|
560
|
+
var quote = false;
|
|
561
|
+
var esc = false;
|
|
562
|
+
var out = '';
|
|
563
|
+
var isGlob = false;
|
|
564
|
+
var i;
|
|
565
|
+
|
|
566
|
+
function parseEnvVar() {
|
|
567
|
+
i += 1;
|
|
568
|
+
var varend;
|
|
569
|
+
var varname;
|
|
570
|
+
var char = s.charAt(i);
|
|
571
|
+
|
|
572
|
+
if (char === '{') {
|
|
573
|
+
i += 1;
|
|
574
|
+
if (s.charAt(i) === '}') {
|
|
575
|
+
throw new Error('Bad substitution: ' + s.slice(i - 2, i + 1));
|
|
576
|
+
}
|
|
577
|
+
varend = s.indexOf('}', i);
|
|
578
|
+
if (varend < 0) {
|
|
579
|
+
throw new Error('Bad substitution: ' + s.slice(i));
|
|
580
|
+
}
|
|
581
|
+
varname = s.slice(i, varend);
|
|
582
|
+
i = varend;
|
|
583
|
+
} else if ((/[*@#?$!_-]/).test(char)) {
|
|
584
|
+
varname = char;
|
|
585
|
+
i += 1;
|
|
586
|
+
} else {
|
|
587
|
+
var slicedFromI = s.slice(i);
|
|
588
|
+
varend = slicedFromI.match(/[^\w\d_]/);
|
|
589
|
+
if (!varend) {
|
|
590
|
+
varname = slicedFromI;
|
|
591
|
+
i = s.length;
|
|
592
|
+
} else {
|
|
593
|
+
varname = slicedFromI.slice(0, varend.index);
|
|
594
|
+
i += varend.index - 1;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
return getVar(env, '', varname);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
for (i = 0; i < s.length; i++) {
|
|
601
|
+
var c = s.charAt(i);
|
|
602
|
+
isGlob = isGlob || (!quote && (c === '*' || c === '?'));
|
|
603
|
+
if (esc) {
|
|
604
|
+
out += c;
|
|
605
|
+
esc = false;
|
|
606
|
+
} else if (quote) {
|
|
607
|
+
if (c === quote) {
|
|
608
|
+
quote = false;
|
|
609
|
+
} else if (quote == SQ) {
|
|
610
|
+
out += c;
|
|
611
|
+
} else { // Double quote
|
|
612
|
+
if (c === BS) {
|
|
613
|
+
i += 1;
|
|
614
|
+
c = s.charAt(i);
|
|
615
|
+
if (c === DQ || c === BS || c === DS) {
|
|
616
|
+
out += c;
|
|
617
|
+
} else {
|
|
618
|
+
out += BS + c;
|
|
619
|
+
}
|
|
620
|
+
} else if (c === DS) {
|
|
621
|
+
out += parseEnvVar();
|
|
622
|
+
} else {
|
|
623
|
+
out += c;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
} else if (c === DQ || c === SQ) {
|
|
627
|
+
quote = c;
|
|
628
|
+
} else if (controlRE.test(c)) {
|
|
629
|
+
return { op: s };
|
|
630
|
+
} else if (hash.test(c)) {
|
|
631
|
+
commented = true;
|
|
632
|
+
var commentObj = { comment: string.slice(match.index + i + 1) };
|
|
633
|
+
if (out.length) {
|
|
634
|
+
return [out, commentObj];
|
|
635
|
+
}
|
|
636
|
+
return [commentObj];
|
|
637
|
+
} else if (c === BS) {
|
|
638
|
+
esc = true;
|
|
639
|
+
} else if (c === DS) {
|
|
640
|
+
out += parseEnvVar();
|
|
641
|
+
} else {
|
|
642
|
+
out += c;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (isGlob) {
|
|
647
|
+
return { op: 'glob', pattern: out };
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return out;
|
|
651
|
+
}).reduce(function (prev, arg) { // finalize parsed arguments
|
|
652
|
+
// TODO: replace this whole reduce with a concat
|
|
653
|
+
return typeof arg === 'undefined' ? prev : prev.concat(arg);
|
|
654
|
+
}, []);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
parse = function parse(s, env, opts) {
|
|
658
|
+
var mapped = parseInternal(s, env, opts);
|
|
659
|
+
if (typeof env !== 'function') {
|
|
660
|
+
return mapped;
|
|
661
|
+
}
|
|
662
|
+
return mapped.reduce(function (acc, s) {
|
|
663
|
+
if (typeof s === 'object') {
|
|
664
|
+
return acc.concat(s);
|
|
665
|
+
}
|
|
666
|
+
var xs = s.split(RegExp('(' + TOKEN + '.*?' + TOKEN + ')', 'g'));
|
|
667
|
+
if (xs.length === 1) {
|
|
668
|
+
return acc.concat(xs[0]);
|
|
669
|
+
}
|
|
670
|
+
return acc.concat(xs.filter(Boolean).map(function (x) {
|
|
671
|
+
if (startsWithToken.test(x)) {
|
|
672
|
+
return JSON.parse(x.split(TOKEN)[1]);
|
|
673
|
+
}
|
|
674
|
+
return x;
|
|
675
|
+
}));
|
|
676
|
+
}, []);
|
|
677
|
+
};
|
|
678
|
+
return parse;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
var hasRequiredShellQuote;
|
|
682
|
+
|
|
683
|
+
function requireShellQuote () {
|
|
684
|
+
if (hasRequiredShellQuote) return shellQuote$1;
|
|
685
|
+
hasRequiredShellQuote = 1;
|
|
686
|
+
|
|
687
|
+
shellQuote$1.quote = requireQuote();
|
|
688
|
+
shellQuote$1.parse = requireParse();
|
|
689
|
+
return shellQuote$1;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
var shellQuoteExports = requireShellQuote();
|
|
693
|
+
var shellQuote = /*@__PURE__*/getDefaultExportFromCjs(shellQuoteExports);
|
|
694
|
+
|
|
419
695
|
// eslint-disable-next-line no-warning-comments
|
|
420
696
|
// TODO: Use a better method when it's added to Node.js (https://github.com/nodejs/node/pull/40240)
|
|
421
697
|
// Lots of optionals here to support Deno.
|
|
@@ -789,46 +1065,65 @@ function yoctoSpinner(options) {
|
|
|
789
1065
|
}
|
|
790
1066
|
|
|
791
1067
|
var LogLevel = {
|
|
792
|
-
INFO: "info"
|
|
793
|
-
|
|
794
|
-
|
|
1068
|
+
INFO: "info",
|
|
1069
|
+
ERROR: "error"};
|
|
1070
|
+
var MastraLogger = class {
|
|
1071
|
+
name;
|
|
1072
|
+
level;
|
|
795
1073
|
transports;
|
|
796
1074
|
constructor(options = {}) {
|
|
797
|
-
this.
|
|
798
|
-
|
|
1075
|
+
this.name = options.name || "Mastra";
|
|
1076
|
+
this.level = options.level || LogLevel.ERROR;
|
|
1077
|
+
this.transports = new Map(Object.entries(options.transports || {}));
|
|
1078
|
+
}
|
|
1079
|
+
getTransports() {
|
|
1080
|
+
return this.transports;
|
|
1081
|
+
}
|
|
1082
|
+
async getLogs(transportId) {
|
|
1083
|
+
if (!transportId || !this.transports.has(transportId)) {
|
|
1084
|
+
return [];
|
|
1085
|
+
}
|
|
1086
|
+
return this.transports.get(transportId).getLogs() ?? [];
|
|
1087
|
+
}
|
|
1088
|
+
async getLogsByRunId({ transportId, runId }) {
|
|
1089
|
+
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1090
|
+
return [];
|
|
1091
|
+
}
|
|
1092
|
+
return this.transports.get(transportId).getLogsByRunId({ runId }) ?? [];
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
var PinoLogger = class extends MastraLogger {
|
|
1097
|
+
logger;
|
|
1098
|
+
constructor(options = {}) {
|
|
1099
|
+
super(options);
|
|
1100
|
+
let prettyStream = void 0;
|
|
1101
|
+
if (!options.overrideDefaultTransports) {
|
|
1102
|
+
prettyStream = pretty({
|
|
1103
|
+
colorize: true,
|
|
1104
|
+
levelFirst: true,
|
|
1105
|
+
ignore: "pid,hostname",
|
|
1106
|
+
colorizeObjects: true,
|
|
1107
|
+
translateTime: "SYS:standard",
|
|
1108
|
+
singleLine: false
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
const transportsAry = [...this.getTransports().entries()];
|
|
799
1112
|
this.logger = pino(
|
|
800
1113
|
{
|
|
801
1114
|
name: options.name || "app",
|
|
802
1115
|
level: options.level || LogLevel.INFO,
|
|
803
1116
|
formatters: {
|
|
804
|
-
level: (label) => {
|
|
805
|
-
return {
|
|
806
|
-
level: label
|
|
807
|
-
};
|
|
808
|
-
}
|
|
1117
|
+
level: (label) => ({ level: label })
|
|
809
1118
|
}
|
|
810
1119
|
},
|
|
811
|
-
options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ?
|
|
812
|
-
colorize: true,
|
|
813
|
-
levelFirst: true,
|
|
814
|
-
ignore: "pid,hostname",
|
|
815
|
-
colorizeObjects: true,
|
|
816
|
-
translateTime: "SYS:standard",
|
|
817
|
-
singleLine: false
|
|
818
|
-
}) : pino.multistream([
|
|
1120
|
+
options.overrideDefaultTransports ? options?.transports?.default : transportsAry.length === 0 ? prettyStream : pino.multistream([
|
|
819
1121
|
...transportsAry.map(([, transport]) => ({
|
|
820
1122
|
stream: transport,
|
|
821
1123
|
level: options.level || LogLevel.INFO
|
|
822
1124
|
})),
|
|
823
1125
|
{
|
|
824
|
-
stream:
|
|
825
|
-
colorize: true,
|
|
826
|
-
levelFirst: true,
|
|
827
|
-
ignore: "pid,hostname",
|
|
828
|
-
colorizeObjects: true,
|
|
829
|
-
translateTime: "SYS:standard",
|
|
830
|
-
singleLine: false
|
|
831
|
-
}),
|
|
1126
|
+
stream: prettyStream,
|
|
832
1127
|
level: options.level || LogLevel.INFO
|
|
833
1128
|
}
|
|
834
1129
|
])
|
|
@@ -846,31 +1141,7 @@ var Logger = class {
|
|
|
846
1141
|
error(message, args = {}) {
|
|
847
1142
|
this.logger.error(args, message);
|
|
848
1143
|
}
|
|
849
|
-
// Stream creation for process output handling
|
|
850
|
-
createStream() {
|
|
851
|
-
return new Transform({
|
|
852
|
-
transform: (chunk, _encoding, callback) => {
|
|
853
|
-
const line = chunk.toString().trim();
|
|
854
|
-
if (line) {
|
|
855
|
-
this.info(line);
|
|
856
|
-
}
|
|
857
|
-
callback(null, chunk);
|
|
858
|
-
}
|
|
859
|
-
});
|
|
860
|
-
}
|
|
861
|
-
async getLogs(transportId) {
|
|
862
|
-
if (!transportId || !this.transports[transportId]) {
|
|
863
|
-
return [];
|
|
864
|
-
}
|
|
865
|
-
return this.transports[transportId].getLogs();
|
|
866
|
-
}
|
|
867
|
-
async getLogsByRunId({ runId, transportId }) {
|
|
868
|
-
return this.transports[transportId]?.getLogsByRunId({ runId });
|
|
869
|
-
}
|
|
870
1144
|
};
|
|
871
|
-
function createLogger(options) {
|
|
872
|
-
return new Logger(options);
|
|
873
|
-
}
|
|
874
1145
|
|
|
875
1146
|
var DepsService = class {
|
|
876
1147
|
packageManager;
|
|
@@ -880,11 +1151,11 @@ var DepsService = class {
|
|
|
880
1151
|
findLockFile(dir) {
|
|
881
1152
|
const lockFiles = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lock"];
|
|
882
1153
|
for (const file of lockFiles) {
|
|
883
|
-
if (fs3__default__default.existsSync(
|
|
1154
|
+
if (fs3__default__default.existsSync(path2.join(dir, file))) {
|
|
884
1155
|
return file;
|
|
885
1156
|
}
|
|
886
1157
|
}
|
|
887
|
-
const parentDir =
|
|
1158
|
+
const parentDir = path2.resolve(dir, "..");
|
|
888
1159
|
if (parentDir !== dir) {
|
|
889
1160
|
return this.findLockFile(parentDir);
|
|
890
1161
|
}
|
|
@@ -921,7 +1192,7 @@ var DepsService = class {
|
|
|
921
1192
|
}
|
|
922
1193
|
async checkDependencies(dependencies) {
|
|
923
1194
|
try {
|
|
924
|
-
const packageJsonPath =
|
|
1195
|
+
const packageJsonPath = path2.join(process.cwd(), "package.json");
|
|
925
1196
|
try {
|
|
926
1197
|
await fs4.access(packageJsonPath);
|
|
927
1198
|
} catch {
|
|
@@ -941,7 +1212,7 @@ var DepsService = class {
|
|
|
941
1212
|
}
|
|
942
1213
|
async getProjectName() {
|
|
943
1214
|
try {
|
|
944
|
-
const packageJsonPath =
|
|
1215
|
+
const packageJsonPath = path2.join(process.cwd(), "package.json");
|
|
945
1216
|
const packageJson = await fs4.readFile(packageJsonPath, "utf-8");
|
|
946
1217
|
const pkg = JSON.parse(packageJson);
|
|
947
1218
|
return pkg.name;
|
|
@@ -952,7 +1223,7 @@ var DepsService = class {
|
|
|
952
1223
|
async getPackageVersion() {
|
|
953
1224
|
const __filename = fileURLToPath(import.meta.url);
|
|
954
1225
|
const __dirname = dirname(__filename);
|
|
955
|
-
const pkgJsonPath =
|
|
1226
|
+
const pkgJsonPath = path2.join(__dirname, "..", "package.json");
|
|
956
1227
|
const content = await fsExtra3.readJSON(pkgJsonPath);
|
|
957
1228
|
return content.version;
|
|
958
1229
|
}
|
|
@@ -1001,49 +1272,110 @@ function getPackageManagerInstallCommand(pm) {
|
|
|
1001
1272
|
}
|
|
1002
1273
|
}
|
|
1003
1274
|
var args = ["-y", "@mastra/mcp-docs-server@latest"];
|
|
1004
|
-
var
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1275
|
+
var createMcpConfig = (editor) => {
|
|
1276
|
+
if (editor === "vscode") {
|
|
1277
|
+
return {
|
|
1278
|
+
servers: {
|
|
1279
|
+
mastra: process.platform === `win32` ? {
|
|
1280
|
+
command: "cmd",
|
|
1281
|
+
args: ["/c", "npx", ...args],
|
|
1282
|
+
type: "stdio"
|
|
1283
|
+
} : {
|
|
1284
|
+
command: "npx",
|
|
1285
|
+
args,
|
|
1286
|
+
type: "stdio"
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1013
1290
|
}
|
|
1291
|
+
return {
|
|
1292
|
+
mcpServers: {
|
|
1293
|
+
mastra: process.platform === `win32` ? {
|
|
1294
|
+
command: "cmd",
|
|
1295
|
+
args: ["/c", "npx", ...args]
|
|
1296
|
+
} : {
|
|
1297
|
+
command: "npx",
|
|
1298
|
+
args
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1014
1302
|
};
|
|
1015
|
-
function makeConfig(original) {
|
|
1303
|
+
function makeConfig(original, editor) {
|
|
1304
|
+
if (editor === "vscode") {
|
|
1305
|
+
return {
|
|
1306
|
+
...original,
|
|
1307
|
+
servers: {
|
|
1308
|
+
...original?.servers || {},
|
|
1309
|
+
...createMcpConfig(editor).servers
|
|
1310
|
+
}
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1016
1313
|
return {
|
|
1017
1314
|
...original,
|
|
1018
1315
|
mcpServers: {
|
|
1019
1316
|
...original?.mcpServers || {},
|
|
1020
|
-
...
|
|
1317
|
+
...createMcpConfig(editor).mcpServers
|
|
1021
1318
|
}
|
|
1022
1319
|
};
|
|
1023
1320
|
}
|
|
1024
|
-
async function writeMergedConfig(configPath) {
|
|
1321
|
+
async function writeMergedConfig(configPath, editor) {
|
|
1025
1322
|
const configExists = existsSync(configPath);
|
|
1026
|
-
const config = makeConfig(configExists ? await readJSON(configPath) : {});
|
|
1323
|
+
const config = makeConfig(configExists ? await readJSON(configPath) : {}, editor);
|
|
1027
1324
|
await ensureFile(configPath);
|
|
1028
1325
|
await writeJSON(configPath, config, {
|
|
1029
1326
|
spaces: 2
|
|
1030
1327
|
});
|
|
1031
1328
|
}
|
|
1032
|
-
var windsurfGlobalMCPConfigPath =
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1329
|
+
var windsurfGlobalMCPConfigPath = path2.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
1330
|
+
var cursorGlobalMCPConfigPath = path2.join(os.homedir(), ".cursor", "mcp.json");
|
|
1331
|
+
path2.join(process.cwd(), ".vscode", "mcp.json");
|
|
1332
|
+
var vscodeGlobalMCPConfigPath = path2.join(
|
|
1333
|
+
os.homedir(),
|
|
1334
|
+
process.platform === "win32" ? path2.join("AppData", "Roaming", "Code", "User", "settings.json") : process.platform === "darwin" ? path2.join("Library", "Application Support", "Code", "User", "settings.json") : path2.join(".config", "Code", "User", "settings.json")
|
|
1335
|
+
);
|
|
1336
|
+
async function installMastraDocsMCPServer({ editor, directory }) {
|
|
1337
|
+
if (editor === `cursor`) {
|
|
1338
|
+
await writeMergedConfig(path2.join(directory, ".cursor", "mcp.json"), "cursor");
|
|
1339
|
+
}
|
|
1340
|
+
if (editor === `vscode`) {
|
|
1341
|
+
await writeMergedConfig(path2.join(directory, ".vscode", "mcp.json"), "vscode");
|
|
1342
|
+
}
|
|
1343
|
+
if (editor === `cursor-global`) {
|
|
1344
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
1345
|
+
if (alreadyInstalled) {
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
await writeMergedConfig(cursorGlobalMCPConfigPath, "cursor-global");
|
|
1349
|
+
}
|
|
1350
|
+
if (editor === `windsurf`) {
|
|
1351
|
+
const alreadyInstalled = await globalMCPIsAlreadyInstalled(editor);
|
|
1352
|
+
if (alreadyInstalled) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
await writeMergedConfig(windsurfGlobalMCPConfigPath, editor);
|
|
1356
|
+
}
|
|
1040
1357
|
}
|
|
1041
|
-
async function
|
|
1042
|
-
|
|
1358
|
+
async function globalMCPIsAlreadyInstalled(editor) {
|
|
1359
|
+
let configPath = ``;
|
|
1360
|
+
if (editor === "windsurf") {
|
|
1361
|
+
configPath = windsurfGlobalMCPConfigPath;
|
|
1362
|
+
} else if (editor === "cursor-global") {
|
|
1363
|
+
configPath = cursorGlobalMCPConfigPath;
|
|
1364
|
+
} else if (editor === "vscode") {
|
|
1365
|
+
configPath = vscodeGlobalMCPConfigPath;
|
|
1366
|
+
}
|
|
1367
|
+
if (!configPath || !existsSync(configPath)) {
|
|
1043
1368
|
return false;
|
|
1044
1369
|
}
|
|
1045
1370
|
try {
|
|
1046
|
-
const configContents = await readJSON(
|
|
1371
|
+
const configContents = await readJSON(configPath);
|
|
1372
|
+
if (editor === "vscode") {
|
|
1373
|
+
if (!configContents?.servers) return false;
|
|
1374
|
+
const hasMastraMCP2 = Object.values(configContents.servers).some(
|
|
1375
|
+
(server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
|
|
1376
|
+
);
|
|
1377
|
+
return hasMastraMCP2;
|
|
1378
|
+
}
|
|
1047
1379
|
if (!configContents?.mcpServers) return false;
|
|
1048
1380
|
const hasMastraMCP = Object.values(configContents.mcpServers).some(
|
|
1049
1381
|
(server) => server?.args?.find((arg) => arg?.includes(`@mastra/mcp-docs-server`))
|
|
@@ -1125,8 +1457,8 @@ var FileService = class {
|
|
|
1125
1457
|
*/
|
|
1126
1458
|
async copyStarterFile(inputFile, outputFilePath, replaceIfExists) {
|
|
1127
1459
|
const __filename = fileURLToPath(import.meta.url);
|
|
1128
|
-
const __dirname =
|
|
1129
|
-
const filePath =
|
|
1460
|
+
const __dirname = path2.dirname(__filename);
|
|
1461
|
+
const filePath = path2.resolve(__dirname, "starter-files", inputFile);
|
|
1130
1462
|
const fileString = fs3__default__default.readFileSync(filePath, "utf8");
|
|
1131
1463
|
if (fs3__default__default.existsSync(outputFilePath) && !replaceIfExists) {
|
|
1132
1464
|
console.log(`${outputFilePath} already exists`);
|
|
@@ -1136,7 +1468,7 @@ var FileService = class {
|
|
|
1136
1468
|
return true;
|
|
1137
1469
|
}
|
|
1138
1470
|
async setupEnvFile({ dbUrl }) {
|
|
1139
|
-
const envPath =
|
|
1471
|
+
const envPath = path2.join(process.cwd(), ".env.development");
|
|
1140
1472
|
await fsExtra3.ensureFile(envPath);
|
|
1141
1473
|
const fileEnvService = new FileEnvService(envPath);
|
|
1142
1474
|
await fileEnvService.setEnvValue("DB_URL", dbUrl);
|
|
@@ -1160,7 +1492,7 @@ var FileService = class {
|
|
|
1160
1492
|
fs3__default__default.writeFileSync(filePath, fileContent);
|
|
1161
1493
|
}
|
|
1162
1494
|
};
|
|
1163
|
-
|
|
1495
|
+
new PinoLogger({
|
|
1164
1496
|
name: "Mastra CLI",
|
|
1165
1497
|
level: "debug"
|
|
1166
1498
|
});
|
|
@@ -1186,7 +1518,7 @@ var getProviderImportAndModelItem = (llmProvider) => {
|
|
|
1186
1518
|
let modelItem = "";
|
|
1187
1519
|
if (llmProvider === "openai") {
|
|
1188
1520
|
providerImport = `import { openai } from '${getAISDKPackage(llmProvider)}';`;
|
|
1189
|
-
modelItem = `openai('gpt-4o')`;
|
|
1521
|
+
modelItem = `openai('gpt-4o-mini')`;
|
|
1190
1522
|
} else if (llmProvider === "anthropic") {
|
|
1191
1523
|
providerImport = `import { anthropic } from '${getAISDKPackage(llmProvider)}';`;
|
|
1192
1524
|
modelItem = `anthropic('claude-3-5-sonnet-20241022')`;
|
|
@@ -1219,13 +1551,20 @@ async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
|
1219
1551
|
const content = `
|
|
1220
1552
|
${providerImport}
|
|
1221
1553
|
import { Agent } from '@mastra/core/agent';
|
|
1222
|
-
|
|
1554
|
+
import { Memory } from '@mastra/memory';
|
|
1555
|
+
import { LibSQLStore } from '@mastra/libsql';
|
|
1556
|
+
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1223
1557
|
|
|
1224
1558
|
export const weatherAgent = new Agent({
|
|
1225
1559
|
name: 'Weather Agent',
|
|
1226
1560
|
instructions: \`${instructions}\`,
|
|
1227
1561
|
model: ${modelItem},
|
|
1228
1562
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1563
|
+
memory: new Memory({
|
|
1564
|
+
storage: new LibSQLStore({
|
|
1565
|
+
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1566
|
+
})
|
|
1567
|
+
})
|
|
1229
1568
|
});
|
|
1230
1569
|
`;
|
|
1231
1570
|
const formattedContent = await prettier.format(content, {
|
|
@@ -1239,7 +1578,7 @@ async function writeWorkflowSample(destPath, llmProvider) {
|
|
|
1239
1578
|
const { providerImport, modelItem } = getProviderImportAndModelItem(llmProvider);
|
|
1240
1579
|
const content = `${providerImport}
|
|
1241
1580
|
import { Agent } from '@mastra/core/agent';
|
|
1242
|
-
import {
|
|
1581
|
+
import { createStep, createWorkflow } from '@mastra/core/workflows';
|
|
1243
1582
|
import { z } from 'zod';
|
|
1244
1583
|
|
|
1245
1584
|
const llm = ${modelItem};
|
|
@@ -1292,80 +1631,106 @@ const agent = new Agent({
|
|
|
1292
1631
|
\`,
|
|
1293
1632
|
});
|
|
1294
1633
|
|
|
1295
|
-
const forecastSchema = z.
|
|
1296
|
-
z.
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
)
|
|
1634
|
+
const forecastSchema = z.object({
|
|
1635
|
+
date: z.string(),
|
|
1636
|
+
maxTemp: z.number(),
|
|
1637
|
+
minTemp: z.number(),
|
|
1638
|
+
precipitationChance: z.number(),
|
|
1639
|
+
condition: z.string(),
|
|
1640
|
+
location: z.string(),
|
|
1641
|
+
})
|
|
1642
|
+
|
|
1643
|
+
function getWeatherCondition(code: number): string {
|
|
1644
|
+
const conditions: Record<number, string> = {
|
|
1645
|
+
0: 'Clear sky',
|
|
1646
|
+
1: 'Mainly clear',
|
|
1647
|
+
2: 'Partly cloudy',
|
|
1648
|
+
3: 'Overcast',
|
|
1649
|
+
45: 'Foggy',
|
|
1650
|
+
48: 'Depositing rime fog',
|
|
1651
|
+
51: 'Light drizzle',
|
|
1652
|
+
53: 'Moderate drizzle',
|
|
1653
|
+
55: 'Dense drizzle',
|
|
1654
|
+
61: 'Slight rain',
|
|
1655
|
+
63: 'Moderate rain',
|
|
1656
|
+
65: 'Heavy rain',
|
|
1657
|
+
71: 'Slight snow fall',
|
|
1658
|
+
73: 'Moderate snow fall',
|
|
1659
|
+
75: 'Heavy snow fall',
|
|
1660
|
+
95: 'Thunderstorm',
|
|
1661
|
+
}
|
|
1662
|
+
return conditions[code] || 'Unknown'
|
|
1663
|
+
}
|
|
1305
1664
|
|
|
1306
|
-
const fetchWeather =
|
|
1665
|
+
const fetchWeather = createStep({
|
|
1307
1666
|
id: 'fetch-weather',
|
|
1308
1667
|
description: 'Fetches weather forecast for a given city',
|
|
1309
1668
|
inputSchema: z.object({
|
|
1310
1669
|
city: z.string().describe('The city to get the weather for'),
|
|
1311
1670
|
}),
|
|
1312
1671
|
outputSchema: forecastSchema,
|
|
1313
|
-
execute: async ({
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
if (!triggerData) {
|
|
1317
|
-
throw new Error('Trigger data not found');
|
|
1672
|
+
execute: async ({ inputData }) => {
|
|
1673
|
+
if (!inputData) {
|
|
1674
|
+
throw new Error('Input data not found');
|
|
1318
1675
|
}
|
|
1319
1676
|
|
|
1320
|
-
const geocodingUrl = \`https://geocoding-api.open-meteo.com/v1/search?name=\${encodeURIComponent(
|
|
1677
|
+
const geocodingUrl = \`https://geocoding-api.open-meteo.com/v1/search?name=\${encodeURIComponent(inputData.city)}&count=1\`;
|
|
1321
1678
|
const geocodingResponse = await fetch(geocodingUrl);
|
|
1322
1679
|
const geocodingData = (await geocodingResponse.json()) as {
|
|
1323
1680
|
results: { latitude: number; longitude: number; name: string }[];
|
|
1324
1681
|
};
|
|
1325
1682
|
|
|
1326
1683
|
if (!geocodingData.results?.[0]) {
|
|
1327
|
-
throw new Error(\`Location '\${
|
|
1684
|
+
throw new Error(\`Location '\${inputData.city}' not found\`);
|
|
1328
1685
|
}
|
|
1329
1686
|
|
|
1330
1687
|
const { latitude, longitude, name } = geocodingData.results[0];
|
|
1331
1688
|
|
|
1332
|
-
const weatherUrl = \`https://api.open-meteo.com/v1/forecast?latitude=\${latitude}&longitude=\${longitude}&
|
|
1689
|
+
const weatherUrl = \`https://api.open-meteo.com/v1/forecast?latitude=\${latitude}&longitude=\${longitude}¤t=precipitation,weathercode&timezone=auto,&hourly=precipitation_probability,temperature_2m\`;
|
|
1333
1690
|
const response = await fetch(weatherUrl);
|
|
1334
1691
|
const data = (await response.json()) as {
|
|
1335
|
-
|
|
1336
|
-
time: string
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1692
|
+
current: {
|
|
1693
|
+
time: string
|
|
1694
|
+
precipitation: number
|
|
1695
|
+
weathercode: number
|
|
1696
|
+
}
|
|
1697
|
+
hourly: {
|
|
1698
|
+
precipitation_probability: number[]
|
|
1699
|
+
temperature_2m: number[]
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1343
1702
|
|
|
1344
|
-
const forecast =
|
|
1345
|
-
date,
|
|
1346
|
-
maxTemp: data.
|
|
1347
|
-
minTemp: data.
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1703
|
+
const forecast = {
|
|
1704
|
+
date: new Date().toISOString(),
|
|
1705
|
+
maxTemp: Math.max(...data.hourly.temperature_2m),
|
|
1706
|
+
minTemp: Math.min(...data.hourly.temperature_2m),
|
|
1707
|
+
condition: getWeatherCondition(data.current.weathercode),
|
|
1708
|
+
precipitationChance: data.hourly.precipitation_probability.reduce(
|
|
1709
|
+
(acc, curr) => Math.max(acc, curr),
|
|
1710
|
+
0
|
|
1711
|
+
),
|
|
1712
|
+
}
|
|
1352
1713
|
|
|
1353
1714
|
return forecast;
|
|
1354
1715
|
},
|
|
1355
1716
|
});
|
|
1356
1717
|
|
|
1357
1718
|
|
|
1358
|
-
const planActivities =
|
|
1719
|
+
const planActivities = createStep({
|
|
1359
1720
|
id: 'plan-activities',
|
|
1360
1721
|
description: 'Suggests activities based on weather conditions',
|
|
1361
|
-
|
|
1362
|
-
|
|
1722
|
+
inputSchema: forecastSchema,
|
|
1723
|
+
outputSchema: z.object({
|
|
1724
|
+
activities: z.string(),
|
|
1725
|
+
}),
|
|
1726
|
+
execute: async ({ inputData }) => {
|
|
1727
|
+
const forecast = inputData
|
|
1363
1728
|
|
|
1364
|
-
if (!forecast
|
|
1365
|
-
throw new Error('Forecast data not found')
|
|
1729
|
+
if (!forecast) {
|
|
1730
|
+
throw new Error('Forecast data not found')
|
|
1366
1731
|
}
|
|
1367
1732
|
|
|
1368
|
-
const prompt = \`Based on the following weather forecast for \${forecast
|
|
1733
|
+
const prompt = \`Based on the following weather forecast for \${forecast.location}, suggest appropriate activities:
|
|
1369
1734
|
\${JSON.stringify(forecast, null, 2)}
|
|
1370
1735
|
\`;
|
|
1371
1736
|
|
|
@@ -1389,35 +1754,16 @@ const planActivities = new Step({
|
|
|
1389
1754
|
},
|
|
1390
1755
|
});
|
|
1391
1756
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
1: 'Mainly clear',
|
|
1396
|
-
2: 'Partly cloudy',
|
|
1397
|
-
3: 'Overcast',
|
|
1398
|
-
45: 'Foggy',
|
|
1399
|
-
48: 'Depositing rime fog',
|
|
1400
|
-
51: 'Light drizzle',
|
|
1401
|
-
53: 'Moderate drizzle',
|
|
1402
|
-
55: 'Dense drizzle',
|
|
1403
|
-
61: 'Slight rain',
|
|
1404
|
-
63: 'Moderate rain',
|
|
1405
|
-
65: 'Heavy rain',
|
|
1406
|
-
71: 'Slight snow fall',
|
|
1407
|
-
73: 'Moderate snow fall',
|
|
1408
|
-
75: 'Heavy snow fall',
|
|
1409
|
-
95: 'Thunderstorm',
|
|
1410
|
-
};
|
|
1411
|
-
return conditions[code] || 'Unknown';
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
const weatherWorkflow = new Workflow({
|
|
1415
|
-
name: 'weather-workflow',
|
|
1416
|
-
triggerSchema: z.object({
|
|
1757
|
+
const weatherWorkflow = createWorkflow({
|
|
1758
|
+
id: 'weather-workflow',
|
|
1759
|
+
inputSchema: z.object({
|
|
1417
1760
|
city: z.string().describe('The city to get the weather for'),
|
|
1418
1761
|
}),
|
|
1762
|
+
outputSchema: z.object({
|
|
1763
|
+
activities: z.string(),
|
|
1764
|
+
})
|
|
1419
1765
|
})
|
|
1420
|
-
.
|
|
1766
|
+
.then(fetchWeather)
|
|
1421
1767
|
.then(planActivities);
|
|
1422
1768
|
|
|
1423
1769
|
weatherWorkflow.commit();
|
|
@@ -1457,7 +1803,7 @@ var writeIndexFile = async ({
|
|
|
1457
1803
|
addWorkflow
|
|
1458
1804
|
}) => {
|
|
1459
1805
|
const indexPath = dirPath + "/index.ts";
|
|
1460
|
-
const destPath =
|
|
1806
|
+
const destPath = path2.join(indexPath);
|
|
1461
1807
|
try {
|
|
1462
1808
|
await fs4.writeFile(destPath, "");
|
|
1463
1809
|
const filteredExports = [
|
|
@@ -1479,13 +1825,18 @@ export const mastra = new Mastra()
|
|
|
1479
1825
|
destPath,
|
|
1480
1826
|
`
|
|
1481
1827
|
import { Mastra } from '@mastra/core/mastra';
|
|
1482
|
-
import {
|
|
1483
|
-
|
|
1484
|
-
${
|
|
1828
|
+
import { PinoLogger } from '@mastra/loggers';
|
|
1829
|
+
import { LibSQLStore } from '@mastra/libsql';
|
|
1830
|
+
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1831
|
+
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1485
1832
|
|
|
1486
1833
|
export const mastra = new Mastra({
|
|
1487
1834
|
${filteredExports.join("\n ")}
|
|
1488
|
-
|
|
1835
|
+
storage: new LibSQLStore({
|
|
1836
|
+
// stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1837
|
+
url: ":memory:",
|
|
1838
|
+
}),
|
|
1839
|
+
logger: new PinoLogger({
|
|
1489
1840
|
name: 'Mastra',
|
|
1490
1841
|
level: 'info',
|
|
1491
1842
|
}),
|
|
@@ -1521,11 +1872,13 @@ var writeAPIKey = async ({
|
|
|
1521
1872
|
apiKey = "your-api-key"
|
|
1522
1873
|
}) => {
|
|
1523
1874
|
const key = await getAPIKey(provider);
|
|
1524
|
-
|
|
1875
|
+
const escapedKey = shellQuote.quote([key]);
|
|
1876
|
+
const escapedApiKey = shellQuote.quote([apiKey]);
|
|
1877
|
+
await exec(`echo ${escapedKey}=${escapedApiKey} >> .env`);
|
|
1525
1878
|
};
|
|
1526
1879
|
var createMastraDir = async (directory) => {
|
|
1527
1880
|
let dir = directory.trim().split("/").filter((item) => item !== "");
|
|
1528
|
-
const dirPath =
|
|
1881
|
+
const dirPath = path2.join(process.cwd(), ...dir, "mastra");
|
|
1529
1882
|
try {
|
|
1530
1883
|
await fs4.access(dirPath);
|
|
1531
1884
|
return { ok: false };
|
|
@@ -1535,7 +1888,7 @@ var createMastraDir = async (directory) => {
|
|
|
1535
1888
|
}
|
|
1536
1889
|
};
|
|
1537
1890
|
var writeCodeSample = async (dirPath, component, llmProvider, importComponents) => {
|
|
1538
|
-
const destPath = dirPath + `/${component}/
|
|
1891
|
+
const destPath = dirPath + `/${component}/weather-${component.slice(0, -1)}.ts`;
|
|
1539
1892
|
try {
|
|
1540
1893
|
await writeCodeSampleForComponents(llmProvider, component, destPath, importComponents);
|
|
1541
1894
|
} catch (err) {
|
|
@@ -1597,16 +1950,32 @@ var interactivePrompt = async () => {
|
|
|
1597
1950
|
initialValue: false
|
|
1598
1951
|
}),
|
|
1599
1952
|
configureEditorWithDocsMCP: async () => {
|
|
1600
|
-
const windsurfIsAlreadyInstalled = await
|
|
1953
|
+
const windsurfIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`windsurf`);
|
|
1954
|
+
const cursorIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`cursor`);
|
|
1955
|
+
const vscodeIsAlreadyInstalled = await globalMCPIsAlreadyInstalled(`vscode`);
|
|
1601
1956
|
const editor = await le({
|
|
1602
1957
|
message: `Make your AI IDE into a Mastra expert? (installs Mastra docs MCP server)`,
|
|
1603
1958
|
options: [
|
|
1604
1959
|
{ value: "skip", label: "Skip for now", hint: "default" },
|
|
1605
|
-
{
|
|
1960
|
+
{
|
|
1961
|
+
value: "cursor",
|
|
1962
|
+
label: "Cursor (project only)",
|
|
1963
|
+
hint: cursorIsAlreadyInstalled ? `Already installed globally` : void 0
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
value: "cursor-global",
|
|
1967
|
+
label: "Cursor (global, all projects)",
|
|
1968
|
+
hint: cursorIsAlreadyInstalled ? `Already installed` : void 0
|
|
1969
|
+
},
|
|
1606
1970
|
{
|
|
1607
1971
|
value: "windsurf",
|
|
1608
1972
|
label: "Windsurf",
|
|
1609
1973
|
hint: windsurfIsAlreadyInstalled ? `Already installed` : void 0
|
|
1974
|
+
},
|
|
1975
|
+
{
|
|
1976
|
+
value: "vscode",
|
|
1977
|
+
label: "VSCode",
|
|
1978
|
+
hint: vscodeIsAlreadyInstalled ? `Already installed` : void 0
|
|
1610
1979
|
}
|
|
1611
1980
|
]
|
|
1612
1981
|
});
|
|
@@ -1616,6 +1985,11 @@ var interactivePrompt = async () => {
|
|
|
1616
1985
|
Windsurf is already installed, skipping.`);
|
|
1617
1986
|
return void 0;
|
|
1618
1987
|
}
|
|
1988
|
+
if (editor === `vscode` && vscodeIsAlreadyInstalled) {
|
|
1989
|
+
v.message(`
|
|
1990
|
+
VSCode is already installed, skipping.`);
|
|
1991
|
+
return void 0;
|
|
1992
|
+
}
|
|
1619
1993
|
if (editor === `cursor`) {
|
|
1620
1994
|
v.message(
|
|
1621
1995
|
`
|
|
@@ -1623,6 +1997,18 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
1623
1997
|
`
|
|
1624
1998
|
);
|
|
1625
1999
|
}
|
|
2000
|
+
if (editor === `cursor-global`) {
|
|
2001
|
+
const confirm2 = await le({
|
|
2002
|
+
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
2003
|
+
options: [
|
|
2004
|
+
{ value: "yes", label: "Yes, I understand" },
|
|
2005
|
+
{ value: "skip", label: "No, skip for now" }
|
|
2006
|
+
]
|
|
2007
|
+
});
|
|
2008
|
+
if (confirm2 !== `yes`) {
|
|
2009
|
+
return void 0;
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
1626
2012
|
if (editor === `windsurf`) {
|
|
1627
2013
|
const confirm2 = await le({
|
|
1628
2014
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
@@ -1684,6 +2070,19 @@ var init = async ({
|
|
|
1684
2070
|
(component) => writeCodeSample(dirPath, component, llmProvider, components)
|
|
1685
2071
|
)
|
|
1686
2072
|
]);
|
|
2073
|
+
const depService = new DepsService();
|
|
2074
|
+
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2075
|
+
if (needsLibsql) {
|
|
2076
|
+
await depService.installPackages(["@mastra/libsql"]);
|
|
2077
|
+
}
|
|
2078
|
+
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2079
|
+
if (needsMemory) {
|
|
2080
|
+
await depService.installPackages(["@mastra/memory"]);
|
|
2081
|
+
}
|
|
2082
|
+
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2083
|
+
if (needsLoggers) {
|
|
2084
|
+
await depService.installPackages(["@mastra/loggers"]);
|
|
2085
|
+
}
|
|
1687
2086
|
}
|
|
1688
2087
|
const key = await getAPIKey(llmProvider || "openai");
|
|
1689
2088
|
const aiSdkPackage = getAISDKPackage(llmProvider);
|
|
@@ -1703,7 +2102,7 @@ var init = async ({
|
|
|
1703
2102
|
${color2.green("Mastra initialized successfully!")}
|
|
1704
2103
|
|
|
1705
2104
|
Add your ${color2.cyan(key)} as an environment variable
|
|
1706
|
-
in your ${color2.cyan(".env
|
|
2105
|
+
in your ${color2.cyan(".env")} file
|
|
1707
2106
|
`);
|
|
1708
2107
|
} else {
|
|
1709
2108
|
me(`
|
|
@@ -1744,6 +2143,21 @@ var execWithTimeout = async (command, timeoutMs) => {
|
|
|
1744
2143
|
throw error;
|
|
1745
2144
|
}
|
|
1746
2145
|
};
|
|
2146
|
+
async function installMastraDependency(pm, dependency, versionTag, isDev, timeout) {
|
|
2147
|
+
let installCommand = getPackageManagerInstallCommand(pm);
|
|
2148
|
+
if (isDev) {
|
|
2149
|
+
installCommand = `${installCommand} --save-dev`;
|
|
2150
|
+
}
|
|
2151
|
+
try {
|
|
2152
|
+
await execWithTimeout(`${pm} ${installCommand} ${dependency}${versionTag}`, timeout);
|
|
2153
|
+
} catch (err) {
|
|
2154
|
+
console.log("err", err);
|
|
2155
|
+
if (versionTag === "@latest") {
|
|
2156
|
+
throw err;
|
|
2157
|
+
}
|
|
2158
|
+
await execWithTimeout(`${pm} ${installCommand} ${dependency}@latest`, timeout);
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
1747
2161
|
var createMastraProject = async ({
|
|
1748
2162
|
projectName: name,
|
|
1749
2163
|
createVersionTag,
|
|
@@ -1778,14 +2192,16 @@ var createMastraProject = async ({
|
|
|
1778
2192
|
s2.message("Creating project");
|
|
1779
2193
|
await exec3(`npm init -y`);
|
|
1780
2194
|
await exec3(`npm pkg set type="module"`);
|
|
2195
|
+
await exec3(`npm pkg set engines.node=">=20.9.0"`);
|
|
1781
2196
|
const depsService = new DepsService();
|
|
1782
2197
|
await depsService.addScriptsToPackageJson({
|
|
1783
|
-
dev: "mastra dev"
|
|
2198
|
+
dev: "mastra dev",
|
|
2199
|
+
build: "mastra build"
|
|
1784
2200
|
});
|
|
1785
2201
|
s2.stop("Project created");
|
|
1786
2202
|
s2.start(`Installing ${pm} dependencies`);
|
|
1787
2203
|
await exec3(`${pm} ${installCommand} zod`);
|
|
1788
|
-
await exec3(`${pm} ${installCommand} typescript
|
|
2204
|
+
await exec3(`${pm} ${installCommand} typescript @types/node --save-dev`);
|
|
1789
2205
|
await exec3(`echo '{
|
|
1790
2206
|
"compilerOptions": {
|
|
1791
2207
|
"target": "ES2022",
|
|
@@ -1795,25 +2211,23 @@ var createMastraProject = async ({
|
|
|
1795
2211
|
"forceConsistentCasingInFileNames": true,
|
|
1796
2212
|
"strict": true,
|
|
1797
2213
|
"skipLibCheck": true,
|
|
2214
|
+
"noEmit": true,
|
|
1798
2215
|
"outDir": "dist"
|
|
1799
2216
|
},
|
|
1800
2217
|
"include": [
|
|
1801
2218
|
"src/**/*"
|
|
1802
|
-
],
|
|
1803
|
-
"exclude": [
|
|
1804
|
-
"node_modules",
|
|
1805
|
-
"dist",
|
|
1806
|
-
".mastra"
|
|
1807
2219
|
]
|
|
1808
2220
|
}' > tsconfig.json`);
|
|
1809
2221
|
s2.stop(`${pm} dependencies installed`);
|
|
1810
2222
|
s2.start("Installing mastra");
|
|
1811
2223
|
const versionTag = createVersionTag ? `@${createVersionTag}` : "@latest";
|
|
1812
|
-
await
|
|
2224
|
+
await installMastraDependency(pm, "mastra", versionTag, true, timeout);
|
|
1813
2225
|
s2.stop("mastra installed");
|
|
1814
|
-
s2.start("Installing
|
|
1815
|
-
await
|
|
1816
|
-
|
|
2226
|
+
s2.start("Installing dependencies");
|
|
2227
|
+
await installMastraDependency(pm, "@mastra/core", versionTag, false, timeout);
|
|
2228
|
+
await installMastraDependency(pm, "@mastra/libsql", versionTag, false, timeout);
|
|
2229
|
+
await installMastraDependency(pm, "@mastra/memory", versionTag, false, timeout);
|
|
2230
|
+
s2.stop("Dependencies installed");
|
|
1817
2231
|
s2.start("Adding .gitignore");
|
|
1818
2232
|
await exec3(`echo output.txt >> .gitignore`);
|
|
1819
2233
|
await exec3(`echo node_modules >> .gitignore`);
|
|
@@ -1834,8 +2248,8 @@ var create = async (args2) => {
|
|
|
1834
2248
|
createVersionTag: args2?.createVersionTag,
|
|
1835
2249
|
timeout: args2?.timeout
|
|
1836
2250
|
});
|
|
1837
|
-
const directory = "/
|
|
1838
|
-
if (
|
|
2251
|
+
const directory = args2.directory || "src/";
|
|
2252
|
+
if (args2.components === void 0 || args2.llmProvider === void 0 || args2.addExample === void 0) {
|
|
1839
2253
|
const result = await interactivePrompt();
|
|
1840
2254
|
await init({
|
|
1841
2255
|
...result,
|
|
@@ -1850,68 +2264,36 @@ var create = async (args2) => {
|
|
|
1850
2264
|
components,
|
|
1851
2265
|
llmProvider,
|
|
1852
2266
|
addExample,
|
|
1853
|
-
llmApiKey
|
|
2267
|
+
llmApiKey,
|
|
2268
|
+
configureEditorWithDocsMCP: args2.mcpServer
|
|
1854
2269
|
});
|
|
1855
2270
|
postCreate({ projectName });
|
|
1856
2271
|
};
|
|
1857
2272
|
var postCreate = ({ projectName }) => {
|
|
2273
|
+
const packageManager = getPackageManager();
|
|
1858
2274
|
ge(`
|
|
1859
2275
|
${color2.green("To start your project:")}
|
|
1860
2276
|
|
|
1861
2277
|
${color2.cyan("cd")} ${projectName}
|
|
1862
|
-
${color2.cyan(
|
|
2278
|
+
${color2.cyan(`${packageManager} run dev`)}
|
|
1863
2279
|
`);
|
|
1864
2280
|
};
|
|
1865
2281
|
|
|
1866
2282
|
async function getPackageVersion() {
|
|
1867
2283
|
const __filename = fileURLToPath(import.meta.url);
|
|
1868
2284
|
const __dirname = dirname(__filename);
|
|
1869
|
-
const pkgJsonPath =
|
|
2285
|
+
const pkgJsonPath = path2.join(__dirname, "..", "package.json");
|
|
1870
2286
|
const content = await fsExtra.readJSON(pkgJsonPath);
|
|
1871
2287
|
return content.version;
|
|
1872
2288
|
}
|
|
1873
|
-
async function tryReadPackageJson(paths) {
|
|
1874
|
-
let lastError;
|
|
1875
|
-
for (const path2 of paths) {
|
|
1876
|
-
try {
|
|
1877
|
-
const content = await fsExtra.readJSON(path2);
|
|
1878
|
-
if (content.name === "create-mastra") {
|
|
1879
|
-
return content;
|
|
1880
|
-
}
|
|
1881
|
-
} catch (err) {
|
|
1882
|
-
lastError = err;
|
|
1883
|
-
continue;
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
throw lastError || new Error("Could not find create-mastra package.json in any of the expected locations");
|
|
1887
|
-
}
|
|
1888
2289
|
async function getCreateVersionTag() {
|
|
1889
2290
|
try {
|
|
1890
|
-
const
|
|
1891
|
-
const
|
|
1892
|
-
const
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
path.join(binDir, "..", "..", "..", "package.json"),
|
|
1897
|
-
path.join(binDir, "..", "..", "..", "..", "package.json"),
|
|
1898
|
-
// Standard node_modules paths
|
|
1899
|
-
path.join(binDir, "..", "create-mastra", "package.json"),
|
|
1900
|
-
path.join(binDir, "..", "..", "create-mastra", "package.json"),
|
|
1901
|
-
path.join(binDir, "..", "..", "..", "create-mastra", "package.json"),
|
|
1902
|
-
path.join(binDir, "..", "..", "..", "..", "create-mastra", "package.json"),
|
|
1903
|
-
// pnpm specific paths (.pnpm directory)
|
|
1904
|
-
path.join(binDir, "..", ".pnpm", "create-mastra@*", "node_modules", "create-mastra", "package.json"),
|
|
1905
|
-
path.join(binDir, "..", "..", ".pnpm", "create-mastra@*", "node_modules", "create-mastra", "package.json"),
|
|
1906
|
-
// pnpm dlx specific path
|
|
1907
|
-
path.join(binDir, "..", "..", "package.json"),
|
|
1908
|
-
path.join(binDir, "..", "..", "node_modules", "create-mastra", "package.json")
|
|
1909
|
-
];
|
|
1910
|
-
const content = await tryReadPackageJson(possiblePaths);
|
|
1911
|
-
if (content.version?.includes("-")) {
|
|
1912
|
-
const tag = content.version.split("-")[1].split(".")[0];
|
|
1913
|
-
return tag;
|
|
1914
|
-
}
|
|
2291
|
+
const pkgPath = fileURLToPath(import.meta.resolve("create-mastra/package.json"));
|
|
2292
|
+
const json = await fsExtra.readJSON(pkgPath);
|
|
2293
|
+
const { stdout } = await execa("npm", ["dist-tag", "create-mastra"]);
|
|
2294
|
+
const tagLine = stdout.split("\n").find((distLine) => distLine.endsWith(`: ${json.version}`));
|
|
2295
|
+
const tag = tagLine ? tagLine.split(":")[0].trim() : "latest";
|
|
2296
|
+
return tag;
|
|
1915
2297
|
} catch {
|
|
1916
2298
|
console.error('We could not resolve the create-mastra version tag, falling back to "latest"');
|
|
1917
2299
|
}
|
|
@@ -1935,15 +2317,20 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
1935
2317
|
} catch {
|
|
1936
2318
|
}
|
|
1937
2319
|
});
|
|
1938
|
-
program.name("create-mastra").description("Create a new Mastra project").
|
|
2320
|
+
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2321
|
+
"-p, --project-name <string>",
|
|
2322
|
+
"Project name that will be used in package.json and as the project directory name."
|
|
2323
|
+
).option("--default", "Quick start with defaults(src, OpenAI, no examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").action(async (projectNameArg, args) => {
|
|
2324
|
+
const projectName = projectNameArg || args.projectName;
|
|
1939
2325
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
1940
2326
|
if (args.default) {
|
|
1941
2327
|
await create({
|
|
1942
2328
|
components: ["agents", "tools", "workflows"],
|
|
1943
2329
|
llmProvider: "openai",
|
|
1944
|
-
addExample:
|
|
2330
|
+
addExample: true,
|
|
1945
2331
|
createVersionTag,
|
|
1946
|
-
timeout
|
|
2332
|
+
timeout,
|
|
2333
|
+
mcpServer: args.mcp
|
|
1947
2334
|
});
|
|
1948
2335
|
return;
|
|
1949
2336
|
}
|
|
@@ -1953,7 +2340,10 @@ program.name("create-mastra").description("Create a new Mastra project").option(
|
|
|
1953
2340
|
addExample: args.example,
|
|
1954
2341
|
llmApiKey: args["llm-api-key"],
|
|
1955
2342
|
createVersionTag,
|
|
1956
|
-
timeout
|
|
2343
|
+
timeout,
|
|
2344
|
+
projectName,
|
|
2345
|
+
directory: args.dir,
|
|
2346
|
+
mcpServer: args.mcp
|
|
1957
2347
|
});
|
|
1958
2348
|
});
|
|
1959
2349
|
program.parse(process.argv);
|