create-mastra 0.0.0-error-handler-fix-20251020202607 → 0.0.0-export-agent-memory-from-local-studio-20251112153946
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -1
- package/dist/index.js +200 -52
- package/dist/index.js.map +1 -1
- package/dist/starter-files/tools.ts +2 -2
- package/dist/templates/dev.entry.js +2 -45
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,64 @@
|
|
|
1
1
|
# create-mastra
|
|
2
2
|
|
|
3
|
-
## 0.0.0-
|
|
3
|
+
## 0.0.0-export-agent-memory-from-local-studio-20251112153946
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Bump minimum required Node.js version to 22.13.0 ([#9706](https://github.com/mastra-ai/mastra/pull/9706))
|
|
8
|
+
|
|
9
|
+
- Removed old tracing code based on OpenTelemetry ([#9237](https://github.com/mastra-ai/mastra/pull/9237))
|
|
10
|
+
|
|
11
|
+
- Mark as stable ([`83d5942`](https://github.com/mastra-ai/mastra/commit/83d5942669ce7bba4a6ca4fd4da697a10eb5ebdc))
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Update MainSidebar component to fit required changes in Cloud CTA link ([#9318](https://github.com/mastra-ai/mastra/pull/9318))
|
|
16
|
+
|
|
17
|
+
- Make MainSidebar toggle button sticky to bottom, always visible ([#9682](https://github.com/mastra-ai/mastra/pull/9682))
|
|
18
|
+
|
|
19
|
+
## 1.0.0-beta.1
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Make MainSidebar toggle button sticky to bottom, always visible ([#9682](https://github.com/mastra-ai/mastra/pull/9682))
|
|
24
|
+
|
|
25
|
+
## 1.0.0-beta.0
|
|
26
|
+
|
|
27
|
+
### Major Changes
|
|
28
|
+
|
|
29
|
+
- Bump minimum required Node.js version to 22.13.0 ([#9706](https://github.com/mastra-ai/mastra/pull/9706))
|
|
30
|
+
|
|
31
|
+
- Removed old tracing code based on OpenTelemetry ([#9237](https://github.com/mastra-ai/mastra/pull/9237))
|
|
32
|
+
|
|
33
|
+
- Mark as stable ([`83d5942`](https://github.com/mastra-ai/mastra/commit/83d5942669ce7bba4a6ca4fd4da697a10eb5ebdc))
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- Update MainSidebar component to fit required changes in Cloud CTA link ([#9318](https://github.com/mastra-ai/mastra/pull/9318))
|
|
38
|
+
|
|
39
|
+
## 0.17.3
|
|
40
|
+
|
|
41
|
+
## 0.17.3-alpha.0
|
|
42
|
+
|
|
43
|
+
## 0.17.2
|
|
44
|
+
|
|
45
|
+
## 0.17.2-alpha.0
|
|
46
|
+
|
|
47
|
+
## 0.17.1
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- Add scorers to the default weather agent in the create command. ([#9042](https://github.com/mastra-ai/mastra/pull/9042))
|
|
52
|
+
|
|
53
|
+
- Fix tool result in playground ([#9087](https://github.com/mastra-ai/mastra/pull/9087))
|
|
54
|
+
|
|
55
|
+
## 0.17.1-alpha.1
|
|
56
|
+
|
|
57
|
+
### Patch Changes
|
|
58
|
+
|
|
59
|
+
- Add scorers to the default weather agent in the create command. ([#9042](https://github.com/mastra-ai/mastra/pull/9042))
|
|
60
|
+
|
|
61
|
+
- Fix tool result in playground ([#9087](https://github.com/mastra-ai/mastra/pull/9087))
|
|
4
62
|
|
|
5
63
|
## 0.17.1-alpha.0
|
|
6
64
|
|
package/dist/index.js
CHANGED
|
@@ -724,13 +724,18 @@ const format = (open, close) => {
|
|
|
724
724
|
// Handle nested colors.
|
|
725
725
|
|
|
726
726
|
// We could have done this, but it's too slow (as of Node.js 22).
|
|
727
|
-
// return openCode + string.replaceAll(closeCode, openCode) + closeCode;
|
|
727
|
+
// return openCode + string.replaceAll(closeCode, (close === 22 ? closeCode : '') + openCode) + closeCode;
|
|
728
728
|
|
|
729
729
|
let result = openCode;
|
|
730
730
|
let lastIndex = 0;
|
|
731
731
|
|
|
732
|
+
// SGR 22 resets both bold (1) and dim (2). When we encounter a nested
|
|
733
|
+
// close for styles that use 22, we need to re-open the outer style.
|
|
734
|
+
const reopenOnNestedClose = close === 22;
|
|
735
|
+
const replaceCode = (reopenOnNestedClose ? closeCode : '') + openCode;
|
|
736
|
+
|
|
732
737
|
while (index !== -1) {
|
|
733
|
-
result += string.slice(lastIndex, index) +
|
|
738
|
+
result += string.slice(lastIndex, index) + replaceCode;
|
|
734
739
|
lastIndex = index + closeCode.length;
|
|
735
740
|
index = string.indexOf(closeCode, lastIndex);
|
|
736
741
|
}
|
|
@@ -882,6 +887,7 @@ class YoctoSpinner {
|
|
|
882
887
|
#exitHandlerBound;
|
|
883
888
|
#isInteractive;
|
|
884
889
|
#lastSpinnerFrameTime = 0;
|
|
890
|
+
#isSpinning = false;
|
|
885
891
|
|
|
886
892
|
constructor(options = {}) {
|
|
887
893
|
const spinner = options.spinner ?? defaultSpinner;
|
|
@@ -903,13 +909,17 @@ class YoctoSpinner {
|
|
|
903
909
|
return this;
|
|
904
910
|
}
|
|
905
911
|
|
|
912
|
+
this.#isSpinning = true;
|
|
906
913
|
this.#hideCursor();
|
|
907
914
|
this.#render();
|
|
908
915
|
this.#subscribeToProcessEvents();
|
|
909
916
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
917
|
+
// Only start the timer in interactive mode
|
|
918
|
+
if (this.#isInteractive) {
|
|
919
|
+
this.#timer = setInterval(() => {
|
|
920
|
+
this.#render();
|
|
921
|
+
}, this.#interval);
|
|
922
|
+
}
|
|
913
923
|
|
|
914
924
|
return this;
|
|
915
925
|
}
|
|
@@ -919,8 +929,12 @@ class YoctoSpinner {
|
|
|
919
929
|
return this;
|
|
920
930
|
}
|
|
921
931
|
|
|
922
|
-
|
|
923
|
-
this.#timer
|
|
932
|
+
this.#isSpinning = false;
|
|
933
|
+
if (this.#timer) {
|
|
934
|
+
clearInterval(this.#timer);
|
|
935
|
+
this.#timer = undefined;
|
|
936
|
+
}
|
|
937
|
+
|
|
924
938
|
this.#showCursor();
|
|
925
939
|
this.clear();
|
|
926
940
|
this.#unsubscribeFromProcessEvents();
|
|
@@ -953,7 +967,7 @@ class YoctoSpinner {
|
|
|
953
967
|
}
|
|
954
968
|
|
|
955
969
|
get isSpinning() {
|
|
956
|
-
return this.#
|
|
970
|
+
return this.#isSpinning;
|
|
957
971
|
}
|
|
958
972
|
|
|
959
973
|
get text() {
|
|
@@ -1090,11 +1104,11 @@ var MastraLogger = class {
|
|
|
1090
1104
|
}
|
|
1091
1105
|
trackException(_error) {
|
|
1092
1106
|
}
|
|
1093
|
-
async
|
|
1107
|
+
async listLogs(transportId, params) {
|
|
1094
1108
|
if (!transportId || !this.transports.has(transportId)) {
|
|
1095
1109
|
return { logs: [], total: 0, page: params?.page ?? 1, perPage: params?.perPage ?? 100, hasMore: false };
|
|
1096
1110
|
}
|
|
1097
|
-
return this.transports.get(transportId).
|
|
1111
|
+
return this.transports.get(transportId).listLogs(params) ?? {
|
|
1098
1112
|
logs: [],
|
|
1099
1113
|
total: 0,
|
|
1100
1114
|
page: params?.page ?? 1,
|
|
@@ -1102,7 +1116,7 @@ var MastraLogger = class {
|
|
|
1102
1116
|
hasMore: false
|
|
1103
1117
|
};
|
|
1104
1118
|
}
|
|
1105
|
-
async
|
|
1119
|
+
async listLogsByRunId({
|
|
1106
1120
|
transportId,
|
|
1107
1121
|
runId,
|
|
1108
1122
|
fromDate,
|
|
@@ -1115,7 +1129,7 @@ var MastraLogger = class {
|
|
|
1115
1129
|
if (!transportId || !this.transports.has(transportId) || !runId) {
|
|
1116
1130
|
return { logs: [], total: 0, page: page ?? 1, perPage: perPage ?? 100, hasMore: false };
|
|
1117
1131
|
}
|
|
1118
|
-
return this.transports.get(transportId).
|
|
1132
|
+
return this.transports.get(transportId).listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) ?? {
|
|
1119
1133
|
logs: [],
|
|
1120
1134
|
total: 0,
|
|
1121
1135
|
page: page ?? 1,
|
|
@@ -1503,7 +1517,7 @@ var getModelIdentifier = (llmProvider) => {
|
|
|
1503
1517
|
return `'mistral/mistral-medium-2508'`;
|
|
1504
1518
|
}
|
|
1505
1519
|
};
|
|
1506
|
-
async function writeAgentSample(llmProvider, destPath, addExampleTool) {
|
|
1520
|
+
async function writeAgentSample(llmProvider, destPath, addExampleTool, addScorers) {
|
|
1507
1521
|
const modelString = getModelIdentifier(llmProvider);
|
|
1508
1522
|
const instructions = `
|
|
1509
1523
|
You are a helpful weather assistant that provides accurate weather information and can help planning activities based on the weather.
|
|
@@ -1524,14 +1538,40 @@ import { Agent } from '@mastra/core/agent';
|
|
|
1524
1538
|
import { Memory } from '@mastra/memory';
|
|
1525
1539
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1526
1540
|
${addExampleTool ? `import { weatherTool } from '../tools/weather-tool';` : ""}
|
|
1541
|
+
${addScorers ? `import { scorers } from '../scorers/weather-scorer';` : ""}
|
|
1527
1542
|
|
|
1528
1543
|
export const weatherAgent = new Agent({
|
|
1544
|
+
id: 'weather-agent',
|
|
1529
1545
|
name: 'Weather Agent',
|
|
1530
1546
|
instructions: \`${instructions}\`,
|
|
1531
1547
|
model: ${modelString},
|
|
1532
1548
|
${addExampleTool ? "tools: { weatherTool }," : ""}
|
|
1549
|
+
${addScorers ? `scorers: {
|
|
1550
|
+
toolCallAppropriateness: {
|
|
1551
|
+
scorer: scorers.toolCallAppropriatenessScorer,
|
|
1552
|
+
sampling: {
|
|
1553
|
+
type: 'ratio',
|
|
1554
|
+
rate: 1,
|
|
1555
|
+
},
|
|
1556
|
+
},
|
|
1557
|
+
completeness: {
|
|
1558
|
+
scorer: scorers.completenessScorer,
|
|
1559
|
+
sampling: {
|
|
1560
|
+
type: 'ratio',
|
|
1561
|
+
rate: 1,
|
|
1562
|
+
},
|
|
1563
|
+
},
|
|
1564
|
+
translation: {
|
|
1565
|
+
scorer: scorers.translationScorer,
|
|
1566
|
+
sampling: {
|
|
1567
|
+
type: 'ratio',
|
|
1568
|
+
rate: 1,
|
|
1569
|
+
},
|
|
1570
|
+
},
|
|
1571
|
+
},` : ""}
|
|
1533
1572
|
memory: new Memory({
|
|
1534
1573
|
storage: new LibSQLStore({
|
|
1574
|
+
id: "memory-storage",
|
|
1535
1575
|
url: "file:../mastra.db", // path is relative to the .mastra/output directory
|
|
1536
1576
|
})
|
|
1537
1577
|
})
|
|
@@ -1741,14 +1781,109 @@ async function writeToolSample(destPath) {
|
|
|
1741
1781
|
const fileService = new FileService();
|
|
1742
1782
|
await fileService.copyStarterFile("tools.ts", destPath);
|
|
1743
1783
|
}
|
|
1784
|
+
async function writeScorersSample(llmProvider, destPath) {
|
|
1785
|
+
const modelString = getModelIdentifier(llmProvider);
|
|
1786
|
+
const content = `import { z } from 'zod';
|
|
1787
|
+
import { createToolCallAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt';
|
|
1788
|
+
import { createCompletenessScorer } from '@mastra/evals/scorers/prebuilt';
|
|
1789
|
+
import { getAssistantMessageFromRunOutput, getUserMessageFromRunInput } from '@mastra/evals/scorers/utils';
|
|
1790
|
+
import { createScorer } from '@mastra/core/evals';
|
|
1791
|
+
|
|
1792
|
+
export const toolCallAppropriatenessScorer = createToolCallAccuracyScorerCode({
|
|
1793
|
+
expectedTool: 'weatherTool',
|
|
1794
|
+
strictMode: false,
|
|
1795
|
+
});
|
|
1796
|
+
|
|
1797
|
+
export const completenessScorer = createCompletenessScorer();
|
|
1798
|
+
|
|
1799
|
+
// Custom LLM-judged scorer: evaluates if non-English locations are translated appropriately
|
|
1800
|
+
export const translationScorer = createScorer({
|
|
1801
|
+
id: 'translation-quality-scorer',
|
|
1802
|
+
name: 'Translation Quality',
|
|
1803
|
+
description: 'Checks that non-English location names are translated and used correctly',
|
|
1804
|
+
type: 'agent',
|
|
1805
|
+
judge: {
|
|
1806
|
+
model: ${modelString},
|
|
1807
|
+
instructions:
|
|
1808
|
+
'You are an expert evaluator of translation quality for geographic locations. ' +
|
|
1809
|
+
'Determine whether the user text mentions a non-English location and whether the assistant correctly uses an English translation of that location. ' +
|
|
1810
|
+
'Be lenient with transliteration differences and diacritics. ' +
|
|
1811
|
+
'Return only the structured JSON matching the provided schema.',
|
|
1812
|
+
},
|
|
1813
|
+
})
|
|
1814
|
+
.preprocess(({ run }) => {
|
|
1815
|
+
const userText = getUserMessageFromRunInput(run.input) || '';
|
|
1816
|
+
const assistantText = getAssistantMessageFromRunOutput(run.output) || '';
|
|
1817
|
+
return { userText, assistantText };
|
|
1818
|
+
})
|
|
1819
|
+
.analyze({
|
|
1820
|
+
description: 'Extract location names and detect language/translation adequacy',
|
|
1821
|
+
outputSchema: z.object({
|
|
1822
|
+
nonEnglish: z.boolean(),
|
|
1823
|
+
translated: z.boolean(),
|
|
1824
|
+
confidence: z.number().min(0).max(1).default(1),
|
|
1825
|
+
explanation: z.string().default(''),
|
|
1826
|
+
}),
|
|
1827
|
+
createPrompt: ({ results }) => \`
|
|
1828
|
+
You are evaluating if a weather assistant correctly handled translation of a non-English location.
|
|
1829
|
+
User text:
|
|
1830
|
+
"""
|
|
1831
|
+
\${results.preprocessStepResult.userText}
|
|
1832
|
+
"""
|
|
1833
|
+
Assistant response:
|
|
1834
|
+
"""
|
|
1835
|
+
\${results.preprocessStepResult.assistantText}
|
|
1836
|
+
"""
|
|
1837
|
+
Tasks:
|
|
1838
|
+
1) Identify if the user mentioned a location that appears non-English.
|
|
1839
|
+
2) If non-English, check whether the assistant used a correct English translation of that location in its response.
|
|
1840
|
+
3) Be lenient with transliteration differences (e.g., accents/diacritics).
|
|
1841
|
+
Return JSON with fields:
|
|
1842
|
+
{
|
|
1843
|
+
"nonEnglish": boolean,
|
|
1844
|
+
"translated": boolean,
|
|
1845
|
+
"confidence": number, // 0-1
|
|
1846
|
+
"explanation": string
|
|
1847
|
+
}
|
|
1848
|
+
\`,
|
|
1849
|
+
})
|
|
1850
|
+
.generateScore(({ results }) => {
|
|
1851
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1852
|
+
if (!r.nonEnglish) return 1; // If not applicable, full credit
|
|
1853
|
+
if (r.translated) return Math.max(0, Math.min(1, 0.7 + 0.3 * (r.confidence ?? 1)));
|
|
1854
|
+
return 0; // Non-English but not translated
|
|
1855
|
+
})
|
|
1856
|
+
.generateReason(({ results, score }) => {
|
|
1857
|
+
const r = (results as any)?.analyzeStepResult || {};
|
|
1858
|
+
return \`Translation scoring: nonEnglish=\${r.nonEnglish ?? false}, translated=\${r.translated ?? false}, confidence=\${r.confidence ?? 0}. Score=\${score}. \${r.explanation ?? ''}\`;
|
|
1859
|
+
});
|
|
1860
|
+
|
|
1861
|
+
export const scorers = {
|
|
1862
|
+
toolCallAppropriatenessScorer,
|
|
1863
|
+
completenessScorer,
|
|
1864
|
+
translationScorer,
|
|
1865
|
+
};`;
|
|
1866
|
+
const formattedContent = await prettier.format(content, {
|
|
1867
|
+
parser: "typescript",
|
|
1868
|
+
singleQuote: true
|
|
1869
|
+
});
|
|
1870
|
+
await fs4.writeFile(destPath, formattedContent);
|
|
1871
|
+
}
|
|
1744
1872
|
async function writeCodeSampleForComponents(llmprovider, component, destPath, importComponents) {
|
|
1745
1873
|
switch (component) {
|
|
1746
1874
|
case "agents":
|
|
1747
|
-
return writeAgentSample(
|
|
1875
|
+
return writeAgentSample(
|
|
1876
|
+
llmprovider,
|
|
1877
|
+
destPath,
|
|
1878
|
+
importComponents.includes("tools"),
|
|
1879
|
+
importComponents.includes("scorers")
|
|
1880
|
+
);
|
|
1748
1881
|
case "tools":
|
|
1749
1882
|
return writeToolSample(destPath);
|
|
1750
1883
|
case "workflows":
|
|
1751
1884
|
return writeWorkflowSample(destPath);
|
|
1885
|
+
case "scorers":
|
|
1886
|
+
return writeScorersSample(llmprovider, destPath);
|
|
1752
1887
|
default:
|
|
1753
1888
|
return "";
|
|
1754
1889
|
}
|
|
@@ -1761,7 +1896,8 @@ var writeIndexFile = async ({
|
|
|
1761
1896
|
dirPath,
|
|
1762
1897
|
addAgent,
|
|
1763
1898
|
addExample,
|
|
1764
|
-
addWorkflow
|
|
1899
|
+
addWorkflow,
|
|
1900
|
+
addScorers
|
|
1765
1901
|
}) => {
|
|
1766
1902
|
const indexPath = dirPath + "/index.ts";
|
|
1767
1903
|
const destPath = path.join(indexPath);
|
|
@@ -1769,13 +1905,14 @@ var writeIndexFile = async ({
|
|
|
1769
1905
|
await fs4.writeFile(destPath, "");
|
|
1770
1906
|
const filteredExports = [
|
|
1771
1907
|
addWorkflow ? `workflows: { weatherWorkflow },` : "",
|
|
1772
|
-
addAgent ? `agents: { weatherAgent },` : ""
|
|
1908
|
+
addAgent ? `agents: { weatherAgent },` : "",
|
|
1909
|
+
addScorers ? `scorers: { toolCallAppropriatenessScorer, completenessScorer, translationScorer },` : ""
|
|
1773
1910
|
].filter(Boolean);
|
|
1774
1911
|
if (!addExample) {
|
|
1775
1912
|
await fs4.writeFile(
|
|
1776
1913
|
destPath,
|
|
1777
1914
|
`
|
|
1778
|
-
import { Mastra } from '@mastra/core';
|
|
1915
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
1779
1916
|
|
|
1780
1917
|
export const mastra = new Mastra()
|
|
1781
1918
|
`
|
|
@@ -1788,12 +1925,15 @@ export const mastra = new Mastra()
|
|
|
1788
1925
|
import { Mastra } from '@mastra/core/mastra';
|
|
1789
1926
|
import { PinoLogger } from '@mastra/loggers';
|
|
1790
1927
|
import { LibSQLStore } from '@mastra/libsql';
|
|
1928
|
+
import { Observability } from '@mastra/observability';
|
|
1791
1929
|
${addWorkflow ? `import { weatherWorkflow } from './workflows/weather-workflow';` : ""}
|
|
1792
1930
|
${addAgent ? `import { weatherAgent } from './agents/weather-agent';` : ""}
|
|
1931
|
+
${addScorers ? `import { toolCallAppropriatenessScorer, completenessScorer, translationScorer } from './scorers/weather-scorer';` : ""}
|
|
1793
1932
|
|
|
1794
1933
|
export const mastra = new Mastra({
|
|
1795
1934
|
${filteredExports.join("\n ")}
|
|
1796
1935
|
storage: new LibSQLStore({
|
|
1936
|
+
id: "mastra-storage",
|
|
1797
1937
|
// stores observability, scores, ... into memory storage, if it needs to persist, change to file:../mastra.db
|
|
1798
1938
|
url: ":memory:",
|
|
1799
1939
|
}),
|
|
@@ -1801,14 +1941,10 @@ export const mastra = new Mastra({
|
|
|
1801
1941
|
name: 'Mastra',
|
|
1802
1942
|
level: 'info',
|
|
1803
1943
|
}),
|
|
1804
|
-
|
|
1805
|
-
//
|
|
1806
|
-
enabled:
|
|
1807
|
-
|
|
1808
|
-
observability: {
|
|
1809
|
-
// Enables DefaultExporter and CloudExporter for AI tracing
|
|
1810
|
-
default: { enabled: true },
|
|
1811
|
-
},
|
|
1944
|
+
observability: new Observability({
|
|
1945
|
+
// Enables DefaultExporter and CloudExporter for tracing
|
|
1946
|
+
default: { enabled: true },
|
|
1947
|
+
}),
|
|
1812
1948
|
});
|
|
1813
1949
|
`
|
|
1814
1950
|
);
|
|
@@ -1816,7 +1952,6 @@ export const mastra = new Mastra({
|
|
|
1816
1952
|
throw err;
|
|
1817
1953
|
}
|
|
1818
1954
|
};
|
|
1819
|
-
yoctoSpinner({ text: "Installing Mastra core dependencies\n" });
|
|
1820
1955
|
var getAPIKey = async (provider) => {
|
|
1821
1956
|
let key = "OPENAI_API_KEY";
|
|
1822
1957
|
switch (provider) {
|
|
@@ -1960,19 +2095,19 @@ Note: you will need to go into Cursor Settings -> MCP Settings and manually enab
|
|
|
1960
2095
|
);
|
|
1961
2096
|
}
|
|
1962
2097
|
if (editor === `cursor-global`) {
|
|
1963
|
-
const
|
|
2098
|
+
const confirm = await ve({
|
|
1964
2099
|
message: `Global install will add/update ${cursorGlobalMCPConfigPath} and make the Mastra docs MCP server available in all your Cursor projects. Continue?`,
|
|
1965
2100
|
options: [
|
|
1966
2101
|
{ value: "yes", label: "Yes, I understand" },
|
|
1967
2102
|
{ value: "skip", label: "No, skip for now" }
|
|
1968
2103
|
]
|
|
1969
2104
|
});
|
|
1970
|
-
if (
|
|
2105
|
+
if (confirm !== `yes`) {
|
|
1971
2106
|
return void 0;
|
|
1972
2107
|
}
|
|
1973
2108
|
}
|
|
1974
2109
|
if (editor === `windsurf`) {
|
|
1975
|
-
const
|
|
2110
|
+
const confirm = await ve({
|
|
1976
2111
|
message: `Windsurf only supports a global MCP config (at ${windsurfGlobalMCPConfigPath}) is it ok to add/update that global config?
|
|
1977
2112
|
This means the Mastra docs MCP server will be available in all your Windsurf projects.`,
|
|
1978
2113
|
options: [
|
|
@@ -1980,7 +2115,7 @@ This means the Mastra docs MCP server will be available in all your Windsurf pro
|
|
|
1980
2115
|
{ value: "skip", label: "No, skip for now" }
|
|
1981
2116
|
]
|
|
1982
2117
|
});
|
|
1983
|
-
if (
|
|
2118
|
+
if (confirm !== `yes`) {
|
|
1984
2119
|
return void 0;
|
|
1985
2120
|
}
|
|
1986
2121
|
}
|
|
@@ -2030,10 +2165,10 @@ var exec2 = util.promisify(child_process.exec);
|
|
|
2030
2165
|
async function cloneTemplate(options) {
|
|
2031
2166
|
const { template, projectName, targetDir } = options;
|
|
2032
2167
|
const projectPath = targetDir ? path.resolve(targetDir, projectName) : path.resolve(projectName);
|
|
2033
|
-
const
|
|
2168
|
+
const spinner4 = yoctoSpinner({ text: `Cloning template "${template.title}"...` }).start();
|
|
2034
2169
|
try {
|
|
2035
2170
|
if (await directoryExists(projectPath)) {
|
|
2036
|
-
|
|
2171
|
+
spinner4.error(`Directory ${projectName} already exists`);
|
|
2037
2172
|
throw new Error(`Directory ${projectName} already exists`);
|
|
2038
2173
|
}
|
|
2039
2174
|
await cloneRepositoryWithoutGit(template.githubUrl, projectPath);
|
|
@@ -2042,10 +2177,10 @@ async function cloneTemplate(options) {
|
|
|
2042
2177
|
if (await fileExists(envExamplePath)) {
|
|
2043
2178
|
await fs4.copyFile(envExamplePath, path.join(projectPath, ".env"));
|
|
2044
2179
|
}
|
|
2045
|
-
|
|
2180
|
+
spinner4.success(`Template "${template.title}" cloned successfully to ${projectName}`);
|
|
2046
2181
|
return projectPath;
|
|
2047
2182
|
} catch (error) {
|
|
2048
|
-
|
|
2183
|
+
spinner4.error(`Failed to clone template: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2049
2184
|
throw error;
|
|
2050
2185
|
}
|
|
2051
2186
|
}
|
|
@@ -2100,16 +2235,16 @@ async function updatePackageJson(projectPath, projectName) {
|
|
|
2100
2235
|
}
|
|
2101
2236
|
}
|
|
2102
2237
|
async function installDependencies(projectPath, packageManager) {
|
|
2103
|
-
const
|
|
2238
|
+
const spinner4 = yoctoSpinner({ text: "Installing dependencies..." }).start();
|
|
2104
2239
|
try {
|
|
2105
2240
|
const pm = packageManager || getPackageManager();
|
|
2106
2241
|
const installCommand = shellQuote2.quote([pm, "install"]);
|
|
2107
2242
|
await exec2(installCommand, {
|
|
2108
2243
|
cwd: projectPath
|
|
2109
2244
|
});
|
|
2110
|
-
|
|
2245
|
+
spinner4.success("Dependencies installed successfully");
|
|
2111
2246
|
} catch (error) {
|
|
2112
|
-
|
|
2247
|
+
spinner4.error(`Failed to install dependencies: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2113
2248
|
throw error;
|
|
2114
2249
|
}
|
|
2115
2250
|
}
|
|
@@ -2183,9 +2318,11 @@ var init = async ({
|
|
|
2183
2318
|
llmProvider = "openai",
|
|
2184
2319
|
llmApiKey,
|
|
2185
2320
|
addExample = false,
|
|
2186
|
-
configureEditorWithDocsMCP
|
|
2321
|
+
configureEditorWithDocsMCP,
|
|
2322
|
+
versionTag
|
|
2187
2323
|
}) => {
|
|
2188
2324
|
s.start("Initializing Mastra");
|
|
2325
|
+
const packageVersionTag = versionTag ? `@${versionTag}` : "";
|
|
2189
2326
|
try {
|
|
2190
2327
|
const result = await createMastraDir(directory);
|
|
2191
2328
|
if (!result.ok) {
|
|
@@ -2198,7 +2335,8 @@ var init = async ({
|
|
|
2198
2335
|
dirPath,
|
|
2199
2336
|
addExample,
|
|
2200
2337
|
addWorkflow: components.includes("workflows"),
|
|
2201
|
-
addAgent: components.includes("agents")
|
|
2338
|
+
addAgent: components.includes("agents"),
|
|
2339
|
+
addScorers: components.includes("scorers")
|
|
2202
2340
|
}),
|
|
2203
2341
|
...components.map((component) => createComponentsDir(dirPath, component)),
|
|
2204
2342
|
writeAPIKey({ provider: llmProvider, apiKey: llmApiKey })
|
|
@@ -2212,15 +2350,23 @@ var init = async ({
|
|
|
2212
2350
|
const depService = new DepsService();
|
|
2213
2351
|
const needsLibsql = await depService.checkDependencies(["@mastra/libsql"]) !== `ok`;
|
|
2214
2352
|
if (needsLibsql) {
|
|
2215
|
-
await depService.installPackages([
|
|
2353
|
+
await depService.installPackages([`@mastra/libsql${packageVersionTag}`]);
|
|
2216
2354
|
}
|
|
2217
2355
|
const needsMemory = components.includes(`agents`) && await depService.checkDependencies(["@mastra/memory"]) !== `ok`;
|
|
2218
2356
|
if (needsMemory) {
|
|
2219
|
-
await depService.installPackages([
|
|
2357
|
+
await depService.installPackages([`@mastra/memory${packageVersionTag}`]);
|
|
2220
2358
|
}
|
|
2221
2359
|
const needsLoggers = await depService.checkDependencies(["@mastra/loggers"]) !== `ok`;
|
|
2222
2360
|
if (needsLoggers) {
|
|
2223
|
-
await depService.installPackages([
|
|
2361
|
+
await depService.installPackages([`@mastra/loggers${packageVersionTag}`]);
|
|
2362
|
+
}
|
|
2363
|
+
const needsObservability = await depService.checkDependencies(["@mastra/observability"]) !== `ok`;
|
|
2364
|
+
if (needsObservability) {
|
|
2365
|
+
await depService.installPackages([`@mastra/observability${packageVersionTag}`]);
|
|
2366
|
+
}
|
|
2367
|
+
const needsEvals = components.includes(`scorers`) && await depService.checkDependencies(["@mastra/evals"]) !== `ok`;
|
|
2368
|
+
if (needsEvals) {
|
|
2369
|
+
await depService.installPackages([`@mastra/evals${packageVersionTag}`]);
|
|
2224
2370
|
}
|
|
2225
2371
|
}
|
|
2226
2372
|
const key = await getAPIKey(llmProvider || "openai");
|
|
@@ -2366,7 +2512,7 @@ var createMastraProject = async ({
|
|
|
2366
2512
|
s2.start(`Installing ${pm} dependencies`);
|
|
2367
2513
|
try {
|
|
2368
2514
|
await exec3(`${pm} ${installCommand} zod@^4`);
|
|
2369
|
-
await exec3(`${pm} ${installCommand} typescript @types/node
|
|
2515
|
+
await exec3(`${pm} ${installCommand} -D typescript @types/node`);
|
|
2370
2516
|
await exec3(`echo '{
|
|
2371
2517
|
"compilerOptions": {
|
|
2372
2518
|
"target": "ES2022",
|
|
@@ -2451,8 +2597,9 @@ var create = async (args2) => {
|
|
|
2451
2597
|
await init({
|
|
2452
2598
|
...result,
|
|
2453
2599
|
llmApiKey: result?.llmApiKey,
|
|
2454
|
-
components: ["agents", "tools", "workflows"],
|
|
2455
|
-
addExample: true
|
|
2600
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2601
|
+
addExample: true,
|
|
2602
|
+
versionTag: args2.createVersionTag
|
|
2456
2603
|
});
|
|
2457
2604
|
postCreate({ projectName });
|
|
2458
2605
|
return;
|
|
@@ -2464,7 +2611,8 @@ var create = async (args2) => {
|
|
|
2464
2611
|
llmProvider,
|
|
2465
2612
|
addExample,
|
|
2466
2613
|
llmApiKey,
|
|
2467
|
-
configureEditorWithDocsMCP: args2.mcpServer
|
|
2614
|
+
configureEditorWithDocsMCP: args2.mcpServer,
|
|
2615
|
+
versionTag: args2.createVersionTag
|
|
2468
2616
|
});
|
|
2469
2617
|
postCreate({ projectName });
|
|
2470
2618
|
};
|
|
@@ -2567,16 +2715,16 @@ async function createFromTemplate(args2) {
|
|
|
2567
2715
|
selectedTemplate = selected;
|
|
2568
2716
|
} else if (args2.template && typeof args2.template === "string") {
|
|
2569
2717
|
if (isGitHubUrl(args2.template)) {
|
|
2570
|
-
const
|
|
2571
|
-
|
|
2718
|
+
const spinner4 = Y();
|
|
2719
|
+
spinner4.start("Validating GitHub repository...");
|
|
2572
2720
|
const validation = await validateGitHubProject(args2.template);
|
|
2573
2721
|
if (!validation.isValid) {
|
|
2574
|
-
|
|
2722
|
+
spinner4.stop("Validation failed");
|
|
2575
2723
|
M.error("This does not appear to be a valid Mastra project:");
|
|
2576
2724
|
validation.errors.forEach((error) => M.error(` - ${error}`));
|
|
2577
2725
|
throw new Error("Invalid Mastra project");
|
|
2578
2726
|
}
|
|
2579
|
-
|
|
2727
|
+
spinner4.stop("Valid Mastra project \u2713");
|
|
2580
2728
|
selectedTemplate = await createFromGitHubUrl(args2.template);
|
|
2581
2729
|
} else {
|
|
2582
2730
|
const templates = await loadTemplates();
|
|
@@ -2673,7 +2821,7 @@ program.version(`${version}`, "-v, --version").description(`create-mastra ${vers
|
|
|
2673
2821
|
program.name("create-mastra").description("Create a new Mastra project").argument("[project-name]", "Directory name of the project").option(
|
|
2674
2822
|
"-p, --project-name <string>",
|
|
2675
2823
|
"Project name that will be used in package.json and as the project directory name."
|
|
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(
|
|
2824
|
+
).option("--default", "Quick start with defaults (src, OpenAI, examples)").option("-c, --components <components>", "Comma-separated list of components (agents, tools, workflows, scorers)").option("-l, --llm <model-provider>", "Default model provider (openai, anthropic, groq, google, or cerebras)").option("-k, --llm-api-key <api-key>", "API key for the model provider").option("-e, --example", "Include example code").option("-n, --no-example", "Do not include example code").option("-t, --timeout [timeout]", "Configurable timeout for package installation, defaults to 60000 ms").option("-d, --dir <directory>", "Target directory for Mastra source code (default: src/)").option("-m, --mcp <mcp>", "MCP Server for code editor (cursor, cursor-global, windsurf, vscode)").option(
|
|
2677
2825
|
"--template [template-name]",
|
|
2678
2826
|
"Create project from a template (use template name, public GitHub URL, or leave blank to select from list)"
|
|
2679
2827
|
).action(async (projectNameArg, args) => {
|
|
@@ -2681,7 +2829,7 @@ program.name("create-mastra").description("Create a new Mastra project").argumen
|
|
|
2681
2829
|
const timeout = args?.timeout ? args?.timeout === true ? 6e4 : parseInt(args?.timeout, 10) : void 0;
|
|
2682
2830
|
if (args.default) {
|
|
2683
2831
|
await create({
|
|
2684
|
-
components: ["agents", "tools", "workflows"],
|
|
2832
|
+
components: ["agents", "tools", "workflows", "scorers"],
|
|
2685
2833
|
llmProvider: "openai",
|
|
2686
2834
|
addExample: true,
|
|
2687
2835
|
createVersionTag,
|