aided-dev 1.0.3 → 1.0.5
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/dist/bmad/loader.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export declare class BMADLoader {
|
|
|
59
59
|
getPath(): string | undefined;
|
|
60
60
|
getFormatType(): 'npm' | 'local' | 'unknown';
|
|
61
61
|
listAgents(): Promise<string[]>;
|
|
62
|
+
listProjectAgents(): Promise<string[]>;
|
|
62
63
|
loadAgent(name: string): Promise<AgentConfig | undefined>;
|
|
63
64
|
loadAgents(names: string[]): Promise<Map<string, AgentConfig>>;
|
|
64
65
|
getLoadedAgents(): Map<string, AgentConfig>;
|
package/dist/bmad/loader.js
CHANGED
|
@@ -149,6 +149,11 @@ export class BMADLoader {
|
|
|
149
149
|
this.agentsPaths = [localAgentsPath];
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
+
const projectAgentsDir = path.join(process.cwd(), 'agents');
|
|
153
|
+
if (fs.existsSync(projectAgentsDir)) {
|
|
154
|
+
this.agentsPaths.push(projectAgentsDir);
|
|
155
|
+
}
|
|
156
|
+
this.agentsPaths.push(process.cwd());
|
|
152
157
|
}
|
|
153
158
|
isAvailable() {
|
|
154
159
|
return !!this.bmadPath && this.agentsPaths.length > 0;
|
|
@@ -176,6 +181,31 @@ export class BMADLoader {
|
|
|
176
181
|
}
|
|
177
182
|
return [...new Set(agents)];
|
|
178
183
|
}
|
|
184
|
+
async listProjectAgents() {
|
|
185
|
+
const agents = [];
|
|
186
|
+
const cwd = process.cwd();
|
|
187
|
+
const agentsDir = path.join(cwd, 'agents');
|
|
188
|
+
if (fs.existsSync(agentsDir)) {
|
|
189
|
+
const files = await fs.readdir(agentsDir);
|
|
190
|
+
for (const file of files) {
|
|
191
|
+
if (file.endsWith('.md') && !file.startsWith('_')) {
|
|
192
|
+
agents.push(file.replace('.md', ''));
|
|
193
|
+
}
|
|
194
|
+
else if (file.endsWith('.agent.yaml')) {
|
|
195
|
+
agents.push(file.replace('.agent.yaml', ''));
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (fs.existsSync(cwd)) {
|
|
200
|
+
const files = await fs.readdir(cwd);
|
|
201
|
+
for (const file of files) {
|
|
202
|
+
if (file.endsWith('.agent.yaml')) {
|
|
203
|
+
agents.push(file.replace('.agent.yaml', ''));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return [...new Set(agents)];
|
|
208
|
+
}
|
|
179
209
|
async loadAgent(name) {
|
|
180
210
|
if (this.agentCache.has(name)) {
|
|
181
211
|
return this.agentCache.get(name);
|
package/dist/cli.js
CHANGED
|
@@ -161,6 +161,21 @@ program
|
|
|
161
161
|
if (allAgents.length > agentNames.length) {
|
|
162
162
|
console.log(chalk.dim(`Other available agents: ${allAgents.filter(a => !agentNames.includes(a)).join(', ')}`));
|
|
163
163
|
}
|
|
164
|
+
const projectAgents = await loader.listProjectAgents();
|
|
165
|
+
if (projectAgents.length > 0) {
|
|
166
|
+
console.log('');
|
|
167
|
+
console.log(chalk.bold('Custom Project Agents'));
|
|
168
|
+
console.log(chalk.dim(`Location: ${process.cwd()}`));
|
|
169
|
+
console.log('');
|
|
170
|
+
for (const agentName of projectAgents) {
|
|
171
|
+
const agent = await loader.loadAgent(agentName);
|
|
172
|
+
if (agent) {
|
|
173
|
+
console.log(`${agent.icon} ${chalk.green(agent.name)} - ${agent.title}`);
|
|
174
|
+
console.log(chalk.dim(` Role: ${agent.persona.role}`));
|
|
175
|
+
console.log('');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
164
179
|
});
|
|
165
180
|
program
|
|
166
181
|
.command('create-agent')
|
|
@@ -12,6 +12,7 @@ export interface WorkflowState {
|
|
|
12
12
|
repoPath: string;
|
|
13
13
|
projectDocuments?: ProjectDocuments;
|
|
14
14
|
stack?: ProjectStack;
|
|
15
|
+
repoFiles?: Map<string, string>;
|
|
15
16
|
plan?: ExecutionPlan;
|
|
16
17
|
outputs: Map<string, string>;
|
|
17
18
|
errors: string[];
|
|
@@ -34,6 +35,8 @@ export declare class Orchestrator {
|
|
|
34
35
|
private phasePlanning;
|
|
35
36
|
private executeplan;
|
|
36
37
|
private executeStep;
|
|
38
|
+
private scanRepository;
|
|
39
|
+
private scanDirectory;
|
|
37
40
|
private buildContext;
|
|
38
41
|
private formatOutputTitle;
|
|
39
42
|
private buildStepPrompt;
|
|
@@ -92,11 +92,16 @@ export class Orchestrator {
|
|
|
92
92
|
state.stack = await detectStack(this.repoPath);
|
|
93
93
|
spinner.text = `Detected: ${state.stack.language}`;
|
|
94
94
|
state.projectDocuments = await discoverProjectDocuments(this.repoPath);
|
|
95
|
+
spinner.text = 'Scanning repository files...';
|
|
96
|
+
state.repoFiles = await this.scanRepository();
|
|
95
97
|
spinner.succeed(chalk.green('Discovery complete'));
|
|
96
98
|
console.log(chalk.dim(` Language: ${state.stack.language}`));
|
|
97
99
|
if (state.stack.framework) {
|
|
98
100
|
console.log(chalk.dim(` Framework: ${state.stack.framework}`));
|
|
99
101
|
}
|
|
102
|
+
if (state.repoFiles && state.repoFiles.size > 0) {
|
|
103
|
+
console.log(chalk.dim(` Scanned ${state.repoFiles.size} source files`));
|
|
104
|
+
}
|
|
100
105
|
if (state.projectDocuments) {
|
|
101
106
|
const docCount = [
|
|
102
107
|
state.projectDocuments.brownfieldArchitecture,
|
|
@@ -219,6 +224,72 @@ export class Orchestrator {
|
|
|
219
224
|
}
|
|
220
225
|
}
|
|
221
226
|
}
|
|
227
|
+
async scanRepository() {
|
|
228
|
+
const files = new Map();
|
|
229
|
+
const keyFiles = [
|
|
230
|
+
'package.json', 'tsconfig.json', 'pyproject.toml', 'requirements.txt',
|
|
231
|
+
'Cargo.toml', 'go.mod', 'pom.xml', 'build.gradle',
|
|
232
|
+
'.env.example', 'docker-compose.yml', 'Dockerfile',
|
|
233
|
+
'README.md', 'CLAUDE.md',
|
|
234
|
+
];
|
|
235
|
+
const keyDirs = ['src', 'app', 'lib', 'routes', 'controllers', 'models', 'services', 'api'];
|
|
236
|
+
for (const file of keyFiles) {
|
|
237
|
+
const filePath = path.join(this.repoPath, file);
|
|
238
|
+
if (fs.existsSync(filePath)) {
|
|
239
|
+
try {
|
|
240
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
241
|
+
if (content.length < 10000) {
|
|
242
|
+
files.set(file, content);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const dir of keyDirs) {
|
|
250
|
+
const dirPath = path.join(this.repoPath, dir);
|
|
251
|
+
if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
|
|
252
|
+
await this.scanDirectory(dirPath, files, dir, 3);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return files;
|
|
256
|
+
}
|
|
257
|
+
async scanDirectory(dirPath, files, relativePath, maxDepth) {
|
|
258
|
+
if (maxDepth <= 0 || files.size > 50)
|
|
259
|
+
return;
|
|
260
|
+
const sourceExtensions = ['.ts', '.js', '.py', '.go', '.rs', '.java', '.rb', '.php'];
|
|
261
|
+
try {
|
|
262
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
263
|
+
for (const entry of entries) {
|
|
264
|
+
if (entry.name.startsWith('.') || entry.name === 'node_modules' || entry.name === '__pycache__') {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
268
|
+
const relPath = path.join(relativePath, entry.name);
|
|
269
|
+
if (entry.isDirectory()) {
|
|
270
|
+
await this.scanDirectory(fullPath, files, relPath, maxDepth - 1);
|
|
271
|
+
}
|
|
272
|
+
else if (entry.isFile()) {
|
|
273
|
+
const ext = path.extname(entry.name);
|
|
274
|
+
if (sourceExtensions.includes(ext)) {
|
|
275
|
+
try {
|
|
276
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
277
|
+
if (content.length < 8000) {
|
|
278
|
+
files.set(relPath, content);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
files.set(relPath, content.substring(0, 8000) + '\n\n... (truncated)');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
}
|
|
292
|
+
}
|
|
222
293
|
buildContext(state, step) {
|
|
223
294
|
const parts = [];
|
|
224
295
|
if (state.stack) {
|
|
@@ -228,6 +299,16 @@ export class Orchestrator {
|
|
|
228
299
|
if (state.projectDocuments) {
|
|
229
300
|
parts.push('\n' + formatDocumentsForPrompt(state.projectDocuments));
|
|
230
301
|
}
|
|
302
|
+
if (state.repoFiles && state.repoFiles.size > 0) {
|
|
303
|
+
parts.push('\n## Repository Files');
|
|
304
|
+
parts.push(`Found ${state.repoFiles.size} key files in the repository:\n`);
|
|
305
|
+
for (const [filePath, content] of state.repoFiles) {
|
|
306
|
+
parts.push(`### ${filePath}`);
|
|
307
|
+
parts.push('```');
|
|
308
|
+
parts.push(content);
|
|
309
|
+
parts.push('```\n');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
231
312
|
for (const dep of step.dependsOn) {
|
|
232
313
|
const depOutput = state.outputs.get(dep);
|
|
233
314
|
if (depOutput) {
|