@mastra/agent-builder 0.0.1-alpha.1 → 0.0.1-alpha.3

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/agent/index.d.ts +5885 -0
  3. package/dist/agent/index.d.ts.map +1 -0
  4. package/dist/defaults.d.ts +6529 -0
  5. package/dist/defaults.d.ts.map +1 -0
  6. package/dist/index.d.ts +4 -4
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +1810 -36
  9. package/dist/index.js.map +1 -0
  10. package/dist/processors/tool-summary.d.ts +29 -0
  11. package/dist/processors/tool-summary.d.ts.map +1 -0
  12. package/dist/processors/write-file.d.ts +10 -0
  13. package/dist/processors/write-file.d.ts.map +1 -0
  14. package/dist/types.d.ts +1121 -0
  15. package/dist/types.d.ts.map +1 -0
  16. package/dist/utils.d.ts +63 -0
  17. package/dist/utils.d.ts.map +1 -0
  18. package/dist/workflows/index.d.ts +5 -0
  19. package/dist/workflows/index.d.ts.map +1 -0
  20. package/dist/workflows/shared/schema.d.ts +139 -0
  21. package/dist/workflows/shared/schema.d.ts.map +1 -0
  22. package/dist/workflows/task-planning/prompts.d.ts +37 -0
  23. package/dist/workflows/task-planning/prompts.d.ts.map +1 -0
  24. package/dist/workflows/task-planning/schema.d.ts +548 -0
  25. package/dist/workflows/task-planning/schema.d.ts.map +1 -0
  26. package/dist/workflows/task-planning/task-planning.d.ts +992 -0
  27. package/dist/workflows/task-planning/task-planning.d.ts.map +1 -0
  28. package/dist/workflows/template-builder/template-builder.d.ts +1910 -0
  29. package/dist/workflows/template-builder/template-builder.d.ts.map +1 -0
  30. package/dist/workflows/workflow-builder/prompts.d.ts +44 -0
  31. package/dist/workflows/workflow-builder/prompts.d.ts.map +1 -0
  32. package/dist/workflows/workflow-builder/schema.d.ts +1170 -0
  33. package/dist/workflows/workflow-builder/schema.d.ts.map +1 -0
  34. package/dist/workflows/workflow-builder/tools.d.ts +309 -0
  35. package/dist/workflows/workflow-builder/tools.d.ts.map +1 -0
  36. package/dist/workflows/workflow-builder/workflow-builder.d.ts +2714 -0
  37. package/dist/workflows/workflow-builder/workflow-builder.d.ts.map +1 -0
  38. package/dist/workflows/workflow-map.d.ts +3735 -0
  39. package/dist/workflows/workflow-map.d.ts.map +1 -0
  40. package/package.json +29 -9
  41. package/.turbo/turbo-build.log +0 -12
  42. package/dist/_tsup-dts-rollup.d.cts +0 -14933
  43. package/dist/_tsup-dts-rollup.d.ts +0 -14933
  44. package/dist/index.cjs +0 -4357
  45. package/dist/index.d.cts +0 -4
  46. package/eslint.config.js +0 -11
  47. package/integration-tests/CHANGELOG.md +0 -9
  48. package/integration-tests/README.md +0 -154
  49. package/integration-tests/docker-compose.yml +0 -39
  50. package/integration-tests/package.json +0 -38
  51. package/integration-tests/src/agent-template-behavior.test.ts +0 -103
  52. package/integration-tests/src/fixtures/minimal-mastra-project/env.example +0 -6
  53. package/integration-tests/src/fixtures/minimal-mastra-project/package.json +0 -17
  54. package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/agents/weather.ts +0 -34
  55. package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/index.ts +0 -15
  56. package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/mcp/index.ts +0 -46
  57. package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/tools/weather.ts +0 -14
  58. package/integration-tests/src/fixtures/minimal-mastra-project/tsconfig.json +0 -17
  59. package/integration-tests/src/template-integration.test.ts +0 -312
  60. package/integration-tests/tsconfig.json +0 -9
  61. package/integration-tests/vitest.config.ts +0 -18
  62. package/src/agent/index.ts +0 -187
  63. package/src/agent-builder.test.ts +0 -313
  64. package/src/defaults.ts +0 -2876
  65. package/src/index.ts +0 -3
  66. package/src/processors/tool-summary.ts +0 -145
  67. package/src/processors/write-file.ts +0 -17
  68. package/src/types.ts +0 -305
  69. package/src/utils.ts +0 -409
  70. package/src/workflows/index.ts +0 -1
  71. package/src/workflows/template-builder.ts +0 -1682
  72. package/tsconfig.json +0 -5
  73. package/vitest.config.ts +0 -11
