@mastra/agent-builder 0.0.1-alpha.1 → 0.0.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/agent/index.d.ts +5885 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/defaults.d.ts +6529 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1810 -36
- package/dist/index.js.map +1 -0
- package/dist/processors/tool-summary.d.ts +29 -0
- package/dist/processors/tool-summary.d.ts.map +1 -0
- package/dist/processors/write-file.d.ts +10 -0
- package/dist/processors/write-file.d.ts.map +1 -0
- package/dist/types.d.ts +1121 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils.d.ts +63 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/workflows/index.d.ts +5 -0
- package/dist/workflows/index.d.ts.map +1 -0
- package/dist/workflows/shared/schema.d.ts +139 -0
- package/dist/workflows/shared/schema.d.ts.map +1 -0
- package/dist/workflows/task-planning/prompts.d.ts +37 -0
- package/dist/workflows/task-planning/prompts.d.ts.map +1 -0
- package/dist/workflows/task-planning/schema.d.ts +548 -0
- package/dist/workflows/task-planning/schema.d.ts.map +1 -0
- package/dist/workflows/task-planning/task-planning.d.ts +992 -0
- package/dist/workflows/task-planning/task-planning.d.ts.map +1 -0
- package/dist/workflows/template-builder/template-builder.d.ts +1910 -0
- package/dist/workflows/template-builder/template-builder.d.ts.map +1 -0
- package/dist/workflows/workflow-builder/prompts.d.ts +44 -0
- package/dist/workflows/workflow-builder/prompts.d.ts.map +1 -0
- package/dist/workflows/workflow-builder/schema.d.ts +1170 -0
- package/dist/workflows/workflow-builder/schema.d.ts.map +1 -0
- package/dist/workflows/workflow-builder/tools.d.ts +309 -0
- package/dist/workflows/workflow-builder/tools.d.ts.map +1 -0
- package/dist/workflows/workflow-builder/workflow-builder.d.ts +2714 -0
- package/dist/workflows/workflow-builder/workflow-builder.d.ts.map +1 -0
- package/dist/workflows/workflow-map.d.ts +3735 -0
- package/dist/workflows/workflow-map.d.ts.map +1 -0
- package/package.json +20 -9
- package/.turbo/turbo-build.log +0 -12
- package/dist/_tsup-dts-rollup.d.cts +0 -14933
- package/dist/_tsup-dts-rollup.d.ts +0 -14933
- package/dist/index.cjs +0 -4357
- package/dist/index.d.cts +0 -4
- package/eslint.config.js +0 -11
- package/integration-tests/CHANGELOG.md +0 -9
- package/integration-tests/README.md +0 -154
- package/integration-tests/docker-compose.yml +0 -39
- package/integration-tests/package.json +0 -38
- package/integration-tests/src/agent-template-behavior.test.ts +0 -103
- package/integration-tests/src/fixtures/minimal-mastra-project/env.example +0 -6
- package/integration-tests/src/fixtures/minimal-mastra-project/package.json +0 -17
- package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/agents/weather.ts +0 -34
- package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/index.ts +0 -15
- package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/mcp/index.ts +0 -46
- package/integration-tests/src/fixtures/minimal-mastra-project/src/mastra/tools/weather.ts +0 -14
- package/integration-tests/src/fixtures/minimal-mastra-project/tsconfig.json +0 -17
- package/integration-tests/src/template-integration.test.ts +0 -312
- package/integration-tests/tsconfig.json +0 -9
- package/integration-tests/vitest.config.ts +0 -18
- package/src/agent/index.ts +0 -187
- package/src/agent-builder.test.ts +0 -313
- package/src/defaults.ts +0 -2876
- package/src/index.ts +0 -3
- package/src/processors/tool-summary.ts +0 -145
- package/src/processors/write-file.ts +0 -17
- package/src/types.ts +0 -305
- package/src/utils.ts +0 -409
- package/src/workflows/index.ts +0 -1
- package/src/workflows/template-builder.ts +0 -1682
- package/tsconfig.json +0 -5
- 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
|
-
}
|
package/src/workflows/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './template-builder';
|