mastra-starter 1.0.9 → 1.0.10

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.
@@ -8,7 +8,10 @@
8
8
  "model": "en_US-male-medium"
9
9
  }
10
10
  },
11
- "plugins": ["github:qpd-v/mcp-communicator-telegram"],
11
+ "plugins": [
12
+ "github:v-3/discordmcp",
13
+ "github:qpd-v/mcp-communicator-telegram"
14
+ ],
12
15
  "bio": [
13
16
  "Just a chill guy living life to the fullest",
14
17
  "Always down to help others out",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mastra-starter",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "main": "index.mjs",
5
5
  "bin": {
6
6
  "mastra-starter": "./index.mjs"
@@ -15,13 +15,13 @@
15
15
  "type": "module",
16
16
  "dependencies": {
17
17
  "@ai-sdk/openai": "^1.2.2",
18
- "@mastra/composio": "^0.1.9",
19
- "@mastra/core": "^0.6.0",
20
- "@mastra/mcp": "^0.3.0",
18
+ "@mastra/composio": "^0.1.12",
19
+ "@mastra/core": "^0.6.3",
20
+ "@mastra/mcp": "^0.3.4",
21
21
  "commander": "^13.1.0",
22
22
  "dedent": "^1.5.3",
23
23
  "dotenv": "^16.4.7",
24
- "mastra": "^0.3.0",
24
+ "mastra": "^0.3.1",
25
25
  "mkdirp": "^3.0.1",
26
26
  "pnpm-package-lookup": "^0.0.2",
27
27
  "rimraf": "^6.0.1",
@@ -3,7 +3,7 @@ import path from "path";
3
3
  import { createOpenAI } from "@ai-sdk/openai";
4
4
  import { Agent, ToolsInput } from "@mastra/core/agent";
5
5
  import dedent from "dedent";
6
- import { PnpmPackageLookup } from 'pnpm-package-lookup';
6
+ import { PnpmPackageLookup } from "pnpm-package-lookup";
7
7
  import { MCPConfiguration } from "@mastra/mcp";
8
8
  import { ComposioIntegration } from "@mastra/composio";
9
9
  import { sortPlugins, getNpmPackageType } from "../../../util.mjs";
@@ -33,31 +33,44 @@ for (const pluginSpecifier of npmPlugins) {
33
33
  let pluginSpecifier2;
34
34
  const packagesDir = path.resolve(rootDir, "packages");
35
35
  if (npmPackageType === "github") {
36
- const packageBasename = path.basename(pluginSpecifier.replace("github:", ""));
36
+ const packageBasename = path.basename(
37
+ pluginSpecifier.replace("github:", "")
38
+ );
37
39
  const packageResolvedName = `file:${path.resolve(packagesDir, packageBasename)}`;
38
- pluginSpecifier2 = await pnpmPackageLookup.getPackageNameBySpecifier(packageResolvedName);
40
+ pluginSpecifier2 =
41
+ await pnpmPackageLookup.getPackageNameBySpecifier(packageResolvedName);
39
42
  if (!pluginSpecifier2) {
40
- throw new Error(`Could not resolve package name for ${JSON.stringify({
41
- pluginSpecifier,
42
- packageBasename,
43
- packageResolvedName,
44
- }, null, 2)}`);
43
+ throw new Error(
44
+ `Could not resolve package name for ${JSON.stringify(
45
+ {
46
+ pluginSpecifier,
47
+ packageBasename,
48
+ packageResolvedName,
49
+ },
50
+ null,
51
+ 2
52
+ )}`
53
+ );
45
54
  }
46
55
  } else {
47
56
  pluginSpecifier2 = pluginSpecifier;
48
57
  }
49
58
  const packagePath = path.resolve(rootDir, "node_modules", pluginSpecifier2);
50
- // console.log('packagePath', {
51
- // pluginSpecifier,
52
- // pluginSpecifier2,
53
- // packagePath,
54
- // });
55
-
56
59
  // check if start script exists
57
60
  const packageJsonPath = path.resolve(packagePath, "package.json");
58
- const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, "utf8"));
61
+ const packageJson = JSON.parse(
62
+ await fs.promises.readFile(packageJsonPath, "utf8")
63
+ );
64
+ const pluginName =
65
+ pluginSpecifier
66
+ // .replace(/^github:/, "")
67
+ .replace(/[\/:]+/g, "-")
68
+ .replace(/[^a-zA-Z0-9_-]/g, "");
69
+ if (!pluginName) {
70
+ throw new Error(`Could not clean up plugin name for ${pluginSpecifier}`);
71
+ }
59
72
  if (packageJson.scripts.start) {
60
- servers[pluginSpecifier] = {
73
+ servers[pluginName] = {
61
74
  command: "pnpm",
62
75
  args: ["--dir", packagePath, "--silent", "start"],
63
76
  env: process.env as any,
@@ -66,17 +79,18 @@ for (const pluginSpecifier of npmPlugins) {
66
79
  // check if any bins exist; if so, use the first one
67
80
  if (packageJson.bin && Object.keys(packageJson.bin).length > 0) {
68
81
  const firstBin = Object.keys(packageJson.bin)[0];
69
- servers[pluginSpecifier] = {
82
+ servers[pluginName] = {
70
83
  command: "pnpm",
71
84
  args: ["--dir", packagePath, "--silent", "exec", firstBin],
72
85
  env: process.env as any,
73
86
  };
74
87
  } else {
75
- throw new Error(`No start script or bins found for ${pluginSpecifier}`);
88
+ throw new Error(
89
+ `No start script or bins found for ${pluginSpecifier} name ${pluginName}`
90
+ );
76
91
  }
77
92
  }
78
93
  }
79
- // console.log('servers', servers);
80
94
 
81
95
  // mcp tools
82
96
  const mcp = new MCPConfiguration({
package/util.mjs CHANGED
@@ -81,8 +81,11 @@ export const sortNpmPackages = (packageSpecifiers) => {
81
81
  const installNpmGithubPackages = async (packageSpecifiers) => {
82
82
  console.log(`Installing github packages: ${packageSpecifiers.join(", ")}`);
83
83
 
84
- // Ensure packages directory exists
84
+ // wipe packages directory
85
85
  const packagesDir = path.resolve(process.cwd(), "packages");
86
+ await rimraf(packagesDir);
87
+
88
+ // Ensure packages directory exists
86
89
  try {
87
90
  await mkdirp(packagesDir);
88
91
  } catch (error) {
@@ -90,130 +93,151 @@ const installNpmGithubPackages = async (packageSpecifiers) => {
90
93
  return Promise.reject(error);
91
94
  }
92
95
 
93
- // remove conflicting package directories
94
- const existingPackageNames = await fs.promises.readdir(packagesDir);
95
- for (const packageName of existingPackageNames) {
96
- const packagePath = path.resolve(packagesDir, packageName);
97
- await rimraf(packagePath);
98
- }
96
+ // Transform package specifiers to GitHub URLs
97
+ const repoNames = packageSpecifiers.map((specifier) => {
98
+ specifier = specifier.replace("github:", "");
99
+ specifier = `https://github.com/${specifier}`;
100
+ return specifier;
101
+ });
99
102
 
100
103
  // git clone all packages
101
- await new Promise((resolve, reject) => {
102
- const repoNames = packageSpecifiers.map((specifier) => {
103
- specifier = specifier.replace("github:", "");
104
- specifier = `https://github.com/${specifier}`;
105
- return specifier;
106
- });
107
- const cp = child_process.spawn(
108
- "git",
109
- ["clone", "--depth", "1", ...repoNames],
110
- {
111
- stdio: "inherit",
112
- cwd: packagesDir,
113
- }
114
- );
115
-
116
- cp.on("error", (error) => {
117
- console.error(`Error executing git clone: ${error.stack}`);
118
- reject(error);
119
- });
120
-
121
- cp.on("close", (code) => {
122
- if (code !== 0) {
123
- console.error(`git clone exited with code ${code}`);
124
- reject(new Error(`git clone exited with code ${code}`));
125
- } else {
126
- resolve();
127
- }
128
- });
129
- });
104
+ await Promise.all(
105
+ repoNames.map(async (repoUrl) => {
106
+ return new Promise((resolveClone, rejectClone) => {
107
+ console.log(`Cloning ${repoUrl}...`);
108
+ const cp = child_process.spawn(
109
+ "git",
110
+ ["clone", "--depth", "1", repoUrl],
111
+ {
112
+ stdio: "inherit",
113
+ cwd: packagesDir,
114
+ }
115
+ );
130
116
 
131
- // pnpm install in local directory
132
- await Promise.all(packageSpecifiers.map(async (packageSpecifier) => {
133
- const packageBasename = path.basename(packageSpecifier.replace("github:", ""));
134
- const packagePath = path.resolve(packagesDir, packageBasename);
117
+ cp.on("error", (error) => {
118
+ console.error(
119
+ `Error executing git clone for ${repoUrl}: ${error.stack}`
120
+ );
121
+ rejectClone(error);
122
+ });
135
123
 
136
- await new Promise((resolveInstall, rejectInstall) => {
137
- const cp = child_process.spawn("pnpm", ["install"], {
138
- stdio: "inherit",
139
- cwd: packagePath,
140
- env: { ...process.env },
124
+ cp.on("close", (code) => {
125
+ if (code !== 0) {
126
+ console.error(`git clone for ${repoUrl} exited with code ${code}`);
127
+ rejectClone(new Error(`git clone exited with code ${code}`));
128
+ } else {
129
+ console.log(`Successfully cloned ${repoUrl}`);
130
+ resolveClone();
131
+ }
132
+ });
141
133
  });
134
+ })
135
+ );
142
136
 
143
- cp.on("error", (error) => {
144
- console.error(
145
- `Error executing pnpm install for ${packageBasename}: ${error.stack}`
146
- );
147
- rejectInstall(error);
148
- });
149
- cp.on("close", (code) => {
150
- if (code !== 0) {
151
- rejectInstall(new Error(`pnpm install exited with code ${code}`));
152
- } else {
153
- resolveInstall();
154
- }
155
- });
156
- });
137
+ // build and install all plugins into local packages
138
+ await Promise.all(
139
+ packageSpecifiers.map(async (packageSpecifier) => {
140
+ const packageBasename = path.basename(
141
+ packageSpecifier.replace("github:", "")
142
+ );
143
+ const packagePath = path.resolve(packagesDir, packageBasename);
144
+
145
+ // pnpm install in local directory
146
+ await new Promise((resolveInstall, rejectInstall) => {
147
+ const cp = child_process.spawn("pnpm", ["install"], {
148
+ stdio: "inherit",
149
+ cwd: packagePath,
150
+ env: { ...process.env },
151
+ });
157
152
 
158
- // pnpm build
159
- // note: this is advisory and allowed to fail
160
- await new Promise((resolveSpawn, rejectSpawn) => {
161
- const cp = child_process.spawn("pnpm", ["build"], {
162
- stdio: "inherit",
163
- cwd: packagePath,
164
- env: { ...process.env },
153
+ cp.on("error", (error) => {
154
+ console.error(
155
+ `Error executing pnpm install for ${packageBasename}: ${error.stack}`
156
+ );
157
+ rejectInstall(error);
158
+ });
159
+ cp.on("close", (code) => {
160
+ if (code !== 0) {
161
+ rejectInstall(new Error(`pnpm install exited with code ${code}`));
162
+ } else {
163
+ resolveInstall();
164
+ }
165
+ });
165
166
  });
166
167
 
167
- cp.on("error", (error) => {
168
- console.error(
169
- `Error executing pnpm build for ${packageBasename}: ${error.stack}`
170
- );
171
- resolveSpawn({
172
- success: false,
173
- package: packageBasename,
174
- error: error.stack,
168
+ // pnpm build
169
+ // note: this is advisory and allowed to fail
170
+ await new Promise((resolveSpawn, rejectSpawn) => {
171
+ const cp = child_process.spawn("pnpm", ["build"], {
172
+ stdio: "inherit",
173
+ cwd: packagePath,
174
+ env: { ...process.env },
175
175
  });
176
- });
177
- cp.on("close", (code) => {
178
- if (code !== 0) {
176
+
177
+ cp.on("error", (error) => {
179
178
  console.error(
180
- `pnpm build for ${packageBasename} exited with code ${code}`
179
+ `Error executing pnpm build for ${packageBasename}: ${error.stack}`
181
180
  );
182
181
  resolveSpawn({
183
182
  success: false,
184
183
  package: packageBasename,
185
- error: `exited with code ${code}`,
184
+ error: error.stack,
186
185
  });
187
- } else {
188
- console.log(`Build completed successfully for ${packageBasename}`);
189
- resolveSpawn({ success: true, package: packageBasename });
190
- }
186
+ });
187
+ cp.on("close", (code) => {
188
+ if (code !== 0) {
189
+ console.error(
190
+ `pnpm build for ${packageBasename} exited with code ${code}`
191
+ );
192
+ resolveSpawn({
193
+ success: false,
194
+ package: packageBasename,
195
+ error: `exited with code ${code}`,
196
+ });
197
+ } else {
198
+ console.log(`Build completed successfully for ${packageBasename}`);
199
+ resolveSpawn({ success: true, package: packageBasename });
200
+ }
201
+ });
191
202
  });
192
- });
203
+ })
204
+ );
193
205
 
194
- // pnpm install to app
195
- await new Promise((resolveInstall, rejectInstall) => {
196
- const cp = child_process.spawn("pnpm", ["install", `file:${packagePath}`], {
206
+ // install all plugins into app
207
+ // pnpm install to app
208
+ await new Promise((resolveInstall, rejectInstall) => {
209
+ const packageRefs = packageSpecifiers.map((packageSpecifier) => {
210
+ const packageBasename = path.basename(
211
+ packageSpecifier.replace("github:", "")
212
+ );
213
+ const packagePath = path.resolve(packagesDir, packageBasename);
214
+ return `file:${packagePath}`;
215
+ });
216
+ console.log(`Installing ${JSON.stringify(packageRefs)} to app`);
217
+ const cp = child_process.spawn(
218
+ "pnpm",
219
+ ["install", ...packageRefs],
220
+ {
197
221
  stdio: "inherit",
198
222
  cwd: process.cwd(),
199
223
  env: { ...process.env },
200
- });
224
+ }
225
+ );
201
226
 
202
- cp.on("error", (error) => {
203
- console.error(
204
- `Error executing pnpm install for ${packageBasename}: ${error.stack}`
205
- );
206
- rejectInstall(error);
207
- });
208
- cp.on("close", (code) => {
209
- if (code !== 0) {
210
- rejectInstall(new Error(`pnpm install exited with code ${code}`));
211
- } else {
212
- resolveInstall();
213
- }
214
- });
227
+ cp.on("error", (error) => {
228
+ console.error(
229
+ `Error executing pnpm install for ${packageBasename}: ${error.stack}`
230
+ );
231
+ rejectInstall(error);
232
+ });
233
+ cp.on("close", (code) => {
234
+ if (code !== 0) {
235
+ rejectInstall(new Error(`pnpm install exited with code ${code}`));
236
+ } else {
237
+ resolveInstall();
238
+ }
215
239
  });
216
- }));
240
+ });
217
241
  };
218
242
  const installNpmBasicPackages = async (packageSpecifiers) => {
219
243
  // packageSpecifiers = uniquify(packageSpecifiers);
@@ -244,6 +268,6 @@ export const installNpmPackages = async (packageSpecifiers) => {
244
268
  const { github, npm } = sortNpmPackages(packageSpecifiers);
245
269
  await Promise.all([
246
270
  installNpmGithubPackages(github),
247
- installNpmBasicPackages(npm)
271
+ installNpmBasicPackages(npm),
248
272
  ]);
249
- };
273
+ };
@@ -1,23 +0,0 @@
1
- export const getPluginType = (plugin: string) => {
2
- if (plugin.startsWith('composio:')) {
3
- return 'composio';
4
- } else {
5
- return 'npm';
6
- }
7
- };
8
- export const sortPlugins = (plugins: string[]) => {
9
- const npm: string[] = [];
10
- const composio: string[] = [];
11
- for (const plugin of plugins) {
12
- const pluginType = getPluginType(plugin);
13
- if (pluginType === 'npm') {
14
- npm.push(plugin);
15
- } else if (pluginType === 'composio') {
16
- composio.push(plugin);
17
- }
18
- }
19
- return {
20
- npm,
21
- composio,
22
- };
23
- };
@@ -1,102 +0,0 @@
1
- import { createTool } from '@mastra/core/tools';
2
- import { z } from 'zod';
3
-
4
- interface GeocodingResponse {
5
- results: {
6
- latitude: number;
7
- longitude: number;
8
- name: string;
9
- }[];
10
- }
11
- interface WeatherResponse {
12
- current: {
13
- time: string;
14
- temperature_2m: number;
15
- apparent_temperature: number;
16
- relative_humidity_2m: number;
17
- wind_speed_10m: number;
18
- wind_gusts_10m: number;
19
- weather_code: number;
20
- };
21
- }
22
-
23
- export const weatherTool = createTool({
24
- id: 'get-weather',
25
- description: 'Get current weather for a location',
26
- inputSchema: z.object({
27
- location: z.string().describe('City name'),
28
- }),
29
- outputSchema: z.object({
30
- temperature: z.number(),
31
- feelsLike: z.number(),
32
- humidity: z.number(),
33
- windSpeed: z.number(),
34
- windGust: z.number(),
35
- conditions: z.string(),
36
- location: z.string(),
37
- }),
38
- execute: async ({ context }) => {
39
- return await getWeather(context.location);
40
- },
41
- });
42
-
43
- const getWeather = async (location: string) => {
44
- const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(location)}&count=1`;
45
- const geocodingResponse = await fetch(geocodingUrl);
46
- const geocodingData = (await geocodingResponse.json()) as GeocodingResponse;
47
-
48
- if (!geocodingData.results?.[0]) {
49
- throw new Error(`Location '${location}' not found`);
50
- }
51
-
52
- const { latitude, longitude, name } = geocodingData.results[0];
53
-
54
- const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&current=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_gusts_10m,weather_code`;
55
-
56
- const response = await fetch(weatherUrl);
57
- const data = (await response.json()) as WeatherResponse;
58
-
59
- return {
60
- temperature: data.current.temperature_2m,
61
- feelsLike: data.current.apparent_temperature,
62
- humidity: data.current.relative_humidity_2m,
63
- windSpeed: data.current.wind_speed_10m,
64
- windGust: data.current.wind_gusts_10m,
65
- conditions: getWeatherCondition(data.current.weather_code),
66
- location: name,
67
- };
68
- };
69
-
70
- function getWeatherCondition(code: number): string {
71
- const conditions: Record<number, string> = {
72
- 0: 'Clear sky',
73
- 1: 'Mainly clear',
74
- 2: 'Partly cloudy',
75
- 3: 'Overcast',
76
- 45: 'Foggy',
77
- 48: 'Depositing rime fog',
78
- 51: 'Light drizzle',
79
- 53: 'Moderate drizzle',
80
- 55: 'Dense drizzle',
81
- 56: 'Light freezing drizzle',
82
- 57: 'Dense freezing drizzle',
83
- 61: 'Slight rain',
84
- 63: 'Moderate rain',
85
- 65: 'Heavy rain',
86
- 66: 'Light freezing rain',
87
- 67: 'Heavy freezing rain',
88
- 71: 'Slight snow fall',
89
- 73: 'Moderate snow fall',
90
- 75: 'Heavy snow fall',
91
- 77: 'Snow grains',
92
- 80: 'Slight rain showers',
93
- 81: 'Moderate rain showers',
94
- 82: 'Violent rain showers',
95
- 85: 'Slight snow showers',
96
- 86: 'Heavy snow showers',
97
- 95: 'Thunderstorm',
98
- 96: 'Thunderstorm with slight hail',
99
- 99: 'Thunderstorm with heavy hail',
100
- };
101
- return conditions[code] || 'Unknown';
102
- }
package/util.d.ts DELETED
@@ -1 +0,0 @@
1
- declare module "util.mjs";