package/src/utils.ts DELETED
@@ -1,409 +0,0 @@
1
- import { exec as execNodejs, execFile as execFileNodejs, spawn as nodeSpawn } from 'child_process';
2
- import type { SpawnOptions } from 'child_process';
3
- import { existsSync, readFileSync } from 'fs';
4
- import { copyFile } from 'fs/promises';
5
- import { createRequire } from 'module';
6
- import { dirname, basename, extname, resolve } from 'path';
7
- import { promisify } from 'util';
8
- import { UNIT_KINDS } from './types';
9
- import type { UnitKind } from './types';
10
-
11
- export const exec = promisify(execNodejs);
12
- export const execFile = promisify(execFileNodejs);
13
-
14
- // Helper function to detect if we're in a workspace subfolder
15
- function isInWorkspaceSubfolder(cwd: string): boolean {
16
- try {
17
- // First, check if current directory has package.json (it's a package)
18
- const currentPackageJson = resolve(cwd, 'package.json');
19
- if (!existsSync(currentPackageJson)) {
20
- return false; // Not a package, so not a workspace subfolder
21
- }
22
-
23
- // Walk up the directory tree looking for workspace indicators
24
- let currentDir = cwd;
25
- let previousDir = '';
26
-
27
- // Keep going up until we reach the filesystem root or stop making progress
28
- while (currentDir !== previousDir && currentDir !== '/') {
29
- previousDir = currentDir;
30
- currentDir = dirname(currentDir);
31
-
32
- // Skip if we're back at the original directory
33
- if (currentDir === cwd) {
34
- continue;
35
- }
36
-
37
- console.log(`Checking for workspace indicators in: ${currentDir}`);
38
-
39
- // Check for pnpm workspace
40
- if (existsSync(resolve(currentDir, 'pnpm-workspace.yaml'))) {
41
- return true;
42
- }
43
-
44
- // Check for npm/yarn workspaces in package.json
45
- const parentPackageJson = resolve(currentDir, 'package.json');
46
- if (existsSync(parentPackageJson)) {
47
- try {
48
- const parentPkg = JSON.parse(readFileSync(parentPackageJson, 'utf-8'));
49
- if (parentPkg.workspaces) {
50
- return true; // Found workspace config
51
- }
52
- } catch {
53
- // Ignore JSON parse errors
54
- }
55
- }
56
-
57
- // Check for lerna
58
- if (existsSync(resolve(currentDir, 'lerna.json'))) {
59
- return true;
60
- }
61
- }
62
-
63
- return false;
64
- } catch (error) {
65
- console.log(`Error in workspace detection: ${error}`);
66
- return false; // Default to false on any error
67
- }
68
- }
69
-
70
- export function spawn(command: string, args: string[], options: any) {
71
- return new Promise((resolve, reject) => {
72
- const childProcess = nodeSpawn(command, args, {
73
- stdio: 'inherit', // Enable proper stdio handling
74
- ...options,
75
- });
76
- childProcess.on('error', error => {
77
- reject(error);
78
- });
79
- childProcess.on('close', code => {
80
- if (code === 0) {
81
- resolve(void 0);
82
- } else {
83
- reject(new Error(`Command failed with exit code ${code}`));
84
- }
85
- });
86
- });
87
- }
88
-
89
- // --- Git environment probes ---
90
- export async function isGitInstalled(): Promise<boolean> {
91
- try {
92
- await spawnWithOutput('git', ['--version'], {});
93
- return true;
94
- } catch {
95
- return false;
96
- }
97
- }
98
-
99
- export async function isInsideGitRepo(cwd: string): Promise<boolean> {
100
- try {
101
- if (!(await isGitInstalled())) return false;
102
- const { stdout } = await spawnWithOutput('git', ['rev-parse', '--is-inside-work-tree'], { cwd });
103
- return stdout.trim() === 'true';
104
- } catch {
105
- return false;
106
- }
107
- }
108
-
109
- // Variant of spawn that captures stdout and stderr
110
- export function spawnWithOutput(
111
- command: string,
112
- args: string[],
113
- options: SpawnOptions,
114
- ): Promise<{ stdout: string; stderr: string; code: number }> {
115
- return new Promise((resolvePromise, rejectPromise) => {
116
- const childProcess = nodeSpawn(command, args, {
117
- ...options,
118
- });
119
- let stdout = '';
120
- let stderr = '';
121
- childProcess.on('error', error => {
122
- rejectPromise(error);
123
- });
124
- childProcess.stdout?.on('data', chunk => {
125
- process.stdout.write(chunk);
126
- stdout += chunk?.toString?.() ?? String(chunk);
127
- });
128
- childProcess.stderr?.on('data', chunk => {
129
- stderr += chunk?.toString?.() ?? String(chunk);
130
- process.stderr.write(chunk);
131
- });
132
- childProcess.on('close', code => {
133
- if (code === 0) {
134
- resolvePromise({ stdout, stderr, code: code ?? 0 });
135
- } else {
136
- const err = new Error(stderr || `Command failed: ${command} ${args.join(' ')}`);
137
- // @ts-expect-error augment
138
- err.code = code;
139
- rejectPromise(err);
140
- }
141
- });
142
- });
143
- }
144
-
145
- export async function spawnSWPM(cwd: string, command: string, packageNames: string[]) {
146
- // 1) Try local swpm module resolution/execution
147
- try {
148
- console.log('Running install command with swpm');
149
- const swpmPath = createRequire(import.meta.filename).resolve('swpm');
150
- await spawn(swpmPath, [command, ...packageNames], { cwd });
151
- return;
152
- } catch (e) {
153
- console.log('Failed to run install command with swpm', e);
154
- // ignore and try fallbacks
155
- }
156
-
157
- // 2) Fallback to native package manager based on lock files
158
- try {
159
- // Detect package manager from lock files
160
- let packageManager: string;
161
-
162
- if (existsSync(resolve(cwd, 'pnpm-lock.yaml'))) {
163
- packageManager = 'pnpm';
164
- } else if (existsSync(resolve(cwd, 'yarn.lock'))) {
165
- packageManager = 'yarn';
166
- } else {
167
- packageManager = 'npm';
168
- }
169
-
170
- // Normalize command
171
- let nativeCommand = command === 'add' ? 'add' : command === 'install' ? 'install' : command;
172
-
173
- // Build args with non-interactive flags for install commands
174
- const args = [nativeCommand];
175
- if (nativeCommand === 'install') {
176
- const inWorkspace = isInWorkspaceSubfolder(cwd);
177
- if (packageManager === 'pnpm') {
178
- args.push('--force'); // pnpm install --force
179
-
180
- // Check if we're in a workspace subfolder
181
- if (inWorkspace) {
182
- args.push('--ignore-workspace');
183
- }
184
- } else if (packageManager === 'npm') {
185
- args.push('--yes'); // npm install --yes
186
-
187
- // Check if we're in a workspace subfolder
188
- if (inWorkspace) {
189
- args.push('--ignore-workspaces');
190
- }
191
- }
192
- }
193
- args.push(...packageNames);
194
-
195
- console.log(`Falling back to ${packageManager} ${args.join(' ')}`);
196
- await spawn(packageManager, args, { cwd });
197
- return;
198
- } catch (e) {
199
- console.log(`Failed to run install command with native package manager: ${e}`);
200
- }
201
-
202
- throw new Error(`Failed to run install command with swpm and native package managers`);
203
- }
204
-
205
- // Utility functions
206
- export function kindWeight(kind: UnitKind): number {
207
- const idx = UNIT_KINDS.indexOf(kind as any);
208
- return idx === -1 ? UNIT_KINDS.length : idx;
209
- }
210
-
211
- // Utility functions to work with Mastra templates
212
- export async function fetchMastraTemplates(): Promise<
213
- Array<{
214
- slug: string;
215
- title: string;
216
- description: string;
217
- githubUrl: string;
218
- tags: string[];
219
- agents: string[];
220
- workflows: string[];
221
- tools: string[];
222
- }>
223
- > {
224
- try {
225
- const response = await fetch('https://mastra.ai/api/templates.json');
226
- const data = (await response.json()) as Array<{
227
- slug: string;
228
- title: string;
229
- description: string;
230
- githubUrl: string;
231
- tags: string[];
232
- agents: string[];
233
- workflows: string[];
234
- tools: string[];
235
- }>;
236
- return data;
237
- } catch (error) {
238
- throw new Error(`Failed to fetch Mastra templates: ${error instanceof Error ? error.message : String(error)}`);
239
- }
240
- }
241
-
242
- // Helper to get a specific template by slug
243
- export async function getMastraTemplate(slug: string) {
244
- const templates = await fetchMastraTemplates();
245
- const template = templates.find(t => t.slug === slug);
246
- if (!template) {
247
- throw new Error(`Template "${slug}" not found. Available templates: ${templates.map(t => t.slug).join(', ')}`);
248
- }
249
- return template;
250
- }
251
-
252
- // Git commit tracking utility
253
- export async function logGitState(targetPath: string, label: string): Promise<void> {
254
- try {
255
- // Skip if not a git repo
256
- if (!(await isInsideGitRepo(targetPath))) return;
257
- const gitStatusResult = await git(targetPath, 'status', '--porcelain');
258
- const gitLogResult = await git(targetPath, 'log', '--oneline', '-3');
259
- const gitCountResult = await git(targetPath, 'rev-list', '--count', 'HEAD');
260
-
261
- console.log(`📊 Git state ${label}:`);
262
- console.log('Status:', gitStatusResult.stdout.trim() || 'Clean working directory');
263
- console.log('Recent commits:', gitLogResult.stdout.trim());
264
- console.log('Total commits:', gitCountResult.stdout.trim());
265
- } catch (gitError) {
266
- console.warn(`Could not get git state ${label}:`, gitError);
267
- }
268
- }
269
-
270
- // Generic git runner that captures stdout/stderr
271
- export async function git(cwd: string, ...args: string[]): Promise<{ stdout: string; stderr: string }> {
272
- const { stdout, stderr } = await spawnWithOutput('git', args, { cwd });
273
- return { stdout: stdout ?? '', stderr: stderr ?? '' };
274
- }
275
-
276
- // Common git helpers
277
- export async function gitClone(repo: string, destDir: string, cwd?: string) {
278
- await git(cwd ?? process.cwd(), 'clone', repo, destDir);
279
- }
280
-
281
- export async function gitCheckoutRef(cwd: string, ref: string) {
282
- if (!(await isInsideGitRepo(cwd))) return;
283
- await git(cwd, 'checkout', ref);
284
- }
285
-
286
- export async function gitRevParse(cwd: string, rev: string): Promise<string> {
287
- if (!(await isInsideGitRepo(cwd))) return '';
288
- const { stdout } = await git(cwd, 'rev-parse', rev);
289
- return stdout.trim();
290
- }
291
-
292
- export async function gitAddFiles(cwd: string, files: string[]) {
293
- if (!files || files.length === 0) return;
294
- if (!(await isInsideGitRepo(cwd))) return;
295
- await git(cwd, 'add', ...files);
296
- }
297
-
298
- export async function gitAddAll(cwd: string) {
299
- if (!(await isInsideGitRepo(cwd))) return;
300
- await git(cwd, 'add', '.');
301
- }
302
-
303
- export async function gitHasStagedChanges(cwd: string): Promise<boolean> {
304
- if (!(await isInsideGitRepo(cwd))) return false;
305
- const { stdout } = await git(cwd, 'diff', '--cached', '--name-only');
306
- return stdout.trim().length > 0;
307
- }
308
-
309
- export async function gitCommit(
310
- cwd: string,
311
- message: string,
312
- opts?: { allowEmpty?: boolean; skipIfNoStaged?: boolean },
313
- ): Promise<boolean> {
314
- try {
315
- if (!(await isInsideGitRepo(cwd))) return false;
316
- if (opts?.skipIfNoStaged) {
317
- const has = await gitHasStagedChanges(cwd);
318
- if (!has) return false;
319
- }
320
- const args = ['commit', '-m', message];
321
- if (opts?.allowEmpty) args.push('--allow-empty');
322
- await git(cwd, ...args);
323
- return true;
324
- } catch (e) {
325
- const msg = e instanceof Error ? e.message : String(e);
326
- if (/nothing to commit/i.test(msg) || /no changes added to commit/i.test(msg)) {
327
- return false;
328
- }
329
- throw e;
330
- }
331
- }
332
-
333
- export async function gitAddAndCommit(
334
- cwd: string,
335
- message: string,
336
- files?: string[],
337
- opts?: { allowEmpty?: boolean; skipIfNoStaged?: boolean },
338
- ): Promise<boolean> {
339
- try {
340
- if (!(await isInsideGitRepo(cwd))) return false;
341
- if (files && files.length > 0) {
342
- await gitAddFiles(cwd, files);
343
- } else {
344
- await gitAddAll(cwd);
345
- }
346
- return gitCommit(cwd, message, opts);
347
- } catch (e) {
348
- console.error(`Failed to add and commit files: ${e instanceof Error ? e.message : String(e)}`);
349
- return false;
350
- }
351
- }
352
-
353
- export async function gitCheckoutBranch(branchName: string, targetPath: string) {
354
- try {
355
- if (!(await isInsideGitRepo(targetPath))) return;
356
- // Try to create new branch using centralized git runner
357
- await git(targetPath, 'checkout', '-b', branchName);
358
- console.log(`Created new branch: ${branchName}`);
359
- } catch (error) {
360
- // If branch exists, check if we can switch to it or create a unique name
361
- const errorStr = error instanceof Error ? error.message : String(error);
362
- if (errorStr.includes('already exists')) {
363
- try {
364
- // Try to switch to existing branch
365
- await git(targetPath, 'checkout', branchName);
366
- console.log(`Switched to existing branch: ${branchName}`);
367
- } catch {
368
- // If can't switch, create a unique branch name
369
- const timestamp = Date.now().toString().slice(-6);
370
- const uniqueBranchName = `${branchName}-${timestamp}`;
371
- await git(targetPath, 'checkout', '-b', uniqueBranchName);
372
- console.log(`Created unique branch: ${uniqueBranchName}`);
373
- }
374
- } else {
375
- throw error; // Re-throw if it's a different error
376
- }
377
- }
378
- }
379
-
380
- // File conflict resolution utilities (for future use)
381
- export async function backupAndReplaceFile(sourceFile: string, targetFile: string): Promise<void> {
382
- // Create backup of existing file
383
- const backupFile = `${targetFile}.backup-${Date.now()}`;
384
- await copyFile(targetFile, backupFile);
385
- console.log(`📦 Created backup: ${basename(backupFile)}`);
386
-
387
- // Replace with template file
388
- await copyFile(sourceFile, targetFile);
389
- console.log(`🔄 Replaced file with template version (backup created)`);
390
- }
391
-
392
- export async function renameAndCopyFile(sourceFile: string, targetFile: string): Promise<string> {
393
- // Find unique filename
394
- let counter = 1;
395
- let uniqueTargetFile = targetFile;
396
- const baseName = basename(targetFile, extname(targetFile));
397
- const extension = extname(targetFile);
398
- const directory = dirname(targetFile);
399
-
400
- while (existsSync(uniqueTargetFile)) {
401
- const uniqueName = `${baseName}.template-${counter}${extension}`;
402
- uniqueTargetFile = resolve(directory, uniqueName);
403
- counter++;
404
- }
405
-
406
- await copyFile(sourceFile, uniqueTargetFile);
407
- console.log(`📝 Copied with unique name: ${basename(uniqueTargetFile)}`);
408
- return uniqueTargetFile;
409
- }
@@ -1 +0,0 @@
1
- export * from './template-builder';